Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14866243
D11021.id26465.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Referenced Files
None
Subscribers
None
D11021.id26465.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1316,6 +1316,7 @@
'PhabricatorAuthLinkController' => 'applications/auth/controller/PhabricatorAuthLinkController.php',
'PhabricatorAuthListController' => 'applications/auth/controller/config/PhabricatorAuthListController.php',
'PhabricatorAuthLoginController' => 'applications/auth/controller/PhabricatorAuthLoginController.php',
+ 'PhabricatorAuthManagementCachePKCS8Workflow' => 'applications/auth/management/PhabricatorAuthManagementCachePKCS8Workflow.php',
'PhabricatorAuthManagementLDAPWorkflow' => 'applications/auth/management/PhabricatorAuthManagementLDAPWorkflow.php',
'PhabricatorAuthManagementListFactorsWorkflow' => 'applications/auth/management/PhabricatorAuthManagementListFactorsWorkflow.php',
'PhabricatorAuthManagementRecoverWorkflow' => 'applications/auth/management/PhabricatorAuthManagementRecoverWorkflow.php',
@@ -4429,6 +4430,7 @@
'PhabricatorAuthLinkController' => 'PhabricatorAuthController',
'PhabricatorAuthListController' => 'PhabricatorAuthProviderConfigController',
'PhabricatorAuthLoginController' => 'PhabricatorAuthController',
+ 'PhabricatorAuthManagementCachePKCS8Workflow' => 'PhabricatorAuthManagementWorkflow',
'PhabricatorAuthManagementLDAPWorkflow' => 'PhabricatorAuthManagementWorkflow',
'PhabricatorAuthManagementListFactorsWorkflow' => 'PhabricatorAuthManagementWorkflow',
'PhabricatorAuthManagementRecoverWorkflow' => 'PhabricatorAuthManagementWorkflow',
diff --git a/src/applications/auth/management/PhabricatorAuthManagementCachePKCS8Workflow.php b/src/applications/auth/management/PhabricatorAuthManagementCachePKCS8Workflow.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/management/PhabricatorAuthManagementCachePKCS8Workflow.php
@@ -0,0 +1,96 @@
+<?php
+
+final class PhabricatorAuthManagementCachePKCS8Workflow
+ extends PhabricatorAuthManagementWorkflow {
+
+ protected function didConstruct() {
+ $this
+ ->setName('cache-pkcs8')
+ ->setExamples('**cache-pkcs8** --public __keyfile__ --pkcs8 __keyfile__')
+ ->setSynopsis(
+ pht(
+ 'Cache the PKCS8 format of a public key. When developing on OSX, '.
+ 'this can be used to work around issues with ssh-keygen. Use '.
+ '`ssh-keygen -e -m PKCS8 -f key.pub` to generate a PKCS8 key to '.
+ 'feed to this command.'))
+ ->setArguments(
+ array(
+ array(
+ 'name' => 'public',
+ 'param' => 'keyfile',
+ 'help' => pht('Path to public keyfile.'),
+ ),
+ array(
+ 'name' => 'pkcs8',
+ 'param' => 'keyfile',
+ 'help' => pht('Path to corresponding PKCS8 key.'),
+ ),
+ ));
+ }
+
+ public function execute(PhutilArgumentParser $args) {
+ $console = PhutilConsole::getConsole();
+
+ $public_keyfile = $args->getArg('public');
+ if (!strlen($public_keyfile)) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'You must specify the path to a public keyfile with --public.'));
+ }
+
+ if (!Filesystem::pathExists($public_keyfile)) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Specified public keyfile "%s" does not exist!',
+ $public_keyfile));
+ }
+
+ $public_key = Filesystem::readFile($public_keyfile);
+
+ $pkcs8_keyfile = $args->getArg('pkcs8');
+ if (!strlen($pkcs8_keyfile)) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'You must specify the path to a pkcs8 keyfile with --pkc8s.'));
+ }
+
+ if (!Filesystem::pathExists($pkcs8_keyfile)) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Specified pkcs8 keyfile "%s" does not exist!',
+ $pkcs8_keyfile));
+ }
+
+ $pkcs8_key = Filesystem::readFile($pkcs8_keyfile);
+
+ $warning = pht(
+ 'Adding a PKCS8 keyfile to the cache can be very dangerous. If the '.
+ 'PKCS8 file really encodes a different public key than the one '.
+ 'specified, an attacker could use it to gain unautorized access.'.
+ "\n\n".
+ 'Generally, you should use this option only in a development '.
+ 'environment where ssh-keygen is broken and it is inconvenient to '.
+ 'fix it, and only if you are certain you understand the risks. You '.
+ 'should never cache a PKCS8 file you did not generate yourself.');
+
+ $console->writeOut(
+ "%s\n",
+ phutil_console_wrap($warning));
+
+ $prompt = pht('Really trust this PKCS8 keyfile?');
+ if (!phutil_console_confirm($prompt)) {
+ throw new PhutilArgumentUsageException(
+ pht('Aborted workflow.'));
+ }
+
+ $key = PhabricatorAuthSSHPublicKey::newFromRawKey($public_key);
+ $key->forcePopulatePKCS8Cache($pkcs8_key);
+
+ $console->writeOut(
+ "%s\n",
+ pht('Cached PKCS8 key for public key.'));
+
+ return 0;
+ }
+
+}
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
@@ -108,17 +108,48 @@
}
public function toPKCS8() {
+ $entire_key = $this->getEntireKey();
+ $cache_key = $this->getPKCS8CacheKey($entire_key);
- // TODO: Put a cache in front of this.
+ $cache = PhabricatorCaches::getImmutableCache();
+ $pkcs8_key = $cache->getKey($cache_key);
+ if ($pkcs8_key) {
+ return $pkcs8_key;
+ }
$tmp = new TempFile();
Filesystem::writeFile($tmp, $this->getEntireKey());
- list($pem_key) = execx(
- 'ssh-keygen -e -m PKCS8 -f %s',
- $tmp);
+ try {
+ list($pkcs8_key) = execx(
+ 'ssh-keygen -e -m PKCS8 -f %s',
+ $tmp);
+ } catch (CommandException $ex) {
+ unset($tmp);
+ throw new PhutilProxyException(
+ pht(
+ 'Failed to convert public key into PKCS8 format. If you are '.
+ 'developing on OSX, you may be able to use `bin/auth cache-pkcs8` '.
+ 'to work around this issue. %s',
+ $ex->getMessage()),
+ $ex);
+ }
unset($tmp);
- return $pem_key;
+ $cache->setKey($cache_key, $pkcs8_key);
+
+ return $pkcs8_key;
+ }
+
+ public function forcePopulatePKCS8Cache($pkcs8_key) {
+ $entire_key = $this->getEntireKey();
+ $cache_key = $this->getPKCS8CacheKey($entire_key);
+
+ $cache = PhabricatorCaches::getImmutableCache();
+ $cache->setKey($cache_key, $pkcs8_key);
+ }
+
+ private function getPKCS8CacheKey($entire_key) {
+ return 'pkcs8:'.PhabricatorHash::digestForIndex($entire_key);
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 9, 12:23 AM (3 h, 28 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7100758
Default Alt Text
D11021.id26465.diff (6 KB)
Attached To
Mode
D11021: Work around lack of PKCS8 support in OSX ssh-keygen
Attached
Detach File
Event Timeline
Log In to Comment