Project

General

Profile

Feature #4640 » base64_hash.patch

Patch against version 1.0.4 - Jerry Van Baren, 2010-12-16 02:47

View differences:

app/models/user.rb
109 109
        return nil unless user.auth_source.authenticate(login, password)
110 110
      else
111 111
        # authentication with local password
112

  
113
        # Backwards compatibility: if the stored password is
114
        # hex-encoded, convert it to base64 prepended with '{SHA}'
115
        # to make it compatible with Apache.
116
        if user.hashed_password[0,5] != '{SHA}'
117
          pw_s = ""
118
          user.hashed_password.unpack(
119
                  'a2'*(user.hashed_password.length / 2)).collect do |x|
120
            pw_s << x.hex
121
          end
122
          user.hashed_password = '{SHA}' + Base64.encode64(pw_s).chomp
123
        end
124

  
112 125
        return nil unless User.hash_password(password) == user.hashed_password        
113 126
      end
114 127
    else
......
391 404
    
392 405
  # Return password digest
393 406
  def self.hash_password(clear_password)
394
    Digest::SHA1.hexdigest(clear_password || "")
407
    # Prefix with {SHA} and use base64 encoding to be compatible with
408
    # Apache basic authentication with mod_authn_dbd.
409
    '{SHA}' + Base64.encode64(Digest::SHA1.digest(clear_password || "")).chomp
395 410
  end
396 411
end
397 412

  
db/migrate/20100130000000_pw_hash_apache_compat.rb
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
(2-2/2)