1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 22:10:55 +01:00

Fix parsing and storage of generated SSH keys

Summary: Fixes T4772. We weren't parsing generated public keys properly, and were storing them in the wrong format.

Test Plan:
  - Updated a private key.
  - Generated a public key.
  - Saved the public key.
  - Used a generated private key to authenticate.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T4772

Differential Revision: https://secure.phabricator.com/D8721
This commit is contained in:
epriestley 2014-04-08 14:52:37 -07:00
parent f79320e64e
commit 563a1ac5bf

View file

@ -70,48 +70,19 @@ final class PhabricatorSettingsPanelSSHKeys
$errors[] = pht('You must provide an SSH Public Key.'); $errors[] = pht('You must provide an SSH Public Key.');
$e_key = pht('Required'); $e_key = pht('Required');
} else { } else {
$parts = str_replace("\n", '', trim($entire_key));
$parts = preg_split('/\s+/', $parts);
if (count($parts) == 2) {
$parts[] = ''; // Add an empty comment part.
} else if (count($parts) == 3) {
// This is the expected case.
} else {
if (preg_match('/private\s*key/i', $entire_key)) {
// Try to give the user a better error message if it looks like
// they uploaded a private key.
$e_key = pht('Invalid');
$errors[] = pht('Provide your public key, not your private key!');
} else {
$e_key = pht('Invalid');
$errors[] = pht('Provided public key is not properly formatted.');
}
}
if (!$errors) { try {
list($type, $body, $comment) = $parts; list($type, $body, $comment) = self::parsePublicKey($entire_key);
$recognized_keys = array( $key->setKeyType($type);
'ssh-dsa', $key->setKeyBody($body);
'ssh-dss', $key->setKeyHash(md5($body));
'ssh-rsa', $key->setKeyComment($comment);
'ecdsa-sha2-nistp256',
'ecdsa-sha2-nistp384',
'ecdsa-sha2-nistp521',
);
if (!in_array($type, $recognized_keys)) { $e_key = null;
$e_key = pht('Invalid'); } catch (Exception $ex) {
$type_list = implode(', ', $recognized_keys); $e_key = pht('Invalid');
$errors[] = pht('Public key should be one of: %s', $type_list); $errors[] = $ex->getMessage();
} else {
$key->setKeyType($type);
$key->setKeyBody($body);
$key->setKeyHash(md5($body));
$key->setKeyComment($comment);
$e_key = null;
}
} }
} }
@ -314,13 +285,15 @@ final class PhabricatorSettingsPanelSSHKeys
'viewPolicy' => PhabricatorPolicies::POLICY_NOONE, 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
)); ));
list($type, $body, $comment) = self::parsePublicKey($public_key);
$key = id(new PhabricatorUserSSHKey()) $key = id(new PhabricatorUserSSHKey())
->setUserPHID($user->getPHID()) ->setUserPHID($user->getPHID())
->setName('id_rsa_phabricator') ->setName('id_rsa_phabricator')
->setKeyType('rsa') ->setKeyType($type)
->setKeyBody($public_key) ->setKeyBody($body)
->setKeyHash(md5($public_key)) ->setKeyHash(md5($body))
->setKeyComment(pht('Generated Key')) ->setKeyComment(pht('Generated'))
->save(); ->save();
// NOTE: We're disabling workflow on submit so the download works. We're // NOTE: We're disabling workflow on submit so the download works. We're
@ -395,4 +368,46 @@ final class PhabricatorSettingsPanelSSHKeys
->setDialog($dialog); ->setDialog($dialog);
} }
private static function parsePublicKey($entire_key) {
$parts = str_replace("\n", '', trim($entire_key));
$parts = preg_split('/\s+/', $parts);
if (count($parts) == 2) {
$parts[] = ''; // Add an empty comment part.
} else if (count($parts) == 3) {
// This is the expected case.
} else {
if (preg_match('/private\s*key/i', $entire_key)) {
// Try to give the user a better error message if it looks like
// they uploaded a private key.
throw new Exception(
pht('Provide your public key, not your private key!'));
} else {
throw new Exception(
pht('Provided public key is not properly formatted.'));
}
}
list($type, $body, $comment) = $parts;
$recognized_keys = array(
'ssh-dsa',
'ssh-dss',
'ssh-rsa',
'ecdsa-sha2-nistp256',
'ecdsa-sha2-nistp384',
'ecdsa-sha2-nistp521',
);
if (!in_array($type, $recognized_keys)) {
$type_list = implode(', ', $recognized_keys);
throw new Exception(
pht(
'Public key type should be one of: %s',
$type_list));
}
return array($type, $body, $comment);
}
} }