@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+28 -23
+28 -23
src/applications/drydock/interface/command/DrydockSSHCommandInterface.php
··· 2 2 3 3 final class DrydockSSHCommandInterface extends DrydockCommandInterface { 4 4 5 + private $passphraseSSHKey; 6 + 7 + private function openCredentialsIfNotOpen() { 8 + if ($this->passphraseSSHKey !== null) { 9 + return; 10 + } 11 + 12 + $credential = id(new PassphraseCredentialQuery()) 13 + ->setViewer(PhabricatorUser::getOmnipotentUser()) 14 + ->withIDs(array($this->getConfig('credential'))) 15 + ->needSecrets(true) 16 + ->executeOne(); 17 + 18 + if ($credential->getProvidesType() !== 19 + PassphraseCredentialTypeSSHPrivateKey::PROVIDES_TYPE) { 20 + throw new Exception("Only private key credentials are supported."); 21 + } 22 + 23 + $this->passphraseSSHKey = PassphraseSSHKey::loadFromPHID( 24 + $credential->getPHID(), 25 + PhabricatorUser::getOmnipotentUser()); 26 + } 27 + 5 28 public function getExecFuture($command) { 29 + $this->openCredentialsIfNotOpen(); 30 + 6 31 $argv = func_get_args(); 7 32 8 33 // This assumes there's a UNIX shell living at the other ··· 21 46 22 47 // NOTE: The "-t -t" is for psuedo-tty allocation so we can "sudo" on some 23 48 // systems, but maybe more trouble than it's worth? 24 - 25 - $credential = id(new PassphraseCredentialQuery()) 26 - ->setViewer(PhabricatorUser::getOmnipotentUser()) 27 - ->withIDs(array($this->getConfig('credential'))) 28 - ->needSecrets(true) 29 - ->executeOne(); 30 - 31 - // FIXME: We can't use text-based SSH files here because the TempFile goes 32 - // out of scope after this function ends and thus the file gets removed 33 - // before it can be used. 34 - if ($credential->getCredentialType() !== 35 - PassphraseCredentialTypeSSHPrivateKeyFile::CREDENTIAL_TYPE) { 36 - throw new Exception("Only private key file credentials are supported."); 37 - } 38 - 39 - $ssh_key = PassphraseSSHKey::loadFromPHID( 40 - $credential->getPHID(), 41 - PhabricatorUser::getOmnipotentUser()); 42 - 43 49 return new ExecFuture( 44 - 'ssh -t -t -o StrictHostKeyChecking=no -p %s -i %s %s@%s -- %s', 50 + 'ssh -t -t -o StrictHostKeyChecking=no -p %s -i %P %P@%s -- %s', 45 51 $this->getConfig('port'), 46 - $ssh_key->getKeyfileEnvelope()->openEnvelope(), 47 - $credential->getUsername(), 52 + $this->passphraseSSHKey->getKeyfileEnvelope(), 53 + $this->passphraseSSHKey->getUsernameEnvelope(), 48 54 $this->getConfig('host'), 49 55 $full_command); 50 56 } 51 - 52 57 }