# HG changeset patch # User Dan # Date 1195167734 18000 # Node ID e7bbbb92385b91675eda4915ba373e20b33de16c # Parent 62ee6685ad189646fd70f5680abac4559305e89c# Parent ba28d43a6b8662ac425ba395c60e2c968187829a Merge in installer fixes from 204 (ba28d43a6b86) diff -r ba28d43a6b86 -r e7bbbb92385b .hgtags --- a/.hgtags Thu Nov 15 17:52:53 2007 -0500 +++ b/.hgtags Thu Nov 15 18:02:14 2007 -0500 @@ -5,3 +5,4 @@ 6f0bbf88c3251ca597cb76ac8b59a1ee61d6dd3d rebrand 0b5244001799fa29e83bf06c5f14eb69350f171c rebrand 42c6c83b8a004163c9cc2d85f3c8eada3b73adf6 rebrand +d53cc29308f4f4b97fc6d054e9e0855f37137409 rebrand diff -r ba28d43a6b86 -r e7bbbb92385b ajax.php diff -r ba28d43a6b86 -r e7bbbb92385b includes/captcha.php --- a/includes/captcha.php Thu Nov 15 17:52:53 2007 -0500 +++ b/includes/captcha.php Thu Nov 15 18:02:14 2007 -0500 @@ -1,7 +1,8 @@ query_backtrace = ''; $this->num_queries = 0; dc_here('dbal: we\'re in, selecting database...'); - $q = $this->sql_query('USE '.$dbname.';'); + $q = $this->sql_query('USE `'.$dbname.'`;'); if(!$q) $this->_die('The database could not be selected.'); dc_here('dbal: connected to MySQL'); $this->disable_errorhandler(); diff -r ba28d43a6b86 -r e7bbbb92385b includes/email.php --- a/includes/email.php Thu Nov 15 17:52:53 2007 -0500 +++ b/includes/email.php Thu Nov 15 18:02:14 2007 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.2 (Coblynau) + * Version 1.1.1 * 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 diff -r ba28d43a6b86 -r e7bbbb92385b includes/functions.php diff -r ba28d43a6b86 -r e7bbbb92385b includes/graphs.php --- a/includes/graphs.php Thu Nov 15 17:52:53 2007 -0500 +++ b/includes/graphs.php Thu Nov 15 18:02:14 2007 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.2 (Coblynau) + * Version 1.1.1 * 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 diff -r ba28d43a6b86 -r e7bbbb92385b includes/js-compressor.php --- a/includes/js-compressor.php Thu Nov 15 17:52:53 2007 -0500 +++ b/includes/js-compressor.php Thu Nov 15 18:02:14 2007 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.2 (Coblynau) + * Version 1.1.1 * 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 * diff -r ba28d43a6b86 -r e7bbbb92385b includes/pageprocess.php --- a/includes/pageprocess.php Thu Nov 15 17:52:53 2007 -0500 +++ b/includes/pageprocess.php Thu Nov 15 18:02:14 2007 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.2 (Coblynau) + * Version 1.1.1 * pageprocess.php - intelligent retrieval of pages * Copyright (C) 2006-2007 Dan Fuhry * diff -r ba28d43a6b86 -r e7bbbb92385b includes/pageutils.php diff -r ba28d43a6b86 -r e7bbbb92385b includes/paths.php diff -r ba28d43a6b86 -r e7bbbb92385b includes/plugins.php --- a/includes/plugins.php Thu Nov 15 17:52:53 2007 -0500 +++ b/includes/plugins.php Thu Nov 15 18:02:14 2007 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.2 (Coblynau) + * Version 1.1.1 * 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 diff -r ba28d43a6b86 -r e7bbbb92385b includes/render.php diff -r ba28d43a6b86 -r e7bbbb92385b includes/search.php --- a/includes/search.php Thu Nov 15 17:52:53 2007 -0500 +++ b/includes/search.php Thu Nov 15 18:02:14 2007 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.2 (Coblynau) + * Version 1.1.1 * Copyright (C) 2006-2007 Dan Fuhry * search.php - algorithm used to search pages * diff -r ba28d43a6b86 -r e7bbbb92385b includes/sessions.php --- a/includes/sessions.php Thu Nov 15 17:52:53 2007 -0500 +++ b/includes/sessions.php Thu Nov 15 18:02:14 2007 -0500 @@ -206,8 +206,8 @@ var $acl_deps = Array(); /** - * Our tell-all list of permissions. - * @access private - or, preferably, protected + * Our tell-all list of permissions. Do not even try to change this. + * @access private * @var array */ @@ -2596,8 +2596,8 @@ var $acl_deps = Array(); /** - * Our tell-all list of permissions. - * @access private - or, preferably, protected...too bad this has to be PHP4 compatible + * Our tell-all list of permissions. Do not even try to change this. + * @access private * @var array */ diff -r ba28d43a6b86 -r e7bbbb92385b includes/stats.php --- a/includes/stats.php Thu Nov 15 17:52:53 2007 -0500 +++ b/includes/stats.php Thu Nov 15 18:02:14 2007 -0500 @@ -1,7 +1,8 @@ fullpage, 'level=' . $session->user_level, true); echo '
'; } if ( $this->site_disabled && $session->user_level >= USER_LEVEL_ADMIN && ( $paths->page != $paths->nslist['Special'] . 'Administration' ) ) diff -r ba28d43a6b86 -r e7bbbb92385b includes/wikiengine/Tables.php --- a/includes/wikiengine/Tables.php Thu Nov 15 17:52:53 2007 -0500 +++ b/includes/wikiengine/Tables.php Thu Nov 15 18:02:14 2007 -0500 @@ -1,8 +1,8 @@ The Enano installer has found a Enano installation in this directory. You MUST delete config.php if you want to re-install Enano.If you wish to upgrade an older Enano installation to this version, please use the upgrade script.
'); - exit; -} - -define('IN_ENANO_INSTALL', 'true'); - -define('ENANO_VERSION', '1.0.2'); -// In beta versions, define ENANO_BETA_VERSION here - -if(!defined('scriptPath')) { - $sp = dirname($_SERVER['REQUEST_URI']); - if($sp == '/' || $sp == '\\') $sp = ''; - define('scriptPath', $sp); -} - -if(!defined('contentPath')) { - $sp = dirname($_SERVER['REQUEST_URI']); - if($sp == '/' || $sp == '\\') $sp = ''; - define('contentPath', $sp); -} -global $_starttime, $this_page, $sideinfo; -$_starttime = microtime(true); - -// Determine directory (special case for development servers) -if ( strpos(__FILE__, '/repo/') && file_exists('.enanodev') ) -{ - $filename = str_replace('/repo/', '/', __FILE__); -} -else -{ - $filename = __FILE__; -} - -define('ENANO_ROOT', dirname($filename)); - -function is_page($p) -{ - return true; -} - -require('includes/wikiformat.php'); -require('includes/constants.php'); -require('includes/rijndael.php'); -require('includes/functions.php'); - -strip_magic_quotes_gpc(); -$neutral_color = 'C'; - -// -// INSTALLER LIBRARY -// - -function run_installer_stage($stage_id, $stage_name, $function, $failure_explanation, $allow_skip = true) -{ - static $resumed = false; - static $resume_stack = array(); - - if ( empty($resume_stack) && isset($_POST['resume_stack']) && preg_match('/[a-z_]+((\|[a-z_]+)+)/', $_POST['resume_stack']) ) - { - $resume_stack = explode('|', $_POST['resume_stack']); - } - - $already_run = false; - if ( in_array($stage_id, $resume_stack) ) - { - $already_run = true; - } - - if ( !$resumed ) - { - if ( !isset($_GET['stage']) ) - $resumed = true; - if ( isset($_GET['stage']) && $_GET['stage'] == $stage_id ) - { - $resumed = true; - } - } - if ( !$resumed && $allow_skip ) - { - echo_stage_success($stage_id, "[dbg: skipped] $stage_name"); - return false; - } - if ( !function_exists($function) ) - die('libenanoinstall: CRITICAL: function "' . $function . '" for ' . $stage_id . ' doesn\'t exist'); - $result = @call_user_func($function, false, $already_run); - if ( $result ) - { - echo_stage_success($stage_id, $stage_name); - $resume_stack[] = $stage_id; - return true; - } - else - { - echo_stage_failure($stage_id, $stage_name, $failure_explanation, $resume_stack); - return false; - } -} - -function start_install_table() -{ - echo 'SECURITY: malformed database name
"); - - // First, try to connect using the normal credentials - $conn = @mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']); - if ( !$conn ) - { - // Connection failed. Do we have the root username and password? - if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) ) - { - $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']); - if ( !$conn_root ) - { - // Couldn't connect using either set of credentials. Bail out. - return false; - } - // Create the user account - $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'localhost' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn_root); - if ( !$q ) - { - return false; - } - // Revoke privileges from test, we don't need them - $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'localhost';", $conn_root); - if ( !$q ) - { - return false; - } - if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' ) - { - // If not connecting to a server running on localhost, allow from any host - // this is safer than trying to detect the hostname of the webserver, but less secure - $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'%' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn_root); - if ( !$q ) - { - return false; - } - // Revoke privileges from test, we don't need them - $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'%';", $conn_root); - if ( !$q ) - { - return false; - } - } - } - } - $q = @mysql_query("USE $db_name;", $conn); - if ( !$q ) - { - // access denied to the database; try the whole root schenanegan again - if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) ) - { - $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']); - if ( !$conn_root ) - { - // Couldn't connect as root; bail out - return false; - } - // create the database, if it doesn't exist - $q = @mysql_query("CREATE DATABASE IF NOT EXISTS $db_name;", $conn_root); - if ( !$q ) - { - // this really should never fail, so don't give any tolerance to it - return false; - } - // we're in with root rights; grant access to the database - $q = @mysql_query("GRANT ALL PRIVILEGES ON $db_name.* TO '{$db_user}'@'localhost';", $conn_root); - if ( !$q ) - { - return false; - } - if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' ) - { - $q = @mysql_query("GRANT ALL PRIVILEGES ON $db_name.* TO '{$db_user}'@'%';", $conn_root); - if ( !$q ) - { - return false; - } - } - } - else - { - return false; - } - // try again - $q = @mysql_query("USE $db_name;", $conn); - if ( !$q ) - { - // really failed this time; bail out - return false; - } - } - // connected and database exists - return true; -} - -function stg_drop_tables() -{ - $conn = stg_mysql_connect(true); - if ( !$conn ) - return false; - // Our list of tables included in Enano - $tables = Array( 'categories', 'comments', 'config', 'logs', 'page_text', 'session_keys', 'pages', 'users', 'users_extra', 'themes', 'buddies', 'banlist', 'files', 'privmsgs', 'sidebar', 'hits', 'search_index', 'groups', 'group_members', 'acl', 'search_cache', 'tags', 'page_groups', 'page_group_members' ); - - // Drop each table individually; if it fails, it probably means we're trying to drop a - // table that didn't exist in the Enano version we're deleting the database for. - foreach ( $tables as $table ) - { - // Remember that table_prefix is sanitized. - $table = "{$_POST['table_prefix']}$table"; - @mysql_query("DROP TABLE $table;", $conn); - } - return true; -} - -function stg_decrypt_admin_pass($act_get = false) -{ - static $decrypted_pass = false; - if ( $act_get ) - return $decrypted_pass; - - $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); - - if ( !empty($_POST['crypt_data']) ) - { - require('config.new.php'); - if ( !isset($cryptkey) ) - { - return false; - } - define('_INSTRESUME_AES_KEYBACKUP', $key); - $key = hexdecode($cryptkey); - - $decrypted_pass = $aes->decrypt($_POST['crypt_data'], $key, ENC_HEX); - - } - else - { - $decrypted_pass = $_POST['admin_pass']; - } - if ( empty($decrypted_pass) ) - return false; - return true; -} - -function stg_generate_aes_key($act_get = false) -{ - static $key = false; - if ( $act_get ) - return $key; - - $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); - $key = $aes->gen_readymade_key(); - return true; -} - -function stg_parse_schema($act_get = false) -{ - static $schema; - if ( $act_get ) - return $schema; - - $admin_pass = stg_decrypt_admin_pass(true); - $key = stg_generate_aes_key(true); - $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); - $key = $aes->hextostring($key); - $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX); - - $cacheonoff = is_writable(ENANO_ROOT.'/cache/') ? '1' : '0'; - - $schema = file_get_contents('schema.sql'); - $schema = str_replace('{{SITE_NAME}}', mysql_real_escape_string($_POST['sitename'] ), $schema); - $schema = str_replace('{{SITE_DESC}}', mysql_real_escape_string($_POST['sitedesc'] ), $schema); - $schema = str_replace('{{COPYRIGHT}}', mysql_real_escape_string($_POST['copyright'] ), $schema); - $schema = str_replace('{{ADMIN_USER}}', mysql_real_escape_string($_POST['admin_user'] ), $schema); - $schema = str_replace('{{ADMIN_PASS}}', mysql_real_escape_string($admin_pass ), $schema); - $schema = str_replace('{{ADMIN_EMAIL}}', mysql_real_escape_string($_POST['admin_email']), $schema); - $schema = str_replace('{{ENABLE_CACHE}}', mysql_real_escape_string($cacheonoff ), $schema); - $schema = str_replace('{{REAL_NAME}}', '', $schema); - $schema = str_replace('{{TABLE_PREFIX}}', $_POST['table_prefix'], $schema); - $schema = str_replace('{{VERSION}}', ENANO_VERSION, $schema); - $schema = str_replace('{{ADMIN_EMBED_PHP}}', $_POST['admin_embed_php'], $schema); - // Not anymore!! :-D - // $schema = str_replace('{{BETA_VERSION}}', ENANO_BETA_VERSION, $schema); - - if(isset($_POST['wiki_mode'])) - { - $schema = str_replace('{{WIKI_MODE}}', '1', $schema); - } - else - { - $schema = str_replace('{{WIKI_MODE}}', '0', $schema); - } - - // Build an array of queries - $schema = explode("\n", $schema); - - foreach ( $schema as $i => $sql ) - { - $query =& $schema[$i]; - $t = trim($query); - if ( empty($t) || preg_match('/^(\#|--)/i', $t) ) - { - unset($schema[$i]); - unset($query); - } - } - - $schema = array_values($schema); - $schema = implode("\n", $schema); - $schema = explode(";\n", $schema); - - foreach ( $schema as $i => $sql ) - { - $query =& $schema[$i]; - if ( substr($query, ( strlen($query) - 1 ), 1 ) != ';' ) - { - $query .= ';'; - } - } - - return true; -} - -function stg_install($_unused, $already_run) -{ - // This one's pretty easy. - $conn = stg_mysql_connect(true); - if ( !is_resource($conn) ) - return false; - $schema = stg_parse_schema(true); - if ( !is_array($schema) ) - return false; - - // If we're resuming installation, the encryption key was regenerated. - // This means we'll have to update the encrypted password in the database. - if ( $already_run ) - { - $admin_pass = stg_decrypt_admin_pass(true); - $key = stg_generate_aes_key(true); - $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); - $key = $aes->hextostring($key); - $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX); - $admin_user = mysql_real_escape_string($_POST['admin_user']); - - $q = @mysql_query("UPDATE {$_POST['table_prefix']}users SET password='$admin_pass' WHERE username='$admin_user';"); - if ( !$q ) - { - echo 'MySQL return: ' . mysql_error() . '
'; - return false; - } - - return true; - } - - // OK, do the loop, baby!!! - foreach($schema as $q) - { - $r = mysql_query($q, $conn); - if ( !$r ) - { - echo 'MySQL return: ' . mysql_error() . '
'; - return false; - } - } - - return true; -} - -function stg_write_config() -{ - $privkey = stg_generate_aes_key(true); - - switch($_POST['urlscheme']) - { - case "ugly": - default: - $cp = scriptPath.'/index.php?title='; - break; - case "short": - $cp = scriptPath.'/index.php/'; - break; - case "tiny": - $cp = scriptPath.'/'; - break; - } - - if ( $_POST['urlscheme'] == 'tiny' ) - { - $contents = '# Begin Enano rules -RewriteEngine on -RewriteCond %{REQUEST_FILENAME} !-d -RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule ^(.+) '.scriptPath.'/index.php?title=$1 [L,QSA] -RewriteRule \.(php|html|gif|jpg|png|css|js)$ - [L] -# End Enano rules -'; - if ( file_exists('./.htaccess') ) - $ht = fopen(ENANO_ROOT.'/.htaccess', 'a+'); - else - $ht = fopen(ENANO_ROOT.'/.htaccess.new', 'w'); - if ( !$ht ) - return false; - fwrite($ht, $contents); - fclose($ht); - } - - $config_file = ''; - - $cf_handle = fopen(ENANO_ROOT.'/config.new.php', 'w'); - if ( !$cf_handle ) - return false; - fwrite($cf_handle, $config_file); - - fclose($cf_handle); - - return true; -} - -function _stg_rename_config_revert() -{ - if ( file_exists('./config.php') ) - { - @rename('./config.php', './config.new.php'); - } - - $handle = @fopen('./config.php.new', 'w'); - if ( !$handle ) - return false; - $contents = ''; - fwrite($handle, $contents); - fclose($handle); - return true; -} - -function stg_rename_config() -{ - if ( !@rename('./config.new.php', './config.php') ) - { - echo 'Can\'t rename config.php
'; - _stg_rename_config_revert(); - return false; - } - - if ( $_POST['urlscheme'] == 'tiny' && !file_exists('./.htaccess') ) - { - if ( !@rename('./.htaccess.new', './.htaccess') ) - { - echo 'Can\'t rename .htaccess
'; - _stg_rename_config_revert(); - return false; - } - } - return true; -} - -function stg_start_api_success() -{ - return true; -} - -function stg_start_api_failure() -{ - return false; -} - -function stg_init_logs() -{ - global $db, $session, $paths, $template, $plugins; // Common objects - - $q = $db->sql_query('INSERT INTO ' . table_prefix . 'logs(log_type,action,time_id,date_string,author,page_text,edit_summary) VALUES(\'security\', \'install_enano\', ' . time() . ', \'' . date('d M Y h:i a') . '\', \'' . mysql_real_escape_string($_POST['admin_user']) . '\', \'' . mysql_real_escape_string(ENANO_VERSION) . '\', \'' . mysql_real_escape_string($_SERVER['REMOTE_ADDR']) . '\');'); - if ( !$q ) - { - echo 'MySQL return: ' . mysql_error() . '
'; - return false; - } - - if ( !$session->get_permissions('clear_logs') ) - { - echo '$session: denied clear_logs
'; - return false; - } - - PageUtils::flushlogs('Main_Page', 'Article'); - - return true; -} - -//die('Key size: ' . AES_BITS . '([\s]*?)<\/p>#is', '', $result);
- $result = preg_replace('#
([\s]*?)
$desc | "; - } elseif(!$val && $warn) { - if($cv) $color='FFFFCC'; else $color='FFFFAA'; - echo " |
$desc $extended_desc | |
$desc $extended_desc |
Now we need some information that will allow Enano to contact your database server. Enano uses MySQL as a data storage backend, - and we need to have access to a MySQL server in order to continue.
-If you do not have access to a MySQL server, and you are using your own server, you can download MySQL for free from - MySQL.com. Please note that, like Enano, MySQL is licensed under the GNU GPL. - If you need to modify MySQL and then distribute your modifications, you must either distribute them under the terms of the GPL - or purchase a proprietary license.
- MySQL login information for this virtual appliance:ERROR: Cannot open config.php for writing - exiting!
'; - $template->footer(); - exit; - } - fwrite($handle, ''); - fclose($handle); - } - // Sorry for the ugly hack, but this f***s up jEdit badly. - echo ' - - '; - ?> - - - restart the installation.'; - $template->footer(); - exit; - } - unset($_POST['_cont']); - ?> - - restart the installation.'; - $template->footer(); - exit; - } - switch($_POST['urlscheme']) - { - case "ugly": - default: - $cp = scriptPath.'/index.php?title='; - break; - case "short": - $cp = scriptPath.'/index.php/'; - break; - case "tiny": - $cp = scriptPath.'/'; - break; - } - function err($t) { global $template; echo $t; $template->footer(); exit; } - - // $stages = array('connect', 'decrypt', 'genkey', 'parse', 'sql', 'writeconfig', 'renameconfig', 'startapi', 'initlogs'); - - if ( !preg_match('/^[a-z0-9_]*$/', $_POST['table_prefix']) ) - err('Hacking attempt was detected in table_prefix.'); - - start_install_table(); - // The stages connect, decrypt, genkey, and parse are preprocessing and don't do any actual data modification. - // Thus, they need to be run on each retry, e.g. never skipped. - run_installer_stage('connect', 'Connect to MySQL', 'stg_mysql_connect', 'MySQL denied our attempt to connect to the database. This is most likely because your login information was incorrect. You will most likely need to restart the installation.', false); - if ( isset($_POST['drop_tables']) ) - { - // Are we supposed to drop any existing tables? If so, do it now - run_installer_stage('drop', 'Drop existing Enano tables', 'stg_drop_tables', 'This step never returns failure'); - } - run_installer_stage('decrypt', 'Decrypt administration password', 'stg_decrypt_admin_pass', 'The administration password you entered couldn\'t be decrypted. It is possible that your server did not properly store the encryption key in the configuration file. Please check the file permissions on config.new.php. You may have to return to the login stage of the installation, clear your browser cache, and then rerun this installation.', false); - run_installer_stage('genkey', 'Generate ' . AES_BITS . '-bit AES private key', 'stg_generate_aes_key', 'Enano encountered an internal error while generating the site encryption key. Please contact the Enano team for support.', false); - run_installer_stage('parse', 'Prepare to execute schema file', 'stg_parse_schema', 'Enano encountered an internal error while parsing the SQL file that contains the database structure and initial data. Please contact the Enano team for support.', false); - run_installer_stage('sql', 'Execute installer schema', 'stg_install', 'The installation failed because an SQL query wasn\'t quite correct. It is possible that you entered malformed data into a form field, or there may be a bug in Enano with your version of MySQL. Please contact the Enano team for support.', false); - run_installer_stage('writeconfig', 'Write configuration files', 'stg_write_config', 'Enano was unable to write the configuration file with your site\'s database credentials. This is almost always because your configuration file does not have the correct permissions. On Windows servers, you may see this message even if the check on the System Requirements page passed. Temporarily running IIS as the Administrator user may help.'); - run_installer_stage('renameconfig', 'Rename configuration files', 'stg_rename_config', 'Enano couldn\'t rename the configuration files to their correct production names. On some UNIX systems, you need to CHMOD the directory with your Enano files to 777 in order for this stage to succeed.'); - - // Mainstream installation complete - Enano should be usable now - // The stage of starting the API is special because it has to be called out of function context. - // To alleviate this, we have two functions, one that returns success and one that returns failure - // If the Enano API load is successful, the success function is called to report the action to the user - // If unsuccessful, the failure report is sent - - $template_bak = $template; - - $_GET['title'] = 'Main_Page'; - require('includes/common.php'); - - if ( is_object($db) && is_object($session) ) - { - run_installer_stage('startapi', 'Start the Enano API', 'stg_start_api_success', '...', false); - } - else - { - run_installer_stage('startapi', 'Start the Enano API', 'stg_start_api_failure', 'The Enano API could not be started. This is an error that should never occur; please contact the Enano team for support.', false); - } - - // We need to be logged in (with admin rights) before logs can be flushed - $admin_password = stg_decrypt_admin_pass(true); - $session->login_without_crypto($_POST['admin_user'], $admin_password, false); - - // Now that login cookies are set, initialize the session manager and ACLs - $session->start(); - $paths->init(); - - run_installer_stage('initlogs', 'Initialize logs', 'stg_init_logs', 'The session manager denied the request to flush logs for the main page.Review any warnings above, and then click here to finish the installation.'; - - // echo ''; - - break; - case "finish": - echo '
You have finished installing Enano on this server.
-Click the link below to see the main page for your website. Where to go from here:
-If you wish to upgrade an older Enano installation to this version, please use the upgrade script.
'); + exit; +} + +define('IN_ENANO_INSTALL', 'true'); + +define('ENANO_VERSION', '1.0.2'); +// In beta versions, define ENANO_BETA_VERSION here + +if(!defined('scriptPath')) { + $sp = dirname($_SERVER['REQUEST_URI']); + if($sp == '/' || $sp == '\\') $sp = ''; + define('scriptPath', $sp); +} + +if(!defined('contentPath')) { + $sp = dirname($_SERVER['REQUEST_URI']); + if($sp == '/' || $sp == '\\') $sp = ''; + define('contentPath', $sp); +} +global $_starttime, $this_page, $sideinfo; +$_starttime = microtime(true); + +// Determine directory (special case for development servers) +if ( strpos(__FILE__, '/repo/') && file_exists('.enanodev') ) +{ + $filename = str_replace('/repo/', '/', __FILE__); +} +else +{ + $filename = __FILE__; +} + +define('ENANO_ROOT', dirname($filename)); + +function is_page($p) +{ + return true; +} + +require('includes/wikiformat.php'); +require('includes/constants.php'); +require('includes/rijndael.php'); +require('includes/functions.php'); + +strip_magic_quotes_gpc(); +$neutral_color = 'C'; + +// +// INSTALLER LIBRARY +// + +function run_installer_stage($stage_id, $stage_name, $function, $failure_explanation, $allow_skip = true) +{ + static $resumed = false; + static $resume_stack = array(); + + if ( empty($resume_stack) && isset($_POST['resume_stack']) && preg_match('/[a-z_]+((\|[a-z_]+)+)/', $_POST['resume_stack']) ) + { + $resume_stack = explode('|', $_POST['resume_stack']); + } + + $already_run = false; + if ( in_array($stage_id, $resume_stack) ) + { + $already_run = true; + } + + if ( !$resumed ) + { + if ( !isset($_GET['stage']) ) + $resumed = true; + if ( isset($_GET['stage']) && $_GET['stage'] == $stage_id ) + { + $resumed = true; + } + } + if ( !$resumed && $allow_skip ) + { + echo_stage_success($stage_id, "[dbg: skipped] $stage_name"); + return false; + } + if ( !function_exists($function) ) + die('libenanoinstall: CRITICAL: function "' . $function . '" for ' . $stage_id . ' doesn\'t exist'); + $result = @call_user_func($function, false, $already_run); + if ( $result ) + { + echo_stage_success($stage_id, $stage_name); + $resume_stack[] = $stage_id; + return true; + } + else + { + echo_stage_failure($stage_id, $stage_name, $failure_explanation, $resume_stack); + return false; + } +} + +function start_install_table() +{ + echo 'SECURITY: malformed database name
"); + + // First, try to connect using the normal credentials + $conn = @mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']); + if ( !$conn ) + { + // Connection failed. Do we have the root username and password? + if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) ) + { + $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']); + if ( !$conn_root ) + { + // Couldn't connect using either set of credentials. Bail out. + return false; + } + // Create the user account + $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'localhost' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn_root); + if ( !$q ) + { + return false; + } + // Revoke privileges from test, we don't need them + $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'localhost';", $conn_root); + if ( !$q ) + { + return false; + } + if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' ) + { + // If not connecting to a server running on localhost, allow from any host + // this is safer than trying to detect the hostname of the webserver, but less secure + $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'%' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn_root); + if ( !$q ) + { + return false; + } + // Revoke privileges from test, we don't need them + $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'%';", $conn_root); + if ( !$q ) + { + return false; + } + } + } + } + $q = @mysql_query("USE $db_name;", $conn); + if ( !$q ) + { + // access denied to the database; try the whole root schenanegan again + if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) ) + { + $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']); + if ( !$conn_root ) + { + // Couldn't connect as root; bail out + return false; + } + // create the database, if it doesn't exist + $q = @mysql_query("CREATE DATABASE IF NOT EXISTS $db_name;", $conn_root); + if ( !$q ) + { + // this really should never fail, so don't give any tolerance to it + return false; + } + // we're in with root rights; grant access to the database + $q = @mysql_query("GRANT ALL PRIVILEGES ON $db_name.* TO '{$db_user}'@'localhost';", $conn_root); + if ( !$q ) + { + return false; + } + if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' ) + { + $q = @mysql_query("GRANT ALL PRIVILEGES ON $db_name.* TO '{$db_user}'@'%';", $conn_root); + if ( !$q ) + { + return false; + } + } + } + else + { + return false; + } + // try again + $q = @mysql_query("USE $db_name;", $conn); + if ( !$q ) + { + // really failed this time; bail out + return false; + } + } + // connected and database exists + return true; +} + +function stg_drop_tables() +{ + $conn = stg_mysql_connect(true); + if ( !$conn ) + return false; + // Our list of tables included in Enano + $tables = Array( 'categories', 'comments', 'config', 'logs', 'page_text', 'session_keys', 'pages', 'users', 'users_extra', 'themes', 'buddies', 'banlist', 'files', 'privmsgs', 'sidebar', 'hits', 'search_index', 'groups', 'group_members', 'acl', 'search_cache', 'tags', 'page_groups', 'page_group_members' ); + + // Drop each table individually; if it fails, it probably means we're trying to drop a + // table that didn't exist in the Enano version we're deleting the database for. + foreach ( $tables as $table ) + { + // Remember that table_prefix is sanitized. + $table = "{$_POST['table_prefix']}$table"; + @mysql_query("DROP TABLE $table;", $conn); + } + return true; +} + +function stg_decrypt_admin_pass($act_get = false) +{ + static $decrypted_pass = false; + if ( $act_get ) + return $decrypted_pass; + + $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); + + if ( !empty($_POST['crypt_data']) ) + { + require('config.new.php'); + if ( !isset($cryptkey) ) + { + return false; + } + define('_INSTRESUME_AES_KEYBACKUP', $key); + $key = hexdecode($cryptkey); + + $decrypted_pass = $aes->decrypt($_POST['crypt_data'], $key, ENC_HEX); + + } + else + { + $decrypted_pass = $_POST['admin_pass']; + } + if ( empty($decrypted_pass) ) + return false; + return true; +} + +function stg_generate_aes_key($act_get = false) +{ + static $key = false; + if ( $act_get ) + return $key; + + $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); + $key = $aes->gen_readymade_key(); + return true; +} + +function stg_parse_schema($act_get = false) +{ + static $schema; + if ( $act_get ) + return $schema; + + $admin_pass = stg_decrypt_admin_pass(true); + $key = stg_generate_aes_key(true); + $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); + $key = $aes->hextostring($key); + $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX); + + $cacheonoff = is_writable(ENANO_ROOT.'/cache/') ? '1' : '0'; + + $schema = file_get_contents('schema.sql'); + $schema = str_replace('{{SITE_NAME}}', mysql_real_escape_string($_POST['sitename'] ), $schema); + $schema = str_replace('{{SITE_DESC}}', mysql_real_escape_string($_POST['sitedesc'] ), $schema); + $schema = str_replace('{{COPYRIGHT}}', mysql_real_escape_string($_POST['copyright'] ), $schema); + $schema = str_replace('{{ADMIN_USER}}', mysql_real_escape_string($_POST['admin_user'] ), $schema); + $schema = str_replace('{{ADMIN_PASS}}', mysql_real_escape_string($admin_pass ), $schema); + $schema = str_replace('{{ADMIN_EMAIL}}', mysql_real_escape_string($_POST['admin_email']), $schema); + $schema = str_replace('{{ENABLE_CACHE}}', mysql_real_escape_string($cacheonoff ), $schema); + $schema = str_replace('{{REAL_NAME}}', '', $schema); + $schema = str_replace('{{TABLE_PREFIX}}', $_POST['table_prefix'], $schema); + $schema = str_replace('{{VERSION}}', ENANO_VERSION, $schema); + $schema = str_replace('{{ADMIN_EMBED_PHP}}', $_POST['admin_embed_php'], $schema); + // Not anymore!! :-D + // $schema = str_replace('{{BETA_VERSION}}', ENANO_BETA_VERSION, $schema); + + if(isset($_POST['wiki_mode'])) + { + $schema = str_replace('{{WIKI_MODE}}', '1', $schema); + } + else + { + $schema = str_replace('{{WIKI_MODE}}', '0', $schema); + } + + // Build an array of queries + $schema = explode("\n", $schema); + + foreach ( $schema as $i => $sql ) + { + $query =& $schema[$i]; + $t = trim($query); + if ( empty($t) || preg_match('/^(\#|--)/i', $t) ) + { + unset($schema[$i]); + unset($query); + } + } + + $schema = array_values($schema); + $schema = implode("\n", $schema); + $schema = explode(";\n", $schema); + + foreach ( $schema as $i => $sql ) + { + $query =& $schema[$i]; + if ( substr($query, ( strlen($query) - 1 ), 1 ) != ';' ) + { + $query .= ';'; + } + } + + return true; +} + +function stg_install($_unused, $already_run) +{ + // This one's pretty easy. + $conn = stg_mysql_connect(true); + if ( !is_resource($conn) ) + return false; + $schema = stg_parse_schema(true); + if ( !is_array($schema) ) + return false; + + // If we're resuming installation, the encryption key was regenerated. + // This means we'll have to update the encrypted password in the database. + if ( $already_run ) + { + $admin_pass = stg_decrypt_admin_pass(true); + $key = stg_generate_aes_key(true); + $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); + $key = $aes->hextostring($key); + $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX); + $admin_user = mysql_real_escape_string($_POST['admin_user']); + + $q = @mysql_query("UPDATE {$_POST['table_prefix']}users SET password='$admin_pass' WHERE username='$admin_user';"); + if ( !$q ) + { + echo 'MySQL return: ' . mysql_error() . '
'; + return false; + } + + return true; + } + + // OK, do the loop, baby!!! + foreach($schema as $q) + { + $r = mysql_query($q, $conn); + if ( !$r ) + { + echo 'MySQL return: ' . mysql_error() . '
'; + return false; + } + } + + return true; +} + +function stg_write_config() +{ + $privkey = stg_generate_aes_key(true); + + switch($_POST['urlscheme']) + { + case "ugly": + default: + $cp = scriptPath.'/index.php?title='; + break; + case "short": + $cp = scriptPath.'/index.php/'; + break; + case "tiny": + $cp = scriptPath.'/'; + break; + } + + if ( $_POST['urlscheme'] == 'tiny' ) + { + $contents = '# Begin Enano rules +RewriteEngine on +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME} !-f +RewriteRule ^(.+) '.scriptPath.'/index.php?title=$1 [L,QSA] +RewriteRule \.(php|html|gif|jpg|png|css|js)$ - [L] +# End Enano rules +'; + if ( file_exists('./.htaccess') ) + $ht = fopen(ENANO_ROOT.'/.htaccess', 'a+'); + else + $ht = fopen(ENANO_ROOT.'/.htaccess.new', 'w'); + if ( !$ht ) + return false; + fwrite($ht, $contents); + fclose($ht); + } + + $config_file = ''; + + $cf_handle = fopen(ENANO_ROOT.'/config.new.php', 'w'); + if ( !$cf_handle ) + return false; + fwrite($cf_handle, $config_file); + + fclose($cf_handle); + + return true; +} + +function _stg_rename_config_revert() +{ + if ( file_exists('./config.php') ) + { + @rename('./config.php', './config.new.php'); + } + + $handle = @fopen('./config.php.new', 'w'); + if ( !$handle ) + return false; + $contents = ''; + fwrite($handle, $contents); + fclose($handle); + return true; +} + +function stg_rename_config() +{ + if ( !@rename('./config.new.php', './config.php') ) + { + echo 'Can\'t rename config.php
'; + _stg_rename_config_revert(); + return false; + } + + if ( $_POST['urlscheme'] == 'tiny' && !file_exists('./.htaccess') ) + { + if ( !@rename('./.htaccess.new', './.htaccess') ) + { + echo 'Can\'t rename .htaccess
'; + _stg_rename_config_revert(); + return false; + } + } + return true; +} + +function stg_start_api_success() +{ + return true; +} + +function stg_start_api_failure() +{ + return false; +} + +function stg_init_logs() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + + $q = $db->sql_query('INSERT INTO ' . table_prefix . 'logs(log_type,action,time_id,date_string,author,page_text,edit_summary) VALUES(\'security\', \'install_enano\', ' . time() . ', \'' . date('d M Y h:i a') . '\', \'' . mysql_real_escape_string($_POST['admin_user']) . '\', \'' . mysql_real_escape_string(ENANO_VERSION) . '\', \'' . mysql_real_escape_string($_SERVER['REMOTE_ADDR']) . '\');'); + if ( !$q ) + { + echo 'MySQL return: ' . mysql_error() . '
'; + return false; + } + + if ( !$session->get_permissions('clear_logs') ) + { + echo '$session: denied clear_logs
'; + return false; + } + + PageUtils::flushlogs('Main_Page', 'Article'); + + return true; +} + +//die('Key size: ' . AES_BITS . '([\s]*?)<\/p>#is', '', $result);
+ $result = preg_replace('#
([\s]*?)
$desc | "; + } elseif(!$val && $warn) { + if($cv) $color='FFFFCC'; else $color='FFFFAA'; + echo " |
$desc $extended_desc | |
$desc $extended_desc |
Now we need some information that will allow Enano to contact your database server. Enano uses MySQL as a data storage backend, + and we need to have access to a MySQL server in order to continue.
+If you do not have access to a MySQL server, and you are using your own server, you can download MySQL for free from + MySQL.com. Please note that, like Enano, MySQL is licensed under the GNU GPL. + If you need to modify MySQL and then distribute your modifications, you must either distribute them under the terms of the GPL + or purchase a proprietary license.
+ MySQL login information for this virtual appliance:ERROR: Cannot open config.php for writing - exiting!
'; + $template->footer(); + exit; + } + fwrite($handle, ''); + fclose($handle); + } + // Sorry for the ugly hack, but this f***s up jEdit badly. + echo ' + + '; + ?> + + + restart the installation.'; + $template->footer(); + exit; + } + unset($_POST['_cont']); + ?> + + restart the installation.'; + $template->footer(); + exit; + } + switch($_POST['urlscheme']) + { + case "ugly": + default: + $cp = scriptPath.'/index.php?title='; + break; + case "short": + $cp = scriptPath.'/index.php/'; + break; + case "tiny": + $cp = scriptPath.'/'; + break; + } + function err($t) { global $template; echo $t; $template->footer(); exit; } + + // $stages = array('connect', 'decrypt', 'genkey', 'parse', 'sql', 'writeconfig', 'renameconfig', 'startapi', 'initlogs'); + + if ( !preg_match('/^[a-z0-9_]*$/', $_POST['table_prefix']) ) + err('Hacking attempt was detected in table_prefix.'); + + start_install_table(); + // The stages connect, decrypt, genkey, and parse are preprocessing and don't do any actual data modification. + // Thus, they need to be run on each retry, e.g. never skipped. + run_installer_stage('connect', 'Connect to MySQL', 'stg_mysql_connect', 'MySQL denied our attempt to connect to the database. This is most likely because your login information was incorrect. You will most likely need to restart the installation.', false); + if ( isset($_POST['drop_tables']) ) + { + // Are we supposed to drop any existing tables? If so, do it now + run_installer_stage('drop', 'Drop existing Enano tables', 'stg_drop_tables', 'This step never returns failure'); + } + run_installer_stage('decrypt', 'Decrypt administration password', 'stg_decrypt_admin_pass', 'The administration password you entered couldn\'t be decrypted. It is possible that your server did not properly store the encryption key in the configuration file. Please check the file permissions on config.new.php. You may have to return to the login stage of the installation, clear your browser cache, and then rerun this installation.', false); + run_installer_stage('genkey', 'Generate ' . AES_BITS . '-bit AES private key', 'stg_generate_aes_key', 'Enano encountered an internal error while generating the site encryption key. Please contact the Enano team for support.', false); + run_installer_stage('parse', 'Prepare to execute schema file', 'stg_parse_schema', 'Enano encountered an internal error while parsing the SQL file that contains the database structure and initial data. Please contact the Enano team for support.', false); + run_installer_stage('sql', 'Execute installer schema', 'stg_install', 'The installation failed because an SQL query wasn\'t quite correct. It is possible that you entered malformed data into a form field, or there may be a bug in Enano with your version of MySQL. Please contact the Enano team for support.', false); + run_installer_stage('writeconfig', 'Write configuration files', 'stg_write_config', 'Enano was unable to write the configuration file with your site\'s database credentials. This is almost always because your configuration file does not have the correct permissions. On Windows servers, you may see this message even if the check on the System Requirements page passed. Temporarily running IIS as the Administrator user may help.'); + run_installer_stage('renameconfig', 'Rename configuration files', 'stg_rename_config', 'Enano couldn\'t rename the configuration files to their correct production names. On some UNIX systems, you need to CHMOD the directory with your Enano files to 777 in order for this stage to succeed.'); + + // Mainstream installation complete - Enano should be usable now + // The stage of starting the API is special because it has to be called out of function context. + // To alleviate this, we have two functions, one that returns success and one that returns failure + // If the Enano API load is successful, the success function is called to report the action to the user + // If unsuccessful, the failure report is sent + + $template_bak = $template; + + $_GET['title'] = 'Main_Page'; + require('includes/common.php'); + + if ( is_object($db) && is_object($session) ) + { + run_installer_stage('startapi', 'Start the Enano API', 'stg_start_api_success', '...', false); + } + else + { + run_installer_stage('startapi', 'Start the Enano API', 'stg_start_api_failure', 'The Enano API could not be started. This is an error that should never occur; please contact the Enano team for support.', false); + } + + // We need to be logged in (with admin rights) before logs can be flushed + $admin_password = stg_decrypt_admin_pass(true); + $session->login_without_crypto($_POST['admin_user'], $admin_password, false); + + // Now that login cookies are set, initialize the session manager and ACLs + $session->start(); + $paths->init(); + + run_installer_stage('initlogs', 'Initialize logs', 'stg_init_logs', 'The session manager denied the request to flush logs for the main page.Review any warnings above, and then click here to finish the installation.'; + + // echo ''; + + break; + case "finish": + echo '
You have finished installing Enano on this server.
+Click the link below to see the main page for your website. Where to go from here:
+