Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
bugzilla
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
etersoft
bugzilla
Commits
179e06d7
Commit
179e06d7
authored
Jan 02, 2009
by
mkanat%bugzilla.org
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bug 211006: Make Bugzilla use SHA-256 instead of crypt() to store hashed passwords in the database
Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=LpSolit, a=LpSolit
parent
5c8dab45
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
75 additions
and
28 deletions
+75
-28
DB.pm
Bugzilla/Auth/Verify/DB.pm
+10
-0
Constants.pm
Bugzilla/Constants.pm
+12
-0
Requirements.pm
Bugzilla/Install/Requirements.pm
+5
-0
Util.pm
Bugzilla/Util.pm
+48
-28
No files found.
Bugzilla/Auth/Verify/DB.pm
View file @
179e06d7
...
...
@@ -64,6 +64,16 @@ sub check_credentials {
# password tokens they may have generated.
Bugzilla::Token::
DeletePasswordTokens
(
$user_id
,
"user_logged_in"
);
# If their old password was using crypt() or some different hash
# than we're using now, convert the stored password to using
# whatever hashing system we're using now.
my
$current_algorithm
=
PASSWORD_DIGEST_ALGORITHM
;
if
(
$real_password_crypted
!~
/{\Q$current_algorithm\E}$/
)
{
my
$new_crypted
=
bz_crypt
(
$password
);
$dbh
->
do
(
'UPDATE profiles SET cryptpassword = ? WHERE userid = ?'
,
undef
,
$new_crypted
,
$user_id
);
}
return
$login_data
;
}
...
...
Bugzilla/Constants.pm
View file @
179e06d7
...
...
@@ -154,6 +154,9 @@ use File::Basename;
MAX_COMPONENT_SIZE
MAX_FIELD_VALUE_SIZE
MAX_FREETEXT_LENGTH
PASSWORD_DIGEST_ALGORITHM
PASSWORD_SALT_LENGTH
)
;
@
Bugzilla::Constants::
EXPORT_OK
=
qw(contenttypes)
;
...
...
@@ -437,6 +440,15 @@ use constant MAX_FIELD_VALUE_SIZE => 64;
# Maximum length allowed for free text fields.
use
constant
MAX_FREETEXT_LENGTH
=>
255
;
# This is the name of the algorithm used to hash passwords before storing
# them in the database. This can be any string that is valid to pass to
# Perl's "Digest" module. Note that if you change this, it won't take
# effect until a user changes his password.
use
constant
PASSWORD_DIGEST_ALGORITHM
=>
'SHA-256'
;
# How long of a salt should we use? Note that if you change this, none
# of your users will be able to log in until they reset their passwords.
use
constant
PASSWORD_SALT_LENGTH
=>
8
;
sub
bz_locations
{
# We know that Bugzilla/Constants.pm must be in %INC at this point.
# So the only question is, what's the name of the directory
...
...
Bugzilla/Install/Requirements.pm
View file @
179e06d7
...
...
@@ -65,6 +65,11 @@ sub REQUIRED_MODULES {
version
=>
(
vers_cmp
(
$perl_ver
,
'5.10'
)
>
-
1
)
?
'3.33'
:
'3.21'
},
{
package
=>
'Digest-SHA'
,
module
=>
'Digest::SHA'
,
version
=>
0
},
{
package
=>
'TimeDate'
,
module
=>
'Date::Format'
,
version
=>
'2.21'
...
...
Bugzilla/Util.pm
View file @
179e06d7
...
...
@@ -52,6 +52,8 @@ use Date::Parse;
use
Date::
Format
;
use
DateTime
;
use
DateTime::
TimeZone
;
use
Digest
;
use
Scalar::
Util
qw(tainted)
;
use
Text::
Wrap
;
# This is from the perlsec page, slightly modified to remove a warning
...
...
@@ -476,37 +478,54 @@ sub file_mod_time {
sub
bz_crypt
{
my
(
$password
,
$salt
)
=
@_
;
my
$algorithm
;
if
(
!
defined
$salt
)
{
# The list of characters that can appear in a salt. Salts and hashes
# are both encoded as a sequence of characters from a set containing
# 64 characters, each one of which represents 6 bits of the salt/hash.
# The encoding is similar to BASE64, the difference being that the
# BASE64 plus sign (+) is replaced with a forward slash (/).
my
@saltchars
=
(
0
..
9
,
'A'
..
'Z'
,
'a'
..
'z'
,
'.'
,
'/'
);
# Generate the salt. We use an 8 character (48 bit) salt for maximum
# security on systems whose crypt uses MD5. Systems with older
# versions of crypt will just use the first two characters of the salt.
$salt
=
''
;
for
(
my
$i
=
0
;
$i
<
8
;
++
$i
)
{
$salt
.=
$saltchars
[
rand
(
64
)];
}
# If you don't use a salt, then people can create tables of
# hashes that map to particular passwords, and then break your
# hashing very easily if they have a large-enough table of common
# (or even uncommon) passwords. So we generate a unique salt for
# each password in the database, and then just prepend it to
# the hash.
$salt
=
generate_random_password
(
PASSWORD_SALT_LENGTH
);
$algorithm
=
PASSWORD_DIGEST_ALGORITHM
;
}
# Wide characters cause crypt to die
if
(
Bugzilla
->
params
->
{
'utf8'
})
{
utf8::
encode
(
$password
)
if
utf8::
is_utf8
(
$password
);
# We append the algorithm used to the string. This is good because then
# we can change the algorithm being used, in the future, without
# disrupting the validation of existing passwords. Also, this tells
# us if a password is using the old "crypt" method of hashing passwords,
# because the algorithm will be missing from the string.
if
(
$salt
=~
/{([^}]+)}$/
)
{
$algorithm
=
$1
;
}
# Crypt the password.
my
$cryptedpassword
=
crypt
(
$password
,
$salt
);
# HACK: Perl has bug where returned crypted password is considered tainted
# Upstream Bug: http://rt.perl.org/rt3/Public/Bug/Display.html?id=59998
trick_taint
(
$cryptedpassword
)
unless
(
is_tainted
(
$password
)
||
is_tainted
(
$salt
));
my
$crypted_password
;
if
(
!
$algorithm
)
{
# Wide characters cause crypt to die
if
(
Bugzilla
->
params
->
{
'utf8'
})
{
utf8::
encode
(
$password
)
if
utf8::
is_utf8
(
$password
);
}
# Crypt the password.
$crypted_password
=
crypt
(
$password
,
$salt
);
# HACK: Perl has bug where returned crypted password is considered
# tainted. See http://rt.perl.org/rt3/Public/Bug/Display.html?id=59998
unless
(
tainted
(
$password
)
||
tainted
(
$salt
))
{
trick_taint
(
$crypted_password
);
}
}
else
{
my
$hasher
=
Digest
->
new
(
$algorithm
);
# We only want to use the first characters of the salt, no
# matter how long of a salt we may have been passed.
$salt
=
substr
(
$salt
,
0
,
PASSWORD_SALT_LENGTH
);
$hasher
->
add
(
$password
,
$salt
);
$crypted_password
=
$salt
.
$hasher
->
b64digest
.
"{$algorithm}"
;
}
# Return the crypted password.
return
$cryptedpassword
;
return
$crypted
_
password
;
}
sub
generate_random_password
{
...
...
@@ -932,11 +951,12 @@ of the "mtime" parameter of the perl "stat" function.
=item C<bz_crypt($password, $salt)>
Takes a string and returns a
C<crypt>ed value for it, using a random salt.
An optional salt string may also be passed in.
Takes a string and returns a
hashed (encrypted) value for it, using a
random salt.
An optional salt string may also be passed in.
Please always use this function instead of the built-in perl "crypt"
when initially encrypting a password.
Please always use this function instead of the built-in perl C<crypt>
function, when checking or setting a password. Bugzilla does not use
C<crypt>.
=begin undocumented
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment