Stuff… And Things…

I do... stuff and build... things.

Building Ruby 1.8.7 on FreeBSD 10

| Comments

If you try to build Ruby 1.8.7 with RVM you will see:

1
2
3
4
5
# rvm install 1.8.7
[...]
./lib/fileutils.rb:1430: [BUG] unexpected local variable
ruby 1.8.7 (2012-02-08 patchlevel 375) [amd-freebsd10]
*** [./.rbconfig.time] Signal 6

This is because FreeBSD 10 ships with the Clang compiler instead of GCC and Ruby versions priory to 1.9.3-p194 do not support Clang.

The work-around, is to install GCC, either with pkg:

1
# pkg install gcc

or from Ports:

1
2
# cd /usr/ports/lang/gcc
# make install clean

Once you have gcc you can install 1.8.7 with:

1
# CC=/usr/local/bin/gcc47 rvm install 1.8.7

This should work with older versions of Ruby 1.9 as well.

What on earth would you want to install 1.8.7? Two words: Legacy Apps…

Dynamic Keys for Strongbox

| Comments

Previously, Strongbox, my gem for using Public Key Encryption with ActiveRecord, allowed only one key pair for encrypting all of the records for a given ActiveRecord model. I’ve had a number of requests to make it possible to dynamically choose the keys on a per record basic and version 0.6.0 adds this feature.

The values of :public_key, :private_key, and :key_pair can be in one of the following formats:

A string containing path to a file. This is the default interpretation of a string.

1
2
encrypt_with_public_key :secret,
   :key_pair => File.join(RAILS_ROOT,'config','keypair.pem')

A string contanting a key in PEM format, needs to match this the regex /^-+BEGIN .* KEY-+$/

1
2
3
encrypt_with_public_key :secret,
  :key_pair =>
    "-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,BFE700E4DDA4C434\n\nDfZD7FKM4zLJdb[...]"

A symbol naming a method to call. Can return any of the other valid key formats.

1
2
3
encrypt_with_public_key :secret,
  :public_key => :public_key_method,
  :private_key => :private_key_attribute

An instance of OpenSSL::PKey::RSA. Must be unlocked to be used as the private key.

1
2
3
4
KEY_PAIR = OpenSSL::PKey::RSA.new(key,password)
# [...]
encrypt_with_public_key :secret,
   :key_pair => KEY_PAIR

Using this, you can automatically create per record public keys:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
require 'openssl'

# Assumes the migration contains:
#  t.string :description
#  t.binary :secret
# that you are collecting a password to encrypt the private key,
# and that the secret is small

class User < ActiveRecord::Base
  attr_accessor :password
  encrypt_with_public_key :secret,
    :key_pair => :key_pair

  def after_initialize
     rsa_key = OpenSSL::PKey::RSA.new(2048)
     cipher =  OpenSSL::Cipher::Cipher.new('des3')
     key_pair = rsa_key.to_pem(cipher,self.password) + rsa_key.public_key.to_pem
  end
end

Important Caveat – Currently, Strongbox encrypts the attribute as soon as it’s assigned (this will change in version 1.0). The means that the public key must be available before the attribute is assigned, hence the use of after_initialize to generate the key pair. Even so, this will fail if you do something like:

1
user = User.new(params[:user])

because the attributes are set before after_initialize is called.

Instead, use something like:

1
2
3
user = User.new
user.password = params[:password]
user.attributes = params[:user]

Version 1.0 will allow you to control when the encryption occurs, making this less of an issue.

Building Emacs.App From Source on OS X Lion

| Comments

As always, I like building Emacs for my Mac from source. It lets me live on the cutting edge and have tigher control of the version I’m running. If building software from source isn’t your thing then skip the rest of this article and consider installing Emacs using Homebrew, MacPorts, or Fink

I’ve written about building Emacs in the past, but OS X Lion brings a few complexities to the process.

Octopress Blog Re-Launch

| Comments

After years of running on Wordpress, today I’m relaunching my blog using Octopress. Octopress is a blogging framework build on top of Jekyll which in turn is system designed for publishing static sites from source files, be they Markdown, HAML, SASS, etc. This style fits nicely in to my everyday workflow, so my hope is it will get me writing on a regular basis.

