|
1 <?php |
|
2 |
|
3 /* |
|
4 * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between |
|
5 * Version 1.1.1 |
|
6 * Copyright (C) 2006-2007 Dan Fuhry |
|
7 * Installation package |
|
8 * payload.php - Installer payload (the installation logic) |
|
9 * |
|
10 * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License |
|
11 * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. |
|
12 * |
|
13 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied |
|
14 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. |
|
15 */ |
|
16 |
|
17 if ( !defined('IN_ENANO_INSTALL') ) |
|
18 die(); |
|
19 |
|
20 return true; |
|
21 |
|
22 function stg_sim_good() |
|
23 { |
|
24 return true; |
|
25 } |
|
26 |
|
27 function stg_sim_bad() |
|
28 { |
|
29 return true; |
|
30 } |
|
31 |
|
32 function stg_password_decode() |
|
33 { |
|
34 global $db; |
|
35 static $pass = false; |
|
36 |
|
37 if ( $pass ) |
|
38 return $pass; |
|
39 |
|
40 if ( !isset($_POST['crypt_data']) && !empty($_POST['password']) && $_POST['password'] === $_POST['password_confirm'] ) |
|
41 $pass = $_POST['password']; |
|
42 |
|
43 $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); |
|
44 // retrieve encryption key |
|
45 $q = $db->sql_query('SELECT config_value FROM ' . table_prefix . 'config WHERE config_name=\'install_aes_key\';'); |
|
46 if ( !$q ) |
|
47 $db->_die(); |
|
48 if ( $db->numrows() < 1 ) |
|
49 return false; |
|
50 list($aes_key) = $db->fetchrow_num(); |
|
51 $aes_key = $aes->hextostring($aes_key); |
|
52 |
|
53 $pass = $aes->decrypt($_POST['crypt_data'], $aes_key, ENC_HEX); |
|
54 if ( !$pass ) |
|
55 return false; |
|
56 |
|
57 return $pass; // Will be true if the password isn't crapped |
|
58 } |
|
59 |
|
60 function stg_make_private_key() |
|
61 { |
|
62 global $db; |
|
63 static $site_key = false; |
|
64 |
|
65 if ( $site_key ) |
|
66 return $site_key; |
|
67 |
|
68 // Is there already a key cached in the database? |
|
69 $q = $db->sql_query('SELECT config_value FROM ' . table_prefix . 'config WHERE config_name=\'site_aes_key\';'); |
|
70 if ( !$q ) |
|
71 $db->_die(); |
|
72 |
|
73 if ( $db->numrows() > 0 ) |
|
74 { |
|
75 list($site_key) = $db->fetchrow_num(); |
|
76 $db->free_result(); |
|
77 return $site_key; |
|
78 } |
|
79 |
|
80 $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); |
|
81 // This will use /dev/urandom if possible |
|
82 $site_key = $aes->gen_readymade_key(); |
|
83 |
|
84 // Stash it in the database, don't check for errors though because we can always regenerate it |
|
85 $db->sql_query('INSERT INTO ' . table_prefix . 'config ( config_name, config_value ) VALUES ( \'site_aes_key\', \'' . $site_key . '\' );'); |
|
86 |
|
87 return $site_key; |
|
88 } |
|
89 |
|
90 function stg_load_schema() |
|
91 { |
|
92 global $db, $dbdriver, $installer_version; |
|
93 static $sql_parser = false; |
|
94 |
|
95 if ( is_object($sql_parser) ) |
|
96 return $sql_parser->parse(); |
|
97 |
|
98 $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); |
|
99 |
|
100 $site_key = stg_make_private_key(); |
|
101 $site_key = $aes->hextostring($site_key); |
|
102 $admin_pass_clean = stg_password_decode(); |
|
103 $admin_pass = $aes->encrypt($admin_pass_clean, $site_key, ENC_HEX); |
|
104 |
|
105 unset($admin_pass_clean); // Security |
|
106 |
|
107 try |
|
108 { |
|
109 $sql_parser = new SQL_Parser( ENANO_ROOT . "/install/schemas/{$dbdriver}_stage2.sql" ); |
|
110 } |
|
111 catch ( Exception $e ) |
|
112 { |
|
113 echo "<pre>$e</pre>"; |
|
114 return false; |
|
115 } |
|
116 |
|
117 $vars = array( |
|
118 'TABLE_PREFIX' => $_POST['table_prefix'], |
|
119 'SITE_NAME' => $db->escape($_POST['site_name']), |
|
120 'SITE_DESC' => $db->escape($_POST['site_desc']), |
|
121 'COPYRIGHT' => $db->escape($_POST['copyright']), |
|
122 // FIXME: update form |
|
123 'WIKI_MODE' => ( isset($_POST['wiki_mode']) ? '1' : '0' ), |
|
124 'ENABLE_CACHE' => ( is_writable( ENANO_ROOT . '/cache/' ) ? '1' : '0' ), |
|
125 'VERSION' => $installer_version['version'], |
|
126 'ADMIN_USER' => $db->escape($_POST['username']), |
|
127 'ADMIN_PASS' => $admin_pass, |
|
128 'ADMIN_EMAIL' => $db->escape($_POST['email']), |
|
129 'REAL_NAME' => '', // This has always been stubbed. |
|
130 'ADMIN_EMBED_PHP' => strval(AUTH_DISALLOW), |
|
131 'UNIX_TIME' => strval(time()) |
|
132 ); |
|
133 |
|
134 $sql_parser->assign_vars($vars); |
|
135 return $sql_parser->parse(); |
|
136 } |
|
137 |
|
138 function stg_deliver_payload() |
|
139 { |
|
140 global $db; |
|
141 $schema = stg_load_schema(); |
|
142 foreach ( $schema as $sql ) |
|
143 { |
|
144 if ( !$db->sql_query($sql) ) |
|
145 { |
|
146 echo $db->get_error(); |
|
147 return false; |
|
148 } |
|
149 } |
|
150 return true; |
|
151 } |
|
152 |
|
153 function stg_write_config() |
|
154 { |
|
155 global $dbhost, $dbuser, $dbpasswd, $dbname, $dbdriver; |
|
156 $db_data = array( |
|
157 'host' => str_replace("'", "\\'", $dbhost), |
|
158 'user' => str_replace("'", "\\'", $dbuser), |
|
159 'pass' => str_replace("'", "\\'", $dbpasswd), |
|
160 'name' => str_replace("'", "\\'", $dbname), |
|
161 'tp' => table_prefix, |
|
162 'drv' => $dbdriver |
|
163 ); |
|
164 |
|
165 // Retrieves the existing key |
|
166 $site_key = stg_make_private_key(); |
|
167 |
|
168 // Determine contentPath |
|
169 switch ( @$_POST['url_scheme'] ) |
|
170 { |
|
171 case 'standard': |
|
172 default: |
|
173 $sp_append = 'index.php?title='; |
|
174 break; |
|
175 case 'shortened': |
|
176 $sp_append = 'index.php/'; |
|
177 break; |
|
178 case 'rewrite': |
|
179 $sp_append = '/'; |
|
180 break; |
|
181 } |
|
182 |
|
183 $scriptpath = scriptPath; |
|
184 $contentpath = $scriptpath . $sp_append; |
|
185 |
|
186 $config_file = <<<EOF |
|
187 <?php |
|
188 |
|
189 /** |
|
190 * Enano site configuration |
|
191 * NOTE ON EDITING: You should almost never need to change anything in this |
|
192 * file. The only exceptions are when your DB password/other info is changed |
|
193 * or if you are moving your Enano installation to another directory. |
|
194 */ |
|
195 |
|
196 // |
|
197 // DATABASE INFO |
|
198 // |
|
199 |
|
200 // Database type to use, currently mysql and postgresql are supported |
|
201 \$dbdriver = '{$db_data['drv']}'; |
|
202 |
|
203 // Hostname of your database server, probably localhost |
|
204 \$dbhost = '{$db_data['host']}'; |
|
205 |
|
206 // Username used to connect to the database |
|
207 \$dbuser = '{$db_data['user']}'; |
|
208 // Database password |
|
209 \$dbpasswd = '{$db_data['pass']}'; |
|
210 |
|
211 // Name of the database |
|
212 \$dbname = '{$db_data['name']}'; |
|
213 |
|
214 // |
|
215 // CONSTANTS |
|
216 // |
|
217 |
|
218 // if they're already defined, no use re-defining them |
|
219 if ( !defined('ENANO_CONSTANTS') ) |
|
220 { |
|
221 // The prefix for the tables in the database. Useful for holding more than |
|
222 // one Enano installation in the same database. |
|
223 define('table_prefix', '{$db_data['tp']}'); |
|
224 |
|
225 // The path to Enano's files on your server, from the document root. If |
|
226 // Enano is installed in your document root this will be blank; installing |
|
227 // Enano in /enano/ will result in "/enano" here, etc. |
|
228 define('scriptPath', '$scriptpath'); |
|
229 |
|
230 // The authoritative prefix for pages. This should be very literal: to |
|
231 // generate a URL on the site, the format is basically |
|
232 // contentPath . \$page_name. This is based off of scriptPath and the URL |
|
233 // scheme selected during installation. Pattern: |
|
234 // |
|
235 // * Standard URLs: scriptPath . '/index.php?title=' |
|
236 // * Shortened URLs: scriptPath . '/index.php/' |
|
237 // * mod_rewrite: scriptPath . '/' |
|
238 |
|
239 define('contentPath', '$contentpath'); |
|
240 |
|
241 // Tell the Enano API that we're installed and that this file is complete |
|
242 define('ENANO_INSTALLED', 'You bet!'); |
|
243 |
|
244 define('ENANO_CONSTANTS', ''); |
|
245 } |
|
246 |
|
247 // The AES encryption key used to store passwords. We have a very specific |
|
248 // reason for doing this; see the rationale at: |
|
249 // http://docs.enanocms.org/Help:Appendix_B |
|
250 \$crypto_key = '$site_key'; |
|
251 |
|
252 EOF; |
|
253 |
|
254 // Write config file |
|
255 |
|
256 $ch = @fopen ( ENANO_ROOT . '/config.new.php', 'w' ); |
|
257 if ( !$ch ) |
|
258 return false; |
|
259 |
|
260 fwrite($ch, $config_file); |
|
261 fclose($ch); |
|
262 |
|
263 // If we are using mod_rewrite, also append any existing .htaccess |
|
264 if ( @$_POST['url_scheme'] === 'rewrite' ) |
|
265 { |
|
266 $hh = @fopen ( ENANO_ROOT . '/.htaccess.new', 'w' ); |
|
267 if ( !$hh ) |
|
268 return false; |
|
269 $hhc = <<<EOF |
|
270 # |
|
271 # START ENANO RULES |
|
272 # |
|
273 |
|
274 # Enable mod_rewrite |
|
275 RewriteEngine on |
|
276 |
|
277 # Don't rewrite if the user requested a real directory or file |
|
278 RewriteCond %{REQUEST_FILENAME} !-f |
|
279 RewriteCond %{REQUEST_FILENAME} !-d |
|
280 |
|
281 # Main rule - short and sweet |
|
282 RewriteRule (.*) index.php?title=\$1 |
|
283 |
|
284 EOF; |
|
285 fwrite($hh, $hhc); |
|
286 fclose($hh); |
|
287 } |
|
288 |
|
289 return true; |
|
290 } |
|
291 |
|
292 function stg_language_setup() |
|
293 { |
|
294 global $languages, $db; |
|
295 global $lang_id; |
|
296 $lang_info =& $languages[$lang_id]; |
|
297 if ( !is_array($lang_info) ) |
|
298 return false; |
|
299 |
|
300 // Install the language |
|
301 // ($lang_code, $lang_name_neutral, $lang_name_local, $lang_file = false) |
|
302 $result = install_language($lang_id, $lang_info['name_eng'], $lang_info['name'], ENANO_ROOT . "/language/{$lang_info['dir']}/core.json"); |
|
303 if ( !$result ) |
|
304 return false; |
|
305 |
|
306 $lang_local = new Language($lang_id); |
|
307 $lang_local->import( ENANO_ROOT . "/language/{$lang_info['dir']}/user.json" ); |
|
308 $lang_local->import( ENANO_ROOT . "/language/{$lang_info['dir']}/tools.json" ); |
|
309 $lang_local->import( ENANO_ROOT . "/language/{$lang_info['dir']}/admin.json" ); |
|
310 |
|
311 return true; |
|
312 } |