/** * Validates the access-token and performs the login. */ protected function checkAccessToken() { if (isset($_REQUEST['at'])) { list($userID, $token) = explode('-', StringUtil::trim($_REQUEST['at'])); if (WCF::getUser()->userID) { if ($userID == WCF::getUser()->userID && PasswordUtil::secureCompare(WCF::getUser()->accessToken, $token)) { // everything is fine, but we are already logged in return; } else { // token is invalid throw new IllegalLinkException(); } } else { $user = new User($userID); if (PasswordUtil::secureCompare($user->accessToken, $token)) { // token is valid -> change user SessionHandler::getInstance()->changeUser($user, true); } else { // token is invalid throw new IllegalLinkException(); } } } }
/** * Sends a new password to the given user. * * @param \wcf\data\user\UserEditor $userEditor */ protected function sendNewPassword(UserEditor $userEditor) { $newPassword = PasswordUtil::getRandomPassword(REGISTER_PASSWORD_MIN_LENGTH > 12 ? REGISTER_PASSWORD_MIN_LENGTH : 12); $userAction = new UserAction(array($userEditor), 'update', array('data' => array('password' => $newPassword))); $userAction->executeAction(); // send mail $mail = new Mail(array($userEditor->username => $userEditor->email), $userEditor->getLanguage()->getDynamicVariable('wcf.acp.user.sendNewPassword.mail.subject'), $userEditor->getLanguage()->getDynamicVariable('wcf.acp.user.sendNewPassword.mail', array('password' => $newPassword, 'username' => $userEditor->username))); $mail->send(); }
/** * @see \wcf\form\IForm::validate() */ public function validate() { parent::validate(); if (empty($this->masterPassword)) { throw new UserInputException('masterPassword'); } // check password if (!PasswordUtil::secureCompare(MASTER_PASSWORD, PasswordUtil::getDoubleSaltedHash($this->masterPassword, MASTER_PASSWORD))) { throw new UserInputException('masterPassword', 'notValid'); } }
/** * @see \wcf\data\DatabaseObjectEditor::update() */ public function update(array $parameters = array()) { // update salt and create new password hash if (isset($parameters['password']) && $parameters['password'] !== '') { $parameters['password'] = PasswordUtil::getDoubleSaltedHash($parameters['password']); $parameters['accessToken'] = StringUtil::getRandomID(); // update accessToken $this->accessToken = $parameters['accessToken']; } else { unset($parameters['password'], $parameters['accessToken']); } parent::update($parameters); }
/** * @see \wcf\page\IPage::assignVariables() */ public function assignVariables() { parent::assignVariables(); WCF::getTPL()->assign(array('confirmMasterPassword' => $this->confirmMasterPassword, 'exampleMasterPassword' => PasswordUtil::getRandomPassword(16), 'relativeWcfDir' => RELATIVE_WCF_DIR)); }
/** * @see \wcf\form\IForm::save() */ public function save() { parent::save(); $success = array(); $updateParameters = array(); // quit if (WCF::getSession()->getPermission('user.profile.canQuit')) { if (!WCF::getUser()->quitStarted && $this->quit == 1) { $updateParameters['quitStarted'] = TIME_NOW; $this->quitStarted = TIME_NOW; $success[] = 'wcf.user.quit.success'; } else { if (WCF::getUser()->quitStarted && $this->cancelQuit == 1) { $updateParameters['quitStarted'] = 0; $this->quitStarted = 0; $success[] = 'wcf.user.quit.cancel.success'; } } } // user name if (WCF::getSession()->getPermission('user.profile.canRename') && $this->username != WCF::getUser()->username) { if (mb_strtolower($this->username) != mb_strtolower(WCF::getUser()->username)) { $updateParameters['lastUsernameChange'] = TIME_NOW; $updateParameters['oldUsername'] = WCF::getUser()->username; } $updateParameters['username'] = $this->username; $success[] = 'wcf.user.changeUsername.success'; } // email if (WCF::getSession()->getPermission('user.profile.canChangeEmail') && $this->email != WCF::getUser()->email && $this->email != WCF::getUser()->newEmail) { if (REGISTER_ACTIVATION_METHOD == 0 || REGISTER_ACTIVATION_METHOD == 2 || mb_strtolower($this->email) == mb_strtolower(WCF::getUser()->email)) { // update email $updateParameters['email'] = $this->email; $success[] = 'wcf.user.changeEmail.success'; } else { if (REGISTER_ACTIVATION_METHOD == 1) { // get reactivation code $activationCode = UserRegistrationUtil::getActivationCode(); // save as new email $updateParameters['reactivationCode'] = $activationCode; $updateParameters['newEmail'] = $this->email; $messageData = array('username' => WCF::getUser()->username, 'userID' => WCF::getUser()->userID, 'activationCode' => $activationCode); $mail = new Mail(array(WCF::getUser()->username => $this->email), WCF::getLanguage()->getDynamicVariable('wcf.user.changeEmail.needReactivation.mail.subject'), WCF::getLanguage()->getDynamicVariable('wcf.user.changeEmail.needReactivation.mail', $messageData)); $mail->send(); $success[] = 'wcf.user.changeEmail.needReactivation'; } } } // password if (!WCF::getUser()->authData) { if (!empty($this->newPassword) || !empty($this->confirmNewPassword)) { $updateParameters['password'] = $this->newPassword; $success[] = 'wcf.user.changePassword.success'; } } // 3rdParty if (GITHUB_PUBLIC_KEY !== '' && GITHUB_PRIVATE_KEY !== '') { if ($this->githubConnect && WCF::getSession()->getVar('__githubToken')) { $updateParameters['authData'] = 'github:' . WCF::getSession()->getVar('__githubToken'); $success[] = 'wcf.user.3rdparty.github.connect.success'; WCF::getSession()->unregister('__githubToken'); WCF::getSession()->unregister('__githubUsername'); } } if ($this->githubDisconnect && StringUtil::startsWith(WCF::getUser()->authData, 'github:')) { $updateParameters['authData'] = ''; $success[] = 'wcf.user.3rdparty.github.disconnect.success'; } if (TWITTER_PUBLIC_KEY !== '' && TWITTER_PRIVATE_KEY !== '') { if ($this->twitterConnect && WCF::getSession()->getVar('__twitterData')) { $twitterData = WCF::getSession()->getVar('__twitterData'); $updateParameters['authData'] = 'twitter:' . $twitterData['user_id']; $success[] = 'wcf.user.3rdparty.twitter.connect.success'; WCF::getSession()->unregister('__twitterData'); WCF::getSession()->unregister('__twitterUsername'); } } if ($this->twitterDisconnect && StringUtil::startsWith(WCF::getUser()->authData, 'twitter:')) { $updateParameters['authData'] = ''; $success[] = 'wcf.user.3rdparty.twitter.disconnect.success'; } if (FACEBOOK_PUBLIC_KEY !== '' && FACEBOOK_PRIVATE_KEY !== '') { if ($this->facebookConnect && WCF::getSession()->getVar('__facebookData')) { $facebookData = WCF::getSession()->getVar('__facebookData'); $updateParameters['authData'] = 'facebook:' . $facebookData['id']; $success[] = 'wcf.user.3rdparty.facebook.connect.success'; WCF::getSession()->unregister('__facebookData'); WCF::getSession()->unregister('__facebookUsername'); } } if ($this->facebookDisconnect && StringUtil::startsWith(WCF::getUser()->authData, 'facebook:')) { $updateParameters['authData'] = ''; $success[] = 'wcf.user.3rdparty.facebook.disconnect.success'; } if (GOOGLE_PUBLIC_KEY !== '' && GOOGLE_PRIVATE_KEY !== '') { if ($this->googleConnect && WCF::getSession()->getVar('__googleData')) { $googleData = WCF::getSession()->getVar('__googleData'); $updateParameters['authData'] = 'google:' . $googleData['id']; $success[] = 'wcf.user.3rdparty.google.connect.success'; WCF::getSession()->unregister('__googleData'); WCF::getSession()->unregister('__googleUsername'); } } if ($this->googleDisconnect && StringUtil::startsWith(WCF::getUser()->authData, 'google:')) { $updateParameters['authData'] = ''; $success[] = 'wcf.user.3rdparty.google.disconnect.success'; } $data = array(); if (!empty($updateParameters) || !empty($this->additionalFields)) { $data['data'] = array_merge($this->additionalFields, $updateParameters); } $this->objectAction = new UserAction(array(WCF::getUser()), 'update', $data); $this->objectAction->executeAction(); // update cookie if (isset($_COOKIE[COOKIE_PREFIX . 'password']) && isset($updateParameters['password'])) { // reload user $user = new User(WCF::getUser()->userID); HeaderUtil::setCookie('password', PasswordUtil::getSaltedHash($updateParameters['password'], $user->password), TIME_NOW + 365 * 24 * 3600); } $this->saved(); $success = array_merge($success, WCF::getTPL()->get('success') ?: array()); // show success message WCF::getTPL()->assign('success', $success); // reset password $this->password = ''; $this->newPassword = $this->confirmNewPassword = ''; }
/** * @see wcf\system\user\authentication\IUserAuthentication::storeAccessData() */ public function storeAccessData(User $user, $username, $password) { HeaderUtil::setCookie('userID', $user->userID, TIME_NOW + 365 * 24 * 3600); HeaderUtil::setCookie('password', PasswordUtil::getSaltedHash($password, $user->password), TIME_NOW + 365 * 24 * 3600); }
/** * Validates the given security token, returns false if * given token is invalid. * * @param string $token * @return boolean */ public function checkSecurityToken($token) { return PasswordUtil::secureCompare($this->getSecurityToken(), $token); }
/** * @see wcf\page\IPage::assignVariables() */ public function assignVariables() { parent::assignVariables(); WCF::getTPL()->assign(array( 'confirmMasterPassword' => $this->confirmMasterPassword, 'exampleMasterPassword' => PasswordUtil::getRandomPassword(12) )); }
/** * Returns true if the given password hash from a cookie is the correct password for this user. * * @param string $passwordHash * @return boolean password correct */ public function checkCookiePassword($passwordHash) { if (PasswordUtil::isBlowfish($this->password) && PasswordUtil::secureCompare($this->password, PasswordUtil::getSaltedHash($passwordHash, $this->password))) { return true; } return false; }
/** * Exports users. */ public function exportUsers($offset, $limit) { // prepare password update $sql = "UPDATE\twcf" . WCF_N . "_user\n\t\t\tSET\tpassword = ?\n\t\t\tWHERE\tuserID = ?"; $passwordUpdateStatement = WCF::getDB()->prepareStatement($sql); $userIDs = $this->database->zrange('users:joindate', $offset, $offset + $limit); if (!$userIDs) { throw new SystemException('Could not fetch userIDs'); } foreach ($userIDs as $userID) { $row = $this->database->hgetall('user:'******'Invalid user'); } $data = array('username' => $row['username'], 'password' => '', 'email' => $row['email'], 'registrationDate' => intval($row['joindate'] / 1000), 'banned' => $row['banned'] ? 1 : 0, 'banReason' => '', 'lastActivityTime' => intval($row['lastonline'] / 1000), 'signature' => self::convertMarkdown($row['signature'])); static $gravatarRegex = null; if ($gravatarRegex === null) { $gravatarRegex = new Regex('https://(?:secure\\.)?gravatar\\.com/avatar/([a-f0-9]{32})'); } if ($gravatarRegex->match($row['picture'])) { $matches = $gravatarRegex->getMatches(); if ($matches[1] === md5($row['email'])) { $data['enableGravatar'] = 1; } } $birthday = \DateTime::createFromFormat('m/d/Y', StringUtil::decodeHTML($row['birthday'])); // get user options $options = array('birthday' => $birthday ? $birthday->format('Y-m-d') : '', 'homepage' => StringUtil::decodeHTML($row['website']), 'location' => StringUtil::decodeHTML($row['location'])); $additionalData = array('options' => $options); $newUserID = ImportHandler::getInstance()->getImporter('com.woltlab.wcf.user')->import($row['uid'], $data, $additionalData); // update password hash if ($newUserID) { $password = PasswordUtil::getSaltedHash($row['password'], $row['password']); $passwordUpdateStatement->execute(array($password, $newUserID)); } } }
/** * Exports users. */ public function exportUsers($offset, $limit) { // prepare password update $sql = "UPDATE\twcf" . WCF_N . "_user\n\t\t\tSET\tpassword = ?\n\t\t\tWHERE\tuserID = ?"; $passwordUpdateStatement = WCF::getDB()->prepareStatement($sql); // get users $sql = "SELECT\t\tuser_table.*, user_profile_table.*, INET_NTOA(ip_table.ip) AS ip,\n\t\t\t\t\tauthenticate_table.scheme_class, authenticate_table.data AS passwordData,\n\t\t\t\t\tlanguage_table.language_code\n\t\t\tFROM\t\txf_user user_table\n\t\t\tLEFT JOIN\txf_user_profile user_profile_table\n\t\t\tON\t\tuser_table.user_id = user_profile_table.user_id\n\t\t\tLEFT JOIN\txf_user_authenticate authenticate_table\n\t\t\tON\t\tuser_table.user_id = authenticate_table.user_id\n\t\t\tLEFT JOIN\txf_language language_table\n\t\t\tON\t\tuser_table.language_id = language_table.language_id\n\t\t\tLEFT JOIN\txf_ip ip_table\n\t\t\tON\t\tuser_table.user_id = ip_table.user_id\n\t\t\t\t\tAND content_type = ?\n\t\t\t\t\tAND action = ?\n\t\t\tWHERE\t\tuser_table.user_id BETWEEN ? AND ?\n\t\t\tORDER BY\tuser_table.user_id"; $statement = $this->database->prepareStatement($sql); $statement->execute(array('user', 'register', $offset + 1, $offset + $limit)); while ($row = $statement->fetchArray()) { $data = array('username' => $row['username'], 'password' => '', 'email' => $row['email'], 'registrationDate' => $row['register_date'], 'banned' => $row['is_banned'] ? 1 : 0, 'banReason' => '', 'registrationIpAddress' => $row['ip'] ? UserUtil::convertIPv4To6($row['ip']) : '', 'signature' => self::fixBBCodes($row['signature']), 'signatureEnableBBCodes' => 1, 'signatureEnableHtml' => 0, 'signatureEnableSmilies' => 1, 'lastActivityTime' => $row['last_activity']); $options = array('location' => $row['location'], 'occupation' => $row['occupation'], 'homepage' => $row['homepage'], 'aboutMe' => self::fixBBCodes($row['about']), 'birthday' => $row['dob_year'] . '-' . $row['dob_month'] . '-' . $row['dob_day']); $customFields = unserialize($row['custom_fields']); if ($customFields) { foreach ($customFields as $key => $value) { if (in_array($key, self::$knownProfileFields)) { $options[$key] = $value; continue; } $options[hexdec(substr(sha1($key), 0, 7))] = $value; } } $languageCode = ''; $countryCode = ''; if ($row['language_code']) { list($languageCode, $countryCode) = explode('-', $row['language_code'], 2); } $additionalData = array('groupIDs' => explode(',', $row['secondary_group_ids'] . ',' . $row['user_group_id']), 'languages' => array($languageCode), 'options' => $options); // import user $newUserID = ImportHandler::getInstance()->getImporter('com.woltlab.wcf.user')->import($row['user_id'], $data, $additionalData); // update password hash if ($newUserID) { $passwordData = unserialize($row['passwordData']); switch ($row['scheme_class']) { case 'XenForo_Authentication_Core12': $password = PasswordUtil::getSaltedHash($passwordData['hash'], $passwordData['hash']); break; case 'XenForo_Authentication_Core': $password = '******' . $passwordData['hash'] . ':' . $passwordData['salt']; break; case 'XenForo_Authentication_MyBb': $password = '******' . $passwordData['hash'] . ':' . $passwordData['salt']; break; case 'XenForo_Authentication_IPBoard': $password = '******' . $passwordData['hash'] . ':' . $passwordData['salt']; break; case 'XenForo_Authentication_vBulletin': $password = '******' . $passwordData['hash'] . ':' . $passwordData['salt']; break; case 'XenForo_Authentication_PhpBb3': $password = '******' . $passwordData['hash'] . ':'; break; case 'XenForo_Authentication_NoPassword': $password = '******'; break; } $passwordUpdateStatement->execute(array($password, $newUserID)); } } }
/** * Exports users. */ public function exportUsers($offset, $limit) { // prepare password update $sql = "UPDATE\twcf" . WCF_N . "_user\n\t\t\tSET\tpassword = ?\n\t\t\tWHERE\tuserID = ?"; $passwordUpdateStatement = WCF::getDB()->prepareStatement($sql); // get users $sql = "SELECT\t\tkunena_users.*, users.*,\n\t\t\t\t\t(\n\t\t\t\t\t\tSELECT\tGROUP_CONCAT(user_usergroup_map.group_id)\n\t\t\t\t\t\tFROM\t" . $this->databasePrefix . "user_usergroup_map user_usergroup_map\n\t\t\t\t\t\tWHERE\tuser_usergroup_map.user_id = kunena_users.userid\n\t\t\t\t\t) AS groupIDs\n\t\t\tFROM\t\t" . $this->databasePrefix . "kunena_users kunena_users,\n\t\t\t\t\t" . $this->databasePrefix . "users users\n\t\t\tWHERE\t\tusers.id = kunena_users.userid\n\t\t\tORDER BY\tkunena_users.userid"; $statement = $this->database->prepareStatement($sql, $limit, $offset); $statement->execute(); while ($row = $statement->fetchArray()) { $data = array('username' => $row['username'], 'password' => StringUtil::getRandomID(), 'email' => $row['email'], 'banned' => $row['banned'] ? 1 : 0, 'registrationDate' => @strtotime($row['registerDate']), 'lastActivityTime' => @strtotime($row['lastvisitDate']), 'signature' => self::fixBBCodes($row['signature'])); // get user options $options = array('location' => $row['location'], 'birthday' => $row['birthdate'], 'icq' => $row['icq'], 'skype' => $row['skype'], 'homepage' => $row['websiteurl'], 'gender' => $row['gender']); $additionalData = array('groupIDs' => explode(',', $row['groupIDs']), 'options' => $options); // import user $newUserID = ImportHandler::getInstance()->getImporter('com.woltlab.wcf.user')->import($row['userid'], $data, $additionalData); // update password hash if ($newUserID) { $password = '******' . $row['password']; if (substr($row['password'], 0, 3) == '$1$') { $password = '******' . $row['password']; } else { if (substr($row['password'], 0, 4) == '$2y$' || substr($row['password'], 0, 4) == '$2a$') { $password = PasswordUtil::getSaltedHash($row['password'], $row['password']); } else { if (substr($row['password'], 0, 3) == '$P$') { $password = '******' . $row['password']; } } } $passwordUpdateStatement->execute(array($password, $newUserID)); } } }
/** * @see \wcf\form\IForm::save() */ public function save() { parent::save(); // generate new password $this->newPassword = PasswordUtil::getRandomPassword(REGISTER_PASSWORD_MIN_LENGTH > 12 ? REGISTER_PASSWORD_MIN_LENGTH : 12); // update user $this->objectAction = new UserAction(array($this->user), 'update', array('data' => array_merge($this->additionalFields, array('password' => $this->newPassword, 'lastLostPasswordRequestTime' => 0, 'lostPasswordKey' => '')))); $this->objectAction->executeAction(); // send mail $mail = new Mail(array($this->user->username => $this->user->email), WCF::getLanguage()->getDynamicVariable('wcf.user.newPassword.mail.subject'), WCF::getLanguage()->getDynamicVariable('wcf.user.newPassword.mail', array('username' => $this->user->username, 'userID' => $this->user->userID, 'newPassword' => $this->newPassword))); $mail->send(); $this->saved(); // forward to index page HeaderUtil::delayedRedirect(LinkHandler::getInstance()->getLink(), WCF::getLanguage()->get('wcf.user.newPassword.success')); exit; }
/** * Exports users. */ public function exportUsers($offset, $limit) { // prepare password update $sql = "UPDATE\twcf" . WCF_N . "_user\n\t\t\tSET\tpassword = ?\n\t\t\tWHERE\tuserID = ?"; $passwordUpdateStatement = WCF::getDB()->prepareStatement($sql); // get users $sql = "SELECT\t\tuser_table.*, textfield.*, useractivation.type AS activationType, useractivation.emailchange, userban.liftdate, userban.reason AS banReason\n\t\t\tFROM\t\t" . $this->databasePrefix . "user user_table\n\t\t\tLEFT JOIN\t" . $this->databasePrefix . "usertextfield textfield\n\t\t\tON\t\tuser_table.userid = textfield.userid\n\t\t\tLEFT JOIN\t" . $this->databasePrefix . "useractivation useractivation\n\t\t\tON\t\tuser_table.userid = useractivation.userid\n\t\t\tLEFT JOIN\t" . $this->databasePrefix . "userban userban\n\t\t\tON\t\tuser_table.userid = userban.userid\n\t\t\tWHERE\t\tuser_table.userid BETWEEN ? AND ?\n\t\t\tORDER BY\tuser_table.userid"; $statement = $this->database->prepareStatement($sql); $statement->execute(array($offset + 1, $offset + $limit)); while ($row = $statement->fetchArray()) { $data = array('username' => $row['username'], 'password' => '', 'email' => $row['email'], 'registrationDate' => $row['joindate'], 'banned' => $row['liftdate'] !== null && $row['liftdate'] == 0 ? 1 : 0, 'banReason' => $row['banReason'], 'activationCode' => $row['activationType'] !== null && $row['activationType'] == 0 && $row['emailchange'] == 0 ? UserRegistrationUtil::getActivationCode() : 0, 'oldUsername' => '', 'registrationIpAddress' => UserUtil::convertIPv4To6($row['ipaddress']), 'signature' => $row['signature'], 'userTitle' => $row['customtitle'] != 0 ? $row['usertitle'] : '', 'lastActivityTime' => $row['lastactivity']); $additionalData = array('groupIDs' => explode(',', $row['membergroupids'] . ',' . $row['usergroupid']), 'options' => array()); // import user $newUserID = ImportHandler::getInstance()->getImporter('com.woltlab.wcf.user')->import($row['userid'], $data, $additionalData); // update password hash if ($newUserID) { if (StringUtil::startsWith($row['scheme'], 'blowfish')) { $password = PasswordUtil::getSaltedHash($row['token'], $row['token']); } else { if ($row['scheme'] == 'legacy') { $password = '******' . implode(':', explode(' ', $row['token'], 2)); } } $passwordUpdateStatement->execute(array($password, $newUserID)); } } }