Wordpress is great if you want a WYSIWYG blog and I still recommend to my clients. But, if you spend your days in Emacs or Vim, running rake tasks and git commits, you might want to give Octopress a try.

Legacy Development With Pow

| Comments

Pow is a zero-config Rack server that makes developing Rack apps (include Rails apps) a snap on Mac OS X.

You install Pow:

1
curl get.pow.cx | sh

You create a symlink to your app:

1
2
cd ~/.pow
ln -s ~/dev/myapp

You point your browser to http://myapp.dev/ and there’s you app!   Awesome!

However, there is a downside:  Pow doesn’t play nicely with Apache (or any server listening on port 80). Life isn’t all greenfield, if in the course of the day you need to work on PHP or CGI legacy apps Pow is not so simple.   Pow creates a firewall rule that redirects port 80 to its port; to access Apache you need to either toggle the firewall rule on and off or move Apache to a different port all together. And now you’re running two web servers.  There has to be a better way.

The Win And there is, make your legacy app a Rack App.  Thanks to the rack-legacy gem, this is actually quite simple.

First, install the rack-legacy and rack-rewrite gems:

1
gem install rack-legacy rack-rewrite

(To sudo or not to sudo, that’s up to you).

Next,  in the top level of your legacy app create this config.ru file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
require 'rack'
require 'rack-legacy'
require 'rack-rewrite'

INDEXES = ['index.html','index.php', 'index.cgi']

use Rack::Rewrite do
  rewrite %r{(.*/$)}, lambda {|match, rack_env|
    INDEXES.each do |index|
      if File.exists?(File.join(Dir.getwd, rack_env['PATH_INFO'], index))
        return rack_env['PATH_INFO'] + index
      end
    end
    rack_env['PATH_INFO']
  }
end

use Rack::Legacy::Php, Dir.getwd
use Rack::Legacy::Cgi, Dir.getwd
run Rack::File.new Dir.getwd

The Details Rack::Legacy::Php runs any requested file with the extension .php. Rack::Legacy::Cgi runs any requested file that is set executable (which means you’ll need to make sure your .html files are not). Files that don’t end in .php and aren’t executable are served as static content by Rack::File.

The INDEXES array contains a list of files to check for if a directory is requested (just like Apache’s DirectoryIndex directive). You can change the order or use different names (default.htm anyone?).

The Catch rack-legacy uses the php-cgi command line program to run scripts and while PHP ships with current versions of OS X, php-cgi is not included. You’ll need to install PHP using MacPort/Homebrew/Fink/etc. That’s beyond the scope of this post but, if you’re doing this kind of development, it’s probably not beyond you.

The Caveat This is probably not a fast as running PHP using the Apache module and it’s certainly not as fast as something like FastCGI. If you are primarily developing legacy apps you probably should stick to Apache. However, if you mostly work with Rack apps and just occasionally need legacy support, this is a great way to go.

Deploying “Modular” Style Sinatra Apps With Phusion Passenger

| Comments

There’s plenty of documentation on how to deploy “Classic” style Sintra applications with Phusion Passenger, but it’s not immediately obviously how to deploy the new “Modular” style app (created with Sinatra::Base). Fortunately, it’s simple, the resulting class can be passed to “run” inside you “config.ru” file, something like:

1
2
3
4
require 'rubygems'
require File.join(File.dirname(__FILE__), 'lib/my_app')

run MyApp

That’s it.

Instructions you find for “Classic” Sintra apps have you setting “:env” to the ENV[‘RACK_ENV’] before running the app. As of Sintra 1.0 it’s “:environment” and it’s automatically set to ENV[‘RACK_ENV’] (or “:development” if RACK_ENV is not set). You’ll also see instructions for setting “:run” to false, this is not nessecary for “Modular” apps.

Handling 403 Forbidden Login Pages With (Ruby) Mechanize

| Comments

