diff -r faef5e62e1e0 -r 90225c988124 includes/sessions.php --- a/includes/sessions.php Tue Aug 25 01:43:11 2009 -0400 +++ b/includes/sessions.php Tue Aug 25 01:43:40 2009 -0400 @@ -2,8 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.1.6 (Caoineag beta 1) - * Copyright (C) 2006-2008 Dan Fuhry + * Copyright (C) 2006-2009 Dan Fuhry * sessions.php - everything related to security and user management * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License @@ -158,6 +157,20 @@ var $auth_level = 1; /** + * Preference for date formatting + * @var string + */ + + var $date_format = DATE_4; + + /** + * Preference for time formatting + * @var string + */ + + var $time_format = TIME_24_NS; + + /** * State variable to track if a session timed out * @var bool */ @@ -413,6 +426,28 @@ return $result; } + /** + * Returns true if we're currently on a page that shouldn't be blocked even if we have an inactive or banned account + * @param bool strict - if true, whitelist of pages is even stricter (Login, Logout and CSS only). if false (default), admin access is allowed, assuming other factors allow it + * @return bool + */ + + function on_critical_page($strict = false) + { + global $title; + list($page_id, $namespace) = RenderMan::strToPageID($title); + list($page_id) = explode('/', $page_id); + + if ( $strict ) + { + return $namespace == 'Special' && in_array($page_id, array('CSS', 'Login', 'Logout')); + } + else + { + return $namespace == 'Admin' || ($namespace == 'Special' && in_array($page_id, array('CSS', 'Login', 'Logout', 'Administration'))); + } + } + # Session restoration and permissions /** @@ -439,13 +474,6 @@ } if ( is_array($userdata) ) { - $data = RenderMan::strToPageID($paths->get_pageid_from_url()); - - if(!$this->compat && $userdata['account_active'] != 1 && $data[1] != 'Special' && $data[1] != 'Admin') - { - $this->show_inactive_error($userdata); - } - $this->sid = $_COOKIE['sid']; $this->user_logged_in = true; $this->user_id = intval($userdata['user_id']); @@ -553,6 +581,12 @@ // make sure we aren't banned $this->check_banlist(); + // make sure the account is active + if ( !$this->compat && $this->user_logged_in && $userdata['account_active'] != 1 && !$this->on_critical_page() ) + { + $this->show_inactive_error($userdata); + } + // Printable page view? Probably the wrong place to control // it but $template is pretty dumb, it will just about always // do what you ask it to do, which isn't always what we want @@ -724,11 +758,11 @@ // This wasn't logged in <1.0.2, dunno how it slipped through if ( $level > USER_LEVEL_MEMBER ) $this->sql('INSERT INTO ' . table_prefix . "logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES\n" - . ' (\'security\', \'admin_auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', ' + . ' (\'security\', \'admin_auth_bad\', '.time().', \''.enano_date(ED_DATE | ED_TIME).'\', \''.$db->escape($username).'\', ' . '\''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); else $this->sql('INSERT INTO ' . table_prefix . "logs(log_type,action,time_id,date_string,author,edit_summary) VALUES\n" - . ' (\'security\', \'auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', ' + . ' (\'security\', \'auth_bad\', '.time().', \''.enano_date(ED_DATE | ED_TIME).'\', \''.$db->escape($username).'\', ' . '\''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); // Do we also need to increment the lockout countdown? @@ -822,13 +856,16 @@ 'success' => false, 'error' => 'too_big_for_britches' ); + + // grant session $sess = $this->register_session($row['user_id'], $username, ( isset($password_hmac) ? $password_hmac : $password ), $level, $remember); + if($sess) { if($level > USER_LEVEL_MEMBER) - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_good\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_good\', '.time().', \''.enano_date(ED_DATE | ED_TIME).'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); else - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_good\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_good\', '.time().', \''.enano_date(ED_DATE | ED_TIME).'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); $code = $plugins->setHook('login_success'); foreach ( $code as $cmd ) @@ -849,9 +886,9 @@ else { if($level > USER_LEVEL_MEMBER) - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.enano_date(ED_DATE | ED_TIME).'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); else - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_bad\', '.time().', \''.enano_date(ED_DATE | ED_TIME).'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); // Do we also need to increment the lockout countdown? if ( !defined('IN_ENANO_INSTALL') && $lockout_data['lockout_policy'] != 'disable' ) @@ -967,6 +1004,7 @@ // For now, make the cookie last forever, we can change this in 1.1.x setcookie( 'sid', $session_key, time()+15552000, scriptPath.'/', null, $GLOBALS['is_https']); $_COOKIE['sid'] = $session_key; + $this->sid = $session_key; } // $keyhash is stored in the database, this is for compatibility with the older DB structure $keyhash = md5($session_key); @@ -1192,7 +1230,7 @@ . " u.reg_time, u.account_active, u.activation_key, u.user_lang, u.user_timezone, u.user_title, u.user_dst,\n" . " k.salt, k.source_ip, k.time, k.auth_level, k.key_type, x.user_id, x.user_aim, x.user_yahoo, x.user_msn,\n" . " x.user_xmpp, x.user_homepage, x.user_location, x.user_job, x.user_hobbies, x.email_public,\n" - . " x.disable_js_fx"; + . " x.disable_js_fx, x.date_format, x.time_format"; $joins = " LEFT JOIN " . table_prefix . "users AS u\n" . " ON ( u.user_id=k.user_id )\n" @@ -1221,14 +1259,14 @@ if ( !$query && ( defined('IN_ENANO_INSTALL') or defined('IN_ENANO_UPGRADE') ) ) { - $query = $this->sql('SELECT u.user_id AS uid,u.username,u.password,\'\' AS password_salt,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,u.reg_time,u.account_active,u.activation_key,k.source_ip,k.time,k.auth_level,COUNT(p.message_id) AS num_pms, 1440 AS user_timezone, \'0;0;0;0;60\' AS user_dst, ' . SK_SHORT . ' AS key_type FROM '.table_prefix.'session_keys AS k + $key_md5 = $loose_call ? $key : md5($key); + $query = $this->sql('SELECT u.user_id AS uid,u.username,u.password,\'\' AS password_salt,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,u.reg_time,u.account_active,u.activation_key,k.source_ip,k.time,k.auth_level,COUNT(p.message_id) AS num_pms, 1440 AS user_timezone, \'0;0;0;0;60\' AS user_dst, ' . SK_SHORT . ' AS key_type, k.salt FROM '.table_prefix.'session_keys AS k LEFT JOIN '.table_prefix.'users AS u ON ( u.user_id=k.user_id ) LEFT JOIN '.table_prefix.'privmsgs AS p ON ( p.message_to=u.username AND p.message_read=0 ) - WHERE k.session_key=\''.$key.'\' - AND k.salt=\''.$salt.'\' - GROUP BY u.user_id,u.username,u.password,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,u.reg_time,u.account_active,u.activation_key,k.source_ip,k.time,k.auth_level;'); + WHERE k.session_key=\''.$key_md5.'\' + GROUP BY u.user_id,u.username,u.password,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,u.reg_time,u.account_active,u.activation_key,k.source_ip,k.time,k.auth_level,k.salt;'); } else if ( !$query ) { @@ -1236,7 +1274,7 @@ } if($db->numrows() < 1) { - // echo '(debug) $session->validate_session: Key was not found in database
'; + // echo '(debug) $session->validate_session: Key was not found in database: ' . $key_md5 . '
'; return false; } $row = $db->fetchrow(); @@ -1346,6 +1384,11 @@ $user_extra[$column] = ''; } + if ( isset($row['date_format']) ) + $this->date_format = $row['date_format']; + if ( isset($row['time_format']) ) + $this->time_format = $row['time_format']; + $this->user_extra = $user_extra; // Leave the rest to PHP's automatic garbage collector ;-) @@ -1476,6 +1519,9 @@ global $db, $session, $paths, $template, $plugins; // Common objects global $lang; + global $title; + $paths->init($title); + $language = intval(getConfig('default_language')); $lang = new Language($language); @setlocale(LC_ALL, $lang->lang_code); @@ -1541,7 +1587,10 @@ } } - die_semicritical($lang->get('user_login_noact_title'), '

