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.0.2'; |
40 $version = '1.0.2'; |
|
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'); |
98 require_once(ENANO_ROOT.'/includes/pageprocess.php'); |
120 require_once(ENANO_ROOT.'/includes/pageprocess.php'); |
99 require_once(ENANO_ROOT.'/includes/tagcloud.php'); |
121 require_once(ENANO_ROOT.'/includes/tagcloud.php'); |
100 |
122 |
101 strip_magic_quotes_gpc(); |
123 strip_magic_quotes_gpc(); |
102 |
124 |
103 // Enano has five parts: the database abstraction layer (DBAL), the session manager, the path/URL manager, the template engine, and the plugin manager. |
125 // Enano has five main components: the database abstraction layer (DBAL), the session manager, |
104 // Each part has its own class and a global var; nearly all Enano functions are handled by one of these five components. |
126 // the path/URL manager, the template engine, and the plugin manager. |
|
127 // Each part has its own class and a global object; nearly all Enano functions are handled by one of these five components. |
|
128 // All of these classes are singletons and are designed to carry as much data as possible within the object |
|
129 // to make data access and function calling easy. |
105 |
130 |
106 global $db, $session, $paths, $template, $plugins; // Common objects |
131 global $db, $session, $paths, $template, $plugins; // Common objects |
107 global $enano_config; // A global used to cache config information without making loads of queries ;-) |
132 global $enano_config; // A global used to cache config information without making loads of queries ;-) |
108 // In addition, $enano_config is used to fetch config information if die_semicritical() is called. |
133 // In addition, $enano_config is used to fetch config information if die_semicritical() is called. |
109 |
134 |
|
135 // Jim Tucek's e-mail encryption code |
110 global $email; |
136 global $email; |
111 |
137 |
112 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>'); |
138 // Because Enano sends out complete URLs in several occasions, we need to know what hostname the user is requesting the page from. |
113 |
139 // In future versions we may include a fallback "safety" host to use, but that's too much to worry about now |
|
140 if ( !isset($_SERVER['HTTP_HOST']) ) |
|
141 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 |
|
143 // |
|
144 // END BACKGROUND AND ENVIRONMENT CHECKS |
|
145 // |
|
146 |
|
147 // |
|
148 // MAIN API INITIALIZATION |
|
149 // |
|
150 |
|
151 // The first thing we need to do is start the database connection. At this point, for all we know, Enano might not |
|
152 // even be installed. If this connection attempt fails and it's because of a missing or corrupt config file, the |
|
153 // user will be redirected (intelligently) to install.php. |
114 $db = new mysql(); |
154 $db = new mysql(); |
115 dc_here('common: calling $db->connect();'); |
155 $db->connect(); |
116 $db->connect(); // Redirects to install.php if an installation is not detected |
156 |
117 |
157 // The URL separator is the character appended to contentPath + url_title type strings. |
118 if(strstr(contentPath, '?')) $sep = '&'; |
158 // If the contentPath has a ? in it, this should be an ampersand; else, it should be a |
119 else $sep = '?'; |
159 // question mark. |
|
160 $sep = ( strstr(contentPath, '?') ) ? '&' : '?'; |
120 define('urlSeparator', $sep); |
161 define('urlSeparator', $sep); |
121 unset($sep); // save 10 bytes of memory... |
162 unset($sep); // save 10 bytes of memory... |
122 |
163 |
123 // See if any diagnostic actions have been requested |
164 // Sometimes there are critical failures triggered by initialization functions in the Enano API that are recurring |
|
165 // and cannot be fixed except for manual intervention. This is where that code should go. |
124 if ( isset($_GET['do']) && $_GET['do'] == 'diag' && isset($_GET['sub']) ) |
166 if ( isset($_GET['do']) && $_GET['do'] == 'diag' && isset($_GET['sub']) ) |
125 { |
167 { |
126 switch($_GET['sub']) |
168 switch($_GET['sub']) |
127 { |
169 { |
128 case 'cookie_destroy': |
170 case 'cookie_destroy': |
133 break; |
175 break; |
134 } |
176 } |
135 } |
177 } |
136 |
178 |
137 // Select and fetch the site configuration |
179 // Select and fetch the site configuration |
138 dc_here('common: selecting global config data'); |
|
139 $e = $db->sql_query('SELECT config_name, config_value FROM '.table_prefix.'config;'); |
180 $e = $db->sql_query('SELECT config_name, config_value FROM '.table_prefix.'config;'); |
140 if(!$e) $db->_die('Some critical configuration information could not be selected.'); |
181 if ( !$e ) |
141 else define('ENANO_CONFIG_FETCHED', ''); // Used in die_semicritical to figure out whether to call getConfig() or not |
182 { |
142 |
183 $db->_die('Some critical configuration information could not be selected.'); |
143 dc_here('common: fetching $enano_config'); |
184 } |
|
185 // Used in die_semicritical to figure out whether to call getConfig() or not |
|
186 define('ENANO_CONFIG_FETCHED', ''); |
|
187 |
|
188 // Initialize and fetch the site configuration array, which is used to cache the config |
144 $enano_config = Array(); |
189 $enano_config = Array(); |
145 while($r = $db->fetchrow()) |
190 while($r = $db->fetchrow()) |
146 { |
191 { |
147 $enano_config[$r['config_name']] = $r['config_value']; |
192 $enano_config[$r['config_name']] = $r['config_value']; |
148 } |
193 } |
149 |
194 |
150 $db->free_result(); |
195 $db->free_result(); |
151 |
196 |
152 if(enano_version(false, true) != $version) |
197 // Now that we have the config, check the Enano version. |
|
198 if ( enano_version(false, true) != $version ) |
153 { |
199 { |
154 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>'); |
200 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>'); |
155 } |
201 } |
156 |
202 |
157 // |
203 // |
209 table_prefix.'page_groups', |
255 table_prefix.'page_groups', |
210 table_prefix.'page_group_members', |
256 table_prefix.'page_group_members', |
211 table_prefix.'tags' |
257 table_prefix.'tags' |
212 ); |
258 ); |
213 |
259 |
214 dc_here('common: initializing base classes'); |
260 // Load plugin manager |
215 $plugins = new pluginLoader(); |
261 $plugins = new pluginLoader(); |
216 |
262 |
217 // So where does the majority of Enano get executed? How about the next nine lines of code :) |
263 // |
218 dc_here('common: ok, we\'re set up, starting mainstream execution'); |
264 // Mainstream API boot-up |
219 |
265 // |
|
266 |
|
267 // Obtain list of plugins |
220 $plugins->loadAll(); |
268 $plugins->loadAll(); |
221 dc_here('common: loading plugins'); |
269 |
222 global $plugins; |
270 global $plugins; |
223 foreach($plugins->load_list as $f) { include_once $f; } // Can't be in object context when this is done |
271 |
224 |
272 // Load plugins from common because we can't give plugins full abilities in object context |
|
273 foreach ( $plugins->load_list as $f ) |
|
274 { |
|
275 include_once $f; |
|
276 } |
|
277 |
|
278 // Three fifths of the Enano API gets the breath of life right here. |
225 $session = new sessionManager(); |
279 $session = new sessionManager(); |
226 $paths = new pathManager(); |
280 $paths = new pathManager(); |
227 $template = new template(); |
281 $template = new template(); |
228 $email = new EmailEncryptor(); |
282 $email = new EmailEncryptor(); |
229 |
283 |
|
284 // We've got the five main objects - flick on the switch so if a problem occurs, we can have a "friendly" UI |
230 define('ENANO_BASE_CLASSES_INITIALIZED', ''); |
285 define('ENANO_BASE_CLASSES_INITIALIZED', ''); |
231 |
286 |
|
287 // From here on out, none of this functionality is needed during the installer stage. |
|
288 // Once $paths->init() is called, we could be redirected to the main page, so we don't want |
|
289 // that if the installer's running. Don't just go and define IN_ENANO_INSTALL from your |
|
290 // script though, because that will make the DBAL look in the wrong place for the config file. |
232 if ( !defined('IN_ENANO_INSTALL') ) |
291 if ( !defined('IN_ENANO_INSTALL') ) |
233 { |
292 { |
|
293 // And here you have it, the de facto way to place a hook. Plugins can place hooks and hook |
|
294 // into other plugins. You just never know. |
234 $code = $plugins->setHook('base_classes_initted'); |
295 $code = $plugins->setHook('base_classes_initted'); |
235 foreach ( $code as $cmd ) |
296 foreach ( $code as $cmd ) |
236 { |
297 { |
237 eval($cmd); |
298 eval($cmd); |
238 } |
299 } |
239 |
300 |
|
301 // For special and administration pages, sometimes there is a "preloader" function that must be run |
|
302 // before the session manager and/or path manager get the init signal. Call it here. |
240 $p = RenderMan::strToPageId($paths->get_pageid_from_url()); |
303 $p = RenderMan::strToPageId($paths->get_pageid_from_url()); |
241 if( ( $p[1] == 'Admin' || $p[1] == 'Special' ) && function_exists('page_'.$p[1].'_'.$p[0].'_preloader')) |
304 if( ( $p[1] == 'Admin' || $p[1] == 'Special' ) && function_exists('page_'.$p[1].'_'.$p[0].'_preloader')) |
242 { |
305 { |
243 @call_user_func('page_'.$p[1].'_'.$p[0].'_preloader'); |
306 @call_user_func('page_'.$p[1].'_'.$p[0].'_preloader'); |
244 } |
307 } |