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 setConnectTimeout($timeout) { $this->connectTimeout = $timeout; return $this; } public function setExecTimeout($timeout) { $this->execTimeout = $timeout; return $this; } public function getExecFuture($command) { $this->openCredentialsIfNotOpen(); $argv = func_get_args(); if ($this->getConfig('platform') === 'windows') { $escape_mode = null; $command_line = null; switch ($this->getEscapingMode()) { case PhutilCommandString::MODE_WINDOWSCMD: case PhutilCommandString::MODE_BASH: $escape_mode = PhutilCommandString::MODE_POWERSHELL; $command_line = 'iex $original_command'; break; case PhutilCommandString::MODE_POWERSHELL: $escape_mode = PhutilCommandString::MODE_POWERSHELL; $command_line = <<getShell())); } // Handle Windows by executing the command under PowerShell. $command = id(new PhutilCommandString($argv)) ->setEscapingMode($escape_mode); $encapsulate_command = array('%s', (string)$command); $double_command = id(new PhutilCommandString($encapsulate_command)) ->setEscapingMode(PhutilCommandString::MODE_POWERSHELL); $change_directory = ''; if ($this->getWorkingDirectory() !== null) { $change_directory .= 'cd '.$this->getWorkingDirectory(); } $script = <<applyWorkingDirectoryToArgv($argv); $full_command = call_user_func_array('csprintf', $argv); } $command_timeout = ''; if ($this->connectTimeout !== null) { $command_timeout = csprintf( '-o %s', 'ConnectTimeout='.$this->connectTimeout); } $future = new ExecFuture( 'ssh '. '-o LogLevel=quiet '. '-o StrictHostKeyChecking=no '. '-o UserKnownHostsFile=/dev/null '. '-o BatchMode=yes '. '%C -p %s -i %P %P@%s -- %s', $command_timeout, $this->getConfig('port'), $this->passphraseSSHKey->getKeyfileEnvelope(), $this->passphraseSSHKey->getUsernameEnvelope(), $this->getConfig('host'), $full_command); $future->setTimeout($this->execTimeout); $future->setPowershellXML($this->getConfig('platform') === 'windows'); return $future; } }