mirror of
https://github.com/libgit2/libgit2.git
synced 2026-06-22 06:26:26 +00:00
ssh: honor core.sshcommand
Callers can specify the ssh command to invoke using `core.sshcommand` or the `GIT_SSH` environment variable. This is useful for specifying alternate configuration, and is particularly useful for our testing environment.
This commit is contained in:
@@ -414,6 +414,8 @@ if [ -z "$SKIP_SSH_TESTS" ]; then
|
||||
export GITTEST_REMOTE_SSH_PASSPHRASE=""
|
||||
export GITTEST_REMOTE_SSH_FINGERPRINT="${SSH_FINGERPRINT}"
|
||||
|
||||
export GITTEST_SSH_CMD="ssh -i ${HOME}/.ssh/id_rsa -o UserKnownHostsFile=${HOME}/.ssh/known_hosts"
|
||||
|
||||
echo ""
|
||||
echo "Running ssh tests"
|
||||
echo ""
|
||||
@@ -430,6 +432,8 @@ if [ -z "$SKIP_SSH_TESTS" ]; then
|
||||
run_test ssh
|
||||
unset GITTEST_REMOTE_URL
|
||||
|
||||
unset GITTEST_SSH_CMD
|
||||
|
||||
unset GITTEST_REMOTE_USER
|
||||
unset GITTEST_REMOTE_SSH_KEY
|
||||
unset GITTEST_REMOTE_SSH_PUBKEY
|
||||
|
||||
@@ -64,6 +64,8 @@ int git_transport_ssh_with_paths(
|
||||
|
||||
*out = transport;
|
||||
return 0;
|
||||
#elif GIT_SSH_EXEC
|
||||
abort();
|
||||
#else
|
||||
GIT_UNUSED(out);
|
||||
GIT_UNUSED(owner);
|
||||
|
||||
@@ -11,10 +11,12 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "net.h"
|
||||
#include "path.h"
|
||||
#include "futils.h"
|
||||
#include "process.h"
|
||||
#include "transports/smart.h"
|
||||
|
||||
typedef struct {
|
||||
git_smart_subtransport_stream parent;
|
||||
@@ -114,17 +116,54 @@ GIT_INLINE(int) ensure_transport_state(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_ssh_cmdline(
|
||||
git_str *out,
|
||||
ssh_exec_subtransport *transport,
|
||||
git_net_url *url,
|
||||
const char *command)
|
||||
{
|
||||
git_remote *remote = ((transport_smart *)transport->owner)->owner;
|
||||
git_repository *repo = remote->repo;
|
||||
git_config *cfg;
|
||||
git_str ssh_cmd = GIT_STR_INIT;
|
||||
const char *default_ssh_cmd = "ssh";
|
||||
int error;
|
||||
|
||||
if ((error = git_repository_config_snapshot(&cfg, repo)) < 0)
|
||||
return error;
|
||||
|
||||
if ((error = git__getenv(&ssh_cmd, "GIT_SSH")) == 0)
|
||||
;
|
||||
else if (error != GIT_ENOTFOUND)
|
||||
goto done;
|
||||
else if ((error = git_config__get_string_buf(&ssh_cmd, cfg, "core.sshcommand")) < 0 && error != GIT_ENOTFOUND)
|
||||
goto done;
|
||||
|
||||
error = git_str_printf(out, "%s -p %s \"%s%s%s\" \"%s\" \"%s\"",
|
||||
ssh_cmd.size > 0 ? ssh_cmd.ptr : default_ssh_cmd,
|
||||
url->port,
|
||||
url->username ? url->username : "",
|
||||
url->username ? "@" : "",
|
||||
url->host,
|
||||
command,
|
||||
url->path);
|
||||
|
||||
done:
|
||||
git_str_dispose(&ssh_cmd);
|
||||
git_config_free(cfg);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int start_ssh(
|
||||
ssh_exec_subtransport *transport,
|
||||
git_smart_service_t action,
|
||||
const char *sshpath)
|
||||
{
|
||||
const char *args[6];
|
||||
const char *env[] = { "GIT_DIR=" };
|
||||
|
||||
git_process_options process_opts = GIT_PROCESS_OPTIONS_INIT;
|
||||
git_net_url url = GIT_NET_URL_INIT;
|
||||
git_str userhost = GIT_STR_INIT;
|
||||
git_str ssh_cmdline = GIT_STR_INIT;
|
||||
const char *command;
|
||||
int error;
|
||||
|
||||
@@ -153,20 +192,11 @@ static int start_ssh(
|
||||
if (error < 0)
|
||||
goto done;
|
||||
|
||||
if (url.username) {
|
||||
git_str_puts(&userhost, url.username);
|
||||
git_str_putc(&userhost, '@');
|
||||
}
|
||||
git_str_puts(&userhost, url.host);
|
||||
if ((error = get_ssh_cmdline(&ssh_cmdline, transport, &url, command)) < 0)
|
||||
goto done;
|
||||
|
||||
args[0] = "/usr/bin/ssh";
|
||||
args[1] = "-p";
|
||||
args[2] = url.port;
|
||||
args[3] = userhost.ptr;
|
||||
args[4] = command;
|
||||
args[5] = url.path;
|
||||
|
||||
if ((error = git_process_new(&transport->process, args, ARRAY_SIZE(args), env, ARRAY_SIZE(env), &process_opts)) < 0 ||
|
||||
if ((error = git_process_new_from_cmdline(&transport->process,
|
||||
ssh_cmdline.ptr, env, ARRAY_SIZE(env), &process_opts)) < 0 ||
|
||||
(error = git_process_start(transport->process)) < 0) {
|
||||
git_process_free(transport->process);
|
||||
transport->process = NULL;
|
||||
@@ -174,7 +204,7 @@ static int start_ssh(
|
||||
}
|
||||
|
||||
done:
|
||||
git_str_dispose(&userhost);
|
||||
git_str_dispose(&ssh_cmdline);
|
||||
git_net_url_dispose(&url);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,9 @@ static char *_orig_http_proxy = NULL;
|
||||
static char *_orig_https_proxy = NULL;
|
||||
static char *_orig_no_proxy = NULL;
|
||||
|
||||
static char *_ssh_cmd = NULL;
|
||||
static char *_orig_ssh_cmd = NULL;
|
||||
|
||||
static int ssl_cert(git_cert *cert, int valid, const char *host, void *payload)
|
||||
{
|
||||
GIT_UNUSED(cert);
|
||||
@@ -102,6 +105,14 @@ void test_online_clone__initialize(void)
|
||||
_orig_https_proxy = cl_getenv("HTTPS_PROXY");
|
||||
_orig_no_proxy = cl_getenv("NO_PROXY");
|
||||
|
||||
_orig_ssh_cmd = cl_getenv("GIT_SSH");
|
||||
_ssh_cmd = cl_getenv("GITTEST_SSH_CMD");
|
||||
|
||||
if (_ssh_cmd)
|
||||
cl_setenv("GIT_SSH", _ssh_cmd);
|
||||
else
|
||||
cl_setenv("GIT_SSH", NULL);
|
||||
|
||||
if (_remote_expectcontinue)
|
||||
git_libgit2_opts(GIT_OPT_ENABLE_HTTP_EXPECT_CONTINUE, 1);
|
||||
}
|
||||
@@ -149,6 +160,11 @@ void test_online_clone__cleanup(void)
|
||||
git__free(_orig_https_proxy);
|
||||
git__free(_orig_no_proxy);
|
||||
|
||||
cl_setenv("GIT_SSH", _orig_ssh_cmd);
|
||||
git__free(_orig_ssh_cmd);
|
||||
|
||||
git__free(_ssh_cmd);
|
||||
|
||||
git_libgit2_opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, NULL, NULL);
|
||||
git_libgit2_opts(GIT_OPT_SET_SERVER_TIMEOUT, 0);
|
||||
git_libgit2_opts(GIT_OPT_SET_SERVER_CONNECT_TIMEOUT, 0);
|
||||
|
||||
@@ -20,6 +20,9 @@ static char *_remote_ssh_passphrase = NULL;
|
||||
static char *_remote_default = NULL;
|
||||
static char *_remote_expectcontinue = NULL;
|
||||
|
||||
static char *_orig_ssh_cmd = NULL;
|
||||
static char *_ssh_cmd = NULL;
|
||||
|
||||
static int cred_acquire_cb(git_credential **, const char *, const char *, unsigned int, void *);
|
||||
|
||||
static git_remote *_remote;
|
||||
@@ -369,6 +372,14 @@ void test_online_push__initialize(void)
|
||||
_remote_expectcontinue = cl_getenv("GITTEST_REMOTE_EXPECTCONTINUE");
|
||||
_remote = NULL;
|
||||
|
||||
_orig_ssh_cmd = cl_getenv("GIT_SSH");
|
||||
_ssh_cmd = cl_getenv("GITTEST_SSH_CMD");
|
||||
|
||||
if (_ssh_cmd)
|
||||
cl_setenv("GIT_SSH", _ssh_cmd);
|
||||
else
|
||||
cl_setenv("GIT_SSH", NULL);
|
||||
|
||||
/* Skip the test if we're missing the remote URL */
|
||||
if (!_remote_url)
|
||||
cl_skip();
|
||||
@@ -423,6 +434,9 @@ void test_online_push__cleanup(void)
|
||||
git__free(_remote_default);
|
||||
git__free(_remote_expectcontinue);
|
||||
|
||||
git__free(_orig_ssh_cmd);
|
||||
git__free(_ssh_cmd);
|
||||
|
||||
/* Freed by cl_git_sandbox_cleanup */
|
||||
_repo = NULL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user