| 1 | <?php |
|---|
| 2 | |
|---|
| 3 | /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
|---|
| 4 | |
|---|
| 5 | // +-------------------------------------------------------------------+ |
|---|
| 6 | // | WiFiDog Authentication Server | |
|---|
| 7 | // | ============================= | |
|---|
| 8 | // | | |
|---|
| 9 | // | The WiFiDog Authentication Server is part of the WiFiDog captive | |
|---|
| 10 | // | portal suite. | |
|---|
| 11 | // +-------------------------------------------------------------------+ |
|---|
| 12 | // | PHP version 5 required. | |
|---|
| 13 | // +-------------------------------------------------------------------+ |
|---|
| 14 | // | Homepage: http://www.wifidog.org/ | |
|---|
| 15 | // | Source Forge: http://sourceforge.net/projects/wifidog/ | |
|---|
| 16 | // +-------------------------------------------------------------------+ |
|---|
| 17 | // | This program is free software; you can redistribute it and/or | |
|---|
| 18 | // | modify it under the terms of the GNU General Public License as | |
|---|
| 19 | // | published by the Free Software Foundation; either version 2 of | |
|---|
| 20 | // | the License, or (at your option) any later version. | |
|---|
| 21 | // | | |
|---|
| 22 | // | This program is distributed in the hope that it will be useful, | |
|---|
| 23 | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|---|
| 24 | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|---|
| 25 | // | GNU General Public License for more details. | |
|---|
| 26 | // | | |
|---|
| 27 | // | You should have received a copy of the GNU General Public License | |
|---|
| 28 | // | along with this program; if not, contact: | |
|---|
| 29 | // | | |
|---|
| 30 | // | Free Software Foundation Voice: +1-617-542-5942 | |
|---|
| 31 | // | 59 Temple Place - Suite 330 Fax: +1-617-542-2652 | |
|---|
| 32 | // | Boston, MA 02111-1307, USA gnu@gnu.org | |
|---|
| 33 | // | | |
|---|
| 34 | // +-------------------------------------------------------------------+ |
|---|
| 35 | |
|---|
| 36 | /** |
|---|
| 37 | * @package WiFiDogAuthServer |
|---|
| 38 | * @author Benoit Gregoire <bock@step.polymtl.ca> |
|---|
| 39 | * @copyright 2004-2006 Benoit Gregoire, Technologies Coeus inc. |
|---|
| 40 | * @version Subversion $Id$ |
|---|
| 41 | * @link http://www.wifidog.org/ |
|---|
| 42 | */ |
|---|
| 43 | |
|---|
| 44 | /** |
|---|
| 45 | * Include PHP initialization file file |
|---|
| 46 | */ |
|---|
| 47 | require_once('init_php.php'); |
|---|
| 48 | |
|---|
| 49 | /** |
|---|
| 50 | * Include configuration file |
|---|
| 51 | */ |
|---|
| 52 | cmnRequireConfig(); |
|---|
| 53 | |
|---|
| 54 | /** |
|---|
| 55 | * Filter super globals |
|---|
| 56 | */ |
|---|
| 57 | undo_magic_quotes(); |
|---|
| 58 | |
|---|
| 59 | /** |
|---|
| 60 | * Set default timezone |
|---|
| 61 | */ |
|---|
| 62 | dateFix(); |
|---|
| 63 | |
|---|
| 64 | /** |
|---|
| 65 | * Include path detection code |
|---|
| 66 | */ |
|---|
| 67 | require_once('path_defines_base.php'); |
|---|
| 68 | |
|---|
| 69 | /** |
|---|
| 70 | * Load required classes |
|---|
| 71 | */ |
|---|
| 72 | require_once('classes/EventLogging.php'); |
|---|
| 73 | |
|---|
| 74 | EventLogging::SetupErrorHandling( "strict~/var:\sDeprecated/(off)", |
|---|
| 75 | array( 'print' => new PrintChannel(new HTMLFormatter(), 'warning,notice', null, true), |
|---|
| 76 | 'debug' => new PrintChannel(new HTMLCommentsFormatter(), '=debug', null, false) ) |
|---|
| 77 | ); |
|---|
| 78 | require_once('classes/AbstractDb.php'); |
|---|
| 79 | require_once('classes/Locale.php'); |
|---|
| 80 | require_once('classes/Dependencies.php'); |
|---|
| 81 | require_once('classes/Server.php'); |
|---|
| 82 | |
|---|
| 83 | global $db; |
|---|
| 84 | |
|---|
| 85 | $db = new AbstractDb(); |
|---|
| 86 | |
|---|
| 87 | /** |
|---|
| 88 | * Check for SSL support |
|---|
| 89 | */ |
|---|
| 90 | |
|---|
| 91 | if (Server::getCurrentServer(true) != null) { |
|---|
| 92 | if (Server::getCurrentServer(true)->isSSLAvailable()) { |
|---|
| 93 | /** |
|---|
| 94 | * @ignore |
|---|
| 95 | */ |
|---|
| 96 | define("SSL_AVAILABLE", true); |
|---|
| 97 | } else { |
|---|
| 98 | /** |
|---|
| 99 | * @ignore |
|---|
| 100 | */ |
|---|
| 101 | define("SSL_AVAILABLE", false); |
|---|
| 102 | } |
|---|
| 103 | } else { |
|---|
| 104 | define("SSL_AVAILABLE", false); |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | /** |
|---|
| 108 | * Set paths |
|---|
| 109 | */ |
|---|
| 110 | require_once('path_defines_url_content.php'); |
|---|
| 111 | |
|---|
| 112 | /* Constant shared with the gateway |
|---|
| 113 | * NEVER edit these, as they mush match the C code of the gateway */ |
|---|
| 114 | define('ACCOUNT_STATUS_ERROR', -1); |
|---|
| 115 | define('ACCOUNT_STATUS_DENIED', 0); |
|---|
| 116 | define('ACCOUNT_STATUS_ALLOWED', 1); |
|---|
| 117 | define('ACCOUNT_STATUS_VALIDATION', 5); |
|---|
| 118 | define('ACCOUNT_STATUS_VALIDATION_FAILED', 6); |
|---|
| 119 | define('ACCOUNT_STATUS_LOCKED', 254); |
|---|
| 120 | |
|---|
| 121 | $account_status_to_text[ACCOUNT_STATUS_ERROR] = "Error"; |
|---|
| 122 | $account_status_to_text[ACCOUNT_STATUS_DENIED] = "Denied"; |
|---|
| 123 | $account_status_to_text[ACCOUNT_STATUS_ALLOWED] = "Allowed"; |
|---|
| 124 | $account_status_to_text[ACCOUNT_STATUS_VALIDATION] = "Validation"; |
|---|
| 125 | $account_status_to_text[ACCOUNT_STATUS_VALIDATION_FAILED] = "Validation Failed"; |
|---|
| 126 | $account_status_to_text[ACCOUNT_STATUS_LOCKED] = "Locked"; |
|---|
| 127 | |
|---|
| 128 | define('TOKEN_UNUSED', 'UNUSED'); |
|---|
| 129 | define('TOKEN_INUSE', 'INUSE'); |
|---|
| 130 | define('TOKEN_USED', 'USED'); |
|---|
| 131 | |
|---|
| 132 | $token_to_text[TOKEN_UNUSED] = _("Unused"); |
|---|
| 133 | $token_to_text[TOKEN_INUSE] = _("In use"); |
|---|
| 134 | $token_to_text[TOKEN_USED] = _("Used"); |
|---|
| 135 | |
|---|
| 136 | define('STAGE_LOGIN', "login"); |
|---|
| 137 | define('STAGE_LOGOUT', "logout"); |
|---|
| 138 | define('STAGE_COUNTERS', "counters"); |
|---|
| 139 | |
|---|
| 140 | define('ONLINE_STATUS_ONLINE', 1); |
|---|
| 141 | define('ONLINE_STATUS_OFFLINE', 2); |
|---|
| 142 | /* End Constant shared with the gateway*/ |
|---|
| 143 | |
|---|
| 144 | /* session constants, perhaps this coulb be moved to Session.php? benoitg, 2005-08-01 */ |
|---|
| 145 | define('SESS_USERNAME_VAR', 'SESS_USERNAME'); |
|---|
| 146 | define('SESS_USER_ID_VAR', 'SESS_USER_ID'); |
|---|
| 147 | define('SESS_PASSWORD_HASH_VAR', 'SESS_PASSWORD_HASH'); |
|---|
| 148 | define('SESS_ORIGINAL_URL_VAR', 'SESS_ORIGINAL_URL'); |
|---|
| 149 | define('SESS_LANGUAGE_VAR', 'SESS_LANGUAGE'); |
|---|
| 150 | define('SESS_GW_ADDRESS_VAR', 'SESS_GW_ADDRESS'); |
|---|
| 151 | define('SESS_GW_PORT_VAR', 'SESS_GW_PORT'); |
|---|
| 152 | define('SESS_GW_ID_VAR', 'SESS_GW_ID'); |
|---|
| 153 | /* End session constants */ |
|---|
| 154 | |
|---|
| 155 | /** Convert a password hash form a NoCat passwd file into the same format as get_password_hash(). |
|---|
| 156 | * @return The 32 character hash. |
|---|
| 157 | */ |
|---|
| 158 | function convert_nocat_password_hash($hash) { |
|---|
| 159 | return $hash.'=='; |
|---|
| 160 | } |
|---|
| 161 | |
|---|
| 162 | function iso8601_date($unix_timestamp) { |
|---|
| 163 | $tzd = date('O', $unix_timestamp); |
|---|
| 164 | $tzd = substr(chunk_split($tzd, 3, ':'), 0, 6); |
|---|
| 165 | $date = date('Y-m-d\TH:i:s', $unix_timestamp).$tzd; |
|---|
| 166 | |
|---|
| 167 | return $date; |
|---|
| 168 | } |
|---|
| 169 | |
|---|
| 170 | /** Cleanup dangling tokens and connections from the database, left if a gateway crashed, etc. */ |
|---|
| 171 | function garbage_collect() { |
|---|
| 172 | global $db; |
|---|
| 173 | |
|---|
| 174 | // 10 minutes |
|---|
| 175 | $expiration = time() - 60 * 10; |
|---|
| 176 | $expiration = iso8601_date($expiration); |
|---|
| 177 | $db->execSqlUpdate("UPDATE connections SET token_status='".TOKEN_USED."' WHERE last_updated < '$expiration' AND token_status = '".TOKEN_INUSE."'", false); |
|---|
| 178 | } |
|---|
| 179 | |
|---|
| 180 | /** Get the url from the local content_specific folder if the file exists, and from the default content folder otherwise */ |
|---|
| 181 | function find_local_content_url($filename) { |
|---|
| 182 | //echo "find_local_content_url(): Looking for: ".NODE_CONTENT_PHP_RELATIVE_PATH.$filename."<br>\n"; |
|---|
| 183 | if (is_file(NODE_CONTENT_PHP_RELATIVE_PATH.$filename)) { |
|---|
| 184 | $retval = NODE_CONTENT_URL.$filename; |
|---|
| 185 | } |
|---|
| 186 | else { |
|---|
| 187 | $retval = DEFAULT_CONTENT_URL.$filename; |
|---|
| 188 | } |
|---|
| 189 | //echo "find_local_content_url(): Returned: $retval<br>\n"; |
|---|
| 190 | return $retval; |
|---|
| 191 | } |
|---|
| 192 | |
|---|
| 193 | /** Return a 32 byte guid valid for database use */ |
|---|
| 194 | function get_guid() { |
|---|
| 195 | return md5(uniqid(rand(), true)); |
|---|
| 196 | } |
|---|
| 197 | |
|---|
| 198 | /** like the php function print_r(), but the way it was meant to be... */ |
|---|
| 199 | function pretty_print_r($param) { |
|---|
| 200 | echo "\n<pre>\n"; |
|---|
| 201 | print_r($param); |
|---|
| 202 | echo "\n</pre>\n"; |
|---|
| 203 | } |
|---|
| 204 | |
|---|
| 205 | /** pop directory path */ |
|---|
| 206 | function cmnPopDir($dirname = null, $popcount = 1) { |
|---|
| 207 | if (empty ($dirname)) |
|---|
| 208 | $dirname = dirname($_SERVER['PHP_SELF']); |
|---|
| 209 | if ($dirname === DIRECTORY_SEPARATOR) |
|---|
| 210 | return DIRECTORY_SEPARATOR; |
|---|
| 211 | if (substr($dirname, -1, 1) === DIRECTORY_SEPARATOR) |
|---|
| 212 | $popcount ++; |
|---|
| 213 | |
|---|
| 214 | $popped = implode(DIRECTORY_SEPARATOR, array_slice(explode(DIRECTORY_SEPARATOR, $dirname), 0, - $popcount)); |
|---|
| 215 | |
|---|
| 216 | return empty ($popped) ? DIRECTORY_SEPARATOR : substr($popped, -1, 1) === DIRECTORY_SEPARATOR ? $popped : $popped.DIRECTORY_SEPARATOR; |
|---|
| 217 | } |
|---|
| 218 | |
|---|
| 219 | function cmnDirectorySlash($dirname) { |
|---|
| 220 | return empty ($dirname) ? DIRECTORY_SEPARATOR : substr($dirname, -1, 1) === DIRECTORY_SEPARATOR ? $dirname : $dirname.DIRECTORY_SEPARATOR; |
|---|
| 221 | } |
|---|
| 222 | |
|---|
| 223 | /** search parent directory hierarchy for a file */ |
|---|
| 224 | function cmnSearchParentDirectories($dirname, $searchfor) { |
|---|
| 225 | $pieces = explode(DIRECTORY_SEPARATOR, $dirname); |
|---|
| 226 | $is_absolute = substr($dirname, 0, 1) === DIRECTORY_SEPARATOR ? 1 : 0; |
|---|
| 227 | |
|---|
| 228 | for ($i = count($pieces); $i > $is_absolute; $i --) { |
|---|
| 229 | $filename = implode(DIRECTORY_SEPARATOR, array_merge(array_slice($pieces, 0, $i), array ($searchfor))); |
|---|
| 230 | if (file_exists($filename)) |
|---|
| 231 | return $filename; |
|---|
| 232 | } |
|---|
| 233 | |
|---|
| 234 | return false; |
|---|
| 235 | } |
|---|
| 236 | |
|---|
| 237 | /** join file path pieces together */ |
|---|
| 238 | function cmnJoinPath() { |
|---|
| 239 | $fullpath = ''; |
|---|
| 240 | |
|---|
| 241 | //$arguments = func_get_args(); |
|---|
| 242 | |
|---|
| 243 | for ($i = 0; $i < func_num_args(); $i ++) { |
|---|
| 244 | $pathelement = func_get_arg($i); |
|---|
| 245 | if ($pathelement == '') |
|---|
| 246 | continue; |
|---|
| 247 | |
|---|
| 248 | if ($fullpath == '') |
|---|
| 249 | $fullpath = $pathelement; |
|---|
| 250 | elseif (substr($fullpath, -1, 1) == DIRECTORY_SEPARATOR) { |
|---|
| 251 | if (substr($pathelement, 0, 1) == DIRECTORY_SEPARATOR) |
|---|
| 252 | $fullpath .= substr($pathelement, 1); |
|---|
| 253 | else |
|---|
| 254 | $fullpath .= $pathelement; |
|---|
| 255 | } |
|---|
| 256 | else { |
|---|
| 257 | if (substr($pathelement, 0, 1) == DIRECTORY_SEPARATOR) |
|---|
| 258 | $fullpath .= $pathelement; |
|---|
| 259 | else |
|---|
| 260 | $fullpath .= DIRECTORY_SEPARATOR.$pathelement; |
|---|
| 261 | } |
|---|
| 262 | } |
|---|
| 263 | |
|---|
| 264 | return $fullpath; |
|---|
| 265 | } |
|---|
| 266 | |
|---|
| 267 | /** find a named file in the include path */ |
|---|
| 268 | function cmnFindPackage($rel_path, $private = false) { |
|---|
| 269 | |
|---|
| 270 | $paths = isset ($private) && ($private === true || $private === 'PRIVATE') ? array (WIFIDOG_ABS_FILE_PATH) : explode(PATH_SEPARATOR, get_include_path()); |
|---|
| 271 | |
|---|
| 272 | foreach ($paths as $topdir) { |
|---|
| 273 | $package = cmnJoinPath($topdir, $rel_path); |
|---|
| 274 | if (file_exists($package)) { |
|---|
| 275 | if ($private) |
|---|
| 276 | return $package; |
|---|
| 277 | else |
|---|
| 278 | return $rel_path; |
|---|
| 279 | } |
|---|
| 280 | } |
|---|
| 281 | |
|---|
| 282 | return false; // package was not found |
|---|
| 283 | } |
|---|
| 284 | |
|---|
| 285 | /** require_once a named file */ |
|---|
| 286 | function cmnRequirePackage($rel_path, $private = false) { |
|---|
| 287 | |
|---|
| 288 | $paths = isset ($private) && ($private === true || $private === 'PRIVATE') ? array (WIFIDOG_ABS_FILE_PATH) : explode(PATH_SEPARATOR, get_include_path()); |
|---|
| 289 | |
|---|
| 290 | foreach ($paths as $topdir) { |
|---|
| 291 | $package = cmnJoinPath($topdir, $rel_path); |
|---|
| 292 | if (file_exists($package)) { |
|---|
| 293 | if ($private) |
|---|
| 294 | @ require_once $package; |
|---|
| 295 | else |
|---|
| 296 | @ require_once $rel_path; |
|---|
| 297 | |
|---|
| 298 | return true; // package was found |
|---|
| 299 | } |
|---|
| 300 | } |
|---|
| 301 | |
|---|
| 302 | return false; // package was not found |
|---|
| 303 | } |
|---|
| 304 | |
|---|
| 305 | /** include_once a named file */ |
|---|
| 306 | function cmnIncludePackage($rel_path, $private = false) { |
|---|
| 307 | |
|---|
| 308 | $paths = isset ($private) && ($private === true || $private === 'PRIVATE') ? array (WIFIDOG_ABS_FILE_PATH) : explode(PATH_SEPARATOR, get_include_path()); |
|---|
| 309 | |
|---|
| 310 | foreach ($paths as $topdir) { |
|---|
| 311 | $package = cmnJoinPath($topdir, $rel_path); |
|---|
| 312 | if (file_exists($package)) { |
|---|
| 313 | if ($private) |
|---|
| 314 | @ include_once $package; |
|---|
| 315 | else |
|---|
| 316 | @ include_once $rel_path; |
|---|
| 317 | |
|---|
| 318 | return true; // package was found |
|---|
| 319 | } |
|---|
| 320 | } |
|---|
| 321 | |
|---|
| 322 | return false; // package was not found |
|---|
| 323 | } |
|---|
| 324 | |
|---|
| 325 | function cmnRequireConfig($config_file = 'config.php') { |
|---|
| 326 | global $AVAIL_LOCALE_ARRAY; // so that nobody has to change their custom config.php |
|---|
| 327 | $config_path = cmnSearchParentDirectories(dirname(__FILE__), $config_file); |
|---|
| 328 | if (!empty ($config_path)) |
|---|
| 329 | require_once ($config_path); |
|---|
| 330 | } |
|---|
| 331 | |
|---|
| 332 | class WifidogSyslogFormatter extends EventFormatter { |
|---|
| 333 | public function formatEvent($event, $info=null) { |
|---|
| 334 | $dt = date("Y-m-d H:i:s (T)", $event->getTimestamp()); |
|---|
| 335 | |
|---|
| 336 | $myFilename = $event->getFilename(); |
|---|
| 337 | $myLinenum = $event->getLinenum(); |
|---|
| 338 | |
|---|
| 339 | // Get information about node |
|---|
| 340 | $myCurrentNode = Node::getCurrentNode(); |
|---|
| 341 | if (empty($myCurrentNode)) $myNodeName = '*nonode*'; |
|---|
| 342 | else $myNodeName = $myCurrentNode->getName(); |
|---|
| 343 | |
|---|
| 344 | // Get information about network |
|---|
| 345 | $myNetwork = Network::getCurrentNetwork(); |
|---|
| 346 | if (empty($myNetwork)) $myNetworkName = '*nonetwork*'; |
|---|
| 347 | else $myNetworkName = $myNetwork->getName(); |
|---|
| 348 | |
|---|
| 349 | // Get information about user |
|---|
| 350 | $myCurrentUser = User::getCurrentUser(); |
|---|
| 351 | if (empty($myCurrentUser)) $myUserName = '*nouser*'; |
|---|
| 352 | else $myUserName = $myCurrentUser->getUsername(); |
|---|
| 353 | |
|---|
| 354 | $string = "$dt " |
|---|
| 355 | . EventObject::PrettyErrorType($event->getLayoutType()) |
|---|
| 356 | . " >$myNetworkName >${myUserName}@$myNodeName [".$_SERVER['REQUEST_URI']."]" |
|---|
| 357 | . ": " |
|---|
| 358 | . $event->getMessage() |
|---|
| 359 | . (!empty($myFilename) ? " in $myFilename". (!empty($myLinenum) ? " on line $myLinenum" : "") : "") |
|---|
| 360 | . "\n"; |
|---|
| 361 | |
|---|
| 362 | if ($event->classifyErrorType() == 'error') { |
|---|
| 363 | $string .= " Stack Backtrace\n" . |
|---|
| 364 | self::FormatBacktrace($event->getContext()) . |
|---|
| 365 | "\n" |
|---|
| 366 | ; |
|---|
| 367 | } |
|---|
| 368 | |
|---|
| 369 | return $string; |
|---|
| 370 | } |
|---|
| 371 | } |
|---|
| 372 | |
|---|
| 373 | $myLogfile = !defined('WIFIDOG_LOGFILE') ? "tmp/wifidog.log" : constant('WIFIDOG_LOGFILE'); |
|---|
| 374 | if (!empty($myLogfile)) { |
|---|
| 375 | if (substr($myLogfile,0,1) != '/') $myLogfile = WIFIDOG_ABS_FILE_PATH.$myLogfile; |
|---|
| 376 | |
|---|
| 377 | EventLogging::stAddChannel( new FileChannel($myLogfile, new WifidogSyslogFormatter(), 'warning,notice'), 'logfile' ); |
|---|
| 378 | } |
|---|
| 379 | |
|---|
| 380 | // trigger_error("here i am", E_USER_NOTICE); |
|---|
| 381 | |
|---|
| 382 | /* |
|---|
| 383 | * Local variables: |
|---|
| 384 | * tab-width: 4 |
|---|
| 385 | * c-basic-offset: 4 |
|---|
| 386 | * c-hanging-comment-ender-p: nil |
|---|
| 387 | * End: |
|---|
| 388 | */ |
|---|
| 389 | |
|---|
| 390 | ?> |
|---|