Merge branch 'next' into feature/ckeditor

This commit is contained in:
bnu 2015-02-24 20:48:20 +09:00
commit 95154d6985
18 changed files with 795 additions and 112 deletions

View file

@ -1699,6 +1699,21 @@
<value xml:lang="en"><![CDATA[password strength]]></value>
<value xml:lang="jp"><![CDATA[パスワード強度]]></value>
</item>
<item name="cmd_password_hashing_algorithm">
<value xml:lang="ko"><![CDATA[비밀번호 암호화 알고리듬]]></value>
<value xml:lang="en"><![CDATA[Password Hashing Algorithm]]></value>
<value xml:lang="jp"><![CDATA[パスワードの暗号化アルゴリズム]]></value>
</item>
<item name="cmd_password_hashing_work_factor">
<value xml:lang="ko"><![CDATA[비밀번호 암호화 소요시간]]></value>
<value xml:lang="en"><![CDATA[Password Hashing Work Factor]]></value>
<value xml:lang="jp"><![CDATA[暗号化のワーク·ファクター]]></value>
</item>
<item name="cmd_password_hashing_auto_upgrade">
<value xml:lang="ko"><![CDATA[알고리듬 자동 업그레이드]]></value>
<value xml:lang="en"><![CDATA[Auto-upgrade Hashing Algorithm]]></value>
<value xml:lang="jp"><![CDATA[暗号化アルゴリズム自動アップグレード]]></value>
</item>
<item name="password_strength_low">
<value xml:lang="ko"><![CDATA[낮음]]></value>
@ -1721,6 +1736,21 @@
<value xml:lang="en"><![CDATA[When members register or change the password, the password must meet the specified password strength. However, the administrator is an exception.]]></value>
<value xml:lang="jp"><![CDATA[会員がパスワードを登録する際に、パスワードが一定の強度を満たす必要があります。ただし、管理者が直接に登録する際には適用されません。]]></value>
</item>
<item name="about_password_hashing_algorithm">
<value xml:lang="ko"><![CDATA[회원들의 비밀번호를 DB에 저장할 때 암호화(해싱)하는 방식을 지정할 수 있습니다.]]></value>
<value xml:lang="en"><![CDATA[You can choose how to encrypt (hash) members' passwords stored in the database.]]></value>
<value xml:lang="jp"><![CDATA[会員のパスワードをDBに保存するときに暗号化ハッシュする方法を指定することができます。]]></value>
</item>
<item name="about_password_hashing_work_factor">
<value xml:lang="ko"><![CDATA[시간이 오래 걸리는 알고리듬일수록 보안이 강하지만, 로그인이 오래 걸릴 수 있습니다. bcrypt 및 pbkdf2 알고리듬에만 적용됩니다.]]></value>
<value xml:lang="en"><![CDATA[Higher work factors are more secure, but logins may take a long time. This only applies to bcrypt and pbkdf2.]]></value>
<value xml:lang="jp"><![CDATA[時間がかかるアルゴリズムほどセキュリティが強いが、ログインがかかることがあります。 bcryptとpbkdf2アルゴリズムにのみ適用されます。]]></value>
</item>
<item name="about_password_hashing_auto_upgrade">
<value xml:lang="ko"><![CDATA[설정된 알고리듬과 다른 방법으로 암호화된 비밀번호가 있으면 다음 로그인시 설정된 알고리듬으로 자동 변환합니다.]]></value>
<value xml:lang="en"><![CDATA[Passwords encrypted using different algorithms will be automatically converted to the configured algorithm at next login.]]></value>
<value xml:lang="jp"><![CDATA[設定されたアルゴリズムとは異なる方法で暗号化されたパスワードがあれば、次のログイン時に設定されたアルゴリズムに自動的に変換します。]]></value>
</item>
<item name="about_password_strength" type="array">
<item name="low">

View file

@ -159,8 +159,31 @@ class memberAdminController extends member
'enable_confirm',
'webmaster_name',
'webmaster_email',
'password_strength'
'password_strength',
'password_hashing_algorithm',
'password_hashing_work_factor',
'password_hashing_auto_upgrade'
);
$oPassword = new Password();
if(!array_key_exists($args->password_hashing_algorithm, $oPassword->getSupportedAlgorithms()))
{
$args->password_hashing_algorithm = 'md5';
}
$args->password_hashing_work_factor = intval($args->password_hashing_work_factor, 10);
if($args->password_hashing_work_factor < 4)
{
$args->password_hashing_work_factor = 4;
}
if($args->password_hashing_work_factor > 16)
{
$args->password_hashing_work_factor = 16;
}
if($args->password_hashing_auto_upgrade != 'Y')
{
$args->password_hashing_auto_upgrade = 'N';
}
if((!$args->webmaster_name || !$args->webmaster_email) && $args->enable_confirm == 'Y')
{

View file

@ -129,8 +129,10 @@ class memberAdminView extends member
*/
public function dispMemberAdminConfig()
{
$oPassword = new Password();
Context::set('password_hashing_algos', $oPassword->getSupportedAlgorithms());
$this->setTemplateFile('default_config');
}
public function dispMemberAdminSignUpConfig()

View file

@ -71,6 +71,20 @@ class member extends ModuleObject {
if($config->group_image_mark!='Y') $config->group_image_mark = 'N';
if(!$config->password_strength) $config->password_strength = 'normal';
if(!$config->password_hashing_algorithm)
{
$oPassword = new Password();
$config->password_hashing_algorithm = $oPassword->getBestAlgorithm();
}
if(!$config->password_hashing_work_factor)
{
$config->password_hashing_work_factor = 8;
}
if(!$config->password_hashing_auto_upgrade)
{
$config->password_hashing_auto_upgrade = 'Y';
}
global $lang;
$oMemberModel = getModel('member');
// Create a member controller object

View file

@ -1119,7 +1119,7 @@ class memberController extends member
}
else
{
$args->password = md5($output->data->new_password);
$args->password = getModel('member')->hashPassword($args->password);
unset($args->denied);
}
// Back up the value of $Output->data->is_register
@ -1974,7 +1974,7 @@ class memberController extends member
$message = Context::getLang('about_password_strength');
return new Object(-1, $message[$config->password_strength]);
}
$args->password = md5($args->password);
$args->password = $oMemberModel->hashPassword($args->password);
}
elseif(!$args->password) unset($args->password);
if($oMemberModel->isDeniedID($args->user_id)) return new Object(-1,'denied_user_id');
@ -2167,7 +2167,7 @@ class memberController extends member
return new Object(-1, $message[$config->password_strength]);
}
$args->password = md5($args->password);
$args->password = $oMemberModel->hashPassword($args->password);
}
else $args->password = $orgMemberInfo->password;
if(!$args->user_name) $args->user_name = $orgMemberInfo->user_name;
@ -2257,14 +2257,7 @@ class memberController extends member
return new Object(-1, $message[$config->password_strength]);
}
if($this->useSha1)
{
$args->password = md5(sha1(md5($args->password)));
}
else
{
$args->password = md5($args->password);
}
$args->password = $oMemberModel->hashPassword($args->password);
}
else if($args->hashed_password)
{

View file

@ -1006,65 +1006,71 @@ class memberModel extends member
/**
* @brief Compare plain text password to the password saved in DB
* @param string $hashed_password The hash that was saved in DB
* @param string $password_text The password to check
* @param int $member_srl Set this to member_srl when comparing a member's password (optional)
* @return bool
*/
function isValidPassword($hashed_password, $password_text, $member_srl=null)
{
// False if no password in entered
if(!$password_text) return false;
$isSha1 = ($this->useSha1 && function_exists('sha1'));
// Return true if the user input is equal to md5 hash value
if($hashed_password == md5($password_text))
if(!$password_text)
{
if($isSha1 && $member_srl > 0)
return false;
}
// Check the password
$oPassword = new Password();
$current_algorithm = $oPassword->checkAlgorithm($hashed_password);
$match = $oPassword->checkPassword($password_text, $hashed_password, $current_algorithm);
if(!$match)
{
return false;
}
// Update the encryption method if necessary
$config = $this->getMemberConfig();
if($member_srl > 0 && $config->password_hashing_auto_upgrade != 'N')
{
$need_upgrade = false;
if(!$need_upgrade)
{
$required_algorithm = $oPassword->getCurrentlySelectedAlgorithm();
if($required_algorithm !== $current_algorithm) $need_upgrade = true;
}
if(!$need_upgrade)
{
$required_work_factor = $oPassword->getWorkFactor();
$current_work_factor = $oPassword->checkWorkFactor($hashed_password);
if($current_work_factor !== false && $required_work_factor > $current_work_factor) $need_upgrade = true;
}
if($need_upgrade === true)
{
$args = new stdClass();
$args->member_srl = $member_srl;
$args->hashed_password = md5(sha1(md5($password_text)));
$args->hashed_password = $this->hashPassword($password_text, $required_algorithm);
$oMemberController = getController('member');
$oMemberController->updateMemberPassword($args);
}
return true;
}
// Return true if the user input is equal to the value of mysql_pre4_hash_password
if(mysql_pre4_hash_password($password_text) == $hashed_password)
{
if($isSha1 && $member_srl > 0)
{
$args = new stdClass();
$args->member_srl = $member_srl;
$args->hashed_password = md5(sha1(md5($password_text)));
$oMemberController = getController('member');
$oMemberController->updateMemberPassword($args);
}
return true;
}
// Verify the password by using old_password if the current db is MySQL. If correct, return true.
if(substr(Context::getDBType(),0,5)=='mysql')
{
$oDB = &DB::getInstance();
if($oDB->isValidOldPassword($password_text, $hashed_password))
{
if($isSha1 && $member_srl > 0)
{
$args = new stdClass();
$args->member_srl = $member_srl;
$args->hashed_password = md5(sha1(md5($password_text)));
$oMemberController = getController('member');
$oMemberController->updateMemberPassword($args);
}
return true;
}
}
if($isSha1 && $hashed_password == md5(sha1(md5($password_text)))) return true;
return false;
return true;
}
/**
* @brief Create a hash of plain text password
* @param string $password_text The password to hash
* @param string $algorithm The algorithm to use (optional, only set this when you want to use a non-default algorithm)
* @return string
*/
function hashPassword($password_text, $algorithm = null)
{
$oPassword = new Password();
return $oPassword->createHash($password_text, $algorithm);
}
function checkPasswordStrength($password, $strength)
{

View file

@ -7,5 +7,8 @@
<field name="webmaster_name" required="true" length="2:40" />
<field name="webmaster_email" length="1:200" rule="email" />
<field name="password_strength" required="true" />
<field name="password_hashing_algorithm" required="true" />
<field name="password_hashing_work_factor" required="true" />
<field name="password_hashing_auto_upgrade" required="true" />
</fields>
</ruleset>

View file

@ -29,6 +29,32 @@
<p class="x_help-block">{$lang->about_password_strength_config}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->cmd_password_hashing_algorithm}</label>
<div class="x_controls">
<select name="password_hashing_algorithm" id="password_hashing_algorithm" style="width:auto">
<option value="{$key}" selected="selected"|cond="$config->password_hashing_algorithm==$key" loop="$password_hashing_algos=>$key,$val">{$val}</option>
</select>
<p class="x_help-block">{$lang->about_password_hashing_algorithm}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->cmd_password_hashing_work_factor}</label>
<div class="x_controls">
<select name="password_hashing_work_factor" id="password_hashing_work_factor" style="width:auto">
<option value="{$i}" selected="selected"|cond="$config->password_hashing_work_factor==$i" loop="$i=4;$i<=16;$i++">{sprintf('%02d', $i)}</option>
</select>
<p class="x_help-block">{$lang->about_password_hashing_work_factor}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->cmd_password_hashing_auto_upgrade}</label>
<div class="x_controls">
<label for="password_hashing_auto_upgrade_y" class="x_inline"><input type="radio" name="password_hashing_auto_upgrade" id="password_hashing_auto_upgrade_y" value="Y" checked="checked"|cond="$config->password_hashing_auto_upgrade == 'Y'" /> {$lang->cmd_yes}</label>
<label for="password_hashing_auto_upgrade_n" class="x_inline"><input type="radio" name="password_hashing_auto_upgrade" id="password_hashing_auto_upgrade_n" value="N" checked="checked"|cond="$config->password_hashing_auto_upgrade != 'Y'" /> {$lang->cmd_no}</label>
<p class="x_help-block">{$lang->about_password_hashing_auto_upgrade}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="webmaster_name">{$lang->webmaster_name}</label>
<div class="x_controls">