Project

General

Profile

Feature #4640 » base64_hash.patch

Patch created against r3319 - Jerry Van Baren, 2010-01-23 20:04

View differences:

app/models/user.rb (working copy)
93 93
        return nil unless user.auth_source.authenticate(login, password)
94 94
      else
95 95
        # authentication with local password
96

  
97
        # Backwards compatibility: if the stored password is
98
        # hex-encoded, convert it to base64 prepended with '{SHA}'
99
        # to make it compatible with Apache.
100
        if user.hashed_password[0,5] != '{SHA}'
101
          pw_s = ""
102
          user.hashed_password.unpack(
103
                  'a2'*(user.hashed_password.length / 2)).collect do |x|
104
            pw_s << x.hex
105
          end
106
          user.hashed_password = '{SHA}' + Base64.encode64(pw_s).chomp
107
        end
108

  
96 109
        return nil unless User.hash_password(password) == user.hashed_password        
97 110
      end
98 111
    else
......
274 287
  
275 288
private
276 289
  # Return password digest
290
  # Prefix with {SHA} and use base64 encoding to be compatible with
291
  # Apache basic authentication with mod_authn_dbd.
277 292
  def self.hash_password(clear_password)
278
    Digest::SHA1.hexdigest(clear_password || "")
293
    '{SHA}' + Base64.encode64(Digest::SHA1.digest(clear_password || "")).chomp
279 294
  end
280 295
end
281 296

  
db/migrate/102_pw_hash_apache_compat.rb (revision 0)
1
class PwHashApacheCompat < ActiveRecord::Migration
2
  def self.up
3
    users = User.find(:all)
4
    users.each do |user|
5
      next if user.hashed_password.blank? or
6
              (user.hashed_password[0,5] == '{SHA}')
7

  
8
      # If the stored password is hex-encoded, convert it to base64
9
      # prepended with '{SHA}' to make it compatible with Apache.
10
      pw_s = ""
11
      user.hashed_password.unpack(
12
              'a2'*(user.hashed_password.length / 2)).collect do |x|
13
        pw_s << x.hex
14
      end
15
      user.hashed_password = '{SHA}' + Base64.encode64(pw_s).chomp
16
      user.save
17

  
18
    end
19
  end
20

  
21
  def self.down
22
    users = User.find(:all)
23
    users.each do |user|
24
      next if user.hashed_password.blank? or
25
              (user.hashed_password[0,5] != '{SHA}')
26
      pw_s = Base64.decode64(user.hashed_password[5..-1])
27
      user.hashed_password = pw_s.unpack('H*').to_s
28
      user.save
29
    end
30
  end
31
end
(1-1/2)