/** * @see SessionFactory::create() */ public function create() { // create new session hash $sessionID = StringUtil::getRandomID(); // check cookies for userID & password require_once WCF_DIR . 'lib/system/auth/UserAuth.class.php'; $user = UserAuth::getInstance()->loginAutomatically(true, $this->userClassName); if ($user === null) { // no valid user found // create guest user $user = new $this->guestClassName(); } // update user session $user->update(); // get spider information $spider = $this->isSpider(UserUtil::getUserAgent()); if ($user->userID != 0) { // user is no guest // delete all other sessions of this user Session::deleteSessions($user->userID, true, false); } $requestMethod = !empty($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : ''; // insert session into database $sql = "INSERT INTO \twcf" . WCF_N . "_session\n\t\t\t\t\t(sessionID, packageID, userID, ipAddress, userAgent,\n\t\t\t\t\tlastActivityTime, requestURI, requestMethod,\n\t\t\t\t\tusername" . ($spider ? ", spiderID" : "") . ")\n\t\t\tVALUES\t\t('" . $sessionID . "',\n\t\t\t\t\t" . PACKAGE_ID . ",\n\t\t\t\t\t" . $user->userID . ",\n\t\t\t\t\t'" . escapeString(UserUtil::getIpAddress()) . "',\n\t\t\t\t\t'" . escapeString(UserUtil::getUserAgent()) . "',\n\t\t\t\t\t" . TIME_NOW . ",\n\t\t\t\t\t'" . escapeString(UserUtil::getRequestURI()) . "',\n\t\t\t\t\t'" . escapeString($requestMethod) . "',\n\t\t\t\t\t'" . ($spider ? escapeString($spider['spiderName']) : escapeString($user->username)) . "'\n\t\t\t\t\t" . ($spider ? ", " . $spider['spiderID'] : "") . ")"; WCF::getDB()->sendQuery($sql); // save user data $serializedUserData = ''; if (ENABLE_SESSION_DATA_CACHE && get_class(WCF::getCache()->getCacheSource()) == 'MemcacheCacheSource') { require_once WCF_DIR . 'lib/system/cache/source/MemcacheAdapter.class.php'; MemcacheAdapter::getInstance()->getMemcache()->set('session_userdata_-' . $sessionID, $user); } else { $serializedUserData = serialize($user); try { $sql = "INSERT INTO \twcf" . WCF_N . "_session_data\n\t\t\t\t\t\t\t(sessionID, userData)\n\t\t\t\t\tVALUES \t\t('" . $sessionID . "',\n\t\t\t\t\t\t\t'" . escapeString($serializedUserData) . "')"; WCF::getDB()->sendQuery($sql); } catch (DatabaseException $e) { // horizon update workaround $sql = "UPDATE \twcf" . WCF_N . "_session\n\t\t\t\t\tSET\tuserData = '" . escapeString($serializedUserData) . "'\n\t\t\t\t\tWHERE\tsessionID = '" . $sessionID . "'"; WCF::getDB()->sendQuery($sql); } } // return new session object return new $this->sessionClassName(null, array('sessionID' => $sessionID, 'packageID' => PACKAGE_ID, 'userID' => $user->userID, 'ipAddress' => UserUtil::getIpAddress(), 'userAgent' => UserUtil::getUserAgent(), 'lastActivityTime' => TIME_NOW, 'requestURI' => UserUtil::getRequestURI(), 'requestMethod' => $requestMethod, 'userData' => $serializedUserData, 'sessionVariables' => '', 'username' => $spider ? $spider['spiderName'] : $user->username, 'spiderID' => $spider ? $spider['spiderID'] : 0, 'isNew' => true)); }
/** * Verifies the challenge and response with the recaptcha verify server. * * Parts of this function are taken from lib/util/FileUtil.class.php from the * WoltLab Community Framework which is licensed unter the * GNU Lesser General Public License <http://www.gnu.org/licenses/lgpl.html>. * More on <http://www.woltlab.com/> and <http://community.woltlab.com/>. * * @param string $challenge * @param string $response * @return string */ protected static function verify($challenge, $response) { // get proxy $options = array(); if (PROXY_SERVER_HTTP) { $options['http']['proxy'] = PROXY_SERVER_HTTP; } require_once WCF_DIR . 'lib/system/io/RemoteFile.class.php'; $remoteFile = new RemoteFile(self::RECAPTCHA_HOST, self::RECAPTCHA_PORT, 30, $options); // the file to read. if (!isset($remoteFile)) { return self::ERROR_NOT_REACHABLE; } // build post string $postData = 'privatekey=' . urlencode(self::getPrivateKey()); $postData .= '&remoteip=' . urlencode(UserUtil::getIpAddress()); $postData .= '&challenge=' . urlencode($challenge); $postData .= '&response=' . urlencode($response); // build and send the http request. $request = "POST " . self::RECAPTCHA_PATH . " HTTP/1.0\r\n"; $request .= "User-Agent: HTTP.PHP (info.codingcorner.wcf.recaptcha; WoltLab Community Framework/" . WCF_VERSION . "; " . WCF::getLanguage()->getLanguageCode() . ")\r\n"; $request .= "Accept: */*\r\n"; $request .= "Accept-Language: " . WCF::getLanguage()->getLanguageCode() . "\r\n"; $request .= "Host: " . self::RECAPTCHA_HOST . "\r\n"; $request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; $request .= "Content-Length: " . strlen($postData) . "\r\n"; $request .= "Connection: Close\r\n\r\n"; $request .= $postData; $remoteFile->puts($request); $waiting = true; $readResponse = array(); $reCaptchaResponse = array(); // read http response. while (!$remoteFile->eof()) { $readResponse[] = $remoteFile->gets(); // look if we are done with transferring the requested file. if ($waiting) { if (rtrim($readResponse[count($readResponse) - 1]) == '') { $waiting = false; } } else { // look if the webserver sent an error http statuscode // This has still to be checked if really sufficient! $arrayHeader = array('201', '301', '302', '303', '307', '404'); foreach ($arrayHeader as $code) { $error = strpos($readResponse[0], $code); } if ($error !== false) { return self::ERROR_NOT_REACHABLE; } // write to the target system. $reCaptchaResponse[] = $readResponse[count($readResponse) - 1]; } } if (StringUtil::trim($reCaptchaResponse[0]) == "true") { return self::VALID_ANSWER; } else { return StringUtil::trim($reCaptchaResponse[1]); } }
/** * Finds an existing session of a search spider. * * @param integer $spiderID * @return CookieSession */ protected function getExistingSpiderSession($spiderID) { if (!ENABLE_SESSION_DATA_CACHE || get_class(WCF::getCache()->getCacheSource()) != 'MemcacheCacheSource') { $sql = "SELECT \t\tsession_data.*, session.* \n\t\t\t\tFROM \t\twcf" . WCF_N . "_session session\n\t\t\t\tLEFT JOIN\twcf" . WCF_N . "_session_data session_data\n\t\t\t\tON\t\t(session_data.sessionID = session.sessionID)\n\t\t\t\tWHERE \t\tsession.spiderID = '" . escapeString($spiderID) . "'\n\t\t\t\t\t\tAND session.userID = 0"; } else { $sql = "SELECT \t\t* \n\t\t\t\tFROM \t\twcf" . WCF_N . "_session\n\t\t\t\tWHERE \t\tspiderID = '" . escapeString($spiderID) . "'\n\t\t\t\t\t\tAND userID = 0"; } $row = WCF::getDB()->getFirstRow($sql); if (!empty($row['sessionID'])) { // fix session validation $row['ipAddress'] = UserUtil::getIpAddress(); $row['userAgent'] = UserUtil::getUserAgent(); // return session object return new $this->sessionClassName(null, $row); } return null; }
/** * Validates the ip address or the user agent of this session. * * @return boolean */ protected function validate() { if (SESSION_VALIDATE_USER_AGENT && $this->userAgent != UserUtil::getUserAgent()) { return false; } if (SESSION_VALIDATE_IP_ADDRESS > 0) { if (SESSION_VALIDATE_IP_ADDRESS == 4) { if ($this->ipAddress != UserUtil::getIpAddress()) { return false; } } else { // skip validation for IPv6 if (strpos($this->ipAddress, '.') !== false) { // validate blocks $oldIpAddressBlocks = explode('.', $this->ipAddress); $newIpAddressBlocks = explode('.', UserUtil::getIpAddress()); for ($i = 0; $i < SESSION_VALIDATE_IP_ADDRESS; $i++) { if (!isset($oldIpAddressBlocks[$i]) || !isset($newIpAddressBlocks[$i]) || $oldIpAddressBlocks[$i] != $newIpAddressBlocks[$i]) { return false; } } } } } return true; }
/** * Creates a new session. * * Generates a new session hash, inserts the new session into database * and returns the object of the created session. * * @return Session $session */ public function create() { // create new session hash $sessionID = StringUtil::getRandomID(); // get user automatically if (!defined('NO_IMPORTS')) { require_once WCF_DIR . 'lib/system/auth/UserAuth.class.php'; } $user = UserAuth::getInstance()->loginAutomatically(); // create user if ($user === null) { // no valid user found // create guest user $user = new $this->userClassName(); } // update user session $user->update(); // insert session into database $requestMethod = !empty($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : ''; $sql = "INSERT INTO \twcf" . WCF_N . "_acp_session\n\t\t\t\t\t(sessionID, packageID, userID, ipAddress, userAgent, lastActivityTime, requestURI, requestMethod)\n\t\t\tVALUES \t\t('" . $sessionID . "',\n\t\t\t\t\t" . PACKAGE_ID . ",\n\t\t\t\t\t" . $user->userID . ",\n\t\t\t\t\t'" . escapeString(UserUtil::getIpAddress()) . "',\n\t\t\t\t\t'" . escapeString(UserUtil::getUserAgent()) . "',\n\t\t\t\t\t" . TIME_NOW . ",\n\t\t\t\t\t'" . escapeString(UserUtil::getRequestURI()) . "',\n\t\t\t\t\t'" . escapeString($requestMethod) . "')"; WCF::getDB()->sendQuery($sql); // save user data $serializedUserData = ''; if (ENABLE_SESSION_DATA_CACHE && get_class(WCF::getCache()->getCacheSource()) == 'MemcacheCacheSource') { require_once WCF_DIR . 'lib/system/cache/source/MemcacheAdapter.class.php'; MemcacheAdapter::getInstance()->getMemcache()->set('acp_session_userdata_' . $sessionID, $user); } else { $serializedUserData = serialize($user); try { $sql = "INSERT INTO \twcf" . WCF_N . "_acp_session_data\n\t\t\t\t\t\t\t(sessionID, userData)\n\t\t\t\t\tVALUES \t\t('" . $sessionID . "',\n\t\t\t\t\t\t\t'" . escapeString($serializedUserData) . "')"; WCF::getDB()->sendQuery($sql); } catch (DatabaseException $e) { // horizon update workaround $sql = "UPDATE \twcf" . WCF_N . "_acp_session\n\t\t\t\t\tSET\tuserData = '" . escapeString($serializedUserData) . "'\n\t\t\t\t\tWHERE\tsessionID = '" . $sessionID . "'"; WCF::getDB()->sendQuery($sql); } } // return new session object return new $this->sessionClassName(null, array('sessionID' => $sessionID, 'packageID' => PACKAGE_ID, 'ipAddress' => UserUtil::getIpAddress(), 'userAgent' => UserUtil::getUserAgent(), 'lastActivityTime' => TIME_NOW, 'requestURI' => UserUtil::getRequestURI(), 'requestMethod' => $requestMethod, 'userData' => $serializedUserData, 'sessionVariables' => '', 'userID' => $user->userID, 'isNew' => true)); }