62 require('includes/constants.php'); |
62 require('includes/constants.php'); |
63 require('includes/rijndael.php'); |
63 require('includes/rijndael.php'); |
64 require('includes/functions.php'); |
64 require('includes/functions.php'); |
65 |
65 |
66 strip_magic_quotes_gpc(); |
66 strip_magic_quotes_gpc(); |
|
67 $neutral_color = 'C'; |
|
68 |
|
69 // |
|
70 // INSTALLER LIBRARY |
|
71 // |
|
72 |
|
73 function run_installer_stage($stage_id, $stage_name, $function, $failure_explanation, $allow_skip = true) |
|
74 { |
|
75 static $resumed = false; |
|
76 static $resume_stack = array(); |
|
77 |
|
78 if ( empty($resume_stack) && isset($_POST['resume_stack']) && preg_match('/[a-z_]+((\|[a-z_]+)+)/', $_POST['resume_stack']) ) |
|
79 { |
|
80 $resume_stack = explode('|', $_POST['resume_stack']); |
|
81 } |
|
82 |
|
83 $already_run = false; |
|
84 if ( in_array($stage_id, $resume_stack) ) |
|
85 { |
|
86 $already_run = true; |
|
87 } |
|
88 |
|
89 if ( !$resumed ) |
|
90 { |
|
91 if ( !isset($_GET['stage']) ) |
|
92 $resumed = true; |
|
93 if ( isset($_GET['stage']) && $_GET['stage'] == $stage_id ) |
|
94 { |
|
95 $resumed = true; |
|
96 } |
|
97 } |
|
98 if ( !$resumed && $allow_skip ) |
|
99 { |
|
100 echo_stage_success($stage_id, "[dbg: skipped] $stage_name"); |
|
101 return false; |
|
102 } |
|
103 if ( !function_exists($function) ) |
|
104 die('libenanoinstall: CRITICAL: function "' . $function . '" for ' . $stage_id . ' doesn\'t exist'); |
|
105 $result = @call_user_func($function, false, $already_run); |
|
106 if ( $result ) |
|
107 { |
|
108 echo_stage_success($stage_id, $stage_name); |
|
109 $resume_stack[] = $stage_id; |
|
110 return true; |
|
111 } |
|
112 else |
|
113 { |
|
114 echo_stage_failure($stage_id, $stage_name, $failure_explanation, $resume_stack); |
|
115 return false; |
|
116 } |
|
117 } |
|
118 |
|
119 function start_install_table() |
|
120 { |
|
121 echo '<table border="0" cellspacing="0" cellpadding="0">' . "\n"; |
|
122 } |
|
123 |
|
124 function close_install_table() |
|
125 { |
|
126 echo '</table>' . "\n\n"; |
|
127 } |
|
128 |
|
129 function echo_stage_success($stage_id, $stage_name) |
|
130 { |
|
131 global $neutral_color; |
|
132 $neutral_color = ( $neutral_color == 'A' ) ? 'C' : 'A'; |
|
133 ob_start(); |
|
134 echo '<tr><td style="width: 500px; background-color: #' . "{$neutral_color}{$neutral_color}FF{$neutral_color}{$neutral_color}" . '; padding: 0 5px;">' . htmlspecialchars($stage_name) . '</td><td style="padding: 0 5px;"><img alt="Done" src="images/good.gif" /></td></tr>' . "\n"; |
|
135 ob_end_flush(); |
|
136 } |
|
137 |
|
138 function echo_stage_failure($stage_id, $stage_name, $failure_explanation, $resume_stack) |
|
139 { |
|
140 global $neutral_color; |
|
141 |
|
142 $neutral_color = ( $neutral_color == 'A' ) ? 'C' : 'A'; |
|
143 ob_start(); |
|
144 echo '<tr><td style="width: 500px; background-color: #' . "FF{$neutral_color}{$neutral_color}{$neutral_color}{$neutral_color}" . '; padding: 0 5px;">' . htmlspecialchars($stage_name) . '</td><td style="padding: 0 5px;"><img alt="Failed" src="images/bad.gif" /></td></tr>' . "\n"; |
|
145 ob_end_flush(); |
|
146 close_install_table(); |
|
147 $post_data = ''; |
|
148 foreach ( $_POST as $key => $value ) |
|
149 { |
|
150 $value = htmlspecialchars($value); |
|
151 $key = htmlspecialchars($key); |
|
152 $post_data .= " <input type=\"hidden\" name=\"$key\" value=\"$value\" />\n"; |
|
153 } |
|
154 echo '<form action="install.php?mode=install&stage=' . $stage_id . '" method="post"> |
|
155 ' . $post_data . ' |
|
156 <input type="hidden" name="resume_stack" value="' . htmlspecialchars(implode('|', $resume_stack)) . '" /> |
|
157 <h3>Enano installation failed.</h3> |
|
158 <p>' . $failure_explanation . '</p> |
|
159 <p>When you have corrected the error, click the button below to attempt to continue the installation.</p> |
|
160 <p style="text-align: center;"><input type="submit" value="Retry installation" /></p> |
|
161 </form>'; |
|
162 global $template, $template_bak; |
|
163 if ( is_object($template_bak) ) |
|
164 $template_bak->footer(); |
|
165 else |
|
166 $template->footer(); |
|
167 exit; |
|
168 } |
|
169 |
|
170 // |
|
171 // INSTALLER STAGES |
|
172 // |
|
173 |
|
174 function stg_mysql_connect($act_get = false) |
|
175 { |
|
176 static $conn = false; |
|
177 if ( $act_get ) |
|
178 return $conn; |
|
179 |
|
180 $db_user = mysql_real_escape_string($_POST['db_user']); |
|
181 $db_pass = mysql_real_escape_string($_POST['db_pass']); |
|
182 $db_name = mysql_real_escape_string($_POST['db_name']); |
|
183 |
|
184 if ( !preg_match('/^[a-z0-9_]+$/', $db_name) ) |
|
185 die("<p>SECURITY: malformed database name</p>"); |
|
186 |
|
187 // First, try to connect using the normal credentials |
|
188 $conn = @mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']); |
|
189 if ( !$conn ) |
|
190 { |
|
191 // Connection failed. Do we have the root username and password? |
|
192 if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) ) |
|
193 { |
|
194 $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']); |
|
195 if ( !$conn_root ) |
|
196 { |
|
197 // Couldn't connect using either set of credentials. Bail out. |
|
198 return false; |
|
199 } |
|
200 // Create the user account |
|
201 $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'localhost' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn); |
|
202 if ( !$q ) |
|
203 return false; |
|
204 // Revoke privileges from test, we don't need them |
|
205 $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'localhost';", $conn); |
|
206 if ( !$q ) |
|
207 return false; |
|
208 if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' ) |
|
209 { |
|
210 // If not connecting to a server running on localhost, allow from any host |
|
211 // this is safer than trying to detect the hostname of the webserver, but less secure |
|
212 $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'%' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn); |
|
213 if ( !$q ) |
|
214 return false; |
|
215 // Revoke privileges from test, we don't need them |
|
216 $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'%';", $conn); |
|
217 if ( !$q ) |
|
218 return false; |
|
219 } |
|
220 } |
|
221 } |
|
222 $q = @mysql_query("USE $db_name;", $conn); |
|
223 if ( !$q ) |
|
224 { |
|
225 // access denied to the database; try the whole root schenanegan again |
|
226 if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) ) |
|
227 { |
|
228 $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']); |
|
229 if ( !$conn_root ) |
|
230 { |
|
231 // Couldn't connect as root; bail out |
|
232 return false; |
|
233 } |
|
234 // create the database, if it doesn't exist |
|
235 $q = @mysql_query("CREATE DATABASE $db_name;", $conn); |
|
236 if ( !$q ) |
|
237 // this really should never fail, so don't give any tolerance to it |
|
238 return false; |
|
239 // we're in with root rights; grant access to the database |
|
240 $q = @mysql_query("GRANT ALL PRIVILEGES ON $db_name.* TO '{$db_user}'@'localhost';", $conn); |
|
241 if ( !$q ) |
|
242 return false; |
|
243 if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' ) |
|
244 { |
|
245 $q = @mysql_query("GRANT ALL PRIVILEGES ON $db_name.* TO '{$db_user}'@'%';", $conn); |
|
246 if ( !$q ) |
|
247 return false; |
|
248 } |
|
249 } |
|
250 else |
|
251 { |
|
252 return false; |
|
253 } |
|
254 // try again |
|
255 $q = @mysql_query("USE '$db_name';", $conn); |
|
256 if ( !$q ) |
|
257 // really failed this time; bail out |
|
258 return false; |
|
259 } |
|
260 // connected and database exists |
|
261 return true; |
|
262 } |
|
263 |
|
264 function stg_drop_tables() |
|
265 { |
|
266 $conn = stg_mysql_connect(true); |
|
267 if ( !$conn ) |
|
268 return false; |
|
269 // Our list of tables included in Enano |
|
270 $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' ); |
|
271 |
|
272 // Drop each table individually; if it fails, it probably means we're trying to drop a |
|
273 // table that didn't exist in the Enano version we're deleting the database for. |
|
274 foreach ( $tables as $table ) |
|
275 { |
|
276 // Remember that table_prefix is sanitized. |
|
277 $table = "{$_POST['table_prefix']}$table"; |
|
278 @mysql_query("DROP TABLE $table;", $conn); |
|
279 } |
|
280 return true; |
|
281 } |
|
282 |
|
283 function stg_decrypt_admin_pass($act_get = false) |
|
284 { |
|
285 static $decrypted_pass = false; |
|
286 if ( $act_get ) |
|
287 return $decrypted_pass; |
|
288 |
|
289 $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); |
|
290 |
|
291 if ( !empty($_POST['crypt_data']) ) |
|
292 { |
|
293 require('config.new.php'); |
|
294 if ( !isset($cryptkey) ) |
|
295 { |
|
296 return false; |
|
297 } |
|
298 define('_INSTRESUME_AES_KEYBACKUP', $key); |
|
299 $key = hexdecode($cryptkey); |
|
300 |
|
301 $decrypted_pass = $aes->decrypt($_POST['crypt_data'], $key, ENC_HEX); |
|
302 |
|
303 } |
|
304 else |
|
305 { |
|
306 $decrypted_pass = $_POST['admin_pass']; |
|
307 } |
|
308 if ( empty($decrypted_pass) ) |
|
309 return false; |
|
310 return true; |
|
311 } |
|
312 |
|
313 function stg_generate_aes_key($act_get = false) |
|
314 { |
|
315 static $key = false; |
|
316 if ( $act_get ) |
|
317 return $key; |
|
318 |
|
319 $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); |
|
320 $key = $aes->gen_readymade_key(); |
|
321 return true; |
|
322 } |
|
323 |
|
324 function stg_parse_schema($act_get = false) |
|
325 { |
|
326 static $schema; |
|
327 if ( $act_get ) |
|
328 return $schema; |
|
329 |
|
330 $admin_pass = stg_decrypt_admin_pass(true); |
|
331 $key = stg_generate_aes_key(true); |
|
332 $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); |
|
333 $key = $aes->hextostring($key); |
|
334 $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX); |
|
335 |
|
336 $cacheonoff = is_writable(ENANO_ROOT.'/cache/') ? '1' : '0'; |
|
337 |
|
338 $schema = file_get_contents('schema.sql'); |
|
339 $schema = str_replace('{{SITE_NAME}}', mysql_real_escape_string($_POST['sitename'] ), $schema); |
|
340 $schema = str_replace('{{SITE_DESC}}', mysql_real_escape_string($_POST['sitedesc'] ), $schema); |
|
341 $schema = str_replace('{{COPYRIGHT}}', mysql_real_escape_string($_POST['copyright'] ), $schema); |
|
342 $schema = str_replace('{{ADMIN_USER}}', mysql_real_escape_string($_POST['admin_user'] ), $schema); |
|
343 $schema = str_replace('{{ADMIN_PASS}}', mysql_real_escape_string($admin_pass ), $schema); |
|
344 $schema = str_replace('{{ADMIN_EMAIL}}', mysql_real_escape_string($_POST['admin_email']), $schema); |
|
345 $schema = str_replace('{{ENABLE_CACHE}}', mysql_real_escape_string($cacheonoff ), $schema); |
|
346 $schema = str_replace('{{REAL_NAME}}', '', $schema); |
|
347 $schema = str_replace('{{TABLE_PREFIX}}', $_POST['table_prefix'], $schema); |
|
348 $schema = str_replace('{{VERSION}}', ENANO_VERSION, $schema); |
|
349 $schema = str_replace('{{ADMIN_EMBED_PHP}}', $_POST['admin_embed_php'], $schema); |
|
350 // Not anymore!! :-D |
|
351 // $schema = str_replace('{{BETA_VERSION}}', ENANO_BETA_VERSION, $schema); |
|
352 |
|
353 if(isset($_POST['wiki_mode'])) |
|
354 { |
|
355 $schema = str_replace('{{WIKI_MODE}}', '1', $schema); |
|
356 } |
|
357 else |
|
358 { |
|
359 $schema = str_replace('{{WIKI_MODE}}', '0', $schema); |
|
360 } |
|
361 |
|
362 // Build an array of queries |
|
363 $schema = explode("\n", $schema); |
|
364 |
|
365 foreach ( $schema as $i => $sql ) |
|
366 { |
|
367 $query =& $schema[$i]; |
|
368 $t = trim($query); |
|
369 if ( empty($t) || preg_match('/^(\#|--)/i', $t) ) |
|
370 { |
|
371 unset($schema[$i]); |
|
372 unset($query); |
|
373 } |
|
374 } |
|
375 |
|
376 $schema = array_values($schema); |
|
377 $schema = implode("\n", $schema); |
|
378 $schema = explode(";\n", $schema); |
|
379 |
|
380 foreach ( $schema as $i => $sql ) |
|
381 { |
|
382 $query =& $schema[$i]; |
|
383 if ( substr($query, ( strlen($query) - 1 ), 1 ) != ';' ) |
|
384 { |
|
385 $query .= ';'; |
|
386 } |
|
387 } |
|
388 |
|
389 return true; |
|
390 } |
|
391 |
|
392 function stg_install($_unused, $already_run) |
|
393 { |
|
394 // This one's pretty easy. |
|
395 $conn = stg_mysql_connect(true); |
|
396 if ( !is_resource($conn) ) |
|
397 return false; |
|
398 $schema = stg_parse_schema(true); |
|
399 if ( !is_array($schema) ) |
|
400 return false; |
|
401 |
|
402 // If we're resuming installation, the encryption key was regenerated. |
|
403 // This means we'll have to update the encrypted password in the database. |
|
404 if ( $already_run ) |
|
405 { |
|
406 $admin_pass = stg_decrypt_admin_pass(true); |
|
407 $key = stg_generate_aes_key(true); |
|
408 $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); |
|
409 $key = $aes->hextostring($key); |
|
410 $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX); |
|
411 $admin_user = mysql_real_escape_string($_POST['admin_user']); |
|
412 |
|
413 $q = @mysql_query("UPDATE {$_POST['table_prefix']}users SET password='$admin_pass' WHERE username='$admin_user';"); |
|
414 if ( !$q ) |
|
415 { |
|
416 echo '<p><tt>MySQL return: ' . mysql_error() . '</tt></p>'; |
|
417 return false; |
|
418 } |
|
419 |
|
420 return true; |
|
421 } |
|
422 |
|
423 // OK, do the loop, baby!!! |
|
424 foreach($schema as $q) |
|
425 { |
|
426 $r = mysql_query($q, $conn); |
|
427 if ( !$r ) |
|
428 { |
|
429 echo '<p><tt>MySQL return: ' . mysql_error() . '</tt></p>'; |
|
430 return false; |
|
431 } |
|
432 } |
|
433 |
|
434 return true; |
|
435 } |
|
436 |
|
437 function stg_write_config() |
|
438 { |
|
439 $privkey = stg_generate_aes_key(true); |
|
440 |
|
441 switch($_POST['urlscheme']) |
|
442 { |
|
443 case "ugly": |
|
444 default: |
|
445 $cp = scriptPath.'/index.php?title='; |
|
446 break; |
|
447 case "short": |
|
448 $cp = scriptPath.'/index.php/'; |
|
449 break; |
|
450 case "tiny": |
|
451 $cp = scriptPath.'/'; |
|
452 break; |
|
453 } |
|
454 |
|
455 if ( $_POST['urlscheme'] == 'tiny' ) |
|
456 { |
|
457 $contents = '# Begin Enano rules |
|
458 RewriteEngine on |
|
459 RewriteCond %{REQUEST_FILENAME} !-d |
|
460 RewriteCond %{REQUEST_FILENAME} !-f |
|
461 RewriteRule ^(.+) '.scriptPath.'/index.php?title=$1 [L,QSA] |
|
462 RewriteRule \.(php|html|gif|jpg|png|css|js)$ - [L] |
|
463 # End Enano rules |
|
464 '; |
|
465 if ( file_exists('./.htaccess') ) |
|
466 $ht = fopen(ENANO_ROOT.'/.htaccess', 'a+'); |
|
467 else |
|
468 $ht = fopen(ENANO_ROOT.'/.htaccess.new', 'w'); |
|
469 if ( !$ht ) |
|
470 return false; |
|
471 fwrite($ht, $contents); |
|
472 fclose($ht); |
|
473 } |
|
474 |
|
475 $config_file = '<?php |
|
476 /* Enano auto-generated configuration file - editing not recommended! */ |
|
477 $dbhost = \''.addslashes($_POST['db_host']).'\'; |
|
478 $dbname = \''.addslashes($_POST['db_name']).'\'; |
|
479 $dbuser = \''.addslashes($_POST['db_user']).'\'; |
|
480 $dbpasswd = \''.addslashes($_POST['db_pass']).'\'; |
|
481 if ( !defined(\'ENANO_CONSTANTS\') ) |
|
482 { |
|
483 define(\'ENANO_CONSTANTS\', \'\'); |
|
484 define(\'table_prefix\', \''.addslashes($_POST['table_prefix']).'\'); |
|
485 define(\'scriptPath\', \''.scriptPath.'\'); |
|
486 define(\'contentPath\', \''.$cp.'\'); |
|
487 define(\'ENANO_INSTALLED\', \'true\'); |
|
488 } |
|
489 $crypto_key = \''.$privkey.'\'; |
|
490 ?>'; |
|
491 |
|
492 $cf_handle = fopen(ENANO_ROOT.'/config.new.php', 'w'); |
|
493 if ( !$cf_handle ) |
|
494 return false; |
|
495 fwrite($cf_handle, $config_file); |
|
496 |
|
497 fclose($cf_handle); |
|
498 |
|
499 return true; |
|
500 } |
|
501 |
|
502 function _stg_rename_config_revert() |
|
503 { |
|
504 if ( file_exists('./config.php') ) |
|
505 { |
|
506 @rename('./config.php', './config.new.php'); |
|
507 } |
|
508 |
|
509 $handle = @fopen('./config.php.new', 'w'); |
|
510 if ( !$handle ) |
|
511 return false; |
|
512 $contents = '<?php $cryptkey = \'' . _INSTRESUME_AES_KEYBACKUP . '\'; ?>'; |
|
513 fwrite($handle, $contents); |
|
514 fclose($handle); |
|
515 return true; |
|
516 } |
|
517 |
|
518 function stg_rename_config() |
|
519 { |
|
520 if ( !@rename('./config.new.php', './config.php') ) |
|
521 { |
|
522 echo '<p>Can\'t rename config.php</p>'; |
|
523 _stg_rename_config_revert(); |
|
524 return false; |
|
525 } |
|
526 |
|
527 if ( $_POST['urlscheme'] == 'tiny' && !file_exists('./.htaccess') ) |
|
528 { |
|
529 if ( !@rename('./.htaccess.new', './.htaccess') ) |
|
530 { |
|
531 echo '<p>Can\'t rename .htaccess</p>'; |
|
532 _stg_rename_config_revert(); |
|
533 return false; |
|
534 } |
|
535 } |
|
536 return true; |
|
537 } |
|
538 |
|
539 function stg_start_api_success() |
|
540 { |
|
541 return true; |
|
542 } |
|
543 |
|
544 function stg_start_api_failure() |
|
545 { |
|
546 return false; |
|
547 } |
|
548 |
|
549 function stg_init_logs() |
|
550 { |
|
551 global $db, $session, $paths, $template, $plugins; // Common objects |
|
552 |
|
553 $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']) . '\');'); |
|
554 if ( !$q ) |
|
555 { |
|
556 echo '<p><tt>MySQL return: ' . mysql_error() . '</tt></p>'; |
|
557 return false; |
|
558 } |
|
559 |
|
560 if ( !$session->get_permissions('clear_logs') ) |
|
561 { |
|
562 echo '<p><tt>$session: denied clear_logs</tt></p>'; |
|
563 return false; |
|
564 } |
|
565 |
|
566 PageUtils::flushlogs('Main_Page', 'Article'); |
|
567 |
|
568 return true; |
|
569 } |
67 |
570 |
68 //die('Key size: ' . AES_BITS . '<br />Block size: ' . AES_BLOCKSIZE); |
571 //die('Key size: ' . AES_BITS . '<br />Block size: ' . AES_BLOCKSIZE); |
69 |
572 |
70 if(!function_exists('wikiFormat')) |
573 if(!function_exists('wikiFormat')) |
71 { |
574 { |
991 $cp = scriptPath.'/'; |
1494 $cp = scriptPath.'/'; |
992 break; |
1495 break; |
993 } |
1496 } |
994 function err($t) { global $template; echo $t; $template->footer(); exit; } |
1497 function err($t) { global $template; echo $t; $template->footer(); exit; } |
995 |
1498 |
|
1499 // $stages = array('connect', 'decrypt', 'genkey', 'parse', 'sql', 'writeconfig', 'renameconfig', 'startapi', 'initlogs'); |
|
1500 |
996 if ( !preg_match('/^[a-z0-9_]*$/', $_POST['table_prefix']) ) |
1501 if ( !preg_match('/^[a-z0-9_]*$/', $_POST['table_prefix']) ) |
997 err('Hacking attempt was detected in table_prefix.'); |
1502 err('Hacking attempt was detected in table_prefix.'); |
998 |
1503 |
999 echo 'Connecting to MySQL...'; |
1504 start_install_table(); |
1000 if($_POST['db_root_user'] != '') |
1505 // The stages connect, decrypt, genkey, and parse are preprocessing and don't do any actual data modification. |
1001 { |
1506 // Thus, they need to be run on each retry, e.g. never skipped. |
1002 $conn = mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']); |
1507 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 <a href="install.php?mode=license">restart the installation</a>.<br /><br />Error message returned by MySQL: ' . mysql_error(), false); |
1003 if(!$conn) err('Error connecting to MySQL: '.mysql_error()); |
1508 if ( isset($_POST['drop_tables']) ) |
1004 $q = mysql_query('USE '.$_POST['db_name']); |
1509 { |
1005 if(!$q) |
1510 // Are we supposed to drop any existing tables? If so, do it now |
1006 { |
1511 run_installer_stage('drop', 'Drop existing Enano tables', 'stg_drop_tables', 'This step never returns failure'); |
1007 $q = mysql_query('CREATE DATABASE '.$_POST['db_name']); |
1512 } |
1008 if(!$q) err('Error initializing database: '.mysql_error()); |
1513 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); |
1009 } |
1514 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); |
1010 $q = mysql_query('GRANT ALL PRIVILEGES ON '.$_POST['db_name'].'.* TO \''.$_POST['db_user'].'\'@\'localhost\' IDENTIFIED BY \''.$_POST['db_pass'].'\' WITH GRANT OPTION;'); |
1515 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); |
1011 if(!$q) err('Could not create the user account'); |
1516 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); |
1012 $q = mysql_query('GRANT ALL PRIVILEGES ON '.$_POST['db_name'].'.* TO \''.$_POST['db_user'].'\'@\'%\' IDENTIFIED BY \''.$_POST['db_pass'].'\' WITH GRANT OPTION;'); |
1517 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.'); |
1013 if(!$q) err('Could not create the user account'); |
1518 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.'); |
1014 mysql_close($conn); |
|
1015 } |
|
1016 $conn = mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']); |
|
1017 if(!$conn) err('Error connecting to MySQL: '.mysql_error()); |
|
1018 $q = mysql_query('USE '.$_POST['db_name']); |
|
1019 if(!$q) err('Error selecting database: '.mysql_error()); |
|
1020 echo 'done!<br />'; |
|
1021 |
1519 |
1022 // Are we supposed to drop any existing tables? If so, do it now |
1520 // Mainstream installation complete - Enano should be usable now |
1023 if(isset($_POST['drop_tables'])) |
1521 // The stage of starting the API is special because it has to be called out of function context. |
1024 { |
1522 // To alleviate this, we have two functions, one that returns success and one that returns failure |
1025 echo 'Dropping existing Enano tables...'; |
1523 // If the Enano API load is successful, the success function is called to report the action to the user |
1026 // Our list of tables included in Enano |
1524 // If unsuccessful, the failure report is sent |
1027 $tables = Array( 'mdg_categories', 'mdg_comments', 'mdg_config', 'mdg_logs', 'mdg_page_text', 'mdg_session_keys', 'mdg_pages', 'mdg_users', 'mdg_users_extra', 'mdg_themes', 'mdg_buddies', 'mdg_banlist', 'mdg_files', 'mdg_privmsgs', 'mdg_sidebar', 'mdg_hits', 'mdg_search_index', 'mdg_groups', 'mdg_group_members', 'mdg_acl', 'mdg_search_cache', 'mdg_tags', 'mdg_page_groups', 'mdg_page_group_members' ); |
|
1028 $tables = implode(', ', $tables); |
|
1029 $tables = str_replace('mdg_', $_POST['table_prefix'], $tables); |
|
1030 $query_of_death = 'DROP TABLE '.$tables.';'; |
|
1031 mysql_query($query_of_death); // We won't check for errors here because if this operation fails it probably means the tables didn't exist |
|
1032 echo 'done!<br />'; |
|
1033 } |
|
1034 |
|
1035 $cacheonoff = is_writable(ENANO_ROOT.'/cache/') ? '1' : '0'; |
|
1036 |
|
1037 echo 'Decrypting administration password...'; |
|
1038 |
|
1039 $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); |
|
1040 |
|
1041 if ( !empty($_POST['crypt_data']) ) |
|
1042 { |
|
1043 require('config.new.php'); |
|
1044 if ( !isset($cryptkey) ) |
|
1045 { |
|
1046 echo 'failed!<br />Cannot get the key from config.new.php'; |
|
1047 break; |
|
1048 } |
|
1049 $key = hexdecode($cryptkey); |
|
1050 |
|
1051 $dec = $aes->decrypt($_POST['crypt_data'], $key, ENC_HEX); |
|
1052 |
|
1053 } |
|
1054 else |
|
1055 { |
|
1056 $dec = $_POST['admin_pass']; |
|
1057 } |
|
1058 echo 'done!<br />Generating '.AES_BITS.'-bit AES private key...'; |
|
1059 $privkey = $aes->gen_readymade_key(); |
|
1060 $pkba = hexdecode($privkey); |
|
1061 $encpass = $aes->encrypt($dec, $pkba, ENC_HEX); |
|
1062 |
|
1063 echo 'done!<br />Preparing for schema execution...'; |
|
1064 $schema = file_get_contents('schema.sql'); |
|
1065 $schema = str_replace('{{SITE_NAME}}', mysql_real_escape_string($_POST['sitename'] ), $schema); |
|
1066 $schema = str_replace('{{SITE_DESC}}', mysql_real_escape_string($_POST['sitedesc'] ), $schema); |
|
1067 $schema = str_replace('{{COPYRIGHT}}', mysql_real_escape_string($_POST['copyright'] ), $schema); |
|
1068 $schema = str_replace('{{ADMIN_USER}}', mysql_real_escape_string($_POST['admin_user'] ), $schema); |
|
1069 $schema = str_replace('{{ADMIN_PASS}}', mysql_real_escape_string($encpass ), $schema); |
|
1070 $schema = str_replace('{{ADMIN_EMAIL}}', mysql_real_escape_string($_POST['admin_email']), $schema); |
|
1071 $schema = str_replace('{{ENABLE_CACHE}}', mysql_real_escape_string($cacheonoff ), $schema); |
|
1072 $schema = str_replace('{{REAL_NAME}}', '', $schema); |
|
1073 $schema = str_replace('{{TABLE_PREFIX}}', $_POST['table_prefix'], $schema); |
|
1074 $schema = str_replace('{{VERSION}}', ENANO_VERSION, $schema); |
|
1075 $schema = str_replace('{{ADMIN_EMBED_PHP}}', $_POST['admin_embed_php'], $schema); |
|
1076 // Not anymore!! :-D |
|
1077 // $schema = str_replace('{{BETA_VERSION}}', ENANO_BETA_VERSION, $schema); |
|
1078 |
|
1079 if(isset($_POST['wiki_mode'])) |
|
1080 { |
|
1081 $schema = str_replace('{{WIKI_MODE}}', '1', $schema); |
|
1082 } |
|
1083 else |
|
1084 { |
|
1085 $schema = str_replace('{{WIKI_MODE}}', '0', $schema); |
|
1086 } |
|
1087 |
|
1088 // Build an array of queries |
|
1089 $schema = explode("\n", $schema); |
|
1090 |
|
1091 foreach ( $schema as $i => $sql ) |
|
1092 { |
|
1093 $query =& $schema[$i]; |
|
1094 $t = trim($query); |
|
1095 if ( empty($t) || preg_match('/^(\#|--)/i', $t) ) |
|
1096 { |
|
1097 unset($schema[$i]); |
|
1098 unset($query); |
|
1099 } |
|
1100 } |
|
1101 |
|
1102 $schema = array_values($schema); |
|
1103 $schema = implode("\n", $schema); |
|
1104 $schema = explode(";\n", $schema); |
|
1105 |
|
1106 foreach ( $schema as $i => $sql ) |
|
1107 { |
|
1108 $query =& $schema[$i]; |
|
1109 if ( substr($query, ( strlen($query) - 1 ), 1 ) != ';' ) |
|
1110 { |
|
1111 $query .= ';'; |
|
1112 } |
|
1113 } |
|
1114 |
|
1115 // echo '<pre>' . htmlspecialchars(print_r($schema, true)) . '</pre>'; |
|
1116 // break; |
|
1117 |
|
1118 echo 'done!<br />Executing schema.sql...'; |
|
1119 |
|
1120 // OK, do the loop, baby!!! |
|
1121 foreach($schema as $q) |
|
1122 { |
|
1123 $r = mysql_query($q, $conn); |
|
1124 if(!$r) err('Error during mainstream installation: '.mysql_error()); |
|
1125 } |
|
1126 |
|
1127 echo 'done!<br />Writing configuration files...'; |
|
1128 if($_POST['urlscheme']=='tiny') |
|
1129 { |
|
1130 $ht = fopen(ENANO_ROOT.'/.htaccess', 'a+'); |
|
1131 if(!$ht) err('Error opening file .htaccess for writing'); |
|
1132 fwrite($ht, ' |
|
1133 RewriteEngine on |
|
1134 RewriteCond %{REQUEST_FILENAME} !-d |
|
1135 RewriteCond %{REQUEST_FILENAME} !-f |
|
1136 RewriteRule ^(.+) '.scriptPath.'/index.php?title=$1 [L,QSA] |
|
1137 RewriteRule \.(php|html|gif|jpg|png|css|js)$ - [L] |
|
1138 '); |
|
1139 fclose($ht); |
|
1140 } |
|
1141 |
|
1142 $config_file = '<?php |
|
1143 /* Enano auto-generated configuration file - editing not recommended! */ |
|
1144 $dbhost = \''.addslashes($_POST['db_host']).'\'; |
|
1145 $dbname = \''.addslashes($_POST['db_name']).'\'; |
|
1146 $dbuser = \''.addslashes($_POST['db_user']).'\'; |
|
1147 $dbpasswd = \''.addslashes($_POST['db_pass']).'\'; |
|
1148 if ( !defined(\'ENANO_CONSTANTS\') ) |
|
1149 { |
|
1150 define(\'ENANO_CONSTANTS\', \'\'); |
|
1151 define(\'table_prefix\', \''.addslashes($_POST['table_prefix']).'\'); |
|
1152 define(\'scriptPath\', \''.scriptPath.'\'); |
|
1153 define(\'contentPath\', \''.$cp.'\'); |
|
1154 define(\'ENANO_INSTALLED\', \'true\'); |
|
1155 } |
|
1156 $crypto_key = \''.$privkey.'\'; |
|
1157 ?>'; |
|
1158 |
|
1159 $cf_handle = fopen(ENANO_ROOT.'/config.new.php', 'w'); |
|
1160 if(!$cf_handle) err('Couldn\'t open file config.php for writing'); |
|
1161 fwrite($cf_handle, $config_file); |
|
1162 fclose($cf_handle); |
|
1163 |
|
1164 echo 'done!<br />Renaming config.new.php and .htaccess.new...'; |
|
1165 if ( !@rename('./config.new.php', './config.php') ) |
|
1166 err('failed!<p>Please rename config.new.php manually to config.php. If you selected Tiny URLs, please also rename .htaccess.new to .htaccess.'); |
|
1167 |
|
1168 if ( $_POST['urlscheme'] == 'tiny' ) |
|
1169 { |
|
1170 if ( !@rename('./.htaccess.new', './.htaccess') ) |
|
1171 err('failed!<p>Please rename .htaccess.new manually to .htaccess.'); |
|
1172 } |
|
1173 |
|
1174 echo 'done!<br />Starting the Enano API...'; |
|
1175 |
1525 |
1176 $template_bak = $template; |
1526 $template_bak = $template; |
1177 |
1527 |
1178 // Get Enano loaded |
|
1179 $_GET['title'] = 'Main_Page'; |
1528 $_GET['title'] = 'Main_Page'; |
1180 require('includes/common.php'); |
1529 require('includes/common.php'); |
1181 |
1530 |
|
1531 if ( is_object($db) && is_object($session) ) |
|
1532 { |
|
1533 run_installer_stage('startapi', 'Start the Enano API', 'stg_start_api_success', '...', false); |
|
1534 } |
|
1535 else |
|
1536 { |
|
1537 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); |
|
1538 } |
|
1539 |
1182 // We need to be logged in (with admin rights) before logs can be flushed |
1540 // We need to be logged in (with admin rights) before logs can be flushed |
1183 $session->login_without_crypto($_POST['admin_user'], $dec, false); |
1541 $admin_password = stg_decrypt_admin_pass(true); |
|
1542 $session->login_without_crypto($_POST['admin_user'], $admin_password, false); |
1184 |
1543 |
1185 // Now that login cookies are set, initialize the session manager and ACLs |
1544 // Now that login cookies are set, initialize the session manager and ACLs |
1186 $session->start(); |
1545 $session->start(); |
1187 $paths->init(); |
1546 $paths->init(); |
1188 |
1547 |
|
1548 run_installer_stage('initlogs', 'Initialize logs', 'stg_init_logs', '<b>The session manager denied the request to flush logs for the main page.</b><br /> |
|
1549 While under most circumstances you can still <a href="install.php?mode=finish">finish the installation</a>, you should be aware that some servers cannot |
|
1550 properly set cookies due to limitations with PHP. These limitations are exposed primarily when this issue is encountered during installation. If you choose |
|
1551 to finish the installation, please be aware that you may be unable to log into your site.'); |
|
1552 close_install_table(); |
|
1553 |
1189 unset($template); |
1554 unset($template); |
1190 $template =& $template_bak; |
1555 $template =& $template_bak; |
1191 |
1556 |
1192 echo 'done!<br />Initializing logs...'; |
1557 echo '<h3>Installation of Enano is complete.</h3><p>Review any warnings above, and then <a href="install.php?mode=finish">click here to finish the installation</a>.'; |
1193 |
|
1194 $q = $db->sql_query('INSERT INTO ' . $_POST['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']) . '\');', $conn); |
|
1195 if ( !$q ) |
|
1196 err('Error setting up logs: '.$db->get_error()); |
|
1197 |
|
1198 // This is only in RAM; it's meant to correct a race condition encountered by several testers |
|
1199 $session->acl_merge(array( |
|
1200 'clear_logs' => AUTH_ALLOW |
|
1201 )); |
|
1202 |
|
1203 if ( !$session->get_permissions('clear_logs') ) |
|
1204 { |
|
1205 echo '<p><b>The session manager denied the request to flush logs for the main page.</b><br /> |
|
1206 While under most circumstances you can still <a href="install.php?mode=finish">finish the installation</a>, you should be aware that some servers cannot |
|
1207 properly set cookies due to limitations with PHP. These limitations are exposed primarily when this issue is encountered during installation. If you choose |
|
1208 to finish the installation, please be aware that you may be unable to log into your site.</p>'; |
|
1209 break; |
|
1210 } |
|
1211 |
|
1212 // unset($session); |
|
1213 // $session = new sessionManager(); |
|
1214 // $session->start(); |
|
1215 |
|
1216 PageUtils::flushlogs('Main_Page', 'Article'); |
|
1217 |
|
1218 echo 'done!<h3>Installation of Enano is complete.</h3><p>Review any warnings above, and then <a href="install.php?mode=finish">click here to finish the installation</a>.'; |
|
1219 |
1558 |
1220 // echo '<script type="text/javascript">window.location="'.scriptPath.'/install.php?mode=finish";</script>'; |
1559 // echo '<script type="text/javascript">window.location="'.scriptPath.'/install.php?mode=finish";</script>'; |
1221 |
1560 |
1222 break; |
1561 break; |
1223 case "finish": |
1562 case "finish": |