TYPO3 API  SVNRelease
class.t3lib_beuserauth.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003  *  Copyright notice
00004  *
00005  *  (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
00006  *  All rights reserved
00007  *
00008  *  This script is part of the TYPO3 project. The TYPO3 project is
00009  *  free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  The GNU General Public License can be found at
00015  *  http://www.gnu.org/copyleft/gpl.html.
00016  *  A copy is found in the textfile GPL.txt and important notices to the license
00017  *  from the author is found in LICENSE.txt distributed with these scripts.
00018  *
00019  *
00020  *  This script is distributed in the hope that it will be useful,
00021  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *  GNU General Public License for more details.
00024  *
00025  *  This copyright notice MUST APPEAR in all copies of the script!
00026  ***************************************************************/
00027 /**
00028  * Contains class for TYPO3 backend user authentication
00029  *
00030  * $Id: class.t3lib_beuserauth.php 10664 2011-02-28 19:37:41Z lolli $
00031  * Revised for TYPO3 3.6 July/2003 by Kasper Skårhøj
00032  *
00033  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00034  * @internal
00035  */
00036 /**
00037  * [CLASS/FUNCTION INDEX of SCRIPT]
00038  *
00039  *
00040  *
00041  *   76: class t3lib_beUserAuth extends t3lib_userAuthGroup
00042  *  150:     function trackBeUser($flag)
00043  *  168:     function checkLockToIP()
00044  *  188:     function backendCheckLogin()
00045  *  216:     function checkCLIuser()
00046  *  240:     function backendSetUC()
00047  *  278:     function overrideUC()
00048  *  288:     function resetUC()
00049  *  301:     function emailAtLogin()
00050  *  353:     function veriCode()
00051  *
00052  * TOTAL FUNCTIONS: 9
00053  * (This index is automatically created/updated by the extension "extdeveval")
00054  *
00055  */
00056 
00057 
00058 /**
00059  * TYPO3 user authentication, backend
00060  * Could technically have been the same class as t3lib_userauthgroup since these two are always used together and only together.
00061  * t3lib_userauthgroup contains most of the functions used for checking permissions, authenticating users, setting up the user etc. This class is most interesting in terms of an API for user from outside.
00062  * This class contains the configuration of the database fields used plus some functions for the authentication process of backend users.
00063  *
00064  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00065  * @package TYPO3
00066  * @subpackage t3lib
00067  */
00068 class t3lib_beUserAuth extends t3lib_userAuthGroup {
00069     var $session_table = 'be_sessions'; // Table to use for session data.
00070     var $name = 'be_typo_user'; // Session/Cookie name
00071 
00072     var $user_table = 'be_users'; // Table in database with userdata
00073     var $username_column = 'username'; // Column for login-name
00074     var $userident_column = 'password'; // Column for password
00075     var $userid_column = 'uid'; // Column for user-id
00076     var $lastLogin_column = 'lastlogin';
00077 
00078     var $enablecolumns = Array(
00079         'rootLevel' => 1,
00080         'deleted' => 'deleted',
00081         'disabled' => 'disable',
00082         'starttime' => 'starttime',
00083         'endtime' => 'endtime'
00084     );
00085 
00086     var $formfield_uname = 'username'; // formfield with login-name
00087     var $formfield_uident = 'userident'; // formfield with password
00088     var $formfield_chalvalue = 'challenge'; // formfield with a unique value which is used to encrypt the password and username
00089     var $formfield_status = 'login_status'; // formfield with status: *'login', 'logout'
00090 
00091     var $writeStdLog = 1; // Decides if the writelog() function is called at login and logout
00092     var $writeAttemptLog = 1; // If the writelog() functions is called if a login-attempt has be tried without success
00093 
00094     var $auth_timeout_field = 6000; // if > 0 : session-timeout in seconds. if false/<0 : no timeout. if string: The string is fieldname from the usertable where the timeout can be found.
00095     var $lifetime = 0; // 0 = Session-cookies. If session-cookies, the browser will stop session when the browser is closed. Else it keeps the session for $lifetime seconds.
00096     var $challengeStoredInCookie = TRUE;
00097 
00098 
00099         // User Config:
00100     var $uc;
00101 
00102         // User Config Default values:
00103         // The array may contain other fields for configuration. For this, see "setup" extension and "TSConfig" document (User TSconfig, "setup.[xxx]....")
00104     /*
00105            Reserved keys for other storage of session data:
00106            moduleData
00107            moduleSessionID
00108        */
00109     var $uc_default = Array(
00110         'interfaceSetup' => '', // serialized content that is used to store interface pane and menu positions. Set by the logout.php-script
00111         'moduleData' => Array(), // user-data for the modules
00112         'thumbnailsByDefault' => 0,
00113         'emailMeAtLogin' => 0,
00114         'condensedMode' => 0,
00115         'noMenuMode' => 0,
00116         'startModule' => 'help_aboutmodules',
00117         'hideSubmoduleIcons' => 0,
00118         'helpText' => 1,
00119         'titleLen' => 30,
00120         'edit_wideDocument' => '0',
00121         'edit_showFieldHelp' => 'icon',
00122         'edit_RTE' => '1',
00123         'edit_docModuleUpload' => '1',
00124         'enableFlashUploader' => '1',
00125         'disableCMlayers' => 0,
00126         'navFrameWidth' => '', // Default is 245 pixels
00127         'navFrameResizable' => 0,
00128         'resizeTextareas' => 1,
00129         'resizeTextareas_MaxHeight' => 300,
00130         'resizeTextareas_Flexible' => 1,
00131     );
00132 
00133 
00134     /**
00135      * Sets the security level for the Backend login
00136      *
00137      * @return  void
00138      */
00139     function start() {
00140         $securityLevel = trim($GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel']);
00141         $this->security_level = $securityLevel ? $securityLevel : 'superchallenged';
00142 
00143         parent::start();
00144     }
00145 
00146     /**
00147      * If TYPO3_CONF_VARS['BE']['enabledBeUserIPLock'] is enabled and an IP-list is found in the User TSconfig objString "options.lockToIP", then make an IP comparison with REMOTE_ADDR and return the outcome (true/false)
00148      *
00149      * @return  boolean     True, if IP address validates OK (or no check is done at all)
00150      * @access private
00151      */
00152     function checkLockToIP() {
00153         global $TYPO3_CONF_VARS;
00154         $out = 1;
00155         if ($TYPO3_CONF_VARS['BE']['enabledBeUserIPLock']) {
00156             $IPList = $this->getTSConfigVal('options.lockToIP');
00157             if (trim($IPList)) {
00158                 $baseIP = t3lib_div::getIndpEnv('REMOTE_ADDR');
00159                 $out = t3lib_div::cmpIP($baseIP, $IPList);
00160             }
00161         }
00162         return $out;
00163     }
00164 
00165     /**
00166      * Check if user is logged in and if so, call ->fetchGroupData() to load group information and access lists of all kind, further check IP, set the ->uc array and send login-notification email if required.
00167      * If no user is logged in the default behaviour is to exit with an error message, but this will happen ONLY if the constant TYPO3_PROCEED_IF_NO_USER is set true.
00168      * This function is called right after ->start() in fx. init.php
00169      *
00170      * @return  void
00171      */
00172     function backendCheckLogin() {
00173         if (!$this->user['uid']) {
00174             if (!defined('TYPO3_PROCEED_IF_NO_USER') || !TYPO3_PROCEED_IF_NO_USER) {
00175                 t3lib_utility_Http::redirect($GLOBALS['BACK_PATH']);
00176             }
00177         } else { // ...and if that's the case, call these functions
00178             $this->fetchGroupData(); // The groups are fetched and ready for permission checking in this initialization.    Tables.php must be read before this because stuff like the modules has impact in this
00179             if ($this->checkLockToIP()) {
00180                 if ($this->isUserAllowedToLogin()) {
00181                     $this->backendSetUC(); // Setting the UC array. It's needed with fetchGroupData first, due to default/overriding of values.
00182                     $this->emailAtLogin(); // email at login - if option set.
00183                 } else {
00184                     throw new RuntimeException('Login Error: TYPO3 is in maintenance mode at the moment. Only administrators are allowed access.');
00185                 }
00186             } else {
00187                 throw new RuntimeException('Login Error: IP locking prevented you from being authorized. Can\'t proceed, sorry.');
00188             }
00189         }
00190     }
00191 
00192     /**
00193      * If the backend script is in CLI mode, it will try to load a backend user named by the CLI module name (in lowercase)
00194      *
00195      * @return  boolean     Returns true if a CLI user was loaded, otherwise false!
00196      */
00197     function checkCLIuser() {
00198             // First, check if cliMode is enabled:
00199         if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) {
00200             if (!$this->user['uid']) {
00201                 if (substr($GLOBALS['MCONF']['name'], 0, 5) == '_CLI_') {
00202                     $userName = strtolower($GLOBALS['MCONF']['name']);
00203                     $this->setBeUserByName($userName);
00204                     if ($this->user['uid']) {
00205                         if (!$this->isAdmin()) {
00206                             return TRUE;
00207                         } else {
00208                             die('ERROR: CLI backend user "' . $userName . '" was ADMIN which is not allowed!' . LF . LF);
00209                         }
00210                     } else {
00211                         die('ERROR: No backend user named "' . $userName . '" was found! [Database: ' . TYPO3_db . ']' . LF . LF);
00212                     }
00213                 } else {
00214                     die('ERROR: Module name, "' . $GLOBALS['MCONF']['name'] . '", was not prefixed with "_CLI_"' . LF . LF);
00215                 }
00216             } else {
00217                 die('ERROR: Another user was already loaded which is impossible in CLI mode!' . LF . LF);
00218             }
00219         }
00220     }
00221 
00222     /**
00223      * Initialize the internal ->uc array for the backend user
00224      * Will make the overrides if necessary, and write the UC back to the be_users record if changes has happend
00225      *
00226      * @return  void
00227      * @internal
00228      */
00229     function backendSetUC() {
00230         global $TYPO3_CONF_VARS;
00231 
00232             // UC - user configuration is a serialized array inside the userobject
00233         $temp_theSavedUC = unserialize($this->user['uc']); // if there is a saved uc we implement that instead of the default one.
00234         if (is_array($temp_theSavedUC)) {
00235             $this->unpack_uc($temp_theSavedUC);
00236         }
00237             // Setting defaults if uc is empty
00238         if (!is_array($this->uc)) {
00239             $this->uc = array_merge(
00240                 $this->uc_default,
00241                 (array) $TYPO3_CONF_VARS['BE']['defaultUC'],
00242                 t3lib_div::removeDotsFromTS((array) $this->getTSConfigProp('setup.default'))
00243             );
00244             $this->overrideUC();
00245             $U = 1;
00246         }
00247             // If TSconfig is updated, update the defaultUC.
00248         if ($this->userTSUpdated) {
00249             $this->overrideUC();
00250             $U = 1;
00251         }
00252             // Setting default lang from be_user record.
00253         if (!isset($this->uc['lang'])) {
00254             $this->uc['lang'] = $this->user['lang'];
00255             $U = 1;
00256         }
00257             // Setting the time of the first login:
00258         if (!isset($this->uc['firstLoginTimeStamp'])) {
00259             $this->uc['firstLoginTimeStamp'] = $GLOBALS['EXEC_TIME'];
00260             $U = TRUE;
00261         }
00262 
00263             // Saving if updated.
00264         if ($U) {
00265             $this->writeUC(); // Method from the t3lib_userauth class.
00266         }
00267     }
00268 
00269     /**
00270      * Override: Call this function every time the uc is updated.
00271      * That is 1) by reverting to default values, 2) in the setup-module, 3) userTS changes (userauthgroup)
00272      *
00273      * @return  void
00274      * @internal
00275      */
00276     function overrideUC() {
00277         $this->uc = array_merge((array) $this->uc, (array) $this->getTSConfigProp('setup.override')); // Candidate for t3lib_div::array_merge() if integer-keys will some day make trouble...
00278     }
00279 
00280     /**
00281      * Clears the user[uc] and ->uc to blank strings. Then calls ->backendSetUC() to fill it again with reset contents
00282      *
00283      * @return  void
00284      * @internal
00285      */
00286     function resetUC() {
00287         $this->user['uc'] = '';
00288         $this->uc = '';
00289         $this->backendSetUC();
00290     }
00291 
00292     /**
00293      * Will send an email notification to warning_email_address/the login users email address when a login session is just started.
00294      * Depends on various parameters whether mails are send and to whom.
00295      *
00296      * @return  void
00297      * @access private
00298      */
00299     function emailAtLogin() {
00300         if ($this->loginSessionStarted) {
00301                 // Send notify-mail
00302             $subject = 'At "' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '"' .
00303                     ' from ' . t3lib_div::getIndpEnv('REMOTE_ADDR') .
00304                     (t3lib_div::getIndpEnv('REMOTE_HOST') ? ' (' . t3lib_div::getIndpEnv('REMOTE_HOST') . ')' : '');
00305             $msg = sprintf('User "%s" logged in from %s (%s) at "%s" (%s)',
00306                 $this->user['username'],
00307                 t3lib_div::getIndpEnv('REMOTE_ADDR'),
00308                 t3lib_div::getIndpEnv('REMOTE_HOST'),
00309                 $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'],
00310                 t3lib_div::getIndpEnv('HTTP_HOST')
00311             );
00312 
00313                 // Warning email address
00314             if ($GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr']) {
00315                 $warn = 0;
00316                 $prefix = '';
00317                 if (intval($GLOBALS['TYPO3_CONF_VARS']['BE']['warning_mode']) & 1) { // first bit: All logins
00318                     $warn = 1;
00319                     $prefix = $this->isAdmin() ? '[AdminLoginWarning]' : '[LoginWarning]';
00320                 }
00321                 if ($this->isAdmin() && (intval($GLOBALS['TYPO3_CONF_VARS']['BE']['warning_mode']) & 2)) { // second bit: Only admin-logins
00322                     $warn = 1;
00323                     $prefix = '[AdminLoginWarning]';
00324                 }
00325                 if ($warn) {
00326                     $from = t3lib_utility_Mail::getSystemFrom();
00327                     /** @var $mail t3lib_mail_Message */
00328                     $mail = t3lib_div::makeInstance('t3lib_mail_Message');
00329                     $mail->setTo($GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'])
00330                             ->setFrom($from)
00331                             ->setSubject($prefix . ' ' . $subject)
00332                             ->setBody($msg);
00333                     $mail->send();
00334                 }
00335             }
00336 
00337                 // If An email should be sent to the current user, do that:
00338             if ($this->uc['emailMeAtLogin'] && strstr($this->user['email'], '@')) {
00339                 $from = t3lib_utility_Mail::getSystemFrom();
00340                 /** @var $mail t3lib_mail_Message */
00341                 $mail = t3lib_div::makeInstance('t3lib_mail_Message');
00342                 $mail->setTo($this->user['email'])
00343                         ->setFrom($from)
00344                         ->setSubject($subject)
00345                         ->setBody($msg);
00346                 $mail->send();
00347             }
00348         }
00349     }
00350 
00351     /**
00352      * Determines whether a backend user is allowed to access the backend.
00353      *
00354      * The conditions are:
00355      *  + backend user is a regular user and adminOnly is not defined
00356      *  + backend user is an admin user
00357      *  + backend user is used in CLI context and adminOnly is explicitely set to "2"
00358      *
00359      * @return  boolean     Whether a backend user is allowed to access the backend
00360      */
00361     protected function isUserAllowedToLogin() {
00362         $isUserAllowedToLogin = FALSE;
00363         $adminOnlyMode = $GLOBALS['TYPO3_CONF_VARS']['BE']['adminOnly'];
00364 
00365             // Backend user is allowed if adminOnly is not set or user is an admin:
00366         if (!$adminOnlyMode || $this->isAdmin()) {
00367             $isUserAllowedToLogin = TRUE;
00368             // Backend user is allowed if adminOnly is set to 2 (CLI) and a CLI process is running:
00369         } elseif ($adminOnlyMode == 2 && (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI)) {
00370             $isUserAllowedToLogin = TRUE;
00371         }
00372 
00373         return $isUserAllowedToLogin;
00374     }
00375 
00376     /**
00377      * Logs out the current user and clears the form protection tokens.
00378      */
00379     public function logoff() {
00380         if (isset($GLOBALS['BE_USER'])) {
00381             t3lib_formProtection_Factory::get()->clean();
00382         }
00383         parent::logoff();
00384     }
00385 }
00386 
00387 
00388 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_beuserauth.php'])) {
00389     include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_beuserauth.php']);
00390 }
00391 
00392 ?>