9 * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. |
9 * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. |
10 * |
10 * |
11 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied |
11 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied |
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. |
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. |
13 */ |
13 */ |
14 |
14 |
15 if(isset($_REQUEST['GLOBALS'])) |
15 /** |
|
16 * The main loader script that initializes everything about Enano in the proper order. Prepare to get |
|
17 * redirected if you don't have $_GET['title'] or $_SERVER['PATH_INFO'] set up. |
|
18 * @package Enano |
|
19 * @subpackage Core |
|
20 * @copyright See header block |
|
21 */ |
|
22 |
|
23 // Make sure we don't have an attempt to inject globals (register_globals on) |
|
24 if ( isset($_REQUEST['GLOBALS']) ) |
16 { |
25 { |
17 ?> |
26 ?> |
18 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html><head><title>Hacking Attempt</title><meta http-equiv="Content-type" content="text/html; charset=utf-8" /></head><style type="text/css">body{background-color:#000;color:#CCC;font-family:trebuchet ms,sans-serif;font-size:9pt;}a{color:#FFF;}</style><body><p>Hacking attempt using <a href="http://www.hardened-php.net/index.76.html">PHP $GLOBALS overwrite vulnerability</a> detected, reported to admin</p><p>You're worse than this guy! Unless you are this guy...</p><p id="billp"><img alt=" " src="about:blank" id="billi" /></p><script type="text/javascript">// <![CDATA[ |
27 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html><head><title>Hacking Attempt</title><meta http-equiv="Content-type" content="text/html; charset=utf-8" /></head><style type="text/css">body{background-color:#000;color:#CCC;font-family:trebuchet ms,sans-serif;font-size:9pt;}a{color:#FFF;}</style><body><p>Hacking attempt using <a href="http://www.hardened-php.net/index.76.html">PHP $GLOBALS overwrite vulnerability</a> detected, reported to admin</p><p>You're worse than this guy! Unless you are this guy...</p><p id="billp"><img alt=" " src="about:blank" id="billi" /></p><script type="text/javascript">// <![CDATA[ |
19 window.onload=function(){counter();setInterval('counter();', 1000);};var text=false;var cnt=10;function counter(){if(!text){text=document.createElement('span');text.id='billc';text.innerHTML=cnt;text.style.fontSize='96pt';text.style.color='#FF0000';p=document.getElementById('billp');p.appendChild(text);}else{if(cnt==1){document.getElementById('billi').src='http://upload.wikimedia.org/wikipedia/commons/7/7f/Bill_Gates_2004_cr.jpg';document.getElementById('billc').innerHTML='';return;}cnt--;document.getElementById('billc').innerHTML=cnt+' ';}} |
28 window.onload=function(){counter();setInterval('counter();', 1000);};var text=false;var cnt=10;function counter(){if(!text){text=document.createElement('span');text.id='billc';text.innerHTML=cnt;text.style.fontSize='96pt';text.style.color='#FF0000';p=document.getElementById('billp');p.appendChild(text);}else{if(cnt==1){document.getElementById('billi').src='http://upload.wikimedia.org/wikipedia/commons/7/7f/Bill_Gates_2004_cr.jpg';document.getElementById('billc').innerHTML='';return;}cnt--;document.getElementById('billc').innerHTML=cnt+' ';}} |
20 // ]]> |
29 // ]]> |
21 </script><p><span style="color:black;">You been f***ed by Enano | valid XHTML 1.1</span></p></body></html> |
30 </script><p><span style="color:black;">You been f***ed by Enano | valid XHTML 1.1</span></p></body></html> |
22 <?php |
31 <?php |
23 exit; |
32 exit; |
24 } |
33 } |
25 |
34 |
|
35 // Our version number |
|
36 // This needs to match the version number in the database. This number should |
|
37 // be the expected output of enano_version(), which will always be in the |
|
38 // format of 1.0.2, 1.0.2a1, 1.0.2b1, 1.0.2RC1 |
|
39 // You'll want to change this for custom distributions. |
26 $version = '1.1.1'; |
40 $version = '1.1.1'; |
|
41 |
|
42 /** |
|
43 * Returns a floating-point number with the current UNIX timestamp in microseconds. Defined very early because we gotta call it |
|
44 * from very early on in the script to measure the starting time of Enano. |
|
45 * @return float |
|
46 */ |
27 |
47 |
28 function microtime_float() |
48 function microtime_float() |
29 { |
49 { |
30 list($usec, $sec) = explode(" ", microtime()); |
50 list($usec, $sec) = explode(" ", microtime()); |
31 return ((float)$usec + (float)$sec); |
51 return ((float)$usec + (float)$sec); |
32 } |
52 } |
33 |
53 |
|
54 // Determine starting time |
34 global $_starttime; |
55 global $_starttime; |
35 $_starttime = microtime_float(); |
56 $_starttime = microtime_float(); |
36 |
57 |
|
58 // Verbose error reporting |
37 error_reporting(E_ALL); |
59 error_reporting(E_ALL); |
38 |
60 |
39 // Determine directory (special case for development servers) |
61 // |
|
62 // Determine the location of Enano as an absolute path. |
|
63 // |
|
64 |
|
65 // We need to see if this is a specially marked Enano development server. You can create an Enano |
|
66 // development server by cloning the Mercurial repository into a directory named repo, and then |
|
67 // using symlinks to reference the original files so as to segregate unique files from non-unique |
|
68 // and distribution-standard ones. Enano will pivot its root directory accordingly if the file |
|
69 // .enanodev is found in the Enano root (not /repo/). |
40 if ( strpos(__FILE__, '/repo/') && ( file_exists('.enanodev') || file_exists('../.enanodev') ) ) |
70 if ( strpos(__FILE__, '/repo/') && ( file_exists('.enanodev') || file_exists('../.enanodev') ) ) |
41 { |
71 { |
|
72 // We have a development directory. Remove /repo/ from the picture. |
42 $filename = str_replace('/repo/', '/', __FILE__); |
73 $filename = str_replace('/repo/', '/', __FILE__); |
43 } |
74 } |
44 else |
75 else |
45 { |
76 { |
|
77 // Standard Enano installation |
46 $filename = __FILE__; |
78 $filename = __FILE__; |
47 } |
79 } |
48 |
80 |
49 if(!defined('ENANO_ROOT')) // ENANO_ROOT is sometimes defined by plugins like AjIM that need the constant before the Enano API is initialized |
81 // ENANO_ROOT is sometimes defined by plugins like AjIM that need the constant before the Enano API is initialized |
|
82 if ( !defined('ENANO_ROOT') ) |
50 define('ENANO_ROOT', dirname(dirname($filename))); |
83 define('ENANO_ROOT', dirname(dirname($filename))); |
51 |
84 |
52 if(defined('ENANO_DEBUG') && version_compare(PHP_VERSION, '5.0.0') < 0) |
85 // Debugging features are PHP5-specifid |
|
86 if ( defined('ENANO_DEBUG') && version_compare(PHP_VERSION, '5.0.0') < 0 ) |
53 { |
87 { |
54 die(__FILE__.':'.__LINE__.': The debugConsole requires PHP 5.x.x or greater. Please comment out the ENANO_DEBUG constant in your index.php.'); |
88 die(__FILE__.':'.__LINE__.': The debugConsole requires PHP 5.x.x or greater. Please comment out the ENANO_DEBUG constant in your index.php.'); |
55 } |
89 } |
56 |
90 |
57 /* |
91 // We deprecated debugConsole in 1.0.2 because it was never used and there were a lot of unneeded debugging points in the code. |
58 if(defined('ENANO_DEBUG')) |
92 |
59 { |
93 // _nightly.php is used to tag non-Mercurial-generated nightly builds |
60 require_once(ENANO_ROOT.'/includes/debugger/debugConsole.php'); |
|
61 } else { |
|
62 */ |
|
63 function dc_here($m) { return false; } |
|
64 function dc_dump($a, $g) { return false; } |
|
65 function dc_watch($n) { return false; } |
|
66 function dc_start_timer($u) { return false; } |
|
67 function dc_stop_timer($m) { return false; } |
|
68 //} |
|
69 |
|
70 if ( file_exists( ENANO_ROOT . '/_nightly.php') ) |
94 if ( file_exists( ENANO_ROOT . '/_nightly.php') ) |
71 require(ENANO_ROOT.'/_nightly.php'); |
95 require(ENANO_ROOT.'/_nightly.php'); |
72 |
96 |
73 // List of scheduled tasks |
97 // List of scheduled tasks (don't change this manually, use register_cron_task()) |
74 $cron_tasks = array(); |
98 $cron_tasks = array(); |
75 |
99 |
76 // Start including files. LOTS of files. Yeah! |
100 // Start including files. LOTS of files. Yeah! |
77 require_once(ENANO_ROOT.'/includes/constants.php'); |
101 require_once(ENANO_ROOT.'/includes/constants.php'); |
78 dc_here('Enano CMS '.$version.' (dev) - debug window<br />Powered by debugConsole'); |
|
79 dc_here('common: including files'); |
|
80 require_once(ENANO_ROOT.'/includes/functions.php'); |
102 require_once(ENANO_ROOT.'/includes/functions.php'); |
81 require_once(ENANO_ROOT.'/includes/dbal.php'); |
103 require_once(ENANO_ROOT.'/includes/dbal.php'); |
82 require_once(ENANO_ROOT.'/includes/paths.php'); |
104 require_once(ENANO_ROOT.'/includes/paths.php'); |
83 require_once(ENANO_ROOT.'/includes/sessions.php'); |
105 require_once(ENANO_ROOT.'/includes/sessions.php'); |
84 require_once(ENANO_ROOT.'/includes/template.php'); |
106 require_once(ENANO_ROOT.'/includes/template.php'); |
99 require_once(ENANO_ROOT.'/includes/pageprocess.php'); |
121 require_once(ENANO_ROOT.'/includes/pageprocess.php'); |
100 require_once(ENANO_ROOT.'/includes/tagcloud.php'); |
122 require_once(ENANO_ROOT.'/includes/tagcloud.php'); |
101 |
123 |
102 strip_magic_quotes_gpc(); |
124 strip_magic_quotes_gpc(); |
103 |
125 |
104 // Enano has five parts: the database abstraction layer (DBAL), the session manager, the path/URL manager, the template engine, and the plugin manager. |
126 // Enano has five main components: the database abstraction layer (DBAL), the session manager, |
105 // Each part has its own class and a global var; nearly all Enano functions are handled by one of these five components. |
127 // the path/URL manager, the template engine, and the plugin manager. |
|
128 // Each part has its own class and a global object; nearly all Enano functions are handled by one of these five components. |
|
129 // All of these classes are singletons and are designed to carry as much data as possible within the object |
|
130 // to make data access and function calling easy. |
106 |
131 |
107 global $db, $session, $paths, $template, $plugins; // Common objects |
132 global $db, $session, $paths, $template, $plugins; // Common objects |
108 global $enano_config; // A global used to cache config information without making loads of queries ;-) |
133 global $enano_config; // A global used to cache config information without making loads of queries ;-) |
109 // In addition, $enano_config is used to fetch config information if die_semicritical() is called. |
134 // In addition, $enano_config is used to fetch config information if die_semicritical() is called. |
110 |
135 |
|
136 // Jim Tucek's e-mail encryption code |
111 global $email; |
137 global $email; |
|
138 |
|
139 // Language object |
112 global $lang; |
140 global $lang; |
113 |
141 |
114 if(!isset($_SERVER['HTTP_HOST'])) grinding_halt('Cannot get hostname', '<p>Your web browser did not provide the HTTP Host: field. This site requires a modern browser that supports the HTTP 1.1 standard.</p>'); |
142 // Because Enano sends out complete URLs in several occasions, we need to know what hostname the user is requesting the page from. |
115 |
143 // In future versions we may include a fallback "safety" host to use, but that's too much to worry about now |
|
144 if ( !isset($_SERVER['HTTP_HOST']) ) |
|
145 grinding_halt('Cannot get hostname', '<p>Your web browser did not provide the HTTP Host: field. This site requires a modern browser that supports the HTTP 1.1 standard.</p>'); |
|
146 |
|
147 // |
|
148 // END BACKGROUND AND ENVIRONMENT CHECKS |
|
149 // |
|
150 |
|
151 // |
|
152 // MAIN API INITIALIZATION |
|
153 // |
|
154 |
|
155 // The first thing we need to do is start the database connection. At this point, for all we know, Enano might not |
|
156 // even be installed. If this connection attempt fails and it's because of a missing or corrupt config file, the |
|
157 // user will be redirected (intelligently) to install.php. |
116 $db = new mysql(); |
158 $db = new mysql(); |
117 dc_here('common: calling $db->connect();'); |
159 $db->connect(); |
118 $db->connect(); // Redirects to install.php if an installation is not detected |
160 |
119 |
161 // The URL separator is the character appended to contentPath + url_title type strings. |
120 if(strstr(contentPath, '?')) $sep = '&'; |
162 // If the contentPath has a ? in it, this should be an ampersand; else, it should be a |
121 else $sep = '?'; |
163 // question mark. |
|
164 $sep = ( strstr(contentPath, '?') ) ? '&' : '?'; |
122 define('urlSeparator', $sep); |
165 define('urlSeparator', $sep); |
123 unset($sep); // save 10 bytes of memory... |
166 unset($sep); // save 10 bytes of memory... |
124 |
167 |
125 // See if any diagnostic actions have been requested |
168 // Sometimes there are critical failures triggered by initialization functions in the Enano API that are recurring |
|
169 // and cannot be fixed except for manual intervention. This is where that code should go. |
126 if ( isset($_GET['do']) && $_GET['do'] == 'diag' && isset($_GET['sub']) ) |
170 if ( isset($_GET['do']) && $_GET['do'] == 'diag' && isset($_GET['sub']) ) |
127 { |
171 { |
128 switch($_GET['sub']) |
172 switch($_GET['sub']) |
129 { |
173 { |
130 case 'cookie_destroy': |
174 case 'cookie_destroy': |
135 break; |
179 break; |
136 } |
180 } |
137 } |
181 } |
138 |
182 |
139 // Select and fetch the site configuration |
183 // Select and fetch the site configuration |
140 dc_here('common: selecting global config data'); |
|
141 $e = $db->sql_query('SELECT config_name, config_value FROM '.table_prefix.'config;'); |
184 $e = $db->sql_query('SELECT config_name, config_value FROM '.table_prefix.'config;'); |
142 if(!$e) $db->_die('Some critical configuration information could not be selected.'); |
185 if ( !$e ) |
143 else define('ENANO_CONFIG_FETCHED', ''); // Used in die_semicritical to figure out whether to call getConfig() or not |
186 { |
144 |
187 $db->_die('Some critical configuration information could not be selected.'); |
145 dc_here('common: fetching $enano_config'); |
188 } |
|
189 // Used in die_semicritical to figure out whether to call getConfig() or not |
|
190 define('ENANO_CONFIG_FETCHED', ''); |
|
191 |
|
192 // Initialize and fetch the site configuration array, which is used to cache the config |
146 $enano_config = Array(); |
193 $enano_config = Array(); |
147 while($r = $db->fetchrow()) |
194 while($r = $db->fetchrow()) |
148 { |
195 { |
149 $enano_config[$r['config_name']] = $r['config_value']; |
196 $enano_config[$r['config_name']] = $r['config_value']; |
150 } |
197 } |
151 |
198 |
152 $db->free_result(); |
199 $db->free_result(); |
153 |
200 |
154 if(enano_version(false, true) != $version) |
201 // Now that we have the config, check the Enano version. |
|
202 if ( enano_version(false, true) != $version ) |
155 { |
203 { |
156 grinding_halt('Version mismatch', '<p>It seems that the Enano release we\'re trying to run ('.$version.') is different from the version specified in your database ('.enano_version().'). Perhaps you need to <a href="'.scriptPath.'/upgrade.php">upgrade</a>?</p>'); |
204 grinding_halt('Version mismatch', '<p>It seems that the Enano release we\'re trying to run ('.$version.') is different from the version specified in your database ('.enano_version().'). Perhaps you need to <a href="'.scriptPath.'/upgrade.php">upgrade</a>?</p>'); |
157 } |
205 } |
158 |
206 |
159 // |
207 // |
232 table_prefix.'page_groups', |
280 table_prefix.'page_groups', |
233 table_prefix.'page_group_members', |
281 table_prefix.'page_group_members', |
234 table_prefix.'tags' |
282 table_prefix.'tags' |
235 ); |
283 ); |
236 |
284 |
237 dc_here('common: initializing base classes'); |
285 // Load plugin manager |
238 $plugins = new pluginLoader(); |
286 $plugins = new pluginLoader(); |
239 |
287 |
240 // So where does the majority of Enano get executed? How about the next nine lines of code :) |
288 // |
241 dc_here('common: ok, we\'re set up, starting mainstream execution'); |
289 // Mainstream API boot-up |
242 |
290 // |
|
291 |
|
292 // Obtain list of plugins |
243 $plugins->loadAll(); |
293 $plugins->loadAll(); |
244 dc_here('common: loading plugins'); |
294 |
245 global $plugins; |
295 global $plugins; |
246 foreach($plugins->load_list as $f) { include_once $f; } // Can't be in object context when this is done |
296 |
247 |
297 // Load plugins from common because we can't give plugins full abilities in object context |
|
298 foreach ( $plugins->load_list as $f ) |
|
299 { |
|
300 include_once $f; |
|
301 } |
|
302 |
|
303 // Three fifths of the Enano API gets the breath of life right here. |
248 $session = new sessionManager(); |
304 $session = new sessionManager(); |
249 $paths = new pathManager(); |
305 $paths = new pathManager(); |
250 $template = new template(); |
306 $template = new template(); |
251 $email = new EmailEncryptor(); |
307 $email = new EmailEncryptor(); |
252 |
308 |
|
309 // We've got the five main objects - flick on the switch so if a problem occurs, we can have a "friendly" UI |
253 define('ENANO_BASE_CLASSES_INITIALIZED', ''); |
310 define('ENANO_BASE_CLASSES_INITIALIZED', ''); |
254 |
311 |
|
312 // From here on out, none of this functionality is needed during the installer stage. |
|
313 // Once $paths->init() is called, we could be redirected to the main page, so we don't want |
|
314 // that if the installer's running. Don't just go and define IN_ENANO_INSTALL from your |
|
315 // script though, because that will make the DBAL look in the wrong place for the config file. |
255 if ( !defined('IN_ENANO_INSTALL') ) |
316 if ( !defined('IN_ENANO_INSTALL') ) |
256 { |
317 { |
|
318 // And here you have it, the de facto way to place a hook. Plugins can place hooks and hook |
|
319 // into other plugins. You just never know. |
257 $code = $plugins->setHook('base_classes_initted'); |
320 $code = $plugins->setHook('base_classes_initted'); |
258 foreach ( $code as $cmd ) |
321 foreach ( $code as $cmd ) |
259 { |
322 { |
260 eval($cmd); |
323 eval($cmd); |
261 } |
324 } |
262 |
325 |
|
326 // For special and administration pages, sometimes there is a "preloader" function that must be run |
|
327 // before the session manager and/or path manager get the init signal. Call it here. |
263 $p = RenderMan::strToPageId($paths->get_pageid_from_url()); |
328 $p = RenderMan::strToPageId($paths->get_pageid_from_url()); |
264 if( ( $p[1] == 'Admin' || $p[1] == 'Special' ) && function_exists('page_'.$p[1].'_'.$p[0].'_preloader')) |
329 if( ( $p[1] == 'Admin' || $p[1] == 'Special' ) && function_exists('page_'.$p[1].'_'.$p[0].'_preloader')) |
265 { |
330 { |
266 @call_user_func('page_'.$p[1].'_'.$p[0].'_preloader'); |
331 @call_user_func('page_'.$p[1].'_'.$p[0].'_preloader'); |
267 } |
332 } |