1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-20 09:18:48 +02:00

Support text-based private key credentials in DrydockSSHCommandInterface

Summary: This updates DrydockSSHCommandInterface to correctly hold open the private key credentials for the life of the interface so that remote commands will execute correctly with a text-based private key.

Test Plan: Created a text-based private key, created a resource based on it and leased against it.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T4111

Differential Revision: https://secure.phabricator.com/D7700
This commit is contained in:
James Rhodes 2013-12-05 09:19:32 +11:00
parent 9c6f6043f0
commit b111bc039d

View file

@ -2,7 +2,32 @@
final class DrydockSSHCommandInterface extends DrydockCommandInterface {
private $passphraseSSHKey;
private function openCredentialsIfNotOpen() {
if ($this->passphraseSSHKey !== null) {
return;
}
$credential = id(new PassphraseCredentialQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withIDs(array($this->getConfig('credential')))
->needSecrets(true)
->executeOne();
if ($credential->getProvidesType() !==
PassphraseCredentialTypeSSHPrivateKey::PROVIDES_TYPE) {
throw new Exception("Only private key credentials are supported.");
}
$this->passphraseSSHKey = PassphraseSSHKey::loadFromPHID(
$credential->getPHID(),
PhabricatorUser::getOmnipotentUser());
}
public function getExecFuture($command) {
$this->openCredentialsIfNotOpen();
$argv = func_get_args();
// This assumes there's a UNIX shell living at the other
@ -21,32 +46,12 @@ final class DrydockSSHCommandInterface extends DrydockCommandInterface {
// NOTE: The "-t -t" is for psuedo-tty allocation so we can "sudo" on some
// systems, but maybe more trouble than it's worth?
$credential = id(new PassphraseCredentialQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withIDs(array($this->getConfig('credential')))
->needSecrets(true)
->executeOne();
// FIXME: We can't use text-based SSH files here because the TempFile goes
// out of scope after this function ends and thus the file gets removed
// before it can be used.
if ($credential->getCredentialType() !==
PassphraseCredentialTypeSSHPrivateKeyFile::CREDENTIAL_TYPE) {
throw new Exception("Only private key file credentials are supported.");
}
$ssh_key = PassphraseSSHKey::loadFromPHID(
$credential->getPHID(),
PhabricatorUser::getOmnipotentUser());
return new ExecFuture(
'ssh -t -t -o StrictHostKeyChecking=no -p %s -i %s %s@%s -- %s',
'ssh -t -t -o StrictHostKeyChecking=no -p %s -i %P %P@%s -- %s',
$this->getConfig('port'),
$ssh_key->getKeyfileEnvelope()->openEnvelope(),
$credential->getUsername(),
$this->passphraseSSHKey->getKeyfileEnvelope(),
$this->passphraseSSHKey->getUsernameEnvelope(),
$this->getConfig('host'),
$full_command);
}
}