/** * Install a private key on the remote * * @param string $key * @param string $password * @throws TransportException * @throws CredentialException */ public function addPrivateKey($key, $password = null) { // Send to remote $key = str_replace("\r\n", "\n", $key); $fn = md5($key); $this->createTextFile($key, $fn); $this->files[] = $fn; // Check we have the SSH Agent running, start if not $agent_pid = $this->shell->sendSmartCommand('eval `ssh-agent -s`', true, self::CMD_TIMEOUT, true); if (!preg_match('/Agent pid [0-9]+/', $agent_pid)) { throw new CredentialException("SSH Agent required for key pair authentication: " . $agent_pid); } // Add to SSH agent on remote if ($password) { // ssh-add will ask for a password $this->shell->sendln('ssh-add ' . $fn); $out = $this->shell->readUntilExpression("/Enter passphrase for .*: /", self::CMD_TIMEOUT, true); if (stripos($out, self::PASSPHRASE_HINT) !== false) { $this->shell->sendln($password); $this->shell->readUntilEndMarker($this->shell->getSmartMarker()); } } else { $out = $this->shell->sendSmartCommand('ssh-add ' . $fn, true, self::CMD_TIMEOUT, true); if (stripos($out, self::PASSPHRASE_HINT) !== false) { throw new CredentialException("Private key requires a password, but none provided"); } } }
/** * Remove the smart console marker * * @param string $output * @return string */ protected function cleanOutput($output) { return str_replace("\n" . $this->shell->getSmartMarker(), '', $this->normaliseEol($output)); }