00001 <?php
00002
00003 DEFINE('_DB_SESSION_HANDLER', getShopBasePath() . 'core/adodblite/session/adodb-session.php');
00004
00005 if (oxConfig::getInstance()->getConfigParam( 'blAdodbSessionHandler' ) ) {
00006 $oDB = oxDb::getDb();
00007 include_once _DB_SESSION_HANDLER;
00008 }
00009
00015 class oxSession extends oxSuperCfg
00016 {
00022 protected $_sName = 'sid';
00023
00029 protected $_sForcedPrefix = 'force_';
00030
00035 protected $_sId = null;
00036
00042 protected static $_blIsNewSession = false;
00043
00047 protected static $_instance = null;
00048
00053 protected static $_oUser = null;
00054
00061 protected $_blNewSession = false;
00062
00068 protected $_sErrorMsg = null;
00069
00075 protected $_oBasket = null;
00076
00085 protected $_aRequireCookiesInFncs = array();
00086
00095 protected $_aRequireSessionWithParams = array(
00096 'cl' => array (
00097 'register' => true,
00098 'account' => true,
00099 ),
00100 'fnc' => array (
00101 'tobasket' => true,
00102 'login_noredirect' => true,
00103 'tocomparelist' => true,
00104 ),
00105 '_artperpage' => true,
00106 'listorderby' => true,
00107 );
00108
00114 protected $_blSidNeeded = null;
00115
00121 protected $_aPersistentParams = array("actshop", "lang", "currency", "language", "tpllanguage");
00122
00128 protected $_sSessionChallenge = '';
00129
00135 public static function getInstance()
00136 {
00137 if ( defined('OXID_PHP_UNIT')) {
00138 if ( isset( modSession::$unitMOD) && is_object( modSession::$unitMOD)) {
00139 return modSession::$unitMOD;
00140 }
00141 }
00142 if (!isset(self::$_instance)) {
00143 self::$_instance = oxNew( 'oxsession' );
00144 }
00145 return self::$_instance;
00146 }
00147
00153 public function getId()
00154 {
00155 return $this->_sId;
00156 }
00157
00165 public function setId($sVal)
00166 {
00167 $this->_sId = $sVal;
00168 }
00169
00177 public function setName($sVal)
00178 {
00179 $this->_sName = $sVal;
00180 }
00181
00187 public function getForcedName()
00188 {
00189 return $this->_sForcedPrefix . $this->getName();
00190 }
00191
00197 public function getName()
00198 {
00199 return $this->_sName;
00200 }
00201
00207 public function start()
00208 {
00209 $myConfig = $this->getConfig();
00210 $sid = null;
00211
00212 if ( $this->isAdmin() ) {
00213 $this->setName("admin_sid");
00214 } else {
00215 $this->setName("sid");
00216 }
00217
00218 $sForceSidParam = oxConfig::getParameter($this->getForcedName());
00219 $sSidParam = oxConfig::getParameter($this->getName());
00220
00221
00222 if ($sForceSidParam) {
00223 $sid = $sForceSidParam;
00224 } elseif ($this->_getSessionUseCookies() && $this->_getCookieSid()) {
00225 $sid = $this->_getCookieSid();
00226 } elseif ($sSidParam) {
00227 $sid = $sSidParam;
00228 }
00229
00230
00231 if ( $this->_allowSessionStart() ) {
00232
00233
00234 if ( !$sid ) {
00235 self::$_blIsNewSession = true;
00236 $this->initNewSession();
00237 } else {
00238 self::$_blIsNewSession = false;
00239 $this->_setSessionId( $sid );
00240 $this->_sessionStart();
00241 }
00242
00243
00244 if ( $this->_sId != session_id() ) {
00245 $this->_setSessionId( session_id() );
00246 }
00247
00248
00249 if ( !self::$_blIsNewSession && $this->_isSwappedClient() ) {
00250 $this->initNewSession();
00251
00252
00253 if ( $this->_sErrorMsg && $myConfig->getConfigParam( 'iDebug' ) ) {
00254 oxUtilsView::getInstance()->addErrorToDisplay( new oxException( $this->_sErrorMsg ) );
00255 }
00256 }
00257 }
00258 }
00259
00265 public function getRequestChallengeToken()
00266 {
00267 if ($this->_sSessionChallenge) {
00268 return $this->_sSessionChallenge;
00269 }
00270
00271 if (isset( $_SERVER['REQUEST_METHOD'] )) {
00272 if ( $_SERVER['REQUEST_METHOD'] == 'POST' && isset( $_POST['stoken'] ) ) {
00273 $this->_sSessionChallenge = $_POST['stoken'];
00274 } elseif ( $_SERVER['REQUEST_METHOD'] == 'GET' && isset( $_GET['stoken'] ) ) {
00275 $this->_sSessionChallenge = $_GET['stoken'];
00276 }
00277 $this->_sSessionChallenge = preg_replace('/[^a-z0-9]/i', '', $this->_sSessionChallenge);
00278 }
00279 return $this->_sSessionChallenge;
00280 }
00281
00287 public function getSessionChallengeToken()
00288 {
00289 $sRet = preg_replace('/[^a-z0-9]/i', '', self::getVar('stoken'));
00290 if (!$sRet) {
00291 $this->_initNewSessionChallenge();
00292 $sRet = self::getVar('stoken');
00293 }
00294 return $sRet;
00295 }
00296
00303 public function checkSessionChallenge()
00304 {
00305 $sToken = $this->getSessionChallengeToken();
00306 return $sToken && ($sToken == $this->getRequestChallengeToken());
00307 }
00308
00314 protected function _initNewSessionChallenge()
00315 {
00316 $this->_sSessionChallenge = sprintf('%X', crc32(oxUtilsObject::getInstance()->generateUID()));
00317 self::setVar('stoken', $this->_sSessionChallenge);
00318 }
00319
00325 protected function _sessionStart()
00326 {
00327
00328 session_cache_limiter( 'nocache' );
00329
00330
00331
00332 if (strpos($_SERVER['HTTP_USER_AGENT'], 'AOL') !== false ) {
00333 session_cache_limiter(false);
00334 header("Cache-Control: no-store, private, must-revalidate, proxy-revalidate, post-check=0, pre-check=0, max-age=0, s-maxage=0");
00335 }
00336
00337 $ret = @session_start();
00338 if (!$this->getSessionChallengeToken()) {
00339 $this->_initNewSessionChallenge();
00340 }
00341
00342 return $ret;
00343 }
00344
00350 public function initNewSession()
00351 {
00352
00353 if ( self::$_blIsNewSession ) {
00354 $this->_sessionStart();
00355 }
00356
00357
00358 $aPersistent = array();
00359 foreach ($this->_aPersistentParams as $sParam) {
00360 if ( self::getVar($sParam)) {
00361 $aPersistent[$sParam] = self::getVar($sParam);
00362 }
00363 }
00364
00365 $sid = md5(oxUtilsObject::getInstance()->generateUID());
00366
00367 $this->_setSessionId($sid);
00368 session_unset();
00369
00370
00371 foreach ($aPersistent as $key => $sParam) {
00372 self::setVar($key, $aPersistent[$key]);
00373 }
00374
00375 $this->_initNewSessionChallenge();
00376
00377
00378 self::setVar( "sessionagent", oxUtilsServer::getInstance()->getServerVar( 'HTTP_USER_AGENT' ) );
00379 }
00380
00386 public function freeze()
00387 {
00388
00389 self::setVar( $this->_getBasketName(), serialize( $this->getBasket() ) );
00390
00391 session_write_close();
00392 }
00393
00399 public function destroy()
00400 {
00401
00402 unset($_SESSION);
00403 session_destroy();
00404 }
00405
00413 public static function hasVar( $name )
00414 {
00415 if ( defined( 'OXID_PHP_UNIT' ) ) {
00416 if ( isset( modSession::$unitMOD ) && is_object( modSession::$unitMOD ) ) {
00417 try{
00418 $sVal = modSession::getInstance()->getVar( $name );
00419 return isset( $sVal );
00420 } catch( Exception $e ) {
00421
00422 }
00423 }
00424 }
00425
00426 return isset($_SESSION[$name]);
00427 }
00428
00437 public static function setVar( $name, $value)
00438 {
00439 if ( defined( 'OXID_PHP_UNIT' ) ) {
00440 if ( isset( modSession::$unitMOD ) && is_object( modSession::$unitMOD ) ) {
00441 try{
00442 return modSession::getInstance()->setVar( $name, $value );
00443 } catch( Exception $e ) {
00444
00445 }
00446 }
00447 }
00448
00449 $_SESSION[$name] = $value;
00450
00451 }
00452
00460 public static function getVar( $name )
00461 {
00462 if ( defined( 'OXID_PHP_UNIT' ) ) {
00463 if ( isset( modSession::$unitMOD ) && is_object( modSession::$unitMOD ) ) {
00464 try{
00465 return modSession::getInstance()->getVar( $name );
00466 } catch( Exception $e ) {
00467
00468 }
00469 }
00470 }
00471
00472 if ( isset( $_SESSION[$name] )) {
00473 return $_SESSION[$name];
00474 } else {
00475 return null;
00476 }
00477 }
00478
00486 public static function deleteVar( $name )
00487 {
00488 if ( defined( 'OXID_PHP_UNIT' ) ) {
00489 if ( isset( modSession::$unitMOD ) && is_object( modSession::$unitMOD ) ) {
00490 try{
00491 return modSession::getInstance()->setVar( $name, null );
00492 } catch( Exception $e ) {
00493
00494 }
00495 }
00496 }
00497
00498 $_SESSION[$name] = null;
00499
00500 unset($_SESSION[$name]);
00501 }
00502
00513 public function url( $sUrl )
00514 {
00515 $myConfig = $this->getConfig();
00516 $blUseCookies = $this->_getSessionUseCookies();
00517 $sSeparator = getStr()->strstr( $sUrl, "?" ) !== false ? "&" : "?";
00518 $sUrl .= $sSeparator;
00519
00520 if ( $blUseCookies && $this->_getCookieSid() ) {
00521
00522 if ( ( strpos( $sUrl, "https:" ) === 0 && !$myConfig->isSsl() ) ||
00523 ( strpos( $sUrl, "http:" ) === 0 && $myConfig->isSsl() ) ) {
00524 $sUrl .= $this->getForcedName(). '=' . $this->getId() . "&";
00525 }
00526 if ($this->isAdmin()) {
00527
00528 $sUrl .= 'stoken='.$this->getSessionChallengeToken().'&';
00529 }
00530 } elseif ( oxUtils::getInstance()->isSearchEngine() ) {
00531
00532 $sLangParam = (int) oxConfig::getParameter( "lang" );
00533 $sConfLang = (int) $myConfig->getConfigParam( "sDefaultLang" );
00534 if ( $sLangParam != $sConfLang ) {
00535 $sUrl .= "lang={$sLangParam}&";
00536 }
00537 } elseif ( ( $sIcludeParams = $this->sid() ) ) {
00538
00539 $sUrl .= "{$sIcludeParams}&";
00540 }
00541
00542 return $sUrl;
00543 }
00544
00554 public function sid( $blForceSid = false )
00555 {
00556 $myConfig = $this->getConfig();
00557 $blUseCookies = $this->_getSessionUseCookies();
00558 $sRet = '';
00559
00560 $blDisableSid = oxUtils::getInstance()->isSearchEngine()
00561 && is_array($myConfig->getConfigParam( 'aCacheViews' ) )
00562 && !$this->isAdmin();
00563
00564
00565 if ( !$blDisableSid && $this->getId() && ($blForceSid || !$blUseCookies || !$this->_getCookieSid())) {
00566 $sRet = ( $blForceSid ? $this->getForcedName() : $this->getName() )."=".$this->getId();
00567 }
00568
00569 if ($this->isAdmin()) {
00570
00571 if ($sRet) {
00572 $sRet .= '&';
00573 }
00574 $sRet .= 'stoken='.$this->getSessionChallengeToken();
00575 }
00576
00577 return $sRet;
00578 }
00579
00585 public function hiddenSid()
00586 {
00587 $sToken = "<input type=\"hidden\" name=\"stoken\" value=\"".$this->getSessionChallengeToken(). "\">";
00588 $sSid = "<input type=\"hidden\" name=\"".$this->getForcedName()."\" value=\"". $this->getId() . "\">";
00589 return $sToken.$sSid;
00590 }
00591
00597 public function getBasket()
00598 {
00599 if ( $this->_oBasket === null ) {
00600 $sBasket = self::getVar( $this->_getBasketName() );
00601 if ( $sBasket && $oBasket = unserialize( $sBasket ) ) {
00602 $this->setBasket( $oBasket );
00603 } else {
00604 $this->setBasket( oxNew( 'oxbasket' ) );
00605 }
00606 }
00607
00608 return $this->_oBasket;
00609 }
00610
00618 public function setBasket( $oBasket )
00619 {
00620
00621 $this->_oBasket = $oBasket;
00622 }
00623
00629 public function delBasket()
00630 {
00631 $this->setBasket( null );
00632 self::deleteVar( $this->_getBasketName());
00633 }
00634
00640 public function isNewSession()
00641 {
00642 return self::$_blIsNewSession;
00643 }
00644
00650 protected function _forceSessionStart()
00651 {
00652 return ( !oxUtils::getInstance()->isSearchEngine() ) && ( ( bool ) $this->getConfig()->getConfigParam( 'blForceSessionStart' ) ) ;
00653 }
00654
00660 protected function _allowSessionStart()
00661 {
00662 $blAllowSessionStart = true;
00663
00664
00665 if ( !$this->isAdmin() ) {
00666 if ( oxUtils::getInstance()->isSearchEngine() || oxConfig::getParameter( 'skipSession' ) ) {
00667 $blAllowSessionStart = false;
00668 } elseif ( !$this->_forceSessionStart() && !oxUtilsServer::getInstance()->getOxCookie( 'sid_key' ) ) {
00669
00670
00671
00672
00673 if ( !oxUtilsServer::getInstance()->getOxCookie( $this->getName() ) &&
00674 !( oxConfig::getParameter( $this->getName() ) || oxConfig::getParameter( $this->getForcedName() ) ) &&
00675 !$this->_isSessionRequiredAction() ) {
00676 $blAllowSessionStart = false;
00677 }
00678 }
00679 }
00680
00681 return $blAllowSessionStart;
00682 }
00683
00691 protected function _isSwappedClient()
00692 {
00693 $blSwapped = false;
00694 $myUtilsServer = oxUtilsServer::getInstance();
00695
00696
00697 if ( !oxUtils::getInstance()->isSearchEngine() && !$myUtilsServer->isTrustedClientIp() ) {
00698
00699 $myConfig = $this->getConfig();
00700
00701
00702 $blSwapped = $this->_checkUserAgent( $myUtilsServer->getServerVar( 'HTTP_USER_AGENT' ), self::getVar( 'sessionagent' ) );
00703 if ( !$blSwapped ) {
00704 if ( $myConfig->getConfigParam( 'blAdodbSessionHandler' ) ) {
00705 $blSwapped = $this->_checkSid();
00706 }
00707
00708 if ( !$blSwapped ) {
00709 $blDisableCookieCheck = $myConfig->getConfigParam( 'blDisableCookieCheck' );
00710 $blUseCookies = $this->_getSessionUseCookies();
00711 if ( !$blDisableCookieCheck && $blUseCookies ) {
00712 $blSwapped = $this->_checkCookies( $myUtilsServer->getOxCookie( 'sid_key' ), self::getVar( "sessioncookieisset" ) );
00713 }
00714 }
00715 }
00716 }
00717
00718 return $blSwapped;
00719 }
00720
00729 protected function _checkUserAgent( $sAgent, $sExistingAgent )
00730 {
00731 $blCheck = false;
00732 if ( $sAgent && $sAgent !== $sExistingAgent ) {
00733 if ( $sExistingAgent ) {
00734 $this->_sErrorMsg = "Different browser ({$sExistingAgent}, {$sAgent}), creating new SID...<br>";
00735 }
00736 $blCheck = true;
00737 }
00738
00739 return $blCheck;
00740 }
00741
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00779 protected function _checkSid()
00780 {
00781
00782 $sSID = oxDb::getDb()->GetOne("select SessionID from oxsessions where SessionID = '".$this->getId()."'");
00783
00784
00785
00786 if ( !$this->_blNewSession && (!isset( $sSID) || !$sSID)) {
00787
00788 $this->_sErrorMsg = "Session has expired in the past and someone uses this sid to reactivate it, creating new SID...<br>";
00789 return true;
00790 }
00791 return false;
00792 }
00793
00803 protected function _checkCookies( $sCookieSid, $aSessCookieSetOnce )
00804 {
00805 $myConfig = $this->getConfig();
00806 $blSwapped = false;
00807
00808 if ( isset( $aSessCookieSetOnce[$myConfig->getCurrentShopURL()] ) ) {
00809 $blSessCookieSetOnce = $aSessCookieSetOnce[$myConfig->getCurrentShopURL()];
00810 } else {
00811 $blSessCookieSetOnce = false;
00812 }
00813
00814
00815 if ( $blSessCookieSetOnce && !$sCookieSid ) {
00816 if ( $myConfig->getConfigParam( 'iDebug' ) ) {
00817 $this->_sErrorMsg = "Cookie not found, creating new SID...<br>";
00818 $this->_sErrorMsg .= "Cookie: $sCookieSid<br>";
00819 $this->_sErrorMsg .= "Session: $blSessCookieSetOnce<br>";
00820 $this->_sErrorMsg .= "URL: ".$myConfig->getCurrentShopURL()."<br>";
00821 }
00822 $blSwapped = true;
00823 }
00824
00825
00826 if ( $sCookieSid == "oxid" && !$blSessCookieSetOnce ) {
00827 $aSessCookieSetOnce[$myConfig->getCurrentShopURL()] = "ox_true";
00828 self::setVar( "sessioncookieisset", $aSessCookieSetOnce );
00829 }
00830
00831
00832 if ( !$sCookieSid ) {
00833 oxUtilsServer::getInstance()->setOxCookie( 'sid_key', 'oxid' );
00834 }
00835 return $blSwapped;
00836 }
00837
00845 protected function _setSessionId($sSessId)
00846 {
00847
00848 if ( $sSessId && session_id() != $sSessId ) {
00849 $this->_blNewSession = true;
00850 }
00851
00852 session_id( $sSessId );
00853
00854 $this->setId( $sSessId );
00855
00856 $blUseCookies = $this->_getSessionUseCookies();
00857
00858 if ( !$this->_allowSessionStart() ) {
00859 if ( $blUseCookies ) {
00860 oxUtilsServer::getInstance()->setOxCookie( $this->getName(), null );
00861 }
00862 return;
00863 }
00864
00865 if ( $blUseCookies ) {
00866
00867 oxUtilsServer::getInstance()->setOxCookie( $this->getName(), $sSessId );
00868 }
00869 }
00870
00876 protected function _getBasketName()
00877 {
00878 $myConfig = $this->getConfig();
00879 if ( $myConfig->getConfigParam( 'blMallSharedBasket' ) == 0 ) {
00880 return $myConfig->getShopId()."_basket";
00881 }
00882 return "basket";
00883 }
00884
00890 protected function _getCookieSid()
00891 {
00892 return oxUtilsServer::getInstance()->getOxCookie($this->getName());
00893 }
00894
00901 protected function _getRequireSessionWithParams()
00902 {
00903 $aCfgArray = $this->getConfig()->getConfigParam('aRequireSessionWithParams');
00904 if (is_array($aCfgArray)) {
00905 $aDefault = $this->_aRequireSessionWithParams;
00906 foreach ($aCfgArray as $key => $val) {
00907 if (!is_array($val) && $val) {
00908 unset($aDefault[$key]);
00909 }
00910 }
00911 return array_merge_recursive($aCfgArray, $aDefault);
00912 }
00913 return $this->_aRequireSessionWithParams;
00914 }
00915
00921 protected function _isSessionRequiredAction()
00922 {
00923
00924 $sFunction = oxConfig::getParameter( 'fnc' );
00925 $sClass = oxConfig::getParameter( 'cl' );
00926
00927 if (( $sFunction && in_array( strtolower( $sFunction ), $this->_aRequireCookiesInFncs ) ) ||
00928 ( $sClass && array_key_exists( strtolower( $sClass ), $this->_aRequireCookiesInFncs ) )) {
00929 return true;
00930 }
00931
00932 foreach ($this->_getRequireSessionWithParams() as $sParam => $aValues) {
00933 $sValue = oxConfig::getParameter( $sParam );
00934 if (isset($sValue)) {
00935 if (is_array($aValues)) {
00936 if (isset($aValues[$sValue]) && $aValues[$sValue]) {
00937 return true;
00938 }
00939 } elseif ($aValues) {
00940 return true;
00941 }
00942 }
00943 }
00944
00945 return ($_SERVER['REQUEST_METHOD'] == 'POST');
00946 }
00947
00955 public function isSidNeeded( $sUrl = null )
00956 {
00957 if ( $blUseCookies && $this->_getCookieSid() ) {
00958
00959 if ( ( strpos( $sUrl, "https:" ) === 0 && !$this->getConfig()->isSsl() ) ||
00960 ( strpos( $sUrl, "http:" ) === 0 && $this->getConfig()->isSsl() ) ) {
00961 return true;
00962 }
00963 }
00964
00965 if ( $sUrl && !$this->getConfig()->isCurrentUrl( $sUrl ) ) {
00966 return true;
00967 } elseif ( $this->_blSidNeeded === null ) {
00968
00969 $this->_blSidNeeded = false;
00970
00971
00972 if ( !oxUtils::getInstance()->isSearchEngine() ) {
00973
00974 if ( oxUtilsServer::getInstance()->getOxCookie( $this->getName() ) ) {
00975 $this->_blSidNeeded = false;
00976 } elseif ( $this->_forceSessionStart() ) {
00977 $this->_blSidNeeded = true;
00978 } else {
00979
00980 if ( $blSidNeeded = self::getVar( 'blSidNeeded' ) ) {
00981 $this->_blSidNeeded = true;
00982 } elseif ( $this->_isSessionRequiredAction() ) {
00983 $this->_blSidNeeded = true;
00984
00985
00986 self::setVar( 'blSidNeeded', $this->_blSidNeeded );
00987 }
00988 }
00989 }
00990 }
00991
00992 return $this->_blSidNeeded;
00993 }
00994
01006 public function processUrl( $sUrl )
01007 {
01008 if (!$this->isAdmin()) {
01009 $sSid = '';
01010 if ( $this->isSidNeeded( $sUrl ) ) {
01011
01012 $sSid = $this->sid( true );
01013 } else {
01014 $sSid = $this->sid();
01015 }
01016 if ($sSid) {
01017 if ( !preg_match('/(\?|&(amp;)?)sid=/i', $sUrl) && (false === strpos($sUrl, $sSid))) {
01018 if (!preg_match('/(\?|&(amp;)?)$/', $sUrl)) {
01019 $oStr = getStr();
01020 $sUrl .= ( $oStr->strstr( $sUrl, '?' ) !== false ? '&' : '?' );
01021 }
01022 $sUrl .= $sSid . '&';
01023 }
01024 }
01025 }
01026 return $sUrl;
01027 }
01028
01034 protected function _getSessionUseCookies()
01035 {
01036 return $this->isAdmin() || $this->getConfig()->getConfigParam( 'blSessionUseCookies');
01037 }
01038 }