' . $lang->get('user_login_noact_msg_intro') . ' '.$solution.'

' . $form); + global $output; + $output = new Output_HTML(); + $output->set_title($lang->get('user_login_noact_title')); + die_friendly($lang->get('user_login_noact_title'), '

' . $lang->get('user_login_noact_msg_intro') . ' '.$solution.'

' . $form); } /** @@ -1757,7 +1806,9 @@ global $db, $session, $paths, $template, $plugins; // Common objects global $lang; - $col_reason = ( $this->compat ) ? '"No reason entered (session manager is in compatibility mode)" AS reason' : 'reason'; + $col_reason = ( $this->compat ) ? '\'No reason available (session manager is in compatibility mode)\' AS reason' : 'reason'; + $remote_addr = ( strstr($_SERVER['REMOTE_ADDR'], ':') ) ? expand_ipv6_address($_SERVER['REMOTE_ADDR']) : $_SERVER['REMOTE_ADDR']; + $banned = false; if ( $this->user_logged_in ) { @@ -1797,7 +1848,7 @@ { continue; } - if ( preg_match("/$regexp/", $_SERVER['REMOTE_ADDR']) ) + if ( preg_match("/$regexp/", $remote_addr) ) { $reason = $reason_temp; $banned = true; @@ -1840,8 +1891,11 @@ // check range $regexp = parse_ip_range_regex($ban_value); if ( !$regexp ) + { + die("bad regexp for $ban_value"); continue; - if ( preg_match("/$regexp/", $_SERVER['REMOTE_ADDR']) ) + } + if ( preg_match("/$regexp/", $remote_addr) ) { $reason = $reason_temp; $banned = true; @@ -1857,7 +1911,7 @@ } $db->free_result(); } - if ( $banned && $paths->get_pageid_from_url() != $paths->nslist['Special'].'CSS' ) + if ( $banned && !$this->on_critical_page(true) ) { // This guy is banned - kill the session, kill the database connection, bail out, and be pretty about it die_semicritical($lang->get('user_ban_msg_title'), '

' . $lang->get('user_ban_msg_body') . '

' . $lang->get('user_ban_lbl_reason') . '
' . $reason . '
'); @@ -2229,7 +2283,7 @@ function admin_activation_request($u) { global $db; - $this->sql('INSERT INTO '.table_prefix.'logs(log_type, action, time_id, date_string, author, edit_summary) VALUES(\'admin\', \'activ_req\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$this->username.'\', \''.$db->escape($u).'\');'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type, action, time_id, date_string, author, edit_summary) VALUES(\'admin\', \'activ_req\', '.time().', \''.enano_date(ED_DATE | ED_TIME).'\', \''.$this->username.'\', \''.$db->escape($u).'\');'); } /** @@ -2245,11 +2299,11 @@ $r = mysql_affected_rows(); if ( $r > 0 ) { - $e = $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'activ_good\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($user).'\', \''.$_SERVER['REMOTE_ADDR'].'\')'); + $e = $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'activ_good\', '.time().', \''.enano_date(ED_DATE | ED_TIME).'\', \''.$db->escape($user).'\', \''.$_SERVER['REMOTE_ADDR'].'\')'); } else { - $e = $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'activ_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($user).'\', \''.$_SERVER['REMOTE_ADDR'].'\')'); + $e = $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'activ_bad\', '.time().', \''.enano_date(ED_DATE | ED_TIME).'\', \''.$db->escape($user).'\', \''.$_SERVER['REMOTE_ADDR'].'\')'); } return $r; }