Quick *nix shadow passwords with Ruby

Just thought I’d share this one to boost the available online information. Using String#crypt and man crypt you’ll come up with something similar to the gist below (extract from a project I’m busy working on).

module Linux
  class User
    class << self
      # Generate an MD5 salt string
      def salt
        seeds = ('a'..'z').to_a
        seeds.concat( ('A'..'Z').to_a )
        seeds.concat( (..9).to_a )
        seeds.concat ['/', '.']
        seeds.compact!

        salt_string = '$1$'
        8.times { salt_string << seeds[ rand(seeds.size) ].to_s }

        salt_string
      end

      # Crypt a password suitable for use in shadow files
      def crypt( string )
        string.crypt( self.salt )
      end
    end
  end
end

And the spec

require File.dirname(__FILE__) + '/../spec_helper'

describe Linux::User do
  describe "generating shadow passwords" do
    it "should generate a salt for crypt" do
      salt = Linux::User.salt
      salt.length.should be(11)
      salt.should match(/^\$1\$[a-zA-Z0-9\.\/]{8}$/)
    end

    it "should generate a shadow password" do
      pass = Linux::User.crypt( 'secret' )
      pass.should match(/^\$1\$[a-zA-Z0-9\.\/]{8}\$[a-zA-Z0-9\.\/]{22}$/)
      pass.length.should be(34)
    end
  end
end

HTH

Flattr this!
comments powered by Disqus