Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
connect: improve check for plink to reduce false positives
The git_connect function has code to handle plink and tortoiseplink
specially, as they require different command line arguments from
OpenSSH (-P instead of -p for ports; tortoiseplink additionally requires
-batch).  However, the match was done by checking for "plink" anywhere
in the string, which led to a GIT_SSH value containing "uplink" being
treated as an invocation of putty's plink.

Improve the check by looking for "plink" or "tortoiseplink" (or those
names suffixed with ".exe") only in the final component of the path.
This has the downside that a program such as "plink-0.63" would no
longer be recognized, but the increased robustness is likely worth it.
Add tests to cover these cases to avoid regressions.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
brian m. carlson authored and Junio C Hamano committed Apr 28, 2015
1 parent d1018c2 commit baaf233
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
18 changes: 15 additions & 3 deletions connect.c
Expand Up @@ -722,7 +722,7 @@ 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;
int putty, tortoiseplink = 0;
char *ssh_host = hostandport;
const char *port = NULL;
get_host_and_port(&ssh_host, &port);
Expand All @@ -747,14 +747,26 @@ struct child_process *git_connect(int fd[2], const char *url,
conn->use_shell = 1;
putty = 0;
} else {
const char *base;
char *ssh_dup;

ssh = getenv("GIT_SSH");
if (!ssh)
ssh = "ssh";
putty = !!strcasestr(ssh, "plink");

ssh_dup = xstrdup(ssh);
base = basename(ssh_dup);

tortoiseplink = !strcasecmp(base, "tortoiseplink") ||
!strcasecmp(base, "tortoiseplink.exe");
putty = !strcasecmp(base, "plink") ||
!strcasecmp(base, "plink.exe") || tortoiseplink;

free(ssh_dup);
}

argv_array_push(&conn->args, ssh);
if (putty && !strcasestr(ssh, "tortoiseplink"))
if (tortoiseplink)
argv_array_push(&conn->args, "-batch");
if (port) {
/* P is for PuTTY, p is for OpenSSH */
Expand Down
33 changes: 33 additions & 0 deletions t/t5601-clone.sh
Expand Up @@ -296,6 +296,12 @@ setup_ssh_wrapper () {
'
}

copy_ssh_wrapper_as () {
cp "$TRASH_DIRECTORY/ssh-wrapper" "$1" &&
GIT_SSH="$1" &&
export GIT_SSH
}

expect_ssh () {
test_when_finished '
(cd "$TRASH_DIRECTORY" && rm -f ssh-expect && >ssh-output)
Expand Down Expand Up @@ -335,6 +341,33 @@ test_expect_success 'bracketed hostnames are still ssh' '
expect_ssh "-p 123" myhost src
'

test_expect_success 'uplink is not treated as putty' '
copy_ssh_wrapper_as "$TRASH_DIRECTORY/uplink" &&
git clone "[myhost:123]:src" ssh-bracket-clone-uplink &&
expect_ssh "-p 123" myhost src
'

test_expect_success 'plink is treated specially (as putty)' '
copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
git clone "[myhost:123]:src" ssh-bracket-clone-plink-0 &&
expect_ssh "-P 123" myhost src
'

test_expect_success 'plink.exe is treated specially (as putty)' '
copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" &&
git clone "[myhost:123]:src" ssh-bracket-clone-plink-1 &&
expect_ssh "-P 123" myhost src
'

test_expect_success 'tortoiseplink is like putty, with extra arguments' '
copy_ssh_wrapper_as "$TRASH_DIRECTORY/tortoiseplink" &&
git clone "[myhost:123]:src" ssh-bracket-clone-plink-2 &&
expect_ssh "-batch -P 123" myhost src
'

# Reset the GIT_SSH environment variable for clone tests.
setup_ssh_wrapper

counter=0
# $1 url
# $2 none|host
Expand Down

0 comments on commit baaf233

Please sign in to comment.