This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "FusionForge".

The branch, 6.0 has been updated
       via  62da2379df0bf38de2f3946e0e2e09e2e4979e6a (commit)
      from  b21fb65ab443f8847d033542af7d3ea7074fa0d5 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=62da2379df0bf38de2f3946e0e2e09e2e4979e6a

commit 62da2379df0bf38de2f3946e0e2e09e2e4979e6a
Author: Sylvain Beucler <[email protected]>
Date:   Wed Nov 18 10:36:24 2015 +0100

    account: improve password hash salts

diff --git a/src/CHANGES b/src/CHANGES
index 7a85fb4..c1eadfb 100644
--- a/src/CHANGES
+++ b/src/CHANGES
@@ -2,6 +2,8 @@ FusionForge 6.0.4:
 * Accounts: do not accept digits-only user and group names, to avoid confusion 
with UID/GID in system commands (Inria)
 * Accounts: drop redundant (and insecure) unsalted MD5 password hashes from 
the database (Inria)
 * Accounts: trigger system replication when user changes password or shell 
(Inria)
+* Accounts: passwords hashes: increase md5crypt salt length to 8; fix invalid 
Blowfish salt (Inria)
+* Accounts: passwords hashes: add support for SHA256/SHA512
 * MTA-Exim4: restart exim4 on install
 * Plugin SCM: fix another race condition when creating project with SCM 
selected (Inria)
 * Plugin SCM Git: improve user matching when computing stats, support git 
.mailmap (Inria)
diff --git a/src/common/include/account.php b/src/common/include/account.php
index e26e565..2e31927 100644
--- a/src/common/include/account.php
+++ b/src/common/include/account.php
@@ -166,25 +166,37 @@ function account_gensalt(){
        // crypt() selects the cipher based on
        // the salt, so ...
 
-       $a = genchr();
-       $b = genchr();
+       $salt_size = 0;
+       $salt_prefix = '';
        switch(forge_get_config('unix_cipher')) {
                case 'DES':
-                       $salt = "$a$b";
+                       $salt_size = 2;
                        break;
                default:
                case 'MD5':
-                       $salt = "$1$" . "$a$b";
+                       $salt_prefix = '$1$';
+                       $salt_size = 8;
+                       break;
+               case 'SHA256':
+                       $salt_prefix = '$5$rounds=5000$';
+                       $salt_size = 16;
+                       break;
+               case 'SHA512':
+                       $salt_prefix = '$6$rounds=5000$';
+                       $salt_size = 16;
                        break;
                case 'Blowfish':
-                       $i = 0;
-                       while (!$i = 16) {
-                               $salt .= rand(64,126);
-                               $i++;
-                        }
-                       return "$2a$".$salt;
+                       $salt_prefix = '$2y$10$';
+                       $salt_size = 22;
                        break;
        }
+
+       $salt = '';
+       for ($i = 0; $i < $salt_size; $i++)
+               $salt .= genchr();
+
+       $salt = $salt_prefix.$salt;
+
        return $salt;
 }
 
diff --git a/tests/unit/common/account.php b/tests/unit/common/account.php
new file mode 100644
index 0000000..e746619
--- /dev/null
+++ b/tests/unit/common/account.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Test account utilities
+ *
+ * Copyright (C) 2015  Inria (Sylvain Beucler)
+ *
+ * This file is part of FusionForge. FusionForge is free software;
+ * you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the Licence, or (at your option)
+ * any later version.
+ *
+ * FusionForge is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with FusionForge; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+require_once 'PHPUnit/Framework/TestCase.php';
+require_once dirname(__FILE__) . '/../../../src/common/include/account.php';
+require_once dirname(__FILE__) . '/../../../src/common/include/utils.php';
+require_once dirname(__FILE__) . '/../../../src/common/include/config.php';
+
+class Account_Tests extends PHPUnit_Framework_TestCase
+{
+       public function test_account_gensalt()
+       {
+               // default to md5crypt
+               forge_define_config_item('unix_cipher', 'core', '');
+               $salt = account_gensalt();
+               $this->assertSame('$1$', substr($salt, 0, 3));
+
+               // ab
+               forge_reset_config_item('unix_cipher', 'core', 'DES');
+               $salt = account_gensalt();
+               $this->assertSame(2, strlen($salt));
+               $this->assertRegExp(',[./0-9a-zA-Z]+,', $salt);
+
+               // $1$abcdefgh
+               forge_reset_config_item('unix_cipher', 'core', 'MD5');
+               $salt = account_gensalt();
+               $this->assertSame('$1$', substr($salt, 0, 3));
+               $this->assertSame(8, strlen(explode('$', $salt)[2]));
+               $this->assertRegExp(',[./0-9a-zA-Z]+,', explode('$', $salt)[2]);
+
+               // $5$rounds=5000$abcdefghij123456
+               forge_reset_config_item('unix_cipher', 'core', 'SHA256');
+               $salt = account_gensalt();
+               $this->assertSame('$5$', substr($salt, 0, 3));
+               $this->assertRegExp('/rounds=[0-9]+/', explode('$', $salt)[2]);
+               $this->assertSame(16, strlen(explode('$', $salt)[3]));
+               $this->assertRegExp(',[./0-9a-zA-Z]+,', explode('$', $salt)[3]);
+
+               // $6$rounds=5000$abcdefghij123456
+               forge_reset_config_item('unix_cipher', 'core', 'SHA512');
+               $salt = account_gensalt();
+               $this->assertSame('$6$', substr($salt, 0, 3));
+               $this->assertRegExp('/rounds=[0-9]+/', explode('$', $salt)[2]);
+               $this->assertSame(16, strlen(explode('$', $salt)[3]));
+               $this->assertRegExp(',[./0-9a-zA-Z]+,', explode('$', $salt)[3]);
+               $this->assertLessThanOrEqual(128, strlen($salt));  // or else 
update the DB schema
+
+               // $2y$10$abcdefghij123456789012
+               // Note that only 2 bits from the last char are used
+               forge_reset_config_item('unix_cipher', 'core', 'Blowfish');
+               $salt = account_gensalt();
+               $this->assertEquals('Blowfish', 
forge_get_config('unix_cipher'));
+               $this->assertSame('$2y$', substr($salt, 0, 4));
+               $cost = explode('$', $salt, 4)[2];
+               $this->assertStringMatchesFormat('%d', $cost);
+               $this->assertGreaterThanOrEqual(4, intval($cost));
+               $this->assertLessThanOrEqual(31, intval($cost));
+               $this->assertSame(22, strlen(explode('$', $salt)[3]));
+               $this->assertRegExp(',[./0-9a-zA-Z]+,', explode('$', $salt)[3]);
+       }
+}

-----------------------------------------------------------------------

Summary of changes:
 src/CHANGES                    |  2 ++
 src/common/include/account.php | 32 +++++++++++------
 tests/unit/common/account.php  | 80 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 104 insertions(+), 10 deletions(-)
 create mode 100644 tests/unit/common/account.php


hooks/post-receive
-- 
FusionForge

_______________________________________________
Fusionforge-commits mailing list
[email protected]
http://lists.fusionforge.org/cgi-bin/mailman/listinfo/fusionforge-commits

Reply via email to