Ruby, iOS, and Other Development

A place to share useful code snippets, ideas, and techniques

All code in posted articles shall be considered public domain unless otherwise noted.
Comments remain the property of their authors.

2008-03-08

SSL Certificates and Net::HTTPS

I was getting tired of seeing "warning: peer certificate won't be verified in this SSL session" from Ruby's net/https library, so I started looking around for how to get it to actually verify the SSL certificate. I found lots of links on how to tell it not to bother verifying, but it wasn't until I found someone's Japanese blog that I found the clue I was looking for. Now, I don't know Japanese, but I can read Ruby. For the benefit of other English speakers/readers out there, I now present the solution.

First off, I'm giving a full example request using basic authentication (not that GMail uses basic authentication, but this is an example) because I was unable to find a good example elsewhere and made it this far by trial and error. The following will produce the warning I mentioned:

require 'net/http'
require 'net/https'
require 'uri'

url = URI.parse 'https://myname:mypass@mail.google.com/'
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme == 'https')
request = Net::HTTP::Get.new(url.path)
request.basic_auth url.user, url.password
response = http.request(request)

To avoid the warning, we can either tell it not to warn us and blithely accept whatever certificate we receive, or we can give it enough information to authenticate the certificate against the root CA certificates. In the following example, we'll do both. If we find the file /usr/share/curl/curl-ca-bundle.crt then we will verify, otherwise we will silently ignore the issue:

require 'net/http'
require 'net/https'
require 'uri'

RootCA = '/usr/share/curl/curl-ca-bundle.crt'

url = URI.parse 'https://myname:mypass@mail.google.com/'
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme == 'https')
if File.exist? RootCA
 http.ca_file = RootCA
 http.verify_mode = OpenSSL::SSL::VERIFY_PEER
 http.verify_depth = 5
else
 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
request = Net::HTTP::Get.new(url.path)
request.basic_auth url.user, url.password
response = http.request(request)

And there you have it. Not all that complicated, but poorly documented. Now it's more findably (i.e. Googleably) documented. Enjoy!

Update 2009-05-21: Thanks to a comment from Chewi, here's an even better approach:

require 'net/http'
require 'net/https'
require 'uri'

RootCA = '/etc/ssl/certs'

url = URI.parse 'https://myname:mypass@mail.google.com/'
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme == 'https')
if File.directory? RootCA
  http.ca_path = RootCA
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
  http.verify_depth = 5
else
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
request = Net::HTTP::Get.new(url.path)
request.basic_auth url.user, url.password
response = http.request(request)

Labels: ,

2008-03-03

CalTerm: Ncurses Calendaring

It's no iCal-killer, but I needed something to let me at least view my ical calendars from the terminal. At this point, other than bugs that can be traced to vpim (having to do with recurring events that hit the wrong days, e.g. leap day), it works. It's far from my first Ruby code, but it's my first public Ruby project.

That's the good news. The bad news is that it's definitely still rough around the edges, it isn't packaged in any way, and you'll have to install the vpim and ncurses gems to use it. Grab it from subversion at http://calterm.rubyforge.org/svn/trunk/ or start at the CalTerm home page.

This is sort of a preliminary announcement before I've figured out how I want to package it, so there's no release version.

Enjoy!

Labels: , , ,