本文整理汇总了PHP中phutil_hashes_are_identical函数的典型用法代码示例。如果您正苦于以下问题:PHP phutil_hashes_are_identical函数的具体用法?PHP phutil_hashes_are_identical怎么用?PHP phutil_hashes_are_identical使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了phutil_hashes_are_identical函数的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: validateSender
public function validateSender(PhabricatorMetaMTAReceivedMail $mail, PhabricatorUser $sender)
{
parent::validateSender($mail, $sender);
$parts = $this->matchObjectAddressInMail($mail);
$pattern = $parts['pattern'];
try {
$object = $this->loadObjectFromMail($mail, $sender);
} catch (PhabricatorPolicyException $policy_exception) {
throw new PhabricatorMetaMTAReceivedMailProcessingException(MetaMTAReceivedMailStatus::STATUS_POLICY_PROBLEM, pht('This mail is addressed to an object ("%s") you do not have ' . 'permission to see: %s', $pattern, $policy_exception->getMessage()));
}
if (!$object) {
throw new PhabricatorMetaMTAReceivedMailProcessingException(MetaMTAReceivedMailStatus::STATUS_NO_SUCH_OBJECT, pht('This mail is addressed to an object ("%s"), but that object ' . 'does not exist.', $pattern));
}
$sender_identifier = $parts['sender'];
if ($sender_identifier === 'public') {
if (!PhabricatorEnv::getEnvConfig('metamta.public-replies')) {
throw new PhabricatorMetaMTAReceivedMailProcessingException(MetaMTAReceivedMailStatus::STATUS_NO_PUBLIC_MAIL, pht('This mail is addressed to the public email address of an object ' . '("%s"), but public replies are not enabled on this Phabricator ' . 'install. An administrator may have recently disabled this ' . 'setting, or you may have replied to an old message. Try ' . 'replying to a more recent message instead.', $pattern));
}
$check_phid = $object->getPHID();
} else {
if ($sender_identifier != $sender->getID()) {
throw new PhabricatorMetaMTAReceivedMailProcessingException(MetaMTAReceivedMailStatus::STATUS_USER_MISMATCH, pht('This mail is addressed to the private email address of an object ' . '("%s"), but you are not the user who is authorized to use the ' . 'address you sent mail to. Each private address is unique to the ' . 'user who received the original mail. Try replying to a message ' . 'which was sent directly to you instead.', $pattern));
}
$check_phid = $sender->getPHID();
}
$expect_hash = self::computeMailHash($object->getMailKey(), $check_phid);
if (!phutil_hashes_are_identical($expect_hash, $parts['hash'])) {
throw new PhabricatorMetaMTAReceivedMailProcessingException(MetaMTAReceivedMailStatus::STATUS_HASH_MISMATCH, pht('This mail is addressed to an object ("%s"), but the address is ' . 'not correct (the security hash is wrong). Check that the address ' . 'is correct.', $pattern));
}
}
示例2: execute
protected function execute(ConduitAPIRequest $request)
{
$client = $request->getValue('client');
$client_version = (int) $request->getValue('clientVersion');
$client_description = (string) $request->getValue('clientDescription');
$client_description = id(new PhutilUTF8StringTruncator())->setMaximumBytes(255)->truncateString($client_description);
$username = (string) $request->getValue('user');
// Log the connection, regardless of the outcome of checks below.
$connection = new PhabricatorConduitConnectionLog();
$connection->setClient($client);
$connection->setClientVersion($client_version);
$connection->setClientDescription($client_description);
$connection->setUsername($username);
$connection->save();
switch ($client) {
case 'arc':
$server_version = 6;
$supported_versions = array($server_version => true, 4 => true, 5 => true);
if (empty($supported_versions[$client_version])) {
if ($server_version < $client_version) {
$ex = new ConduitException('ERR-BAD-VERSION');
$ex->setErrorDescription(pht("Your '%s' client version is '%d', which is newer than the " . "server version, '%d'. Upgrade your Phabricator install.", 'arc', $client_version, $server_version));
} else {
$ex = new ConduitException('NEW-ARC-VERSION');
$ex->setErrorDescription(pht('A new version of arc is available! You need to upgrade ' . 'to connect to this server (you are running version ' . '%d, the server is running version %d).', $client_version, $server_version));
}
throw $ex;
}
break;
default:
// Allow new clients by default.
break;
}
$token = $request->getValue('authToken');
$signature = $request->getValue('authSignature');
$user = id(new PhabricatorUser())->loadOneWhere('username = %s', $username);
if (!$user) {
throw new ConduitException('ERR-INVALID-USER');
}
$session_key = null;
if ($token && $signature) {
$threshold = 60 * 15;
$now = time();
if (abs($token - $now) > $threshold) {
throw id(new ConduitException('ERR-INVALID-TOKEN'))->setErrorDescription(pht('The request you submitted is signed with a timestamp, but that ' . 'timestamp is not within %s of the current time. The ' . 'signed timestamp is %s (%s), and the current server time is ' . '%s (%s). This is a difference of %s seconds, but the ' . 'timestamp must differ from the server time by no more than ' . '%s seconds. Your client or server clock may not be set ' . 'correctly.', phutil_format_relative_time($threshold), $token, date('r', $token), $now, date('r', $now), $token - $now, $threshold));
}
$valid = sha1($token . $user->getConduitCertificate());
if (!phutil_hashes_are_identical($valid, $signature)) {
throw new ConduitException('ERR-INVALID-CERTIFICATE');
}
$session_key = id(new PhabricatorAuthSessionEngine())->establishSession(PhabricatorAuthSession::TYPE_CONDUIT, $user->getPHID(), $partial = false);
} else {
throw new ConduitException('ERR-NO-CERTIFICATE');
}
return array('connectionID' => $connection->getID(), 'sessionKey' => $session_key, 'userPHID' => $user->getPHID());
}
示例3: verifyMessage
private function verifyMessage()
{
$api_key = PhabricatorEnv::getEnvConfig('mailgun.api-key');
$request = $this->getRequest();
$timestamp = $request->getStr('timestamp');
$token = $request->getStr('token');
$sig = $request->getStr('signature');
$hash = hash_hmac('sha256', $timestamp . $token, $api_key);
return phutil_hashes_are_identical($sig, $hash);
}
示例4: processRequest
public function processRequest(AphrontRequest $request)
{
$viewer = $request->getUser();
$accounts = id(new PhabricatorExternalAccountQuery())->setViewer($viewer)->withUserPHIDs(array($viewer->getPHID()))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->execute();
$identity_phids = mpull($accounts, 'getPHID');
$identity_phids[] = $viewer->getPHID();
$sessions = id(new PhabricatorAuthSessionQuery())->setViewer($viewer)->withIdentityPHIDs($identity_phids)->execute();
$handles = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs($identity_phids)->execute();
$current_key = PhabricatorHash::digest($request->getCookie(PhabricatorCookies::COOKIE_SESSION));
$rows = array();
$rowc = array();
foreach ($sessions as $session) {
$is_current = phutil_hashes_are_identical($session->getSessionKey(), $current_key);
if ($is_current) {
$rowc[] = 'highlighted';
$button = phutil_tag('a', array('class' => 'small grey button disabled'), pht('Current'));
} else {
$rowc[] = null;
$button = javelin_tag('a', array('href' => '/auth/session/terminate/' . $session->getID() . '/', 'class' => 'small grey button', 'sigil' => 'workflow'), pht('Terminate'));
}
$hisec = $session->getHighSecurityUntil() - time();
$rows[] = array($handles[$session->getUserPHID()]->renderLink(), substr($session->getSessionKey(), 0, 6), $session->getType(), $hisec > 0 ? phutil_format_relative_time($hisec) : null, phabricator_datetime($session->getSessionStart(), $viewer), phabricator_date($session->getSessionExpires(), $viewer), $button);
}
$table = new AphrontTableView($rows);
$table->setNoDataString(pht("You don't have any active sessions."));
$table->setRowClasses($rowc);
$table->setHeaders(array(pht('Identity'), pht('Session'), pht('Type'), pht('HiSec'), pht('Created'), pht('Expires'), pht('')));
$table->setColumnClasses(array('wide', 'n', '', 'right', 'right', 'right', 'action'));
$terminate_icon = id(new PHUIIconView())->setIconFont('fa-exclamation-triangle');
$terminate_button = id(new PHUIButtonView())->setText(pht('Terminate All Sessions'))->setHref('/auth/session/terminate/all/')->setTag('a')->setWorkflow(true)->setIcon($terminate_icon);
$header = id(new PHUIHeaderView())->setHeader(pht('Active Login Sessions'))->addActionLink($terminate_button);
$hisec = $viewer->getSession()->getHighSecurityUntil() - time();
if ($hisec > 0) {
$hisec_icon = id(new PHUIIconView())->setIconFont('fa-lock');
$hisec_button = id(new PHUIButtonView())->setText(pht('Leave High Security'))->setHref('/auth/session/downgrade/')->setTag('a')->setWorkflow(true)->setIcon($hisec_icon);
$header->addActionLink($hisec_button);
}
$panel = id(new PHUIObjectBoxView())->setHeader($header)->setTable($table);
return $panel;
}
示例5: handleRequest
public function handleRequest(AphrontRequest $request)
{
$viewer = $this->getViewer();
$id = $request->getURIData('id');
$is_all = $id === 'all';
$query = id(new PhabricatorAuthSessionQuery())->setViewer($viewer)->withIdentityPHIDs(array($viewer->getPHID()));
if (!$is_all) {
$query->withIDs(array($id));
}
$current_key = PhabricatorHash::digest($request->getCookie(PhabricatorCookies::COOKIE_SESSION));
$sessions = $query->execute();
foreach ($sessions as $key => $session) {
$is_current = phutil_hashes_are_identical($session->getSessionKey(), $current_key);
if ($is_current) {
// Don't terminate the current login session.
unset($sessions[$key]);
}
}
$panel_uri = '/settings/panel/sessions/';
if (!$sessions) {
return $this->newDialog()->setTitle(pht('No Matching Sessions'))->appendParagraph(pht('There are no matching sessions to terminate.'))->appendParagraph(pht('(You can not terminate your current login session. To ' . 'terminate it, log out.)'))->addCancelButton($panel_uri);
}
if ($request->isDialogFormPost()) {
foreach ($sessions as $session) {
$session->delete();
}
return id(new AphrontRedirectResponse())->setURI($panel_uri);
}
if ($is_all) {
$title = pht('Terminate Sessions?');
$short = pht('Terminate Sessions');
$body = pht('Really terminate all sessions? (Your current login session will ' . 'not be terminated.)');
} else {
$title = pht('Terminate Session?');
$short = pht('Terminate Session');
$body = pht('Really terminate session %s?', phutil_tag('strong', array(), substr($session->getSessionKey(), 0, 6)));
}
return $this->newDialog()->setTitle($title)->setShortTitle($short)->appendParagraph($body)->addSubmitButton(pht('Terminate'))->addCancelButton($panel_uri);
}
示例6: authenticateUser
//.........这里部分代码省略.........
return array('ERR-INVALID-AUTH', pht('Provided "%s" ("%s") is not recognized.', 'auth.type', $auth_type));
}
}
$token_string = idx($metadata, 'token');
if (strlen($token_string)) {
if (strlen($token_string) != 32) {
return array('ERR-INVALID-AUTH', pht('API token "%s" has the wrong length. API tokens should be ' . '32 characters long.', $token_string));
}
$type = head(explode('-', $token_string));
$valid_types = PhabricatorConduitToken::getAllTokenTypes();
$valid_types = array_fuse($valid_types);
if (empty($valid_types[$type])) {
return array('ERR-INVALID-AUTH', pht('API token "%s" has the wrong format. API tokens should be ' . '32 characters long and begin with one of these prefixes: %s.', $token_string, implode(', ', $valid_types)));
}
$token = id(new PhabricatorConduitTokenQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withTokens(array($token_string))->withExpired(false)->executeOne();
if (!$token) {
$token = id(new PhabricatorConduitTokenQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withTokens(array($token_string))->withExpired(true)->executeOne();
if ($token) {
return array('ERR-INVALID-AUTH', pht('API token "%s" was previously valid, but has expired.', $token_string));
} else {
return array('ERR-INVALID-AUTH', pht('API token "%s" is not valid.', $token_string));
}
}
// If this is a "cli-" token, it expires shortly after it is generated
// by default. Once it is actually used, we extend its lifetime and make
// it permanent. This allows stray tokens to get cleaned up automatically
// if they aren't being used.
if ($token->getTokenType() == PhabricatorConduitToken::TYPE_COMMANDLINE) {
if ($token->getExpires()) {
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
$token->setExpires(null);
$token->save();
unset($unguarded);
}
}
// If this is a "clr-" token, Phabricator must be configured in cluster
// mode and the remote address must be a cluster node.
if ($token->getTokenType() == PhabricatorConduitToken::TYPE_CLUSTER) {
if (!PhabricatorEnv::isClusterRemoteAddress()) {
return array('ERR-INVALID-AUTH', pht('This request originates from outside of the Phabricator ' . 'cluster address range. Requests signed with cluster API ' . 'tokens must originate from within the cluster.'));
}
// Flag this as an intracluster request.
$api_request->setIsClusterRequest(true);
}
$user = $token->getObject();
if (!$user instanceof PhabricatorUser) {
return array('ERR-INVALID-AUTH', pht('API token is not associated with a valid user.'));
}
return $this->validateAuthenticatedUser($api_request, $user);
}
// handle oauth
$access_token = idx($metadata, 'access_token');
$method_scope = idx($metadata, 'scope');
if ($access_token && $method_scope != PhabricatorOAuthServerScope::SCOPE_NOT_ACCESSIBLE) {
$token = id(new PhabricatorOAuthServerAccessToken())->loadOneWhere('token = %s', $access_token);
if (!$token) {
return array('ERR-INVALID-AUTH', pht('Access token does not exist.'));
}
$oauth_server = new PhabricatorOAuthServer();
$valid = $oauth_server->validateAccessToken($token, $method_scope);
if (!$valid) {
return array('ERR-INVALID-AUTH', pht('Access token is invalid.'));
}
// valid token, so let's log in the user!
$user_phid = $token->getUserPHID();
$user = id(new PhabricatorUser())->loadOneWhere('phid = %s', $user_phid);
if (!$user) {
return array('ERR-INVALID-AUTH', pht('Access token is for invalid user.'));
}
return $this->validateAuthenticatedUser($api_request, $user);
}
// Handle sessionless auth.
// TODO: This is super messy.
// TODO: Remove this in favor of token-based auth.
if (isset($metadata['authUser'])) {
$user = id(new PhabricatorUser())->loadOneWhere('userName = %s', $metadata['authUser']);
if (!$user) {
return array('ERR-INVALID-AUTH', pht('Authentication is invalid.'));
}
$token = idx($metadata, 'authToken');
$signature = idx($metadata, 'authSignature');
$certificate = $user->getConduitCertificate();
$hash = sha1($token . $certificate);
if (!phutil_hashes_are_identical($hash, $signature)) {
return array('ERR-INVALID-AUTH', pht('Authentication is invalid.'));
}
return $this->validateAuthenticatedUser($api_request, $user);
}
// Handle session-based auth.
// TODO: Remove this in favor of token-based auth.
$session_key = idx($metadata, 'sessionKey');
if (!$session_key) {
return array('ERR-INVALID-SESSION', pht('Session key is not present.'));
}
$user = id(new PhabricatorAuthSessionEngine())->loadUserForSession(PhabricatorAuthSession::TYPE_CONDUIT, $session_key);
if (!$user) {
return array('ERR-INVALID-SESSION', pht('Session key is invalid.'));
}
return $this->validateAuthenticatedUser($api_request, $user);
}
示例7: verifyAuthCSRFCode
protected function verifyAuthCSRFCode(AphrontRequest $request, $actual)
{
$expect = $this->getAuthCSRFCode($request);
if (!strlen($actual)) {
throw new Exception(pht('The authentication provider did not return a client state ' . 'parameter in its response, but one was expected. If this ' . 'problem persists, you may need to clear your cookies.'));
}
if (!phutil_hashes_are_identical($actual, $expect)) {
throw new Exception(pht('The authentication provider did not return the correct client ' . 'state parameter in its response. If this problem persists, you may ' . 'need to clear your cookies.'));
}
}
示例8: terminateLoginSessions
/**
* Terminate all of a user's login sessions.
*
* This is used when users change passwords, linked accounts, or add
* multifactor authentication.
*
* @param PhabricatorUser User whose sessions should be terminated.
* @param string|null Optionally, one session to keep. Normally, the current
* login session.
*
* @return void
*/
public function terminateLoginSessions(PhabricatorUser $user, $except_session = null)
{
$sessions = id(new PhabricatorAuthSessionQuery())->setViewer($user)->withIdentityPHIDs(array($user->getPHID()))->execute();
if ($except_session !== null) {
$except_session = PhabricatorHash::digest($except_session);
}
foreach ($sessions as $key => $session) {
if ($except_session !== null) {
$is_except = phutil_hashes_are_identical($session->getSessionKey(), $except_session);
if ($is_except) {
continue;
}
}
$session->delete();
}
}
示例9: loadAccountForRegistrationOrLinking
protected function loadAccountForRegistrationOrLinking($account_key)
{
$request = $this->getRequest();
$viewer = $request->getUser();
$account = null;
$provider = null;
$response = null;
if (!$account_key) {
$response = $this->renderError(pht('Request did not include account key.'));
return array($account, $provider, $response);
}
// NOTE: We're using the omnipotent user because the actual user may not
// be logged in yet, and because we want to tailor an error message to
// distinguish between "not usable" and "does not exist". We do explicit
// checks later on to make sure this account is valid for the intended
// operation. This requires edit permission for completeness and consistency
// but it won't actually be meaningfully checked because we're using the
// ominpotent user.
$account = id(new PhabricatorExternalAccountQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withAccountSecrets(array($account_key))->needImages(true)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
if (!$account) {
$response = $this->renderError(pht('No valid linkable account.'));
return array($account, $provider, $response);
}
if ($account->getUserPHID()) {
if ($account->getUserPHID() != $viewer->getPHID()) {
$response = $this->renderError(pht('The account you are attempting to register or link is already ' . 'linked to another user.'));
} else {
$response = $this->renderError(pht('The account you are attempting to link is already linked ' . 'to your account.'));
}
return array($account, $provider, $response);
}
$registration_key = $request->getCookie(PhabricatorCookies::COOKIE_REGISTRATION);
// NOTE: This registration key check is not strictly necessary, because
// we're only creating new accounts, not linking existing accounts. It
// might be more hassle than it is worth, especially for email.
//
// The attack this prevents is getting to the registration screen, then
// copy/pasting the URL and getting someone else to click it and complete
// the process. They end up with an account bound to credentials you
// control. This doesn't really let you do anything meaningful, though,
// since you could have simply completed the process yourself.
if (!$registration_key) {
$response = $this->renderError(pht('Your browser did not submit a registration key with the request. ' . 'You must use the same browser to begin and complete registration. ' . 'Check that cookies are enabled and try again.'));
return array($account, $provider, $response);
}
// We store the digest of the key rather than the key itself to prevent a
// theoretical attacker with read-only access to the database from
// hijacking registration sessions.
$actual = $account->getProperty('registrationKey');
$expect = PhabricatorHash::digest($registration_key);
if (!phutil_hashes_are_identical($actual, $expect)) {
$response = $this->renderError(pht('Your browser submitted a different registration key than the one ' . 'associated with this account. You may need to clear your cookies.'));
return array($account, $provider, $response);
}
$other_account = id(new PhabricatorExternalAccount())->loadAllWhere('accountType = %s AND accountDomain = %s AND accountID = %s
AND id != %d', $account->getAccountType(), $account->getAccountDomain(), $account->getAccountID(), $account->getID());
if ($other_account) {
$response = $this->renderError(pht('The account you are attempting to register with already belongs ' . 'to another user.'));
return array($account, $provider, $response);
}
$provider = PhabricatorAuthProvider::getEnabledProviderByKey($account->getProviderKey());
if (!$provider) {
$response = $this->renderError(pht('The account you are attempting to register with uses a nonexistent ' . 'or disabled authentication provider (with key "%s"). An ' . 'administrator may have recently disabled this provider.', $account->getProviderKey()));
return array($account, $provider, $response);
}
return array($account, $provider, null);
}
示例10: verifyPassword
/**
* Verify that a password matches a hash.
*
* The default implementation checks for equality; if a hasher embeds salt in
* hashes it should override this method and perform a salt-aware comparison.
*
* @param PhutilOpaqueEnvelope Password to compare.
* @param PhutilOpaqueEnvelope Bare password hash.
* @return bool True if the passwords match.
* @task hasher
*/
protected function verifyPassword(PhutilOpaqueEnvelope $password, PhutilOpaqueEnvelope $hash)
{
$actual_hash = $this->getPasswordHash($password)->openEnvelope();
$expect_hash = $hash->openEnvelope();
return phutil_hashes_are_identical($actual_hash, $expect_hash);
}
示例11: validateCSRFToken
public function validateCSRFToken($token)
{
// We expect a BREACH-mitigating token. See T3684.
$breach_prefix = self::CSRF_BREACH_PREFIX;
$breach_prelen = strlen($breach_prefix);
if (strncmp($token, $breach_prefix, $breach_prelen) !== 0) {
return false;
}
$salt = substr($token, $breach_prelen, self::CSRF_SALT_LENGTH);
$token = substr($token, $breach_prelen + self::CSRF_SALT_LENGTH);
// When the user posts a form, we check that it contains a valid CSRF token.
// Tokens cycle each hour (every CSRF_CYLCE_FREQUENCY seconds) and we accept
// either the current token, the next token (users can submit a "future"
// token if you have two web frontends that have some clock skew) or any of
// the last 6 tokens. This means that pages are valid for up to 7 hours.
// There is also some Javascript which periodically refreshes the CSRF
// tokens on each page, so theoretically pages should be valid indefinitely.
// However, this code may fail to run (if the user loses their internet
// connection, or there's a JS problem, or they don't have JS enabled).
// Choosing the size of the window in which we accept old CSRF tokens is
// an issue of balancing concerns between security and usability. We could
// choose a very narrow (e.g., 1-hour) window to reduce vulnerability to
// attacks using captured CSRF tokens, but it's also more likely that real
// users will be affected by this, e.g. if they close their laptop for an
// hour, open it back up, and try to submit a form before the CSRF refresh
// can kick in. Since the user experience of submitting a form with expired
// CSRF is often quite bad (you basically lose data, or it's a big pain to
// recover at least) and I believe we gain little additional protection
// by keeping the window very short (the overwhelming value here is in
// preventing blind attacks, and most attacks which can capture CSRF tokens
// can also just capture authentication information [sniffing networks]
// or act as the user [xss]) the 7 hour default seems like a reasonable
// balance. Other major platforms have much longer CSRF token lifetimes,
// like Rails (session duration) and Django (forever), which suggests this
// is a reasonable analysis.
$csrf_window = 6;
for ($ii = -$csrf_window; $ii <= 1; $ii++) {
$valid = $this->getRawCSRFToken($ii);
$digest = PhabricatorHash::digest($valid, $salt);
$digest = substr($digest, 0, self::CSRF_TOKEN_LENGTH);
if (phutil_hashes_are_identical($digest, $token)) {
return true;
}
}
return false;
}
示例12: verifyTOTPCode
public static function verifyTOTPCode(PhabricatorUser $user, PhutilOpaqueEnvelope $key, $code)
{
// TODO: This should use rate limiting to prevent multiple attempts in a
// short period of time.
$now = (int) (time() / 30);
// Allow the user to enter a code a few minutes away on either side, in
// case the server or client has some clock skew.
for ($offset = -2; $offset <= 2; $offset++) {
$real = self::getTOTPCode($key, $now + $offset);
if (phutil_hashes_are_identical($real, $code)) {
return true;
}
}
// TODO: After validating a code, this should mark it as used and prevent
// it from being reused.
return false;
}