git_connect includes circuitry to use specific command line arguments
when using PuTTY's plink. This circuitry is enabled based on the
presence of the "plink" and "tortoiseplink" substrings in the name
of the SSH program to use. When using GIT_SSH_CMD to specify a complete
shell command to run for ssh connections, look for these substrings only
in the program name (not in subsequent arguments).

Signed-off-by: Thomas Quinot <tho...@quinot.org>
---
 connect.c | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/connect.c b/connect.c
index ecb1821..fcb928a 100644
--- a/connect.c
+++ b/connect.c
@@ -700,22 +700,42 @@ struct child_process *git_connect(int fd[2], const char 
*url,
 
                conn->in = conn->out = -1;
                if (protocol == PROTO_SSH) {
-                       const char *ssh;
-                       int putty;
+                       const char *ssh_cmd, *ssh;
+                       char *ssh_cmd_var = NULL;
+                       char *putty;
                        char *ssh_host = hostandport;
                        const char *port = NULL;
                        get_host_and_port(&ssh_host, &port);
                        port = get_port_numeric(port);
 
-                       ssh = getenv("GIT_SSH_CMD");
-                       if (ssh)
+                       ssh_cmd = getenv("GIT_SSH_CMD");
+                       if (ssh_cmd) {
+                               /*
+                                * Split command line to check for plink in
+                                * ssh_argv[0].
+                                */
+                               const char **ssh_argv;
+                               ssh_cmd_var = xstrdup(ssh_cmd);
+                               int ssh_argc =
+                                   split_cmdline(ssh_cmd_var, &ssh_argv);
+                               if (ssh_argv < 0) {
+                                       free(ssh_argv);
+                                       free(ssh_cmd_var);
+                                       die("invalid GIT_SSH_CMD '%s': %s",
+                                           ssh,
+                                           split_cmdline_strerror(ssh_argc));
+                               }
+                               ssh = ssh_argv[0];
+                               free(ssh_argv);
+
                                conn->use_shell = 1;
-                       else {
+                               argv_array_push(&conn->args, ssh_cmd);
+                       } else {
                                ssh = getenv("GIT_SSH");
                                if (!ssh) ssh = "ssh";
+                               argv_array_push(&conn->args, ssh);
                        }
 
-                       argv_array_push(&conn->args, ssh);
                        putty = strcasestr(ssh, "plink");
                        if (putty && !strcasestr(ssh, "tortoiseplink"))
                                argv_array_push(&conn->args, "-batch");
@@ -725,6 +745,7 @@ struct child_process *git_connect(int fd[2], const char 
*url,
                                argv_array_push(&conn->args, port);
                        }
                        argv_array_push(&conn->args, ssh_host);
+                       if (ssh_cmd_var) free(ssh_cmd_var);
                } else {
                        /* remove repo-local variables from the environment */
                        conn->env = local_repo_env;
-- 
2.1.2

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to