--- a/plugins/SpecialUserFuncs.php Sat Jan 03 18:11:18 2009 -0500
+++ b/plugins/SpecialUserFuncs.php Sun Jan 04 00:55:40 2009 -0500
@@ -12,7 +12,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.5 (Caoineag alpha 5)
+ * Version 1.1.6 (Caoineag beta 1)
* Copyright (C) 2006-2008 Dan Fuhry
*
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
@@ -121,12 +121,6 @@
global $__login_status;
global $lang;
- require_once( ENANO_ROOT . '/includes/diffiehellman.php' );
- global $dh_supported, $_math;
-
- $pubkey = $session->rijndael_genkey();
- $challenge = $session->dss_rand();
-
$locked_out = false;
// are we locked out?
$threshold = ( $_ = getConfig('lockout_threshold') ) ? intval($_) : 5;
@@ -436,10 +430,6 @@
</tr>
</table>
</div>
- <input type="hidden" name="challenge_data" value="<?php echo $challenge; ?>" />
- <input type="hidden" name="use_crypt" value="no" />
- <input type="hidden" name="crypt_key" value="<?php echo $pubkey; ?>" />
- <input type="hidden" name="crypt_data" value="" />
<input type="hidden" name="auth_level" value="<?php echo (string)$level; ?>" />
<?php if ( $level <= USER_LEVEL_MEMBER ): ?>
<script type="text/javascript">
@@ -451,34 +441,11 @@
</script>
<?php endif; ?>
<?php
- // 1.1.4
-
- require_once( ENANO_ROOT . '/includes/diffiehellman.php' );
-
- global $dh_supported, $_math;
- if ( $dh_supported )
- {
- $dh_key_priv = dh_gen_private();
- $dh_key_pub = dh_gen_public($dh_key_priv);
- $dh_key_priv = $_math->str($dh_key_priv);
- $dh_key_pub = $_math->str($dh_key_pub);
- // store the keys in the DB
- $q = $db->sql_query('INSERT INTO ' . table_prefix . "diffiehellman( public_key, private_key ) VALUES ( '$dh_key_pub', '$dh_key_priv' );");
- if ( !$q )
- $db->_die();
-
- echo "<input type=\"hidden\" name=\"dh_supported\" value=\"true\" />
- <input type=\"hidden\" name=\"dh_public_key\" value=\"$dh_key_pub\" />
- <input type=\"hidden\" name=\"dh_client_public_key\" value=\"\" />";
- }
- else
- {
- echo "<input type=\"hidden\" name=\"dh_supported\" value=\"false\" />";
- }
+ echo $session->generate_aes_form();
?>
</form>
<?php
- echo $session->aes_javascript('loginform', 'pass', 'use_crypt', 'crypt_key', 'crypt_data', 'challenge_data', 'dh_supported', 'dh_public_key', 'dh_client_public_key');
+ echo $session->aes_javascript('loginform', 'pass');
?>
<?php
$template->footer();
@@ -516,93 +483,28 @@
}
if ( isset($_GET['act']) && $_GET['act'] == 'ajaxlogin' )
{
- echo 'This version of the Enano LoginAPI is deprecated. Please use the action.json method instead.';
+ echo 'This version of the Enano LoginAPI is deprecated. Please clear your browser\'s cache and try your login again. Developers, please use the action.json method instead.';
return true;
}
if(isset($_POST['login']))
{
$captcha_hash = ( isset($_POST['captcha_hash']) ) ? $_POST['captcha_hash'] : false;
$captcha_code = ( isset($_POST['captcha_code']) ) ? $_POST['captcha_code'] : false;
- if ( $_POST['use_crypt'] == 'yes' )
+
+ try
{
- $result = $session->login_with_crypto($_POST['username'], $_POST['crypt_data'], $_POST['crypt_key'], $_POST['challenge_data'], intval($_POST['auth_level']), $captcha_hash, $captcha_code, isset($_POST['remember']));
+ $password = $session->get_aes_post('pass');
}
- else if ( $_POST['use_crypt'] == 'yes_dh' )
+ catch ( Exception $e )
{
- // retrieve and decrypt the password using DiffieHellman
-
- require_once( ENANO_ROOT . '/includes/diffiehellman.php' );
- global $dh_supported, $_math;
-
- if ( !$dh_supported )
- {
- die_semicritical('DiffieHellman error', 'Server does not support DiffieHellman, denying logon request');
- }
-
- // Fetch private key
- $dh_public = $_POST['dh_public_key'];
- if ( !preg_match('/^[0-9]+$/', $dh_public) )
- {
- $__login_status = array(
- 'success' => false,
- 'error' => 'ERR_DH_KEY_NOT_INTEGER',
- 'debug' => "public key: $dh_public"
- );
- return false;
- }
- $q = $db->sql_query('SELECT private_key, key_id FROM ' . table_prefix . "diffiehellman WHERE public_key = '$dh_public';");
- if ( !$q )
- $db->die_json();
-
- if ( $db->numrows() < 1 )
- {
- $__login_status = array(
- 'success' => false,
- 'error' => 'ERR_DH_KEY_NOT_FOUND',
- 'debug' => "public key: $dh_public"
- );
- return false;
- }
-
- list($dh_private, $dh_key_id) = $db->fetchrow_num();
- $db->free_result();
-
- // We have the private key, now delete the key pair, we no longer need it
- $q = $db->sql_query('DELETE FROM ' . table_prefix . "diffiehellman WHERE key_id = $dh_key_id;");
- if ( !$q )
- $db->die_json();
-
- // Generate the shared secret
- $dh_secret = dh_gen_shared_secret($dh_private, $_POST['dh_client_public_key']);
- $dh_secret = $_math->str($dh_secret);
-
- // Did we get all our math right?
- $dh_secret_check = sha1($dh_secret);
- $dh_hash = $_POST['crypt_key'];
- if ( $dh_secret_check !== $dh_hash )
- {
- $__login_status = array(
- 'success' => false,
- 'error' => 'ERR_DH_HASH_NO_MATCH',
- 'debug' => "dh_secret_check = $dh_secret_check\ndh_hash_input = $dh_hash"
- );
- return false;
- }
-
- // All good! Generate the AES key
- $aes_key = substr(sha256($dh_secret), 0, ( AES_BITS / 4 ));
-
- // decrypt user info
- $aes_key = hexdecode($aes_key);
- $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE);
- $password = $aes->decrypt($_POST['crypt_data'], $aes_key, ENC_HEX);
-
- $result = $session->login_without_crypto($_POST['username'], $password, false, intval($_POST['auth_level']), $captcha_hash, $captcha_code, isset($_POST['remember']));
+ $__login_status = array(
+ 'mode' => 'error',
+ 'error' => $e->getMessage()
+ );
+ return false;
}
- else
- {
- $result = $session->login_without_crypto($_POST['username'], $_POST['pass'], false, intval($_POST['auth_level']), $captcha_hash, $captcha_code, isset($_POST['remember']));
- }
+
+ $result = $session->login_without_crypto($_POST['username'], $password, false, intval($_POST['auth_level']), $captcha_hash, $captcha_code, isset($_POST['remember']));
if($result['success'])
{
@@ -1598,6 +1500,9 @@
$template->header();
if($paths->getParam(0) == 'stage2')
{
+ require_once(ENANO_ROOT . '/includes/math.php');
+ require_once(ENANO_ROOT . '/includes/diffiehellman.php');
+
$user_id = intval($paths->getParam(1));
$encpass = $paths->getParam(2);
if ( $user_id < 2 )
@@ -1613,7 +1518,7 @@
return false;
}
- $q = $db->sql_query('SELECT username,temp_password_time FROM '.table_prefix.'users WHERE user_id='.$user_id.' AND temp_password=\'' . $encpass . '\';');
+ $q = $db->sql_query('SELECT username,temp_password_time,temp_password,password_salt FROM '.table_prefix.'users WHERE user_id='.$user_id.';');
if($db->numrows() < 1)
{
echo '<p>Invalid credentials</p>';
@@ -1623,6 +1528,16 @@
$row = $db->fetchrow();
$db->free_result();
+ $temp_pass = $session->pk_decrypt($encpass);
+ $temp_hmac = hmac_sha1($temp_pass, $row['password_salt']);
+
+ if ( $temp_hmac !== $row['temp_password'] )
+ {
+ echo '<p>Invalid credentials</p>';
+ $template->footer();
+ return false;
+ }
+
if ( ( intval($row['temp_password_time']) + ( 3600 * 24 ) ) < time() )
{
echo '<p>' . $lang->get('userfuncs_passreset_err_pass_expired', array('reset_url' => makeUrlNS('Special', 'PasswordReset'))) . '</p>';
@@ -1632,48 +1547,29 @@
if ( isset($_POST['do_stage2']) )
{
- $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE);
- if($_POST['use_crypt'] == 'yes')
- {
- $crypt_key = $session->fetch_public_key($_POST['crypt_key']);
- if(!$crypt_key)
- {
- echo $lang->get('user_err_key_not_found');
- $template->footer();
- return false;
- }
- $crypt_key = hexdecode($crypt_key);
- $data = $aes->decrypt($_POST['crypt_data'], $crypt_key, ENC_HEX);
- if(strlen($data) < 6)
- {
- echo $lang->get('userfuncs_passreset_err_too_short');
- $template->footer();
- return false;
- }
- }
- else
- {
- $data = $_POST['pass'];
- $conf = $_POST['pass_confirm'];
- if($data != $conf)
- {
- echo $lang->get('userfuncs_passreset_err_no_match');
- $template->footer();
- return false;
- }
- if(strlen($data) < 6)
- {
- echo $lang->get('userfuncs_passreset_err_too_short');
- $template->footer();
- return false;
- }
- }
+ $data = $session->get_aes_post('pass');
+
if(empty($data))
{
echo 'ERROR: Sanity check failed!';
$template->footer();
return false;
}
+ if ( strlen($data) < 6 )
+ {
+ echo '<p>' . $lang->get('userfuncs_passreset_err_too_short') . '</p>';
+ $template->footer();
+ return false;
+ }
+ if ( $_POST['use_crypt'] == 'no' )
+ {
+ if ( $_POST['pass'] !== $_POST['pass_confirm'] )
+ {
+ echo '<p>' . $lang->get('userfuncs_passreset_err_no_match') . '</p>';
+ $template->footer();
+ return false;
+ }
+ }
if ( getConfig('pw_strength_enable') == '1' )
{
$min_score = intval(getConfig('pw_strength_minimum'));
@@ -1686,8 +1582,10 @@
return false;
}
}
- $encpass = $session->pk_encrypt($data, ENC_HEX);
- $q = $db->sql_query('UPDATE '.table_prefix.'users SET password=\'' . $encpass . '\',temp_password=\'\',temp_password_time=0 WHERE user_id='.$user_id.';');
+
+ $session->set_password($user_id, $data);
+
+ $q = $db->sql_query('UPDATE '.table_prefix.'users SET temp_password=\'\',temp_password_time=0 WHERE user_id = '.$user_id.';');
if($q)
{
@@ -1704,10 +1602,8 @@
}
// Password reset form
- $pubkey = $session->rijndael_genkey();
-
$evt_get_score = ( getConfig('pw_strength_enable') == '1' ) ? 'onkeyup="password_score_field(this);" ' : '';
- $pw_meter = ( getConfig('pw_strength_enable') == '1' ) ? '<tr><td class="row1">' . $lang->get('userfuncs_passreset_stage2_lbl_strength') . '</td><td class="row1"><div id="pwmeter"></div><script type="text/javascript">password_score_field(document.forms.resetform.pass);</script></td></tr>' : '';
+ $pw_meter = ( getConfig('pw_strength_enable') == '1' ) ? '<tr><td class="row1">' . $lang->get('userfuncs_passreset_stage2_lbl_strength') . '</td><td class="row1"><div id="pwmeter"></div></td></tr>' : '';
$pw_blurb = ( getConfig('pw_strength_enable') == '1' && intval(getConfig('pw_strength_minimum')) > -10 ) ? '<br /><small>' . $lang->get('userfuncs_passreset_stage2_blurb_strength') . '</small>' : '';
?>
@@ -1721,86 +1617,23 @@
<?php echo $pw_meter; ?>
<tr>
<td colspan="2" class="row3" style="text-align: center;">
- <input type="hidden" name="use_crypt" value="no" />
- <input type="hidden" name="crypt_key" value="<?php echo $pubkey; ?>" />
- <input type="hidden" name="crypt_data" value="" />
+
<input type="submit" name="do_stage2" value="<?php echo $lang->get('userfuncs_passreset_stage2_btn_submit'); ?>" />
</td>
</tr>
</table>
</div>
+ <?php echo $session->generate_aes_form(); ?>
</form>
<script type="text/javascript">
- if ( !KILL_SWITCH )
- {
- disableJSONExts();
- str = '';
- for(i=0;i<keySizeInBits/4;i++) str+='0';
- var key = hexToByteArray(str);
- var pt = hexToByteArray(str);
- var ct = rijndaelEncrypt(pt, key, "ECB");
- var ct = byteArrayToHex(ct);
- switch(keySizeInBits)
- {
- case 128:
- v = '66e94bd4ef8a2c3b884cfa59ca342b2e';
- break;
- case 192:
- v = 'aae06992acbf52a3e8f4a96ec9300bd7aae06992acbf52a3e8f4a96ec9300bd7';
- break;
- case 256:
- v = 'dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087';
- break;
- }
- var testpassed = ( ct == v && md5_vm_test() );
- var frm = document.forms.resetform;
- if(testpassed)
+ addOnloadHook(function()
{
- frm.use_crypt.value = 'yes';
- var cryptkey = frm.crypt_key.value;
- frm.crypt_key.value = hex_md5(cryptkey);
- cryptkey = hexToByteArray(cryptkey);
- if(!cryptkey || ( ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ) && cryptkey.length != keySizeInBits / 8 )
- {
- frm._login.disabled = true;
- len = ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ? '\nLen: '+cryptkey.length : '';
- alert('The key is messed up\nType: '+typeof(cryptkey)+len);
- }
- }
- function runEncryption()
- {
- var frm = document.forms.resetform;
- pass1 = frm.pass.value;
- pass2 = frm.pass_confirm.value;
- if ( pass1 != pass2 )
- {
- alert($lang.get('userfuncs_passreset_err_no_match'));
- return false;
- }
- if ( pass1.length < 6 )
- {
- alert($lang.get('userfuncs_passreset_err_too_short'));
- return false;
- }
- if(testpassed)
- {
- pass = frm.pass.value;
- pass = stringToByteArray(pass);
- cryptstring = rijndaelEncrypt(pass, cryptkey, 'ECB');
- if(!cryptstring)
- {
- return false;
- }
- cryptstring = byteArrayToHex(cryptstring);
- frm.crypt_data.value = cryptstring;
- frm.pass.value = "";
- frm.pass_confirm.value = "";
- }
- return true;
- }
- }
+ load_component('pwstrength');
+ password_score_field(document.forms.resetform.pass);
+ });
</script>
<?php
+ echo $session->aes_javascript('resetform', 'pass', 'use_crypt', 'crypt_key', 'crypt_data', 'challenge_data', 'dh_supported', 'dh_public_key', 'dh_client_public_key');
$template->footer();
return true;
}