Fixed some stray version numbers (again!); added support for Diffie-Hellman logins in the normal login form (not AJAX) - even works in IE
--- a/cron.php Mon Mar 17 09:47:19 2008 -0400
+++ b/cron.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
*
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
--- a/includes/captcha.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/captcha.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* captcha.php - visual confirmation system used during registration
*
--- a/includes/captcha/engine_default.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/captcha/engine_default.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* captcha.php - visual confirmation system used during registration
*
--- a/includes/captcha/engine_failsafe.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/captcha/engine_failsafe.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* captcha.php - visual confirmation system used during registration
*
--- a/includes/captcha/engine_potpourri.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/captcha/engine_potpourri.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* captcha.php - visual confirmation system used during registration
*
--- a/includes/clientside/jsres.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/clientside/jsres.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* jsres.php - the Enano client-side runtime, a.k.a. AJAX on steroids
*
--- a/includes/clientside/static/faders.js Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/clientside/static/faders.js Tue Mar 18 14:32:40 2008 -0400
@@ -487,3 +487,30 @@
}
}
+function whiteOutElement(el)
+{
+ var top = $(el).Top();
+ var left = $(el).Left();
+ var width = $(el).Width();
+ var height = $(el).Height();
+
+ var blackout = document.createElement('div');
+ blackout.style.position = 'absolute';
+ blackout.style.top = top + 'px';
+ blackout.style.left = left + 'px';
+ blackout.style.width = width + 'px';
+ blackout.style.height = height + 'px';
+
+ blackout.style.backgroundColor = '#FFFFFF';
+ domObjChangeOpac(60, blackout);
+ blackout.style.backgroundImage = 'url(' + scriptPath + '/includes/clientside/tinymce/themes/advanced/skins/default/img/progress.gif)';
+ blackout.style.backgroundPosition = 'center center';
+ blackout.style.backgroundRepeat = 'no-repeat';
+ blackout.style.zIndex = getHighestZ() + 2;
+
+ var body = document.getElementsByTagName('body')[0];
+ body.appendChild(blackout);
+
+ return blackout;
+}
+
--- a/includes/comment.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/comment.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
*
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
--- a/includes/constants.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/constants.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* constants.php - important defines used Enano-wide
*
@@ -104,10 +104,6 @@
define('PROTECT_FULL', 1);
define('PROTECT_SEMI', 2);
-// Special comments - plugin blocks
-define('PLUGIN_METABLOCK_LANGUAGE_START', '/**!language**');
-define('PLUGIN_METABLOCK_LANGUAGE_END', '**!*/');
-
//
// Enano versions progress
//
--- a/includes/diffiehellman.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/diffiehellman.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* diffiehellman.php - Diffie Hellman key exchange and supporting functions
*
@@ -17,7 +17,16 @@
* The Diffie-Hellman key exchange protocol
*/
-$GLOBALS['_math'] = enanomath_create();
+global $dh_supported;
+$dh_supported = true;
+try
+{
+ $GLOBALS['_math'] = enanomath_create();
+}
+catch ( Exception $e )
+{
+ $dh_supported = false;
+}
// Our prime number as a base for operations.
$GLOBALS['dh_prime'] = '82818079787776757473727170696867666564636261605958575655545352515049484746454443424140393837363534333231302928272625242322212019181716151413121110987654321';
--- a/includes/email.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/email.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
*
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
--- a/includes/functions.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/functions.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
*
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
--- a/includes/http.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/http.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* class_http.php - Pure PHP HTTP client library
*
--- a/includes/js-compressor.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/js-compressor.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* Javascript compression library - used to compact the client-side Javascript code (all 72KB of it!) to save some bandwidth
*
--- a/includes/lang.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/lang.php Tue Mar 18 14:32:40 2008 -0400
@@ -364,23 +364,13 @@
if ( $this->lang_id == 0 )
$db->_die('lang.php - BUG: trying to perform import when $lang->lang_id == 0');
- $contents = trim(@file_get_contents($file));
-
- if ( empty($contents) )
- $db->_die('lang.php - can\'t load the contents of the language file');
-
- // If there isn't a specially formed comment block, bail out quietly.
- if ( !strpos($contents, PLUGIN_METABLOCK_LANGUAGE_START) || !strpos($contents, PLUGIN_METABLOCK_LANGUAGE_END) )
- return null;
+ $block = pluginLoader::parse_plugin_blocks($file, 'language');
+ if ( !is_array($block) )
+ return false;
+ if ( !isset($block[0]) )
+ return false;
- // Get all data in the language block
- $block_start = strpos($contents, PLUGIN_METABLOCK_LANGUAGE_START) + strlen(PLUGIN_METABLOCK_LANGUAGE_START);
- $block_end = strpos($contents, PLUGIN_METABLOCK_LANGUAGE_END);
- $block_len = $block_end - $block_start;
- if ( $block_len < 1 )
- $db->_die('lang.php - plugin file contains corrupt language data');
-
- $contents = substr($contents, $block_start, $block_len);
+ $contents =& $block[0]['value'];
// Trim off all text before and after the starting and ending braces
$contents = preg_replace('/^([^{]+)\{/', '{', $contents);
--- a/includes/math.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/math.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* diffiehellman.php - Diffie Hellman key exchange and supporting functions
*
--- a/includes/pageprocess.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/pageprocess.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* pageprocess.php - intelligent retrieval of pages
* Copyright (C) 2006-2007 Dan Fuhry
*
--- a/includes/paths.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/paths.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/**
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* paths.php - The part of Enano that actually manages content. Everything related to page handling and namespaces is in here.
*
--- a/includes/plugins.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/plugins.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
*
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
@@ -172,6 +172,77 @@
{
return isset( $this->loaded_plugins[$plugid] );
}
+
+ /**
+ * Parses all special comment blocks in a plugin and returns an array in the format:
+ <code>
+ array(
+ 0 => array(
+ 'block' => 'upgrade',
+ // parsed from the block's parameters section
+ 'release_from' => '1.0b1',
+ 'release_to' => '1.0b2',
+ 'value' => 'foo'
+ ),
+ 1 => array(
+ ...
+ )
+ );
+ </code>
+ * @param string Path to plugin file
+ * @param string Optional. The type of block to fetch. If this is specified, only the block type specified will be read, all others will be discarded.
+ * @return array
+ */
+
+ public static function parse_plugin_blocks($file, $type = false)
+ {
+ if ( !file_exists($file) )
+ {
+ return array();
+ }
+ $blocks = array();
+ $contents = @file_get_contents($file);
+ if ( empty($contents) )
+ {
+ return array();
+ }
+
+ $regexp = '#^/\*\*!([a-z0-9_]+)' // block header and type
+ . '(([\s]+[a-z0-9_]+[\s]*=[\s]*".+?"[\s]*;)*)' // parameters
+ . '[\s]*\*\*' . "\n" // spacing and header close
+ . '([\w\W]+?)' . "\n" // value
+ . '\*\*!\*/' // closing comment
+ . '#m';
+
+ // Match out all blocks
+
+ $results = preg_match_all($regexp, $contents, $blocks);
+
+ $return = array();
+ foreach ( $blocks[0] as $i => $_ )
+ {
+ if ( is_string($type) && $blocks[1][$i] !== $type )
+ continue;
+
+ $el = self::parse_vars($blocks[2][$i]);
+ $el['block'] = $blocks[1][$i];
+ $el['value'] = $blocks[4][$i];
+ $return[] = $el;
+ }
+
+ return $return;
+ }
+
+ private static function parse_vars($var_block)
+ {
+ preg_match_all('/[\s]+([a-z0-9_]+)[\s]*=[\s]*"(.+?)";/', $var_block, $matches);
+ $return = array();
+ foreach ( $matches[0] as $i => $_ )
+ {
+ $return[ $matches[1][$i] ] = $matches[2][$i];
+ }
+ return $return;
+ }
}
?>
--- a/includes/render.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/render.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* render.php - handles fetching pages and parsing them into HTML
*
--- a/includes/search.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/search.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* search.php - algorithm used to search pages
*
--- a/includes/sessions.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/sessions.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* sessions.php - everything related to security and user management
*
@@ -864,20 +864,22 @@
$duration = ( $_ = getConfig('lockout_duration') ) ? intval($_) : 15;
// convert to minutes
$duration = $duration * 60;
+ $policy = ( $x = getConfig('lockout_policy') && in_array(getConfig('lockout_policy'), array('lockout', 'disable', 'captcha')) ) ? getConfig('lockout_policy') : 'lockout';
- // get the lockout status
$timestamp_cutoff = time() - $duration;
$ipaddr = $db->escape($_SERVER['REMOTE_ADDR']);
$q = $this->sql('SELECT timestamp FROM '.table_prefix.'lockout WHERE timestamp > ' . $timestamp_cutoff . ' AND ipaddr = \'' . $ipaddr . '\' ORDER BY timestamp DESC;');
$fails = $db->numrows();
- $policy = ( $x = getConfig('lockout_policy') && in_array(getConfig('lockout_policy'), array('lockout', 'disable', 'captcha')) ) ? getConfig('lockout_policy') : 'lockout';
$captcha_good = false;
if ( $policy == 'captcha' && $captcha_hash && $captcha_code )
{
// policy is captcha -- check if it's correct, and if so, bypass lockout check
$real_code = $this->get_captcha($captcha_hash);
- $captcha_good = ( strtolower($real_code) === strtolower($captcha_code) );
+ if ( strtolower($real_code) === strtolower($captcha_code) )
+ {
+ $captcha_good = true;
+ }
}
if ( $policy != 'disable' && !$captcha_good )
{
@@ -2926,38 +2928,86 @@
* @param string The name of the field that contains the encryption key
* @param string The name of the field that will contain the encrypted password
* @param string The name of the field that handles MD5 challenge data
+ * @param string The name of the field that tells if the server supports DiffieHellman
+ * @param string The name of the field with the DiffieHellman public key
+ * @param string The name of the field that the client should populate with its public key
* @return string
*/
- function aes_javascript($form_name, $pw_field, $use_crypt, $crypt_key, $crypt_data, $challenge)
+ function aes_javascript($form_name, $pw_field, $use_crypt, $crypt_key, $crypt_data, $challenge, $dh_supported = false, $dh_pubkey = false, $dh_client_pubkey = false)
{
$code = '
<script type="text/javascript">
- 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 = ' . ( ( isset($_GET['use_crypt']) && $_GET['use_crypt']=='0') ? 'false; // CRYPTO-AUTH DISABLED ON USER REQUEST // ' : '' ) . '( ct == v && md5_vm_test() );
- var frm = document.forms.'.$form_name.';
+
function runEncryption()
{
+ var testpassed = ' . ( ( isset($_GET['use_crypt']) && $_GET['use_crypt']=='0') ? 'false; // CRYPTO-AUTH DISABLED ON USER REQUEST // ' : '' ) . '( aes_self_test() && md5_vm_test() );
var frm = document.forms.'.$form_name.';
- if(testpassed)
+ var use_diffiehellman = false;' . "\n";
+ if ( $dh_supported && $dh_pubkey )
+ {
+ $code .= <<<EOF
+ if ( frm.$dh_supported.value == 'true' )
+ use_diffiehellman = true;
+EOF;
+ }
+ $code .= '
+
+ if ( frm[\'' . $dh_supported . '\'] )
+ {
+ frm[\'' . $dh_supported . '\'].value = ( use_diffiehellman ) ? "true" : "false";
+ }
+
+ if ( testpassed && use_diffiehellman )
+ {
+ // try to blank out the table to prevent double submits and what have you
+ var el = frm.' . $pw_field . ';
+ while ( el.tagName != "BODY" && el.tagName != "TABLE" )
+ {
+ el = el.parentNode;
+ }
+ if ( el.tagName == "TABLE" )
+ {
+ whiteOutElement(el);
+ }
+
+ frm.'.$use_crypt.'.value = \'yes_dh\';
+
+ // Perform Diffie Hellman stuff
+ // console.info("DiffieHellman: started keygen process");
+ var dh_priv = dh_gen_private();
+ var dh_pub = dh_gen_public(dh_priv);
+ var secret = dh_gen_shared_secret(dh_priv, frm.' . $dh_pubkey . '.value);
+ // console.info("DiffieHellman: finished keygen process");
+
+ // secret_hash is used to verify that the server guesses the correct secret
+ var secret_hash = hex_sha1(secret);
+
+ // give the server our values
+ frm.' . $crypt_key . '.value = secret_hash;
+ frm.' . $dh_client_pubkey . '.value = dh_pub;
+
+ // console.info("DiffieHellman: set public values");
+
+ // crypt_key is the actual AES key
+ var crypt_key = (hex_sha256(secret)).substr(0, (keySizeInBits / 4));
+
+ // Perform encryption
+ crypt_key = hexToByteArray(crypt_key);
+ var pass = frm.'.$pw_field.'.value;
+ pass = stringToByteArray(pass);
+ var cryptstring = rijndaelEncrypt(pass, crypt_key, \'ECB\');
+ if(!cryptstring)
+ {
+ return false;
+ }
+ cryptstring = byteArrayToHex(cryptstring);
+ // console.info("DiffieHellman: finished AES");
+ frm.'.$crypt_data.'.value = cryptstring;
+ frm.'.$pw_field.'.value = \'\';
+ // console.info("DiffieHellman: ready to submit");
+ }
+ else if ( testpassed && !use_diffiehellman )
{
frm.'.$use_crypt.'.value = \'yes\';
var cryptkey = frm.'.$crypt_key.'.value;
--- a/includes/stats.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/stats.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
* stats.php - handles statistics for pages (disablable in the admin CP)
*
--- a/includes/tagcloud.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/tagcloud.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
*
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
--- a/includes/template.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/template.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
*
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
--- a/includes/wikiengine/Tables.php Mon Mar 17 09:47:19 2008 -0400
+++ b/includes/wikiengine/Tables.php Tue Mar 18 14:32:40 2008 -0400
@@ -2,7 +2,7 @@
/*
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
+ * Version 1.1.3 (Caoineag alpha 3)
* Copyright (C) 2006-2007 Dan Fuhry
*
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
--- a/plugins/SpecialUserFuncs.php Mon Mar 17 09:47:19 2008 -0400
+++ b/plugins/SpecialUserFuncs.php Tue Mar 18 14:32:40 2008 -0400
@@ -169,6 +169,7 @@
}
// 1.1.3: generate diffie hellman key
+ require_once( ENANO_ROOT . '/includes/diffiehellman.php' );
global $dh_supported, $_math;
$response['dh_supported'] = $dh_supported;
@@ -206,7 +207,7 @@
if ( $level <= USER_LEVEL_MEMBER && $session->user_logged_in )
$paths->main_page();
$template->header();
- echo '<form action="'.makeUrl($paths->nslist['Special'].'Login').'" method="post" name="loginform" onsubmit="runEncryption();">';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Login').'" method="post" name="loginform" onsubmit="try{runEncryption();}catch(e){};">';
$header = ( $level > USER_LEVEL_MEMBER ) ? $lang->get('user_login_message_short_elev') : $lang->get('user_login_message_short');
if ( isset($_POST['login']) )
{
@@ -226,11 +227,11 @@
$errstring = $lang->get('user_err_invalid_credentials');
if ( $__login_status['lockout_policy'] == 'lockout' )
{
- $errstring .= $lang->get('err_invalid_credentials_lockout', array('lockout_fails' => $__login_status['lockout_fails']));
+ $errstring .= $lang->get('err_invalid_credentials_lockout', array('fails' => $__login_status['lockout_fails']));
}
else if ( $__login_status['lockout_policy'] == 'captcha' )
{
- $errstring .= $lang->get('user_err_invalid_credentials_lockout_captcha', array('lockout_fails' => $__login_status['lockout_fails']));
+ $errstring .= $lang->get('user_err_invalid_credentials_lockout_captcha', array('fails' => $__login_status['lockout_fails']));
}
break;
case 'backend_fail':
@@ -248,7 +249,7 @@
$s = ( $time_rem == 1 ) ? '' : $lang->get('meta_plural');
- $captcha_string = ( $__login_status['lockout_policy'] == 'captcha' ) ? $lang->get('err_locked_out_captcha_blurb') : '';
+ $captcha_string = ( $__login_status['lockout_policy'] == 'captcha' ) ? $lang->get('user_err_locked_out_captcha_blurb') : '';
$errstring = $lang->get('user_err_locked_out', array('plural' => $s, 'captcha_blurb' => $captcha_string, 'time_rem' => $time_rem));
break;
@@ -330,26 +331,35 @@
<?php
}
?>
- <tr>
- <td class="row3" colspan="3">
- <?php
- if ( $level <= USER_LEVEL_MEMBER && ( !isset($_GET['use_crypt']) || ( isset($_GET['use_crypt']) && $_GET['use_crypt']!='0' ) ) )
- {
- $returnpage_link = ( $return = $paths->getAllParams() ) ? '/' . $return : '';
- $nocrypt_link = makeUrlNS('Special', "Login$returnpage_link", "level=$level&use_crypt=0", true);
- echo '<p><b>' . $lang->get('user_login_nocrypt_title') . '</b> ' . $lang->get('user_login_nocrypt_body', array('nocrypt_link' => $nocrypt_link)) . '</p>';
- echo '<p>' . $lang->get('user_login_nocrypt_countrylist') . '</p>';
- }
- else if ( $level <= USER_LEVEL_MEMBER && ( isset($_GET['use_crypt']) && $_GET['use_crypt']=='0' ) )
- {
- $returnpage_link = ( $return = $paths->getAllParams() ) ? '/' . $return : '';
- $usecrypt_link = makeUrlNS('Special', "Login$returnpage_link", "level=$level&use_crypt=1", true);
- echo '<p><b>' . $lang->get('user_login_usecrypt_title') . '</b> ' . $lang->get('user_login_usecrypt_body', array('usecrypt_link' => $usecrypt_link)) . '</p>';
- echo '<p>' . $lang->get('user_login_usecrypt_countrylist') . '</p>';
- }
- ?>
- </td>
- </tr>
+ <?php
+ if ( $level <= USER_LEVEL_MEMBER && ( !isset($_GET['use_crypt']) || ( isset($_GET['use_crypt']) && $_GET['use_crypt']!='0' ) ) )
+ {
+ echo '<tr>
+ <td class="row3" colspan="3">';
+
+ $returnpage_link = ( $return = $paths->getAllParams() ) ? '/' . $return : '';
+ $nocrypt_link = makeUrlNS('Special', "Login$returnpage_link", "level=$level&use_crypt=0", true);
+ echo '<p><b>' . $lang->get('user_login_nocrypt_title') . '</b> ' . $lang->get('user_login_nocrypt_body', array('nocrypt_link' => $nocrypt_link)) . '</p>';
+ echo '<p>' . $lang->get('user_login_nocrypt_countrylist') . '</p>';
+
+ echo ' </td>
+ </tr>';
+ }
+ else if ( $level <= USER_LEVEL_MEMBER && ( isset($_GET['use_crypt']) && $_GET['use_crypt']=='0' ) )
+ {
+ echo '<tr>
+ <td class="row3" colspan="3">';
+
+ $returnpage_link = ( $return = $paths->getAllParams() ) ? '/' . $return : '';
+ $usecrypt_link = makeUrlNS('Special', "Login$returnpage_link", "level=$level&use_crypt=1", true);
+ echo '<p><b>' . $lang->get('user_login_usecrypt_title') . '</b> ' . $lang->get('user_login_usecrypt_body', array('usecrypt_link' => $usecrypt_link)) . '</p>';
+ echo '<p>' . $lang->get('user_login_usecrypt_countrylist') . '</p>';
+
+ echo ' </td>
+ </tr>';
+ }
+ ?>
+
<tr>
<th colspan="3" style="text-align: center" class="subhead"><input type="submit" name="login" value="Log in" tabindex="<?php echo ( $level <= USER_LEVEL_MEMBER ) ? '3' : '2'; ?>" /></th>
</tr>
@@ -369,9 +379,35 @@
document.forms.loginform.pass.focus();
</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\" />";
+ }
+ ?>
</form>
<?php
- echo $session->aes_javascript('loginform', 'pass', 'use_crypt', 'crypt_key', 'crypt_data', 'challenge_data');
+ echo $session->aes_javascript('loginform', 'pass', 'use_crypt', 'crypt_key', 'crypt_data', 'challenge_data', 'dh_supported', 'dh_public_key', 'dh_client_public_key');
?>
<?php
$template->footer();
@@ -407,103 +443,74 @@
}
if ( isset($_GET['act']) && $_GET['act'] == 'ajaxlogin' )
{
- $plugins->attachHook('login_password_reset', 'SpecialLogin_SendResponse_PasswordReset($row[\'user_id\'], $row[\'temp_password\']);');
- $data = enano_json_decode($_POST['params']);
- $captcha_hash = ( isset($data['captcha_hash']) ) ? $data['captcha_hash'] : false;
- $captcha_code = ( isset($data['captcha_code']) ) ? $data['captcha_code'] : false;
- $level = ( isset($data['level']) ) ? intval($data['level']) : USER_LEVEL_MEMBER;
-
- // 1.1.3: Diffie Hellman
- global $dh_supported;
- global $_math;
- if ( $data['diffiehellman'] && isset($data['publickey_client']) && isset($data['publickey_server']) && isset($data['crypt_key_check']) )
+ die('This version of the Enano LoginAPI is deprecated. Please use the action.json method instead.');
+ $db->close();
+ exit;
+ }
+ 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' )
{
+ $result = $session->login_with_crypto($_POST['username'], $_POST['crypt_data'], $_POST['crypt_key'], $_POST['challenge_data'], intval($_POST['auth_level']), $captcha_hash, $captcha_code);
+ }
+ else if ( $_POST['use_crypt'] == 'yes_dh' )
+ {
+ // retrieve and decrypt the password using DiffieHellman
+
+ require_once( ENANO_ROOT . '/includes/diffiehellman.php' );
+ global $dh_supported, $_math;
+
if ( !$dh_supported )
{
- die('Special:Login: Illegal request for Diffie Hellman exchange');
+ die_semicritical('DiffieHellman error', 'Server does not support DiffieHellman, denying logon request');
}
- // retrieve our public key
- if ( !preg_match('/^[0-9]+$/', $data['publickey_server']) )
+
+ // Fetch private key
+ $dh_public = $_POST['dh_public_key'];
+ if ( !preg_match('/^[0-9]+$/', $dh_public) )
{
- die('Special:Login: Illegal request for Diffie Hellman exchange');
+ die_semicritical('DiffieHellman error', 'Public key not integer: ' . $dh_public);
}
- $pubkey_server =& $data['publickey_server'];
-
- // retrieve our private key
- $q = $db->sql_query('SELECT private_key, key_id FROM ' . table_prefix . "diffiehellman WHERE public_key = '$pubkey_server';");
+ $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 )
{
- die('Special:Login: Couldn\'t lookup Diffie Hellman key: ' . $pubkey_server);
+ die_semicritical('DiffieHellman error', 'ERR_DH_KEY_NOT_FOUND');
}
- list($privkey_server, $key_id) = $db->fetchrow_num();
+
+ list($dh_private, $dh_key_id) = $db->fetchrow_num();
$db->free_result();
- // get shared secret
- $dh_secret = dh_gen_shared_secret($privkey_server, $data['publickey_client']);
+ // 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);
- $secret_check = sha1($dh_secret);
- if ( $secret_check !== $data['crypt_key_check'] )
+
+ // Did we get all our math right?
+ $dh_secret_check = sha1($dh_secret);
+ $dh_hash = $_POST['crypt_key'];
+ if ( $dh_secret_check !== $dh_hash )
{
- die(enano_json_encode(array(
- 'mode' => 'error',
- 'error' => 'Diffie Hellman redundancy check failed, couldn\'t rebuild the AES key.',
- 'debug' => array(
- 'server private key' => $privkey_server,
- 'client public key' => $data['publickey_client'],
- 'expected sha1' => $data['crypt_key_check'],
- 'actual sha1' => $secret_check
- )
- )));
+ die_semicritical('DiffieHellman error', 'ERR_DH_HASH_NO_MATCH');
}
- // we have the secret, now get the sha256 hash
- $crypt_key = substr(sha256($dh_secret), 0, ( AES_BITS / 4 ));
- }
- else if ( !$data['diffiehellman'] && isset($data['crypt_key']) && isset($data['crypt_data']) )
- {
- $crypt_key = $data['crypt_key'];
- }
- else
- {
- die('Special:Login: Illegal request');
- }
-
- $result = $session->login_with_crypto($data['username'], $data['crypt_data'], $crypt_key, $data['challenge'], $level, $captcha_hash, $captcha_code, !$dh_supported);
-
- if ( $result['success'] )
- {
- $response = Array(
- 'result' => 'success',
- 'key' => $session->sid_super // ( ( $session->sid_super ) ? $session->sid_super : $session->sid )
- );
- }
- else
- {
- $captcha = '';
- if ( $result['error'] == 'locked_out' && $result['lockout_policy'] == 'captcha' )
- {
- $session->kill_captcha();
- $captcha = $session->make_captcha();
- }
- $response = Array(
- 'result' => 'error',
- 'data' => $result,
- 'captcha' => $captcha
- );
- }
- $response = enano_json_encode($response);
- echo $response;
- $db->close();
- exit;
- }
- 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')
- {
- $result = $session->login_with_crypto($_POST['username'], $_POST['crypt_data'], $_POST['crypt_key'], $_POST['challenge_data'], intval($_POST['auth_level']), $captcha_hash, $captcha_code);
+
+ // 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);
}
else
{