/** * Overwrite the default SSH command that git uses so we can tell it to use * our own ssh key * * @throws GD_Exception */ private function sshKeys() { if ($this->_repotype == self::GIT_REPOTYPE_SSH) { // Write the id_rsa key to the gitcache $id_rsa = $this->_project->getSSHKey()->getPrivateKey(); $project_id = $this->_project->getId(); $this->_ssh_key = $this->_base_gitdir . "id_rsa." . $project_id; if (file_exists($this->_ssh_key)) { unlink($this->_ssh_key); } file_put_contents($this->_ssh_key, $id_rsa); chmod($this->_ssh_key, 0600); // Get the hostname part of the URL $x = strrchr($this->_url, ':'); $host = substr($this->_url, 0, -strlen($x)); $host = preg_replace("/[^@0-9a-zA-Z-_.]/", "", $host); $ssh_cmd = "ssh -T -o StrictHostKeyChecking=no -i {$this->_ssh_key} -o UserKnownHostsFile=/dev/null "; // Use a script file $script = "#!/bin/sh\n\n{$ssh_cmd} \$*\n"; $this->_ssh_script = $this->_base_gitdir . "ssh." . $project_id . ".sh"; file_put_contents($this->_ssh_script, $script); chmod($this->_ssh_script, 0755); putenv("GIT_SSH={$this->_ssh_script}"); // Test the connection $this->runShell("\$GIT_SSH -T -o StrictHostKeyChecking=no {$host}", false); if ($this->_last_errno != 0) { // First check if we're a Github sort of repo // Github returns: Hi [USER]! You've successfully authenticated, but GitHub does not provide shell access. // Codebase returns: You've successfully uploaded your public key to Codebase and authenticated. $valid_string = "You've successfully"; $is_valid = false; foreach ($this->_last_output as $o) { if (strpos($o, $valid_string) !== false) { return; } } if (in_array("ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment.", $this->_last_output)) { /* * This is actually a correct response - default gitosis setup will serve up one of these: * * PTY allocation request failed on channel 0 * ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment. * * or just * * ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment. * */ return; } else { if (strpos($this->_last_output[0], "Could not resolve hostname") !== false || isset($this->_last_output[1]) && strpos($this->_last_output[1], "Could not resolve hostname") !== false) { throw new GD_Exception("Could not resolve hostname '{$host}'", 0, self::GIT_SSH_ERROR_HOSTNME); } else { $final_error = end($this->_last_output); throw new GD_Exception("Tried setting up SSH authentication but failed. Final error was: {$final_error}", 0, self::GIT_SSH_ERROR_UNKNOWN); } } } } }
/** * Generate a new GD_Git instance based on a GD_Model_Project object * * @param GD_Model_Project $project * @return GD_Git */ public static function FromProject(GD_Model_Project $project) { return new GD_Git($project->getId(), $project->getRepositoryUrl(), $project->getDeploymentBranch(), $project->getSSHKey()->getPrivateKey()); }