862 // Lockout stuff |
862 // Lockout stuff |
863 $threshold = ( $_ = getConfig('lockout_threshold') ) ? intval($_) : 5; |
863 $threshold = ( $_ = getConfig('lockout_threshold') ) ? intval($_) : 5; |
864 $duration = ( $_ = getConfig('lockout_duration') ) ? intval($_) : 15; |
864 $duration = ( $_ = getConfig('lockout_duration') ) ? intval($_) : 15; |
865 // convert to minutes |
865 // convert to minutes |
866 $duration = $duration * 60; |
866 $duration = $duration * 60; |
|
867 $policy = ( $x = getConfig('lockout_policy') && in_array(getConfig('lockout_policy'), array('lockout', 'disable', 'captcha')) ) ? getConfig('lockout_policy') : 'lockout'; |
867 |
868 |
868 // get the lockout status |
|
869 $timestamp_cutoff = time() - $duration; |
869 $timestamp_cutoff = time() - $duration; |
870 $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']); |
870 $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']); |
871 $q = $this->sql('SELECT timestamp FROM '.table_prefix.'lockout WHERE timestamp > ' . $timestamp_cutoff . ' AND ipaddr = \'' . $ipaddr . '\' ORDER BY timestamp DESC;'); |
871 $q = $this->sql('SELECT timestamp FROM '.table_prefix.'lockout WHERE timestamp > ' . $timestamp_cutoff . ' AND ipaddr = \'' . $ipaddr . '\' ORDER BY timestamp DESC;'); |
872 $fails = $db->numrows(); |
872 $fails = $db->numrows(); |
873 |
873 |
874 $policy = ( $x = getConfig('lockout_policy') && in_array(getConfig('lockout_policy'), array('lockout', 'disable', 'captcha')) ) ? getConfig('lockout_policy') : 'lockout'; |
|
875 $captcha_good = false; |
874 $captcha_good = false; |
876 if ( $policy == 'captcha' && $captcha_hash && $captcha_code ) |
875 if ( $policy == 'captcha' && $captcha_hash && $captcha_code ) |
877 { |
876 { |
878 // policy is captcha -- check if it's correct, and if so, bypass lockout check |
877 // policy is captcha -- check if it's correct, and if so, bypass lockout check |
879 $real_code = $this->get_captcha($captcha_hash); |
878 $real_code = $this->get_captcha($captcha_hash); |
880 $captcha_good = ( strtolower($real_code) === strtolower($captcha_code) ); |
879 if ( strtolower($real_code) === strtolower($captcha_code) ) |
|
880 { |
|
881 $captcha_good = true; |
|
882 } |
881 } |
883 } |
882 if ( $policy != 'disable' && !$captcha_good ) |
884 if ( $policy != 'disable' && !$captcha_good ) |
883 { |
885 { |
884 if ( $fails >= $threshold ) |
886 if ( $fails >= $threshold ) |
885 { |
887 { |
2924 * @param string The name of the password field |
2926 * @param string The name of the password field |
2925 * @param string The name of the field that switches encryption on or off |
2927 * @param string The name of the field that switches encryption on or off |
2926 * @param string The name of the field that contains the encryption key |
2928 * @param string The name of the field that contains the encryption key |
2927 * @param string The name of the field that will contain the encrypted password |
2929 * @param string The name of the field that will contain the encrypted password |
2928 * @param string The name of the field that handles MD5 challenge data |
2930 * @param string The name of the field that handles MD5 challenge data |
|
2931 * @param string The name of the field that tells if the server supports DiffieHellman |
|
2932 * @param string The name of the field with the DiffieHellman public key |
|
2933 * @param string The name of the field that the client should populate with its public key |
2929 * @return string |
2934 * @return string |
2930 */ |
2935 */ |
2931 |
2936 |
2932 function aes_javascript($form_name, $pw_field, $use_crypt, $crypt_key, $crypt_data, $challenge) |
2937 function aes_javascript($form_name, $pw_field, $use_crypt, $crypt_key, $crypt_data, $challenge, $dh_supported = false, $dh_pubkey = false, $dh_client_pubkey = false) |
2933 { |
2938 { |
2934 $code = ' |
2939 $code = ' |
2935 <script type="text/javascript"> |
2940 <script type="text/javascript"> |
2936 disableJSONExts(); |
2941 |
2937 str = \'\'; |
|
2938 for(i=0;i<keySizeInBits/4;i++) str+=\'0\'; |
|
2939 var key = hexToByteArray(str); |
|
2940 var pt = hexToByteArray(str); |
|
2941 var ct = rijndaelEncrypt(pt, key, \'ECB\'); |
|
2942 var ct = byteArrayToHex(ct); |
|
2943 switch(keySizeInBits) |
|
2944 { |
|
2945 case 128: |
|
2946 v = \'66e94bd4ef8a2c3b884cfa59ca342b2e\'; |
|
2947 break; |
|
2948 case 192: |
|
2949 v = \'aae06992acbf52a3e8f4a96ec9300bd7aae06992acbf52a3e8f4a96ec9300bd7\'; |
|
2950 break; |
|
2951 case 256: |
|
2952 v = \'dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087\'; |
|
2953 break; |
|
2954 } |
|
2955 var testpassed = ' . ( ( isset($_GET['use_crypt']) && $_GET['use_crypt']=='0') ? 'false; // CRYPTO-AUTH DISABLED ON USER REQUEST // ' : '' ) . '( ct == v && md5_vm_test() ); |
|
2956 var frm = document.forms.'.$form_name.'; |
|
2957 function runEncryption() |
2942 function runEncryption() |
2958 { |
2943 { |
|
2944 var testpassed = ' . ( ( isset($_GET['use_crypt']) && $_GET['use_crypt']=='0') ? 'false; // CRYPTO-AUTH DISABLED ON USER REQUEST // ' : '' ) . '( aes_self_test() && md5_vm_test() ); |
2959 var frm = document.forms.'.$form_name.'; |
2945 var frm = document.forms.'.$form_name.'; |
2960 if(testpassed) |
2946 var use_diffiehellman = false;' . "\n"; |
|
2947 if ( $dh_supported && $dh_pubkey ) |
|
2948 { |
|
2949 $code .= <<<EOF |
|
2950 if ( frm.$dh_supported.value == 'true' ) |
|
2951 use_diffiehellman = true; |
|
2952 EOF; |
|
2953 } |
|
2954 $code .= ' |
|
2955 |
|
2956 if ( frm[\'' . $dh_supported . '\'] ) |
|
2957 { |
|
2958 frm[\'' . $dh_supported . '\'].value = ( use_diffiehellman ) ? "true" : "false"; |
|
2959 } |
|
2960 |
|
2961 if ( testpassed && use_diffiehellman ) |
|
2962 { |
|
2963 // try to blank out the table to prevent double submits and what have you |
|
2964 var el = frm.' . $pw_field . '; |
|
2965 while ( el.tagName != "BODY" && el.tagName != "TABLE" ) |
|
2966 { |
|
2967 el = el.parentNode; |
|
2968 } |
|
2969 if ( el.tagName == "TABLE" ) |
|
2970 { |
|
2971 whiteOutElement(el); |
|
2972 } |
|
2973 |
|
2974 frm.'.$use_crypt.'.value = \'yes_dh\'; |
|
2975 |
|
2976 // Perform Diffie Hellman stuff |
|
2977 // console.info("DiffieHellman: started keygen process"); |
|
2978 var dh_priv = dh_gen_private(); |
|
2979 var dh_pub = dh_gen_public(dh_priv); |
|
2980 var secret = dh_gen_shared_secret(dh_priv, frm.' . $dh_pubkey . '.value); |
|
2981 // console.info("DiffieHellman: finished keygen process"); |
|
2982 |
|
2983 // secret_hash is used to verify that the server guesses the correct secret |
|
2984 var secret_hash = hex_sha1(secret); |
|
2985 |
|
2986 // give the server our values |
|
2987 frm.' . $crypt_key . '.value = secret_hash; |
|
2988 frm.' . $dh_client_pubkey . '.value = dh_pub; |
|
2989 |
|
2990 // console.info("DiffieHellman: set public values"); |
|
2991 |
|
2992 // crypt_key is the actual AES key |
|
2993 var crypt_key = (hex_sha256(secret)).substr(0, (keySizeInBits / 4)); |
|
2994 |
|
2995 // Perform encryption |
|
2996 crypt_key = hexToByteArray(crypt_key); |
|
2997 var pass = frm.'.$pw_field.'.value; |
|
2998 pass = stringToByteArray(pass); |
|
2999 var cryptstring = rijndaelEncrypt(pass, crypt_key, \'ECB\'); |
|
3000 if(!cryptstring) |
|
3001 { |
|
3002 return false; |
|
3003 } |
|
3004 cryptstring = byteArrayToHex(cryptstring); |
|
3005 // console.info("DiffieHellman: finished AES"); |
|
3006 frm.'.$crypt_data.'.value = cryptstring; |
|
3007 frm.'.$pw_field.'.value = \'\'; |
|
3008 // console.info("DiffieHellman: ready to submit"); |
|
3009 } |
|
3010 else if ( testpassed && !use_diffiehellman ) |
2961 { |
3011 { |
2962 frm.'.$use_crypt.'.value = \'yes\'; |
3012 frm.'.$use_crypt.'.value = \'yes\'; |
2963 var cryptkey = frm.'.$crypt_key.'.value; |
3013 var cryptkey = frm.'.$crypt_key.'.value; |
2964 frm.'.$crypt_key.'.value = hex_md5(cryptkey); |
3014 frm.'.$crypt_key.'.value = hex_md5(cryptkey); |
2965 cryptkey = hexToByteArray(cryptkey); |
3015 cryptkey = hexToByteArray(cryptkey); |