diff -r 9cdfe82c56cd -r eb8b23f11744 plugins/SpecialUserFuncs.php --- 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 @@ - - - - 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 " - - "; - } - else - { - echo ""; - } + echo $session->generate_aes_form(); ?> 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'); ?> 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 '

Invalid credentials

'; @@ -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 '

Invalid credentials

'; + $template->footer(); + return false; + } + if ( ( intval($row['temp_password_time']) + ( 3600 * 24 ) ) < time() ) { echo '

' . $lang->get('userfuncs_passreset_err_pass_expired', array('reset_url' => makeUrlNS('Special', 'PasswordReset'))) . '

'; @@ -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 '

' . $lang->get('userfuncs_passreset_err_too_short') . '

'; + $template->footer(); + return false; + } + if ( $_POST['use_crypt'] == 'no' ) + { + if ( $_POST['pass'] !== $_POST['pass_confirm'] ) + { + echo '

' . $lang->get('userfuncs_passreset_err_no_match') . '

'; + $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' ) ? '' . $lang->get('userfuncs_passreset_stage2_lbl_strength') . '
' : ''; + $pw_meter = ( getConfig('pw_strength_enable') == '1' ) ? '' . $lang->get('userfuncs_passreset_stage2_lbl_strength') . '
' : ''; $pw_blurb = ( getConfig('pw_strength_enable') == '1' && intval(getConfig('pw_strength_minimum')) > -10 ) ? '
' . $lang->get('userfuncs_passreset_stage2_blurb_strength') . '' : ''; ?> @@ -1721,86 +1617,23 @@ - - - + + generate_aes_form(); ?> 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; }