Page MenuHomePhabricator

D10401.id26033.diff
No OneTemporary

D10401.id26033.diff

diff --git a/src/applications/auth/sshkey/PhabricatorAuthSSHPublicKey.php b/src/applications/auth/sshkey/PhabricatorAuthSSHPublicKey.php
--- a/src/applications/auth/sshkey/PhabricatorAuthSSHPublicKey.php
+++ b/src/applications/auth/sshkey/PhabricatorAuthSSHPublicKey.php
@@ -99,4 +99,26 @@
return PhabricatorHash::digestForIndex($body);
}
+ public function getEntireKey() {
+ $key = $this->type.' '.$this->body;
+ if (strlen($this->comment)) {
+ $key = $key.' '.$this->comment;
+ }
+ return $key;
+ }
+
+ public function toPCKS8() {
+
+ // TODO: Put a cache in front of this.
+
+ $tmp = new TempFile();
+ Filesystem::writeFile($tmp, $this->getEntireKey());
+ list($pem_key) = execx(
+ 'ssh-keygen -e -m pcks8 -f %s',
+ $tmp);
+ unset($tmp);
+
+ return $pem_key;
+ }
+
}
diff --git a/src/applications/conduit/controller/PhabricatorConduitAPIController.php b/src/applications/conduit/controller/PhabricatorConduitAPIController.php
--- a/src/applications/conduit/controller/PhabricatorConduitAPIController.php
+++ b/src/applications/conduit/controller/PhabricatorConduitAPIController.php
@@ -209,6 +209,84 @@
$request->getUser());
}
+ $auth_type = idx($metadata, 'auth.type');
+ if ($auth_type === ConduitClient::AUTH_ASYMMETRIC) {
+ $host = idx($metadata, 'auth.host');
+ if (!$host) {
+ return array(
+ 'ERR-INVALID-AUTH',
+ pht(
+ 'Request is missing required "auth.host" parameter.'),
+ );
+ }
+
+ // TODO: Validate that we are the host!
+
+ $raw_key = idx($metadata, 'auth.key');
+ $public_key = PhabricatorAuthSSHPublicKey::newFromRawKey($raw_key);
+ $ssl_public_key = $public_key->toPCKS8();
+
+ // First, verify the signature.
+ try {
+ $protocol_data = $metadata;
+
+ // TODO: We should stop writing this into the protocol data when
+ // processing a request.
+ unset($protocol_data['scope']);
+
+ ConduitClient::verifySignature(
+ $this->method,
+ $api_request->getAllParameters(),
+ $protocol_data,
+ $ssl_public_key);
+ } catch (Exception $ex) {
+ return array(
+ 'ERR-INVALID-AUTH',
+ pht(
+ 'Signature verification failure. %s',
+ $ex->getMessage()),
+ );
+ }
+
+ // If the signature is valid, find the user or device which is
+ // associated with this public key.
+
+ $stored_key = id(new PhabricatorAuthSSHKeyQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withKeys(array($public_key))
+ ->executeOne();
+ if (!$stored_key) {
+ return array(
+ 'ERR-INVALID-AUTH',
+ pht(
+ 'No user or device is associated with that public key.'),
+ );
+ }
+
+ $object = $stored_key->getObject();
+
+ if ($object instanceof PhabricatorUser) {
+ $user = $object;
+ } else {
+ throw new Exception(
+ pht('Not Implemented: Would authenticate Almanac device.'));
+ }
+
+ return $this->validateAuthenticatedUser(
+ $api_request,
+ $user);
+ } else if ($auth_type === null) {
+ // No specified authentication type, continue with other authentication
+ // methods below.
+ } else {
+ return array(
+ 'ERR-INVALID-AUTH',
+ pht(
+ 'Provided "auth.type" ("%s") is not recognized.',
+ $auth_type),
+ );
+ }
+
// handle oauth
$access_token = $request->getStr('access_token');
$method_scope = $metadata['scope'];

File Metadata

Mime Type
text/plain
Expires
Sat, May 11, 11:31 AM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6285522
Default Alt Text
D10401.id26033.diff (3 KB)

Event Timeline