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 $mysql_error = mysql_error(); |
|
149 foreach ( $_POST as $key => $value ) |
|
150 { |
|
151 $value = htmlspecialchars($value); |
|
152 $key = htmlspecialchars($key); |
|
153 $post_data .= " <input type=\"hidden\" name=\"$key\" value=\"$value\" />\n"; |
|
154 } |
|
155 echo '<form action="install.php?mode=install&stage=' . $stage_id . '" method="post"> |
|
156 ' . $post_data . ' |
|
157 <input type="hidden" name="resume_stack" value="' . htmlspecialchars(implode('|', $resume_stack)) . '" /> |
|
158 <h3>Enano installation failed.</h3> |
|
159 <p>' . $failure_explanation . '</p> |
|
160 ' . ( !empty($mysql_error) ? "<p>The error returned from MySQL was: $mysql_error</p>" : '' ) . ' |
|
161 <p>When you have corrected the error, click the button below to attempt to continue the installation.</p> |
|
162 <p style="text-align: center;"><input type="submit" value="Retry installation" /></p> |
|
163 </form>'; |
|
164 global $template, $template_bak; |
|
165 if ( is_object($template_bak) ) |
|
166 $template_bak->footer(); |
|
167 else |
|
168 $template->footer(); |
|
169 exit; |
|
170 } |
|
171 |
|
172 // |
|
173 // INSTALLER STAGES |
|
174 // |
|
175 |
|
176 function stg_mysql_connect($act_get = false) |
|
177 { |
|
178 static $conn = false; |
|
179 if ( $act_get ) |
|
180 return $conn; |
|
181 |
|
182 $db_user = mysql_real_escape_string($_POST['db_user']); |
|
183 $db_pass = mysql_real_escape_string($_POST['db_pass']); |
|
184 $db_name = mysql_real_escape_string($_POST['db_name']); |
|
185 |
|
186 if ( !preg_match('/^[a-z0-9_]+$/', $db_name) ) |
|
187 die("<p>SECURITY: malformed database name</p>"); |
|
188 |
|
189 // First, try to connect using the normal credentials |
|
190 $conn = @mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']); |
|
191 if ( !$conn ) |
|
192 { |
|
193 // Connection failed. Do we have the root username and password? |
|
194 if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) ) |
|
195 { |
|
196 $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']); |
|
197 if ( !$conn_root ) |
|
198 { |
|
199 // Couldn't connect using either set of credentials. Bail out. |
|
200 return false; |
|
201 } |
|
202 // Create the user account |
|
203 $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'localhost' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn_root); |
|
204 if ( !$q ) |
|
205 { |
|
206 return false; |
|
207 } |
|
208 // Revoke privileges from test, we don't need them |
|
209 $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'localhost';", $conn_root); |
|
210 if ( !$q ) |
|
211 { |
|
212 return false; |
|
213 } |
|
214 if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' ) |
|
215 { |
|
216 // If not connecting to a server running on localhost, allow from any host |
|
217 // this is safer than trying to detect the hostname of the webserver, but less secure |
|
218 $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'%' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn_root); |
|
219 if ( !$q ) |
|
220 { |
|
221 return false; |
|
222 } |
|
223 // Revoke privileges from test, we don't need them |
|
224 $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'%';", $conn_root); |
|
225 if ( !$q ) |
|
226 { |
|
227 return false; |
|
228 } |
|
229 } |
|
230 } |
|
231 } |
|
232 $q = @mysql_query("USE $db_name;", $conn); |
|
233 if ( !$q ) |
|
234 { |
|
235 // access denied to the database; try the whole root schenanegan again |
|
236 if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) ) |
|
237 { |
|
238 $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']); |
|
239 if ( !$conn_root ) |
|
240 { |
|
241 // Couldn't connect as root; bail out |
|
242 return false; |
|
243 } |
|
244 // create the database, if it doesn't exist |
|
245 $q = @mysql_query("CREATE DATABASE IF NOT EXISTS $db_name;", $conn_root); |
|
246 if ( !$q ) |
|
247 { |
|
248 // this really should never fail, so don't give any tolerance to it |
|
249 return false; |
|
250 } |
|
251 // we're in with root rights; grant access to the database |
|
252 $q = @mysql_query("GRANT ALL PRIVILEGES ON $db_name.* TO '{$db_user}'@'localhost';", $conn_root); |
|
253 if ( !$q ) |
|
254 { |
|
255 return false; |
|
256 } |
|
257 if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' ) |
|
258 { |
|
259 $q = @mysql_query("GRANT ALL PRIVILEGES ON $db_name.* TO '{$db_user}'@'%';", $conn_root); |
|
260 if ( !$q ) |
|
261 { |
|
262 return false; |
|
263 } |
|
264 } |
|
265 } |
|
266 else |
|
267 { |
|
268 return false; |
|
269 } |
|
270 // try again |
|
271 $q = @mysql_query("USE $db_name;", $conn); |
|
272 if ( !$q ) |
|
273 { |
|
274 // really failed this time; bail out |
|
275 return false; |
|
276 } |
|
277 } |
|
278 // connected and database exists |
|
279 return true; |
|
280 } |
|
281 |
|
282 function stg_drop_tables() |
|
283 { |
|
284 $conn = stg_mysql_connect(true); |
|
285 if ( !$conn ) |
|
286 return false; |
|
287 // Our list of tables included in Enano |
|
288 $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' ); |
|
289 |
|
290 // Drop each table individually; if it fails, it probably means we're trying to drop a |
|
291 // table that didn't exist in the Enano version we're deleting the database for. |
|
292 foreach ( $tables as $table ) |
|
293 { |
|
294 // Remember that table_prefix is sanitized. |
|
295 $table = "{$_POST['table_prefix']}$table"; |
|
296 @mysql_query("DROP TABLE $table;", $conn); |
|
297 } |
|
298 return true; |
|
299 } |
|
300 |
|
301 function stg_decrypt_admin_pass($act_get = false) |
|
302 { |
|
303 static $decrypted_pass = false; |
|
304 if ( $act_get ) |
|
305 return $decrypted_pass; |
|
306 |
|
307 $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); |
|
308 |
|
309 if ( !empty($_POST['crypt_data']) ) |
|
310 { |
|
311 require('config.new.php'); |
|
312 if ( !isset($cryptkey) ) |
|
313 { |
|
314 return false; |
|
315 } |
|
316 define('_INSTRESUME_AES_KEYBACKUP', $key); |
|
317 $key = hexdecode($cryptkey); |
|
318 |
|
319 $decrypted_pass = $aes->decrypt($_POST['crypt_data'], $key, ENC_HEX); |
|
320 |
|
321 } |
|
322 else |
|
323 { |
|
324 $decrypted_pass = $_POST['admin_pass']; |
|
325 } |
|
326 if ( empty($decrypted_pass) ) |
|
327 return false; |
|
328 return true; |
|
329 } |
|
330 |
|
331 function stg_generate_aes_key($act_get = false) |
|
332 { |
|
333 static $key = false; |
|
334 if ( $act_get ) |
|
335 return $key; |
|
336 |
|
337 $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); |
|
338 $key = $aes->gen_readymade_key(); |
|
339 return true; |
|
340 } |
|
341 |
|
342 function stg_parse_schema($act_get = false) |
|
343 { |
|
344 static $schema; |
|
345 if ( $act_get ) |
|
346 return $schema; |
|
347 |
|
348 $admin_pass = stg_decrypt_admin_pass(true); |
|
349 $key = stg_generate_aes_key(true); |
|
350 $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); |
|
351 $key = $aes->hextostring($key); |
|
352 $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX); |
|
353 |
|
354 $cacheonoff = is_writable(ENANO_ROOT.'/cache/') ? '1' : '0'; |
|
355 |
|
356 $schema = file_get_contents('schema.sql'); |
|
357 $schema = str_replace('{{SITE_NAME}}', mysql_real_escape_string($_POST['sitename'] ), $schema); |
|
358 $schema = str_replace('{{SITE_DESC}}', mysql_real_escape_string($_POST['sitedesc'] ), $schema); |
|
359 $schema = str_replace('{{COPYRIGHT}}', mysql_real_escape_string($_POST['copyright'] ), $schema); |
|
360 $schema = str_replace('{{ADMIN_USER}}', mysql_real_escape_string($_POST['admin_user'] ), $schema); |
|
361 $schema = str_replace('{{ADMIN_PASS}}', mysql_real_escape_string($admin_pass ), $schema); |
|
362 $schema = str_replace('{{ADMIN_EMAIL}}', mysql_real_escape_string($_POST['admin_email']), $schema); |
|
363 $schema = str_replace('{{ENABLE_CACHE}}', mysql_real_escape_string($cacheonoff ), $schema); |
|
364 $schema = str_replace('{{REAL_NAME}}', '', $schema); |
|
365 $schema = str_replace('{{TABLE_PREFIX}}', $_POST['table_prefix'], $schema); |
|
366 $schema = str_replace('{{VERSION}}', ENANO_VERSION, $schema); |
|
367 $schema = str_replace('{{ADMIN_EMBED_PHP}}', $_POST['admin_embed_php'], $schema); |
|
368 // Not anymore!! :-D |
|
369 // $schema = str_replace('{{BETA_VERSION}}', ENANO_BETA_VERSION, $schema); |
|
370 |
|
371 if(isset($_POST['wiki_mode'])) |
|
372 { |
|
373 $schema = str_replace('{{WIKI_MODE}}', '1', $schema); |
|
374 } |
|
375 else |
|
376 { |
|
377 $schema = str_replace('{{WIKI_MODE}}', '0', $schema); |
|
378 } |
|
379 |
|
380 // Build an array of queries |
|
381 $schema = explode("\n", $schema); |
|
382 |
|
383 foreach ( $schema as $i => $sql ) |
|
384 { |
|
385 $query =& $schema[$i]; |
|
386 $t = trim($query); |
|
387 if ( empty($t) || preg_match('/^(\#|--)/i', $t) ) |
|
388 { |
|
389 unset($schema[$i]); |
|
390 unset($query); |
|
391 } |
|
392 } |
|
393 |
|
394 $schema = array_values($schema); |
|
395 $schema = implode("\n", $schema); |
|
396 $schema = explode(";\n", $schema); |
|
397 |
|
398 foreach ( $schema as $i => $sql ) |
|
399 { |
|
400 $query =& $schema[$i]; |
|
401 if ( substr($query, ( strlen($query) - 1 ), 1 ) != ';' ) |
|
402 { |
|
403 $query .= ';'; |
|
404 } |
|
405 } |
|
406 |
|
407 return true; |
|
408 } |
|
409 |
|
410 function stg_install($_unused, $already_run) |
|
411 { |
|
412 // This one's pretty easy. |
|
413 $conn = stg_mysql_connect(true); |
|
414 if ( !is_resource($conn) ) |
|
415 return false; |
|
416 $schema = stg_parse_schema(true); |
|
417 if ( !is_array($schema) ) |
|
418 return false; |
|
419 |
|
420 // If we're resuming installation, the encryption key was regenerated. |
|
421 // This means we'll have to update the encrypted password in the database. |
|
422 if ( $already_run ) |
|
423 { |
|
424 $admin_pass = stg_decrypt_admin_pass(true); |
|
425 $key = stg_generate_aes_key(true); |
|
426 $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); |
|
427 $key = $aes->hextostring($key); |
|
428 $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX); |
|
429 $admin_user = mysql_real_escape_string($_POST['admin_user']); |
|
430 |
|
431 $q = @mysql_query("UPDATE {$_POST['table_prefix']}users SET password='$admin_pass' WHERE username='$admin_user';"); |
|
432 if ( !$q ) |
|
433 { |
|
434 echo '<p><tt>MySQL return: ' . mysql_error() . '</tt></p>'; |
|
435 return false; |
|
436 } |
|
437 |
|
438 return true; |
|
439 } |
|
440 |
|
441 // OK, do the loop, baby!!! |
|
442 foreach($schema as $q) |
|
443 { |
|
444 $r = mysql_query($q, $conn); |
|
445 if ( !$r ) |
|
446 { |
|
447 echo '<p><tt>MySQL return: ' . mysql_error() . '</tt></p>'; |
|
448 return false; |
|
449 } |
|
450 } |
|
451 |
|
452 return true; |
|
453 } |
|
454 |
|
455 function stg_write_config() |
|
456 { |
|
457 $privkey = stg_generate_aes_key(true); |
|
458 |
|
459 switch($_POST['urlscheme']) |
|
460 { |
|
461 case "ugly": |
|
462 default: |
|
463 $cp = scriptPath.'/index.php?title='; |
|
464 break; |
|
465 case "short": |
|
466 $cp = scriptPath.'/index.php/'; |
|
467 break; |
|
468 case "tiny": |
|
469 $cp = scriptPath.'/'; |
|
470 break; |
|
471 } |
|
472 |
|
473 if ( $_POST['urlscheme'] == 'tiny' ) |
|
474 { |
|
475 $contents = '# Begin Enano rules |
|
476 RewriteEngine on |
|
477 RewriteCond %{REQUEST_FILENAME} !-d |
|
478 RewriteCond %{REQUEST_FILENAME} !-f |
|
479 RewriteRule ^(.+) '.scriptPath.'/index.php?title=$1 [L,QSA] |
|
480 RewriteRule \.(php|html|gif|jpg|png|css|js)$ - [L] |
|
481 # End Enano rules |
|
482 '; |
|
483 if ( file_exists('./.htaccess') ) |
|
484 $ht = fopen(ENANO_ROOT.'/.htaccess', 'a+'); |
|
485 else |
|
486 $ht = fopen(ENANO_ROOT.'/.htaccess.new', 'w'); |
|
487 if ( !$ht ) |
|
488 return false; |
|
489 fwrite($ht, $contents); |
|
490 fclose($ht); |
|
491 } |
|
492 |
|
493 $config_file = '<?php |
|
494 /* Enano auto-generated configuration file - editing not recommended! */ |
|
495 $dbhost = \''.addslashes($_POST['db_host']).'\'; |
|
496 $dbname = \''.addslashes($_POST['db_name']).'\'; |
|
497 $dbuser = \''.addslashes($_POST['db_user']).'\'; |
|
498 $dbpasswd = \''.addslashes($_POST['db_pass']).'\'; |
|
499 if ( !defined(\'ENANO_CONSTANTS\') ) |
|
500 { |
|
501 define(\'ENANO_CONSTANTS\', \'\'); |
|
502 define(\'table_prefix\', \''.addslashes($_POST['table_prefix']).'\'); |
|
503 define(\'scriptPath\', \''.scriptPath.'\'); |
|
504 define(\'contentPath\', \''.$cp.'\'); |
|
505 define(\'ENANO_INSTALLED\', \'true\'); |
|
506 } |
|
507 $crypto_key = \''.$privkey.'\'; |
|
508 ?>'; |
|
509 |
|
510 $cf_handle = fopen(ENANO_ROOT.'/config.new.php', 'w'); |
|
511 if ( !$cf_handle ) |
|
512 return false; |
|
513 fwrite($cf_handle, $config_file); |
|
514 |
|
515 fclose($cf_handle); |
|
516 |
|
517 return true; |
|
518 } |
|
519 |
|
520 function _stg_rename_config_revert() |
|
521 { |
|
522 if ( file_exists('./config.php') ) |
|
523 { |
|
524 @rename('./config.php', './config.new.php'); |
|
525 } |
|
526 |
|
527 $handle = @fopen('./config.php.new', 'w'); |
|
528 if ( !$handle ) |
|
529 return false; |
|
530 $contents = '<?php $cryptkey = \'' . _INSTRESUME_AES_KEYBACKUP . '\'; ?>'; |
|
531 fwrite($handle, $contents); |
|
532 fclose($handle); |
|
533 return true; |
|
534 } |
|
535 |
|
536 function stg_rename_config() |
|
537 { |
|
538 if ( !@rename('./config.new.php', './config.php') ) |
|
539 { |
|
540 echo '<p>Can\'t rename config.php</p>'; |
|
541 _stg_rename_config_revert(); |
|
542 return false; |
|
543 } |
|
544 |
|
545 if ( $_POST['urlscheme'] == 'tiny' && !file_exists('./.htaccess') ) |
|
546 { |
|
547 if ( !@rename('./.htaccess.new', './.htaccess') ) |
|
548 { |
|
549 echo '<p>Can\'t rename .htaccess</p>'; |
|
550 _stg_rename_config_revert(); |
|
551 return false; |
|
552 } |
|
553 } |
|
554 return true; |
|
555 } |
|
556 |
|
557 function stg_start_api_success() |
|
558 { |
|
559 return true; |
|
560 } |
|
561 |
|
562 function stg_start_api_failure() |
|
563 { |
|
564 return false; |
|
565 } |
|
566 |
|
567 function stg_init_logs() |
|
568 { |
|
569 global $db, $session, $paths, $template, $plugins; // Common objects |
|
570 |
|
571 $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']) . '\');'); |
|
572 if ( !$q ) |
|
573 { |
|
574 echo '<p><tt>MySQL return: ' . mysql_error() . '</tt></p>'; |
|
575 return false; |
|
576 } |
|
577 |
|
578 if ( !$session->get_permissions('clear_logs') ) |
|
579 { |
|
580 echo '<p><tt>$session: denied clear_logs</tt></p>'; |
|
581 return false; |
|
582 } |
|
583 |
|
584 PageUtils::flushlogs('Main_Page', 'Article'); |
|
585 |
|
586 return true; |
|
587 } |
67 |
588 |
68 //die('Key size: ' . AES_BITS . '<br />Block size: ' . AES_BLOCKSIZE); |
589 //die('Key size: ' . AES_BITS . '<br />Block size: ' . AES_BLOCKSIZE); |
69 |
590 |
70 if(!function_exists('wikiFormat')) |
591 if(!function_exists('wikiFormat')) |
71 { |
592 { |
388 run_test('return version_compare(\'4.3.0\', PHP_VERSION, \'<\');', 'PHP Version >=4.3.0', 'It seems that the version of PHP that your server is running is too old to support Enano properly. If this is your server, please upgrade to the most recent version of PHP, remembering to use the --with-mysql configure option if you compile it yourself. If this is not your server, please contact your webhost and ask them if it would be possible to upgrade PHP. If this is not possible, you will need to switch to a different webhost in order to use Enano.'); |
909 run_test('return version_compare(\'4.3.0\', PHP_VERSION, \'<\');', 'PHP Version >=4.3.0', 'It seems that the version of PHP that your server is running is too old to support Enano properly. If this is your server, please upgrade to the most recent version of PHP, remembering to use the --with-mysql configure option if you compile it yourself. If this is not your server, please contact your webhost and ask them if it would be possible to upgrade PHP. If this is not possible, you will need to switch to a different webhost in order to use Enano.'); |
389 run_test('return function_exists(\'mysql_connect\');', 'MySQL extension for PHP', 'It seems that your PHP installation does not have the MySQL extension enabled. If this is your own server, you may need to just enable the "libmysql.so" extension in php.ini. If you do not have the MySQL extension installed, you will need to either use your distribution\'s package manager to install it, or you will have to compile PHP from source. If you compile PHP from source, please remember to use the "--with-mysql" configure option, and you will have to have the MySQL development files installed (they usually are). If this is not your server, please contact your hosting company and ask them to install the PHP MySQL extension.'); |
910 run_test('return function_exists(\'mysql_connect\');', 'MySQL extension for PHP', 'It seems that your PHP installation does not have the MySQL extension enabled. If this is your own server, you may need to just enable the "libmysql.so" extension in php.ini. If you do not have the MySQL extension installed, you will need to either use your distribution\'s package manager to install it, or you will have to compile PHP from source. If you compile PHP from source, please remember to use the "--with-mysql" configure option, and you will have to have the MySQL development files installed (they usually are). If this is not your server, please contact your hosting company and ask them to install the PHP MySQL extension.'); |
390 run_test('return @ini_get(\'file_uploads\');', 'File upload support', 'It seems that your server does not support uploading files. Enano *requires* this functionality in order to work properly. Please ask your server administrator to set the "file_uploads" option in php.ini to "On".'); |
911 run_test('return @ini_get(\'file_uploads\');', 'File upload support', 'It seems that your server does not support uploading files. Enano *requires* this functionality in order to work properly. Please ask your server administrator to set the "file_uploads" option in php.ini to "On".'); |
391 run_test('return is_apache();', 'Apache HTTP Server', 'Apparently your server is running a web server other than Apache. Enano will work nontheless, but there are some known bugs with non-Apache servers, and the "fancy" URLs will not work properly. The "Standard URLs" option will be set on the website configuration page, only change it if you are absolutely certain that your server is running Apache.', true); |
912 run_test('return is_apache();', 'Apache HTTP Server', 'Apparently your server is running a web server other than Apache. Enano will work nontheless, but there are some known bugs with non-Apache servers, and the "fancy" URLs will not work properly. The "Standard URLs" option will be set on the website configuration page, only change it if you are absolutely certain that your server is running Apache.', true); |
392 //run_test('return function_exists(\'finfo_file\');', 'Fileinfo PECL extension', 'The MIME magic PHP extension is used to determine the type of a file by looking for a certain "magic" string of characters inside it. This functionality is used by Enano to more effectively prevent malicious file uploads. The MIME magic option will be disabled by default.', true); |
913 //run_test('return function_exists(\'finfo_file\');', 'Fileinfo PECL extension', 'The MIME magic PHP extension is used to determine the type of a file by looking for a certain "magic" string of characters inside it. This functionality is used by Enano to more effectively prevent malicious file uploads. The MIME magic option will be disabled by default.', true); |
393 run_test('return is_writable(ENANO_ROOT.\'/config.php\');', 'Configuration file writable', 'It looks like the configuration file, config.php, is not writable. Enano needs to be able to write to this file in order to install.<br /><br /><b>If you are installing Enano on a SourceForge web site:</b><br />SourceForge mounts the web partitions read-only now, so you will need to use the project shell service to symlink config.php to a file in the /tmp/persistent directory.'); |
914 run_test('return is_writable(ENANO_ROOT.\'/config.new.php\');', 'Configuration file writable', 'It looks like the configuration file, config.new.php, is not writable. Enano needs to be able to write to this file in order to install.<br /><br /><b>If you are installing Enano on a SourceForge web site:</b><br />SourceForge mounts the web partitions read-only now, so you will need to use the project shell service to symlink config.php to a file in the /tmp/persistent directory.'); |
394 run_test('return file_exists(\'/usr/bin/convert\');', 'ImageMagick support', 'Enano uses ImageMagick to scale images into thumbnails. Because ImageMagick was not found on your server, Enano will use the width= and height= attributes on the <img> tag to scale images. This can cause somewhat of a performance increase, but bandwidth usage will be higher, especially if you use high-resolution images on your site.<br /><br />If you are sure that you have ImageMagick, you can set the location of the "convert" program using the administration panel after installation is complete.', true); |
915 run_test('return file_exists(\'/usr/bin/convert\');', 'ImageMagick support', 'Enano uses ImageMagick to scale images into thumbnails. Because ImageMagick was not found on your server, Enano will use the width= and height= attributes on the <img> tag to scale images. This can cause somewhat of a performance increase, but bandwidth usage will be higher, especially if you use high-resolution images on your site.<br /><br />If you are sure that you have ImageMagick, you can set the location of the "convert" program using the administration panel after installation is complete.', true); |
395 run_test('return is_writable(ENANO_ROOT.\'/cache/\');', 'Cache directory writable', 'Apparently the cache/ directory is not writable. Enano will still work, but you will not be able to cache thumbnails, meaning the server will need to re-render them each time they are requested. In some cases, this can cause a significant slowdown.', true); |
916 run_test('return is_writable(ENANO_ROOT.\'/cache/\');', 'Cache directory writable', 'Apparently the cache/ directory is not writable. Enano will still work, but you will not be able to cache thumbnails, meaning the server will need to re-render them each time they are requested. In some cases, this can cause a significant slowdown.', true); |
396 run_test('return is_writable(ENANO_ROOT.\'/files/\');', 'File uploads directory writable', 'It seems that the directory where uploaded files are stored (' . ENANO_ROOT . '/files) cannot be written by the server. Enano will still function, but file uploads will not function, and will be disabled by default.', true); |
917 run_test('return is_writable(ENANO_ROOT.\'/files/\');', 'File uploads directory writable', 'It seems that the directory where uploaded files are stored (' . ENANO_ROOT . '/files) cannot be written by the server. Enano will still function, but file uploads will not function, and will be disabled by default.', true); |
397 echo '</table>'; |
918 echo '</table>'; |
398 if(!$failed) |
919 if(!$failed) |
986 $cp = scriptPath.'/'; |
1511 $cp = scriptPath.'/'; |
987 break; |
1512 break; |
988 } |
1513 } |
989 function err($t) { global $template; echo $t; $template->footer(); exit; } |
1514 function err($t) { global $template; echo $t; $template->footer(); exit; } |
990 |
1515 |
991 echo 'Connecting to MySQL...'; |
1516 // $stages = array('connect', 'decrypt', 'genkey', 'parse', 'sql', 'writeconfig', 'renameconfig', 'startapi', 'initlogs'); |
992 if($_POST['db_root_user'] != '') |
1517 |
993 { |
1518 if ( !preg_match('/^[a-z0-9_]*$/', $_POST['table_prefix']) ) |
994 $conn = mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']); |
1519 err('Hacking attempt was detected in table_prefix.'); |
995 if(!$conn) err('Error connecting to MySQL: '.mysql_error()); |
1520 |
996 $q = mysql_query('USE '.$_POST['db_name']); |
1521 start_install_table(); |
997 if(!$q) |
1522 // The stages connect, decrypt, genkey, and parse are preprocessing and don't do any actual data modification. |
998 { |
1523 // Thus, they need to be run on each retry, e.g. never skipped. |
999 $q = mysql_query('CREATE DATABASE '.$_POST['db_name']); |
1524 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>.', false); |
1000 if(!$q) err('Error initializing database: '.mysql_error()); |
1525 if ( isset($_POST['drop_tables']) ) |
1001 } |
1526 { |
1002 $q = mysql_query('GRANT ALL PRIVILEGES ON '.$_POST['db_name'].'.* TO \''.$_POST['db_user'].'\'@\'localhost\' IDENTIFIED BY \''.$_POST['db_pass'].'\' WITH GRANT OPTION;'); |
1527 // Are we supposed to drop any existing tables? If so, do it now |
1003 if(!$q) err('Could not create the user account'); |
1528 run_installer_stage('drop', 'Drop existing Enano tables', 'stg_drop_tables', 'This step never returns failure'); |
1004 $q = mysql_query('GRANT ALL PRIVILEGES ON '.$_POST['db_name'].'.* TO \''.$_POST['db_user'].'\'@\'%\' IDENTIFIED BY \''.$_POST['db_pass'].'\' WITH GRANT OPTION;'); |
1529 } |
1005 if(!$q) err('Could not create the user account'); |
1530 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); |
1006 mysql_close($conn); |
1531 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); |
1007 } |
1532 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); |
1008 $conn = mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']); |
1533 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); |
1009 if(!$conn) err('Error connecting to MySQL: '.mysql_error()); |
1534 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.'); |
1010 $q = mysql_query('USE '.$_POST['db_name']); |
1535 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.'); |
1011 if(!$q) err('Error selecting database: '.mysql_error()); |
|
1012 echo 'done!<br />'; |
|
1013 |
1536 |
1014 // Are we supposed to drop any existing tables? If so, do it now |
1537 // Mainstream installation complete - Enano should be usable now |
1015 if(isset($_POST['drop_tables'])) |
1538 // The stage of starting the API is special because it has to be called out of function context. |
1016 { |
1539 // To alleviate this, we have two functions, one that returns success and one that returns failure |
1017 echo 'Dropping existing Enano tables...'; |
1540 // If the Enano API load is successful, the success function is called to report the action to the user |
1018 // Our list of tables included in Enano |
1541 // If unsuccessful, the failure report is sent |
1019 $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' ); |
|
1020 $tables = implode(', ', $tables); |
|
1021 $tables = str_replace('mdg_', $_POST['table_prefix'], $tables); |
|
1022 $query_of_death = 'DROP TABLE '.$tables.';'; |
|
1023 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 |
|
1024 echo 'done!<br />'; |
|
1025 } |
|
1026 |
|
1027 $cacheonoff = is_writable(ENANO_ROOT.'/cache/') ? '1' : '0'; |
|
1028 |
|
1029 echo 'Decrypting administration password...'; |
|
1030 |
|
1031 $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); |
|
1032 |
|
1033 if ( !empty($_POST['crypt_data']) ) |
|
1034 { |
|
1035 require('config.php'); |
|
1036 if ( !isset($cryptkey) ) |
|
1037 { |
|
1038 echo 'failed!<br />Cannot get the key from config.php'; |
|
1039 break; |
|
1040 } |
|
1041 $key = hexdecode($cryptkey); |
|
1042 |
|
1043 $dec = $aes->decrypt($_POST['crypt_data'], $key, ENC_HEX); |
|
1044 |
|
1045 } |
|
1046 else |
|
1047 { |
|
1048 $dec = $_POST['admin_pass']; |
|
1049 } |
|
1050 echo 'done!<br />Generating '.AES_BITS.'-bit AES private key...'; |
|
1051 $privkey = $aes->gen_readymade_key(); |
|
1052 $pkba = hexdecode($privkey); |
|
1053 $encpass = $aes->encrypt($dec, $pkba, ENC_HEX); |
|
1054 |
|
1055 echo 'done!<br />Preparing for schema execution...'; |
|
1056 $schema = file_get_contents('schema.sql'); |
|
1057 $schema = str_replace('{{SITE_NAME}}', mysql_real_escape_string($_POST['sitename'] ), $schema); |
|
1058 $schema = str_replace('{{SITE_DESC}}', mysql_real_escape_string($_POST['sitedesc'] ), $schema); |
|
1059 $schema = str_replace('{{COPYRIGHT}}', mysql_real_escape_string($_POST['copyright'] ), $schema); |
|
1060 $schema = str_replace('{{ADMIN_USER}}', mysql_real_escape_string($_POST['admin_user'] ), $schema); |
|
1061 $schema = str_replace('{{ADMIN_PASS}}', mysql_real_escape_string($encpass ), $schema); |
|
1062 $schema = str_replace('{{ADMIN_EMAIL}}', mysql_real_escape_string($_POST['admin_email']), $schema); |
|
1063 $schema = str_replace('{{ENABLE_CACHE}}', mysql_real_escape_string($cacheonoff ), $schema); |
|
1064 $schema = str_replace('{{REAL_NAME}}', '', $schema); |
|
1065 $schema = str_replace('{{TABLE_PREFIX}}', $_POST['table_prefix'], $schema); |
|
1066 $schema = str_replace('{{VERSION}}', ENANO_VERSION, $schema); |
|
1067 $schema = str_replace('{{ADMIN_EMBED_PHP}}', $_POST['admin_embed_php'], $schema); |
|
1068 // Not anymore!! :-D |
|
1069 // $schema = str_replace('{{BETA_VERSION}}', ENANO_BETA_VERSION, $schema); |
|
1070 |
|
1071 if(isset($_POST['wiki_mode'])) |
|
1072 { |
|
1073 $schema = str_replace('{{WIKI_MODE}}', '1', $schema); |
|
1074 } |
|
1075 else |
|
1076 { |
|
1077 $schema = str_replace('{{WIKI_MODE}}', '0', $schema); |
|
1078 } |
|
1079 |
|
1080 // Build an array of queries |
|
1081 $schema = explode("\n", $schema); |
|
1082 |
|
1083 foreach ( $schema as $i => $sql ) |
|
1084 { |
|
1085 $query =& $schema[$i]; |
|
1086 $t = trim($query); |
|
1087 if ( empty($t) || preg_match('/^(\#|--)/i', $t) ) |
|
1088 { |
|
1089 unset($schema[$i]); |
|
1090 unset($query); |
|
1091 } |
|
1092 } |
|
1093 |
|
1094 $schema = array_values($schema); |
|
1095 $schema = implode("\n", $schema); |
|
1096 $schema = explode(";\n", $schema); |
|
1097 |
|
1098 foreach ( $schema as $i => $sql ) |
|
1099 { |
|
1100 $query =& $schema[$i]; |
|
1101 if ( substr($query, ( strlen($query) - 1 ), 1 ) != ';' ) |
|
1102 { |
|
1103 $query .= ';'; |
|
1104 } |
|
1105 } |
|
1106 |
|
1107 // echo '<pre>' . htmlspecialchars(print_r($schema, true)) . '</pre>'; |
|
1108 // break; |
|
1109 |
|
1110 echo 'done!<br />Executing schema.sql...'; |
|
1111 |
|
1112 // OK, do the loop, baby!!! |
|
1113 foreach($schema as $q) |
|
1114 { |
|
1115 $r = mysql_query($q, $conn); |
|
1116 if(!$r) err('Error during mainstream installation: '.mysql_error()); |
|
1117 } |
|
1118 |
|
1119 echo 'done!<br />Writing configuration files...'; |
|
1120 if($_POST['urlscheme']=='tiny') |
|
1121 { |
|
1122 $ht = fopen(ENANO_ROOT.'/.htaccess', 'a+'); |
|
1123 if(!$ht) err('Error opening file .htaccess for writing'); |
|
1124 fwrite($ht, ' |
|
1125 RewriteEngine on |
|
1126 RewriteCond %{REQUEST_FILENAME} !-d |
|
1127 RewriteCond %{REQUEST_FILENAME} !-f |
|
1128 RewriteRule ^(.+) '.scriptPath.'/index.php?title=$1 [L,QSA] |
|
1129 RewriteRule \.(php|html|gif|jpg|png|css|js)$ - [L] |
|
1130 '); |
|
1131 fclose($ht); |
|
1132 } |
|
1133 |
|
1134 $config_file = '<?php |
|
1135 /* Enano auto-generated configuration file - editing not recommended! */ |
|
1136 $dbhost = \''.addslashes($_POST['db_host']).'\'; |
|
1137 $dbname = \''.addslashes($_POST['db_name']).'\'; |
|
1138 $dbuser = \''.addslashes($_POST['db_user']).'\'; |
|
1139 $dbpasswd = \''.addslashes($_POST['db_pass']).'\'; |
|
1140 if(!defined(\'ENANO_CONSTANTS\')) { |
|
1141 define(\'ENANO_CONSTANTS\', \'\'); |
|
1142 define(\'table_prefix\', \''.$_POST['table_prefix'].'\'); |
|
1143 define(\'scriptPath\', \''.scriptPath.'\'); |
|
1144 define(\'contentPath\', \''.$cp.'\'); |
|
1145 define(\'ENANO_INSTALLED\', \'true\'); |
|
1146 } |
|
1147 $crypto_key = \''.$privkey.'\'; |
|
1148 ?>'; |
|
1149 |
|
1150 $cf_handle = fopen(ENANO_ROOT.'/config.php', 'w'); |
|
1151 if(!$cf_handle) err('Couldn\'t open file config.php for writing'); |
|
1152 fwrite($cf_handle, $config_file); |
|
1153 fclose($cf_handle); |
|
1154 |
|
1155 echo 'done!<br />Starting the Enano API...'; |
|
1156 |
1542 |
1157 $template_bak = $template; |
1543 $template_bak = $template; |
1158 |
1544 |
1159 // Get Enano loaded |
|
1160 $_GET['title'] = 'Main_Page'; |
1545 $_GET['title'] = 'Main_Page'; |
1161 require('includes/common.php'); |
1546 require('includes/common.php'); |
1162 |
1547 |
|
1548 if ( is_object($db) && is_object($session) ) |
|
1549 { |
|
1550 run_installer_stage('startapi', 'Start the Enano API', 'stg_start_api_success', '...', false); |
|
1551 } |
|
1552 else |
|
1553 { |
|
1554 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); |
|
1555 } |
|
1556 |
1163 // We need to be logged in (with admin rights) before logs can be flushed |
1557 // We need to be logged in (with admin rights) before logs can be flushed |
1164 $session->login_without_crypto($_POST['admin_user'], $dec, false); |
1558 $admin_password = stg_decrypt_admin_pass(true); |
|
1559 $session->login_without_crypto($_POST['admin_user'], $admin_password, false); |
1165 |
1560 |
1166 // Now that login cookies are set, initialize the session manager and ACLs |
1561 // Now that login cookies are set, initialize the session manager and ACLs |
1167 $session->start(); |
1562 $session->start(); |
1168 $paths->init(); |
1563 $paths->init(); |
1169 |
1564 |
|
1565 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 /> |
|
1566 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 |
|
1567 properly set cookies due to limitations with PHP. These limitations are exposed primarily when this issue is encountered during installation. If you choose |
|
1568 to finish the installation, please be aware that you may be unable to log into your site.'); |
|
1569 close_install_table(); |
|
1570 |
1170 unset($template); |
1571 unset($template); |
1171 $template =& $template_bak; |
1572 $template =& $template_bak; |
1172 |
1573 |
1173 echo 'done!<br />Initializing logs...'; |
1574 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>.'; |
1174 |
|
1175 $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); |
|
1176 if ( !$q ) |
|
1177 err('Error setting up logs: '.$db->get_error()); |
|
1178 |
|
1179 if ( !$session->get_permissions('clear_logs') ) |
|
1180 { |
|
1181 echo '<br />Error: session manager won\'t permit flushing logs, these is a bug.'; |
|
1182 break; |
|
1183 } |
|
1184 |
|
1185 // unset($session); |
|
1186 // $session = new sessionManager(); |
|
1187 // $session->start(); |
|
1188 |
|
1189 PageUtils::flushlogs('Main_Page', 'Article'); |
|
1190 |
|
1191 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>.'; |
|
1192 |
1575 |
1193 // echo '<script type="text/javascript">window.location="'.scriptPath.'/install.php?mode=finish";</script>'; |
1576 // echo '<script type="text/javascript">window.location="'.scriptPath.'/install.php?mode=finish";</script>'; |
1194 |
1577 |
1195 break; |
1578 break; |
1196 case "finish": |
1579 case "finish": |