| 1 | <?php
 | 
  
    | 2 | /**
 | 
  
    | 3 |  *
 | 
  
    | 4 |  * @category        framework
 | 
  
    | 5 |  * @package         backend login
 | 
  
    | 6 |  * @author          Ryan Djurovich (2004-2009), WebsiteBaker Project
 | 
  
    | 7 |  * @copyright       2009-2012, WebsiteBaker Org. e.V.
 | 
  
    | 8 |  * @link			http://www.websitebaker2.org/
 | 
  
    | 9 |  * @license         http://www.gnu.org/licenses/gpl.html
 | 
  
    | 10 |  * @platform        WebsiteBaker 2.8.x
 | 
  
    | 11 |  * @requirements    PHP 5.2.2 and higher
 | 
  
    | 12 |  * @version         $Id: class.Login.php 2125 2015-06-17 18:42:26Z darkviper $
 | 
  
    | 13 |  * @filesource		$HeadURL: svn://isteam.dynxs.de/wb-archiv/branches/2.8.x/wb/framework/class.Login.php $
 | 
  
    | 14 |  * @lastmodified    $Date: 2015-06-17 20:42:26 +0200 (Wed, 17 Jun 2015) $
 | 
  
    | 15 |  *
 | 
  
    | 16 |  */
 | 
  
    | 17 | define('LOGIN_CLASS_LOADED', true);
 | 
  
    | 18 | 
 | 
  
    | 19 | // Get WB version
 | 
  
    | 20 | require_once(ADMIN_PATH.'/interface/version.php');
 | 
  
    | 21 | 
 | 
  
    | 22 | class Login extends admin {
 | 
  
    | 23 | 
 | 
  
    | 24 |     const PASS_CHARS = '\w!#$%&*+\-.:=?@\|';
 | 
  
    | 25 |     const USER_CHARS = 'a-z0-9&\-.=@_';
 | 
  
    | 26 | 
 | 
  
    | 27 |     protected $oReg    = null;
 | 
  
    | 28 |     protected $oDb     = null;
 | 
  
    | 29 |     protected $oTrans  = null;
 | 
  
    | 30 |     protected $message = '';
 | 
  
    | 31 | 
 | 
  
    | 32 |     public function __construct($config_array)
 | 
  
    | 33 |     {
 | 
  
    | 34 |         $this->oReg   = WbAdaptor::getInstance();
 | 
  
    | 35 |         $this->oDb    = $this->oReg->Db;
 | 
  
    | 36 |         $this->oTrans = $this->oReg->Trans;
 | 
  
    | 37 | 
 | 
  
    | 38 |         parent::__construct();
 | 
  
    | 39 |     // Get configuration values
 | 
  
    | 40 |         while(list($key, $value) = each($config_array)) {
 | 
  
    | 41 |             $this->{(strtolower($key))} = $value;
 | 
  
    | 42 |         }
 | 
  
    | 43 |     // calculate redirect URL
 | 
  
    | 44 |         if(!isset($this->redirect_url)) { $this->redirect_url = ''; }
 | 
  
    | 45 |         $aServerUrl = $this->mb_parse_url($this->oReg->AppUrl);
 | 
  
    | 46 |         $sServerUrl = $_SERVER['SERVER_NAME'];
 | 
  
    | 47 |         $sServerScheme =
 | 
  
    | 48 |             isset($_SERVER['REQUEST_SCHEME'])
 | 
  
    | 49 |             ? $_SERVER['REQUEST_SCHEME']
 | 
  
    | 50 |             : isset($aServerUrl['scheme']) ? $aServerUrl['scheme'] : ' http';
 | 
  
    | 51 |         $sServerPath = $_SERVER['SCRIPT_NAME'];
 | 
  
    | 52 |         // If the url is blank, set it to the default url
 | 
  
    | 53 |         $this->url = $this->get_post('url');
 | 
  
    | 54 |         if (preg_match('/%0d|%0a|\s/i', $this->url)) {
 | 
  
    | 55 |             throw new Exception('Warning: possible intruder detected on login');
 | 
  
    | 56 |         }
 | 
  
    | 57 |         $aUrl = $this->mb_parse_url( $this->url );
 | 
  
    | 58 |         $this->url =
 | 
  
    | 59 |             isset($aRedirecthUrl['host']) &&($sServerUrl == $aUrl['host'])
 | 
  
    | 60 |             ? $this->url
 | 
  
    | 61 |             : $this->oReg->AcpUrl.'start/index.php';
 | 
  
    | 62 |         if ($this->redirect_url!='') {
 | 
  
    | 63 |             $aRedirecthUrl = $this->mb_parse_url( $this->redirect_url );
 | 
  
    | 64 |             $this->redirect_url =
 | 
  
    | 65 |                 isset($aRedirecthUrl['host']) &&($sServerUrl==$aRedirecthUrl['host'])
 | 
  
    | 66 |                 ? $this->redirect_url
 | 
  
    | 67 |                 : $sServerScheme.'://'.$sServerUrl;
 | 
  
    | 68 |             $this->url = $this->redirect_url;
 | 
  
    | 69 |         }
 | 
  
    | 70 |         if(strlen($this->url) < 2) {
 | 
  
    | 71 |             $aDefaultUrl = $this->mb_parse_url( $this->default_url );
 | 
  
    | 72 |             $this->default_url =
 | 
  
    | 73 |                 isset($aDefaultUrl['host']) &&($sServerUrl==$aDefaultUrl['host'])
 | 
  
    | 74 |                 ? $this->default_url
 | 
  
    | 75 |                 : $sServerScheme.'://'.$sServerUrl;
 | 
  
    | 76 |             $this->url = $this->default_url;
 | 
  
    | 77 |         }
 | 
  
    | 78 |     // get username & password and validate it
 | 
  
    | 79 |         $username_fieldname = (string)$this->get_post('username_fieldname');
 | 
  
    | 80 |         $username_fieldname = (preg_match('/^_?[a-z][\w]+$/i', $username_fieldname) ? $username_fieldname : 'username');
 | 
  
    | 81 |         $sUsername = strtolower(trim((string)$this->get_post($username_fieldname)));
 | 
  
    | 82 |         $this->username = (preg_match(
 | 
  
    | 83 |             '/^['.self::USER_CHARS.']{'.$this->min_username_len.','.$this->max_username_len.'}$/is',
 | 
  
    | 84 |             $sUsername
 | 
  
    | 85 |         ) ? $sUsername : '');
 | 
  
    | 86 |         $password_fieldname = (string)$this->get_post('password_fieldname');
 | 
  
    | 87 |         $password_fieldname = (preg_match('/^_?[a-z][\w]+$/i', $password_fieldname) ? $password_fieldname : 'password');
 | 
  
    | 88 | 
 | 
  
    | 89 |         if ($this->username) {
 | 
  
    | 90 | /** @TODO implement crypting */
 | 
  
    | 91 |             $this->password = md5(trim((string)$this->get_post($password_fieldname)));
 | 
  
    | 92 |             // Figure out if the "remember me" option has been checked
 | 
  
    | 93 |             $this->remember = (@$_POST['remember'] == 'true' ? true : false);
 | 
  
    | 94 |         // try to authenticate
 | 
  
    | 95 |             $bSuccess = false;
 | 
  
    | 96 |             if (!($bSuccess = $this->is_authenticated())) {
 | 
  
    | 97 |                 if ($this->is_remembered()) {
 | 
  
    | 98 |                     $sql = 'SELECT * FROM `'.$this->oDb->TablePrefix.'users` '
 | 
  
    | 99 |                          . 'WHERE `user_id`='.$this->get_safe_remember_key();
 | 
  
    | 100 |                     if (($oUsers = $this->oDb->doQuery($sql))) {
 | 
  
    | 101 |                         if (($aUser = $oUsers->fetchArray())) {
 | 
  
    | 102 |                             $this->username = $aUser['username'];
 | 
  
    | 103 |                             $this->password = $aUser['password'];
 | 
  
    | 104 |                             // Check if the user exists (authenticate them)
 | 
  
    | 105 |                             $bSuccess = $this->authenticate();
 | 
  
    | 106 |                         }
 | 
  
    | 107 |                     }
 | 
  
    | 108 |                 } else {
 | 
  
    | 109 |                     // Check if the user exists (authenticate them)
 | 
  
    | 110 |                     $bSuccess = $this->authenticate();
 | 
  
    | 111 |                 }
 | 
  
    | 112 |             }
 | 
  
    | 113 |             if ($bSuccess) {
 | 
  
    | 114 |                 // Authentication successful
 | 
  
    | 115 |                 $this->send_header($this->url);
 | 
  
    | 116 |             } else {
 | 
  
    | 117 |                 $this->message = $this->oTrans->MESSAGE_LOGIN_AUTHENTICATION_FAILED;
 | 
  
    | 118 |                 $this->increase_attemps();
 | 
  
    | 119 |             }
 | 
  
    | 120 |         } else {
 | 
  
    | 121 |             $this->display_login();
 | 
  
    | 122 |         }
 | 
  
    | 123 |     }
 | 
  
    | 124 | 
 | 
  
    | 125 |     // Authenticate the user (check if they exist in the database)
 | 
  
    | 126 |     function authenticate()
 | 
  
    | 127 |     {
 | 
  
    | 128 |         // Get user information
 | 
  
    | 129 |         $loginname = ( preg_match('/^['.self::USER_CHARS.']+$/s',$this->username) ? $this->username : '0');
 | 
  
    | 130 |         $aSettings = array();
 | 
  
    | 131 |         $aSettings['SYSTEM_PERMISSIONS']   = array();
 | 
  
    | 132 |         $aSettings['MODULE_PERMISSIONS']   = array();
 | 
  
    | 133 |         $aSettings['TEMPLATE_PERMISSIONS'] = array();
 | 
  
    | 134 |         $bRetval = false;
 | 
  
    | 135 | 
 | 
  
    | 136 |         $sql = 'SELECT * FROM `'.$this->oDb->TablePrefix.'users` '
 | 
  
    | 137 |              . 'WHERE `username`=\''.$this->oDb->escapeString($loginname).'\'';
 | 
  
    | 138 |         if (($oUser = $this->oDb->doQuery($sql))) {
 | 
  
    | 139 |             if (($aUser = $oUser->fetchArray())) {
 | 
  
    | 140 |                 if (
 | 
  
    | 141 |                     $aUser['password'] == $this->password &&
 | 
  
    | 142 |                     $aUser['active'] == 1
 | 
  
    | 143 |                 ) {
 | 
  
    | 144 |                 // valide authentcation !!
 | 
  
    | 145 |                     $user_id                   = $aUser['user_id'];
 | 
  
    | 146 |                     $this->user_id             = $user_id;
 | 
  
    | 147 |                     $aSettings['USER_ID']      = $user_id;
 | 
  
    | 148 |                     $aSettings['GROUP_ID']     = $aUser['group_id'];
 | 
  
    | 149 |                     $aSettings['GROUPS_ID']    = $aUser['groups_id'];
 | 
  
    | 150 |                     $aSettings['USERNAME']     = $aUser['username'];
 | 
  
    | 151 |                     $aSettings['DISPLAY_NAME'] = $aUser['display_name'];
 | 
  
    | 152 |                     $aSettings['EMAIL']        = $aUser['email'];
 | 
  
    | 153 |                     $aSettings['HOME_FOLDER']  = $aUser['home_folder'];
 | 
  
    | 154 |                     // Run remember function if needed
 | 
  
    | 155 |                     if($this->remember == true) {
 | 
  
    | 156 |                         $this->remember($this->user_id);
 | 
  
    | 157 |                     }
 | 
  
    | 158 |                     // Set language
 | 
  
    | 159 |                     if($aUser['language'] != '') {
 | 
  
    | 160 |                         $aSettings['LANGUAGE'] = $aUser['language'];
 | 
  
    | 161 |                     }
 | 
  
    | 162 |                     // Set timezone
 | 
  
    | 163 |                     if($aUser['timezone'] != '-72000') {
 | 
  
    | 164 |                         $aSettings['TIMEZONE'] = $aUser['timezone'];
 | 
  
    | 165 |                     } else {
 | 
  
    | 166 |                         // Set a session var so apps can tell user is using default tz
 | 
  
    | 167 |                         $aSettings['USE_DEFAULT_TIMEZONE'] = true;
 | 
  
    | 168 |                     }
 | 
  
    | 169 |                     // Set date format
 | 
  
    | 170 |                     if($aUser['date_format'] != '') {
 | 
  
    | 171 |                         $aSettings['DATE_FORMAT'] = $aUser['date_format'];
 | 
  
    | 172 |                     } else {
 | 
  
    | 173 |                         // Set a session var so apps can tell user is using default date format
 | 
  
    | 174 |                         $aSettings['USE_DEFAULT_DATE_FORMAT'] = true;
 | 
  
    | 175 |                     }
 | 
  
    | 176 |                     // Set time format
 | 
  
    | 177 |                     if($aUser['time_format'] != '') {
 | 
  
    | 178 |                         $aSettings['TIME_FORMAT'] = $aUser['time_format'];
 | 
  
    | 179 |                     } else {
 | 
  
    | 180 |                         // Set a session var so apps can tell user is using default time format
 | 
  
    | 181 |                         $aSettings['USE_DEFAULT_TIME_FORMAT'] = true;
 | 
  
    | 182 |                     }
 | 
  
    | 183 |                     // Get group information
 | 
  
    | 184 |                     $aSettings['GROUP_NAME'] = array();
 | 
  
    | 185 |                     $bOnlyAdminGroup = $this->ami_group_member('1') && (sizeof($aGroupsIds) == 1);
 | 
  
    | 186 |                     $sql = 'SELECT * FROM `'.$this->oDb->TablePrefix.'groups` '
 | 
  
    | 187 |                          . 'WHERE `group_id` IN (\''.$aUser['groups_id'].',0\') '
 | 
  
    | 188 |                          . 'ORDER BY `group_id`';
 | 
  
    | 189 |                     if (($oGroups = $this->oDb->doQuery($sql))) {
 | 
  
    | 190 |                         while (($aGroup = $oGroups->fetchArray())) {
 | 
  
    | 191 |                             $aSettings['GROUP_NAME'][$aGroup['group_id']] = $aGroup['name'];
 | 
  
    | 192 |                         // collect system_permissions (additively)
 | 
  
    | 193 |                             $aSettings['SYSTEM_PERMISSIONS'] = array_merge(
 | 
  
    | 194 |                                 $aSettings['SYSTEM_PERMISSIONS'],
 | 
  
    | 195 |                                 explode(',', $aGroup['system_permissions'])
 | 
  
    | 196 |                             );
 | 
  
    | 197 |                         // collect module_permission (subtractive)
 | 
  
    | 198 |                             if (!sizeof($aSettings['MODULE_PERMISSIONS'])) {
 | 
  
    | 199 |                                 $aSettings['MODULE_PERMISSIONS'] = explode(',', $aGroup['module_permissions']);
 | 
  
    | 200 |                             } else {
 | 
  
    | 201 |                                 $aSettings['MODULE_PERMISSIONS'] = array_intersect(
 | 
  
    | 202 |                                     $aSettings['MODULE_PERMISSIONS'],
 | 
  
    | 203 |                                     preg_split('/\s*[,;\|\+]/', $aGroup['module_permissions'], -1, PREG_SPLIT_NO_EMPTY)
 | 
  
    | 204 |                                 );
 | 
  
    | 205 |                             }
 | 
  
    | 206 |                         // collect template_permission (subtractive)
 | 
  
    | 207 |                             if (!sizeof($aSettings['TEMPLATE_PERMISSIONS'])) {
 | 
  
    | 208 |                                 $aSettings['TEMPLATE_PERMISSIONS'] = explode(',', $aGroup['template_permissions']);
 | 
  
    | 209 |                             } else {
 | 
  
    | 210 |                                 $aSettings['TEMPLATE_PERMISSIONS'] = array_intersect(
 | 
  
    | 211 |                                     $aSettings['TEMPLATE_PERMISSIONS'],
 | 
  
    | 212 |                                     preg_split('/\s*[,;\|\+]/', $aGroup['template_permissions'], -1, PREG_SPLIT_NO_EMPTY)
 | 
  
    | 213 |                                 );
 | 
  
    | 214 |                             }
 | 
  
    | 215 |                         }
 | 
  
    | 216 |                     }
 | 
  
    | 217 |                     // Update the users table with current ip and timestamp
 | 
  
    | 218 |                     $sRemoteAddress = @$_SERVER['REMOTE_ADDR'] ?: 'unknown';
 | 
  
    | 219 |                     $sql = 'UPDATE `'.$this->oDb->TablePrefix.'users` '
 | 
  
    | 220 |                          . 'SET `login_when`='.time().', '
 | 
  
    | 221 |                          .     '`login_ip`=\''.$sRemoteAddress.'\' '
 | 
  
    | 222 |                          . 'WHERE `user_id`=\''.$user_id.'\'';
 | 
  
    | 223 |                     $this->oDb->doQuery($sql);
 | 
  
    | 224 |                     $bRetval = true;
 | 
  
    | 225 |                 }
 | 
  
    | 226 |             }
 | 
  
    | 227 |         }
 | 
  
    | 228 |         // merge settings into $_SESSION and overwrite older one values
 | 
  
    | 229 |         $_SESSION = array_merge($_SESSION, $aSettings);
 | 
  
    | 230 |         // Return if the user exists or not
 | 
  
    | 231 |         return $bRetval;
 | 
  
    | 232 |     }
 | 
  
    | 233 | 
 | 
  
    | 234 |     // Increase the count for login attemps
 | 
  
    | 235 |     function increase_attemps()
 | 
  
    | 236 |     {
 | 
  
    | 237 |         $_SESSION['ATTEMPS'] = (isset($_SESSION['ATTEMPS']) ? $_SESSION['ATTEMPS']++ : 0);
 | 
  
    | 238 |         $this->display_login();
 | 
  
    | 239 |     }
 | 
  
    | 240 | 
 | 
  
    | 241 |     // Function to set a "remembering" cookie for the user - removed
 | 
  
    | 242 |     function remember($user_id)
 | 
  
    | 243 |     {
 | 
  
    | 244 |         return true;
 | 
  
    | 245 |     }
 | 
  
    | 246 | 
 | 
  
    | 247 |     // Function to check if a user has been remembered - removed
 | 
  
    | 248 |     function is_remembered()
 | 
  
    | 249 |     {
 | 
  
    | 250 |         return false;
 | 
  
    | 251 |     }
 | 
  
    | 252 | 
 | 
  
    | 253 |     // Display the login screen
 | 
  
    | 254 |     function display_login()
 | 
  
    | 255 |     {
 | 
  
    | 256 |         // If attemps more than allowed, warn the user
 | 
  
    | 257 |         if($this->get_session('ATTEMPS') > $this->max_attemps) {
 | 
  
    | 258 |             $this->warn();
 | 
  
    | 259 |         }
 | 
  
    | 260 |         // Show the login form
 | 
  
    | 261 |         if($this->frontend != true) {
 | 
  
    | 262 |             $template = new Template(dirname($this->correct_theme_source($this->template_file)));
 | 
  
    | 263 |             $template->set_file('page', $this->template_file);
 | 
  
    | 264 |             $template->set_block('page', 'mainBlock', 'main');
 | 
  
    | 265 |             $template->set_var('DISPLAY_REMEMBER_ME', ($this->remember_me_option ? '' : 'display: none;'));
 | 
  
    | 266 |             $template->set_var($this->oTrans->getLangArray());
 | 
  
    | 267 |             $template->set_var(
 | 
  
    | 268 |                 array(
 | 
  
    | 269 |                     'TITLE_LOGOUT'           => $this->oTrans->MENU_LOGIN,
 | 
  
    | 270 |                     'TITLE_VIEW'             => $this->oTrans->TEXT_WEBSITE,
 | 
  
    | 271 |                     'SECTION_NAME'           => $this->oTrans->MENU_LOGIN,
 | 
  
    | 272 |                     'SECTION_LOGIN'          => $this->oTrans->MENU_LOGIN,
 | 
  
    | 273 |                     'ACTION_URL'             => $this->login_url,
 | 
  
    | 274 |                     'URL'                    => $this->default_url,
 | 
  
    | 275 |                     'ATTEMPS'                => $this->get_session('ATTEMPS'),
 | 
  
    | 276 |                     'USERNAME'               => $this->username,
 | 
  
    | 277 |                     'USERNAME_FIELDNAME'     => $this->username_fieldname,
 | 
  
    | 278 |                     'PASSWORD_FIELDNAME'     => $this->password_fieldname,
 | 
  
    | 279 |                     'MESSAGE'                => $this->message,
 | 
  
    | 280 |                     'WEBSITE_TITLE'          => $this->oReg->WebsiteTitle,
 | 
  
    | 281 |                     'INTERFACE_DIR_URL'      => $this->oReg->AcpUrl.'interface',
 | 
  
    | 282 |                     'MAX_USERNAME_LEN'       => $this->max_username_len,
 | 
  
    | 283 |                     'MAX_PASSWORD_LEN'       => $this->max_password_len,
 | 
  
    | 284 |                     'ADMIN_URL'              => $this->oReg->AcpUrl,
 | 
  
    | 285 |                     'WB_URL'                 => $this->oReg->AppUrl,
 | 
  
    | 286 |                     'URL_VIEW'               => $this->oReg->AppUrl,
 | 
  
    | 287 |                     'THEME_URL'              => $this->oReg->ThemeUrl,
 | 
  
    | 288 |                     'VERSION'                => $this->oReg->Version,
 | 
  
    | 289 |                     'SP'                     => (isset($this->oReg->Sp) ? $this->oReg->Sp : ''),
 | 
  
    | 290 |                     'REVISION'               => $this->oReg->Revision,
 | 
  
    | 291 |                     'LANGUAGE'               => strtolower($this->oReg->Language),
 | 
  
    | 292 |                     'FORGOTTEN_DETAILS_APP'  => $this->forgotten_details_app,
 | 
  
    | 293 |                     'PAGES_DIRECTORY'        => $this->oReg->PagesDir,
 | 
  
    | 294 |                     'LOGIN_DISPLAY_HIDDEN'   => !$this->is_authenticated() ? 'hidden' : '',
 | 
  
    | 295 |                     'LOGIN_DISPLAY_NONE'     => !$this->is_authenticated() ? 'none' : '',
 | 
  
    | 296 |                     'LOGIN_LINK'             => $_SERVER['SCRIPT_NAME'],
 | 
  
    | 297 |                     'LOGIN_ICON'             => 'login',
 | 
  
    | 298 |                     'START_ICON'             => 'blank',
 | 
  
    | 299 |                     'URL_HELP'               => 'http://wiki.websitebaker.org/',
 | 
  
    | 300 |                 )
 | 
  
    | 301 |             );
 | 
  
    | 302 |             $template->set_var('CHARSET', (isset($this->oReg->DefaultCharset) ? $this->oReg->DefaultCharset : 'utf-8'));
 | 
  
    | 303 |             $template->parse('main', 'mainBlock', false);
 | 
  
    | 304 |             $template->pparse('output', 'page');
 | 
  
    | 305 |         }
 | 
  
    | 306 |     }
 | 
  
    | 307 |     // sanities the REMEMBER_KEY cookie to avoid SQL injection
 | 
  
    | 308 |     function get_safe_remember_key()
 | 
  
    | 309 |     {
 | 
  
    | 310 |         $iMatches = 0;
 | 
  
    | 311 |         if (isset($_COOKIE['REMEMBER_KEY'])) {
 | 
  
    | 312 |             $sRetval = preg_replace(
 | 
  
    | 313 |                 '/^([0-9]{11})_([0-9a-f]{11})$/i',
 | 
  
    | 314 |                 '\1\2',
 | 
  
    | 315 |                 $_COOKIE['REMEMBER_KEY'], -1, $iMatches
 | 
  
    | 316 |             );
 | 
  
    | 317 |         }
 | 
  
    | 318 |         return ($iMatches ? $sRetval : '');
 | 
  
    | 319 |     }
 | 
  
    | 320 |     // Warn user that they have had to many login attemps
 | 
  
    | 321 |     function warn()
 | 
  
    | 322 |     {
 | 
  
    | 323 |         $this->send_header($this->warning_url);
 | 
  
    | 324 |         exit;
 | 
  
    | 325 |     }
 | 
  
    | 326 | 
 | 
  
    | 327 | }
 |