Instead of having a dedicated login page, some sites return a 403 Forbidden HTTP status code and include the login form in an HTML body of a custom 403 page. For example, Drupal admin pages work this way. While this may seem a little odd, it works; all modern browser will display the HTML and few, if any, will note the Forbidden status.

Mechanize on the other hand raise an exception when it receives a 403 status. Fortunately, it returns the page it received as part of that exception. Here’s how to handle it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mechanize = Mechanize.new

begin
  login_page = mechanize.get("http://localhost/admin")
rescue Mechanize::ResponseCodeError => exception
  if exception.response_code == '403'
    login_page = exception.page
  else
    raise # Some other error, re-raise
  end
end
login = login_page.form_with(:action => '/login') do |f|
  f.field_with(:name => 'user').value = user
  f.field_with(:name => 'password').value = password
end.submit
raise 'Login Failed' if login.body !~ /Logged in!/

This code also works in the case where you don’t get a forbidden status, so it can be used generically.

For bonus points you can use the same code in a Cucumber step by changing:

1
login_page = mechanize.get("http://localhost/admin")

to:

1
login_page = webrat.adapter.mechanize.get(path_to('the admin page'))

(assuming you’ve set up “the admin page” in paths.rb).

Generating RSA Key Pairs in Ruby

| Comments

I’ve given a number of examples of using Public-key cryptography in blog posts and in the Strongbox documentation, but I’ve always generated the RSA key pair using the openssl command line tool, i.e.

1
2
3
4
5
6
7
8
9
% openssl genrsa -des3 -out private.pem 2048
Generating RSA private key, 2048 bit long modulus
......+++
.+++
e is 65537 (0x10001)
Enter pass phrase for private.pem:
Verifying - Enter pass phrase for private.pem:
% openssl rsa -in private.pem -out public.pem -outform PEM -pubout
% cat private.pem public.pem > key_pair.pem

This is fine if you want to generate a key pair once, but what if you want to do it on the fly? The Ruby OpenSSL library has support for generating key pairs:

1
2
require 'openssl'
rsa_key = OpenSSL::PKey::RSA.new(2048)

2048 is the key size, and a good value to use for it.

What’s not obvious is how to encrypt the private key.   You don’t have to encrypt it, but, if you don’t, anyone who gets a hold of the key can decrypt your data.  Using an unencrypted private key gives you one layer of security (something you have – the key), encrypting it gives you an additional layer (something you know – the password).

To encrypt the private key you need a Cipher object:

1
cipher =  OpenSSL::Cipher::Cipher.new('des3')

Then, using the Cipher object, you convert the the key_pair to PEM format:

1
2
3
private_key = rsa_key.to_pem(cipher,'password')
public_key = rsa_key.public_key.to_pem
key_pair = private_key + public_key

The resulting PEM strings be saved and then later fed to OpenSSL::PKey::RSA.new() or used with Strongbox.

Compiling Emacs.app on Snow Leopard

| Comments

UPDATE: Emacs.app builds fine (and has for a while) as a 64 bit application.

As previous noted, when it comes to Emacs for the Mac, I’m a fan of Emacs.app. However, Emacs.app is not quite ready for Snow Leopard’s 64 bit support. You must compile it as a 32 bit executable.

1
2
3
4
5
cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/sources/emacs co emacs
cd emacs
./configure --with-ns
make
make install  # This builds the .app wrapper, it does not install anything.

Then move nextstep/Emacs.app in to /Applications.

The developers have been actively working on Snow Leopard issues; hopefully 64 bit support is not far behind.

Pro Git

| Comments

Scott Chacon, one of the guys behind GitHub, has released Pro Git, which, as the name suggests, is a new Git book.   He’s made it available under the Creative Commons Attribution-Non Commercial-Share Alike 3.0 license, which is to say it’s free.  It cover the basics you’d except, but really shines when it comes to advanced usages, customization, policy, hosting, internals, etc.  It’s the resource to reach for when it’s time to loose your amateur status.   And did I mention it’s free?

You can show your support by buying a print copy (the author’s link, not mine).

It also plays nicely with Fluid, using http://progit.org/book for the Fluid URL and perhaps picking up an image from Amazon for the icon.