public function getBuiltinFileKey() { $name = $this->getName(); $desc = "disk(name={$name})"; $hash = PhabricatorHash::digestToLength($desc, 40); return "builtin:{$hash}"; }
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn); if ($this->ids !== null) { $where[] = qsprintf($conn, 'service.id IN (%Ld)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf($conn, 'service.phid IN (%Ls)', $this->phids); } if ($this->names !== null) { $hashes = array(); foreach ($this->names as $name) { $hashes[] = PhabricatorHash::digestForIndex($name); } $where[] = qsprintf($conn, 'service.nameIndex IN (%Ls)', $hashes); } if ($this->serviceTypes !== null) { $where[] = qsprintf($conn, 'service.serviceType IN (%Ls)', $this->serviceTypes); } if ($this->devicePHIDs !== null) { $where[] = qsprintf($conn, 'binding.devicePHID IN (%Ls)', $this->devicePHIDs); } if ($this->namePrefix !== null) { $where[] = qsprintf($conn, 'service.name LIKE %>', $this->namePrefix); } if ($this->nameSuffix !== null) { $where[] = qsprintf($conn, 'service.name LIKE %<', $this->nameSuffix); } return $where; }
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { $where = array(); if ($this->ids !== null) { $where[] = qsprintf($conn_r, 'id IN (%Ld)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf($conn_r, 'phid IN (%Ls)', $this->phids); } if ($this->emailAddresses !== null) { $where[] = qsprintf($conn_r, 'emailAddress IN (%Ls)', $this->emailAddresses); } if ($this->verificationCodes !== null) { $hashes = array(); foreach ($this->verificationCodes as $code) { $hashes[] = PhabricatorHash::digestForIndex($code); } $where[] = qsprintf($conn_r, 'verificationHash IN (%Ls)', $hashes); } if ($this->authorPHIDs !== null) { $where[] = qsprintf($conn_r, 'authorPHID IN (%Ls)', $this->authorPHIDs); } $where[] = $this->buildPagingClause($conn_r); return $this->formatWhereClause($where); }
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { $where = array(); if ($this->ids !== null) { $where[] = qsprintf($conn_r, 'id IN (%Ld)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf($conn_r, 'phid IN (%Ls)', $this->phids); } if ($this->names !== null) { $hashes = array(); foreach ($this->names as $name) { $hashes[] = PhabricatorHash::digestForIndex($name); } $where[] = qsprintf($conn_r, 'nameIndex IN (%Ls)', $hashes); } if ($this->namePrefix !== null) { $where[] = qsprintf($conn_r, 'name LIKE %>', $this->namePrefix); } if ($this->nameSuffix !== null) { $where[] = qsprintf($conn_r, 'name LIKE %<', $this->nameSuffix); } $where[] = $this->buildPagingClause($conn_r); return $this->formatWhereClause($where); }
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn); if ($this->ids !== null) { $where[] = qsprintf($conn, 'id IN (%Ld)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf($conn, 'phid IN (%Ls)', $this->phids); } if ($this->repositoryPHIDs !== null) { $where[] = qsprintf($conn, 'repositoryPHID IN (%Ls)', $this->repositoryPHIDs); } if ($this->refTypes !== null) { $where[] = qsprintf($conn, 'refType IN (%Ls)', $this->refTypes); } if ($this->refNames !== null) { $name_hashes = array(); foreach ($this->refNames as $name) { $name_hashes[] = PhabricatorHash::digestForIndex($name); } $where[] = qsprintf($conn, 'refNameHash IN (%Ls)', $name_hashes); } if (strlen($this->datasourceQuery)) { $where[] = qsprintf($conn, 'refNameRaw LIKE %>', $this->datasourceQuery); } return $where; }
public function setRefName($ref_raw) { $this->setRefNameRaw($ref_raw); $this->setRefNameHash(PhabricatorHash::digestForIndex($ref_raw)); $this->setRefNameEncoding($this->detectEncodingForStorage($ref_raw)); return $this; }
public static function getArtifactIndex(HarbormasterBuildTarget $target, $artifact_key) { $build = $target->getBuild(); $parts = array($build->getPHID(), $target->getBuildGeneration(), $artifact_key); $parts = implode("", $parts); return PhabricatorHash::digestForIndex($parts); }
public function getBuiltinFileKey() { $icon = $this->getIcon(); $color = $this->getColor(); $desc = "compose(icon={$icon}, color={$color})"; $hash = PhabricatorHash::digestToLength($desc, 40); return "builtin:{$hash}"; }
public function getIndexVersion($object) { $ngrams = $object->newNgrams(); $map = mpull($ngrams, 'getValue', 'getNgramKey'); ksort($map); $serialized = serialize($map); return PhabricatorHash::digestForIndex($serialized); }
public function save() { if (!$this->getVerificationHash()) { $hash = PhabricatorHash::digestForIndex($this->getVerificationCode()); $this->setVerificationHash($hash); } return parent::save(); }
private function getPasswordHashInput(PhutilOpaqueEnvelope $password, PhabricatorUser $user) { if ($user->getPHID() != $this->getUserPHID()) { throw new Exception(pht('User does not match password user PHID!')); } $raw_input = PhabricatorHash::digestPassword($password, $user->getPHID()); return new PhutilOpaqueEnvelope($raw_input); }
/** * @task markup */ public function getMarkupFieldKey($field) { if ($this->shouldUseMarkupCache($field)) { $id = $this->getID(); } else { $id = PhabricatorHash::digest($this->getMarkupText($field)); } return "phriction:{$field}:{$id}"; }
public function save() { AlmanacNames::validateName($this->getName()); $this->nameIndex = PhabricatorHash::digestForIndex($this->getName()); if (!$this->mailKey) { $this->mailKey = Filesystem::readRandomCharacters(20); } return parent::save(); }
public static function newHTTPAuthorization(PhabricatorRepository $repository, PhabricatorUser $viewer, $operation) { $lfs_user = self::HTTP_USERNAME; $lfs_pass = Filesystem::readRandomCharacters(32); $lfs_hash = PhabricatorHash::digest($lfs_pass); $ttl = PhabricatorTime::getNow() + phutil_units('1 day in seconds'); $token = id(new PhabricatorAuthTemporaryToken())->setTokenResource($repository->getPHID())->setTokenType(self::TOKENTYPE)->setTokenCode($lfs_hash)->setUserPHID($viewer->getPHID())->setTemporaryTokenProperty('lfs.operation', $operation)->setTokenExpires($ttl)->save(); $authorization_header = base64_encode($lfs_user . ':' . $lfs_pass); return 'Basic ' . $authorization_header; }
public function setSession($session) { // Store the hash of the session, not the actual session key, so that // seeing the logs doesn't compromise all the sessions which appear in // them. This just prevents casual leaks, like in a screenshot. if (strlen($session)) { $this->session = PhabricatorHash::digest($session); } return $this; }
protected function doWork() { $resource_phid = $this->getTaskDataValue('resourcePHID'); $hash = PhabricatorHash::digestForIndex($resource_phid); $lock_key = 'drydock.resource:' . $hash; $lock = PhabricatorGlobalLock::newLock($lock_key)->lock(1); $resource = $this->loadResource($resource_phid); $this->updateResource($resource); $lock->unlock(); }
/** * Digest a string into a password hash. This is similar to @{method:digest}, * but requires a salt and iterates the hash to increase cost. */ public static function digestPassword(PhutilOpaqueEnvelope $envelope, $salt) { $result = $envelope->openEnvelope(); if (!$result) { throw new Exception('Trying to digest empty password!'); } for ($ii = 0; $ii < 1000; $ii++) { $result = PhabricatorHash::digest($result, $salt); } return $result; }
public static function clearCacheForAllUsers($key) { if (PhabricatorEnv::isReadOnly()) { return; } $table = new self(); $conn_w = $table->establishConnection('w'); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); queryfx($conn_w, 'DELETE FROM %T WHERE cacheIndex = %s', $table->getTableName(), PhabricatorHash::digestForIndex($key)); unset($unguarded); }
public function save() { if ($this->getEngineClassName() === null) { throw new Exception(pht('Engine class is null.')); } // Instantiate the engine to make sure it's valid. $this->newEngine(); $serial = $this->getEngineClassName() . serialize($this->parameters); $this->queryKey = PhabricatorHash::digestForIndex($serial); return parent::save(); }
public function processAddFactorForm(AphrontFormView $form, AphrontRequest $request, PhabricatorUser $user) { $totp_token_type = PhabricatorAuthTOTPKeyTemporaryTokenType::TOKENTYPE; $key = $request->getStr('totpkey'); if (strlen($key)) { // If the user is providing a key, make sure it's a key we generated. // This raises the barrier to theoretical attacks where an attacker might // provide a known key (such attacks are already prevented by CSRF, but // this is a second barrier to overcome). // (We store and verify the hash of the key, not the key itself, to limit // how useful the data in the table is to an attacker.) $temporary_token = id(new PhabricatorAuthTemporaryTokenQuery())->setViewer($user)->withTokenResources(array($user->getPHID()))->withTokenTypes(array($totp_token_type))->withExpired(false)->withTokenCodes(array(PhabricatorHash::digest($key)))->executeOne(); if (!$temporary_token) { // If we don't have a matching token, regenerate the key below. $key = null; } } if (!strlen($key)) { $key = self::generateNewTOTPKey(); // Mark this key as one we generated, so the user is allowed to submit // a response for it. $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); id(new PhabricatorAuthTemporaryToken())->setTokenResource($user->getPHID())->setTokenType($totp_token_type)->setTokenExpires(time() + phutil_units('1 hour in seconds'))->setTokenCode(PhabricatorHash::digest($key))->save(); unset($unguarded); } $code = $request->getStr('totpcode'); $e_code = true; if ($request->getExists('totp')) { $okay = self::verifyTOTPCode($user, new PhutilOpaqueEnvelope($key), $code); if ($okay) { $config = $this->newConfigForUser($user)->setFactorName(pht('Mobile App (TOTP)'))->setFactorSecret($key); return $config; } else { if (!strlen($code)) { $e_code = pht('Required'); } else { $e_code = pht('Invalid'); } } } $form->addHiddenInput('totp', true); $form->addHiddenInput('totpkey', $key); $form->appendRemarkupInstructions(pht('First, download an authenticator application on your phone. Two ' . 'applications which work well are **Authy** and **Google ' . 'Authenticator**, but any other TOTP application should also work.')); $form->appendInstructions(pht('Launch the application on your phone, and add a new entry for ' . 'this Phabricator install. When prompted, scan the QR code or ' . 'manually enter the key shown below into the application.')); $prod_uri = new PhutilURI(PhabricatorEnv::getProductionURI('/')); $issuer = $prod_uri->getDomain(); $uri = urisprintf('otpauth://totp/%s:%s?secret=%s&issuer=%s', $issuer, $user->getUsername(), $key, $issuer); $qrcode = $this->renderQRCode($uri); $form->appendChild($qrcode); $form->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('Key'))->setValue(phutil_tag('strong', array(), $key))); $form->appendInstructions(pht('(If given an option, select that this key is "Time Based", not ' . '"Counter Based".)')); $form->appendInstructions(pht('After entering the key, the application should display a numeric ' . 'code. Enter that code below to confirm that you have configured ' . 'the authenticator correctly:')); $form->appendChild(id(new PHUIFormNumberControl())->setLabel(pht('TOTP Code'))->setName('totpcode')->setValue($code)->setError($e_code)); }
public function applyApplicationTransactionExternalEffects(PhabricatorApplicationTransaction $xaction) { $object = $this->getObject(); $phid = $object->getPHID(); $key = $this->getFieldKey(); $property = id(new AlmanacPropertyQuery())->setViewer($this->getViewer())->withObjectPHIDs(array($phid))->withNames(array($key))->executeOne(); if (!$property) { $property = id(new AlmanacProperty())->setObjectPHID($phid)->setFieldIndex(PhabricatorHash::digestForIndex($key))->setFieldName($key); } $property->setFieldValue($xaction->getNewValue())->save(); }
public function handleRequest(AphrontRequest $request) { $show_prototypes = PhabricatorEnv::getEnvConfig('phabricator.show-prototypes'); if (!$show_prototypes) { throw new Exception(pht('Show prototypes is disabled. Set `phabricator.show-prototypes` to `true` to use the image proxy')); } $viewer = $request->getViewer(); $img_uri = $request->getStr('uri'); // Validate the URI before doing anything PhabricatorEnv::requireValidRemoteURIForLink($img_uri); $uri = new PhutilURI($img_uri); $proto = $uri->getProtocol(); if (!in_array($proto, array('http', 'https'))) { throw new Exception(pht('The provided image URI must be either http or https')); } // Check if we already have the specified image URI downloaded $cached_request = id(new PhabricatorFileExternalRequest())->loadOneWhere('uriIndex = %s', PhabricatorHash::digestForIndex($img_uri)); if ($cached_request) { return $this->getExternalResponse($cached_request); } $ttl = PhabricatorTime::getNow() + phutil_units('7 days in seconds'); $external_request = id(new PhabricatorFileExternalRequest())->setURI($img_uri)->setTTL($ttl); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); // Cache missed so we'll need to validate and download the image try { // Rate limit outbound fetches to make this mechanism less useful for // scanning networks and ports. PhabricatorSystemActionEngine::willTakeAction(array($viewer->getPHID()), new PhabricatorFilesOutboundRequestAction(), 1); $file = PhabricatorFile::newFromFileDownload($uri, array('viewPolicy' => PhabricatorPolicies::POLICY_NOONE, 'canCDN' => true)); if (!$file->isViewableImage()) { $mime_type = $file->getMimeType(); $engine = new PhabricatorDestructionEngine(); $engine->destroyObject($file); $file = null; throw new Exception(pht('The URI "%s" does not correspond to a valid image file, got ' . 'a file with MIME type "%s". You must specify the URI of a ' . 'valid image file.', $uri, $mime_type)); } else { $file->save(); } $external_request->setIsSuccessful(true)->setFilePHID($file->getPHID())->save(); unset($unguarded); return $this->getExternalResponse($external_request); } catch (HTTPFutureHTTPResponseStatus $status) { $external_request->setIsSuccessful(false)->setResponseMessage($status->getMessage())->save(); return $this->getExternalResponse($external_request); } catch (Exception $ex) { // Not actually saving the request in this case $external_request->setResponseMessage($ex->getMessage()); return $this->getExternalResponse($external_request); } }
public function setHeaders(array $headers) { // Normalize headers to lowercase. $normalized = array(); foreach ($headers as $name => $value) { $name = $this->normalizeMailHeaderName($name); if ($name == 'message-id') { $this->setMessageIDHash(PhabricatorHash::digestForIndex($value)); } $normalized[$name] = $value; } $this->headers = $normalized; return $this; }
protected function doWork() { $lease_phid = $this->getTaskDataValue('leasePHID'); $hash = PhabricatorHash::digestForIndex($lease_phid); $lock_key = 'drydock.lease:' . $hash; $lock = PhabricatorGlobalLock::newLock($lock_key)->lock(1); try { $lease = $this->loadLease($lease_phid); $this->handleUpdate($lease); } catch (Exception $ex) { $lock->unlock(); throw $ex; } $lock->unlock(); }
public static function newLock($name) { $namespace = PhabricatorLiskDAO::getStorageNamespace(); $namespace = PhabricatorHash::digestToLength($namespace, 20); $full_name = 'ph:' . $namespace . ':' . $name; $length_limit = 64; if (strlen($full_name) > $length_limit) { throw new Exception(pht('Lock name "%s" is too long (full lock name is "%s"). The ' . 'full lock name must not be longer than %s bytes.', $name, $full_name, new PhutilNumber($length_limit))); } $lock = self::getLock($full_name); if (!$lock) { $lock = new PhabricatorGlobalLock($full_name); self::registerLock($lock); } return $lock; }
protected function doWork() { $resource_phid = $this->getTaskDataValue('resourcePHID'); $hash = PhabricatorHash::digestForIndex($resource_phid); $lock_key = 'drydock.resource:' . $hash; $lock = PhabricatorGlobalLock::newLock($lock_key)->lock(1); try { $resource = $this->loadResource($resource_phid); $this->handleUpdate($resource); } catch (Exception $ex) { $lock->unlock(); $this->flushDrydockTaskQueue(); throw $ex; } $lock->unlock(); }
private function getEngine() { $options = $this->options; $viewer = $this->getViewer(); $viewer_key = $viewer->getCacheFragment(); ksort($options); $engine_key = serialize($options); $engine_key = PhabricatorHash::digestForIndex($engine_key); $cache = PhabricatorCaches::getRequestCache(); $cache_key = "remarkup.engine({$viewer_key}, {$engine_key})"; $engine = $cache->getKey($cache_key); if (!$engine) { $engine = PhabricatorMarkupEngine::newMarkupEngine($options); $cache->setKey($cache_key, $engine); } return $engine; }
public function testHashForIndex() { $map = array('dog' => 'Aliif7Qjd5ct', 'cat' => 'toudDsue3Uv8', 'rat' => 'RswaKgTjqOuj', 'bat' => 'rAkJKyX4YdYm'); foreach ($map as $input => $expect) { $this->assertEqual($expect, PhabricatorHash::digestForIndex($input), "Input: {$input}"); } // Test that the encoding produces 6 bits of entropy per byte. $entropy = array('dog', 'cat', 'rat', 'bat', 'dig', 'fig', 'cot', 'cut', 'fog', 'rig', 'rug', 'dug', 'mat', 'pat', 'eat', 'tar', 'pot'); $seen = array(); foreach ($entropy as $input) { $chars = preg_split('//', PhabricatorHash::digestForIndex($input)); foreach ($chars as $char) { $seen[$char] = true; } } $this->assertEqual(1 << 6, count($seen), "Distinct characters in hash of: {$input}"); }
protected function doWork() { $item_phid = $this->getTaskDataValue('itemPHID'); $hash = PhabricatorHash::digestForIndex($item_phid); $lock_key = "nuance.item.{$hash}"; $lock = PhabricatorGlobalLock::newLock($lock_key); $lock->lock(1); try { $item = $this->loadItem($item_phid); $this->updateItem($item); $this->routeItem($item); $this->applyCommands($item); } catch (Exception $ex) { $lock->unlock(); throw $ex; } $lock->unlock(); }
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn); if ($this->ids !== null) { $where[] = qsprintf($conn, 'id IN (%Ld)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf($conn, 'phid IN (%Ls)', $this->phids); } if ($this->names !== null) { $name_indexes = array(); foreach ($this->names as $name) { $name_indexes[] = PhabricatorHash::digestForIndex($name); } $where[] = qsprintf($conn, 'nameIndex IN (%Ls)', $name_indexes); } return $where; }