summaryrefslogtreecommitdiff
path: root/usr.bin/ssh
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2012-08-17 01:30:01 +0000
committerDamien Miller <djm@cvs.openbsd.org>2012-08-17 01:30:01 +0000
commita77b178190c37b2b1c3be3f653542ee1157b9b96 (patch)
tree203a8968f3e2e2e434bcb5ddfa7570dff8d301fa /usr.bin/ssh
parent86f6c38314ac830ce063daa9f9498f00f0a16f05 (diff)
Send client banner immediately, rather than waiting for the server to
move first for SSH protocol 2 connections (the default). Patch based on one in bz#1999 by tls AT panix.com, feedback dtucker@ ok markus@
Diffstat (limited to 'usr.bin/ssh')
-rw-r--r--usr.bin/ssh/compat.c4
-rw-r--r--usr.bin/ssh/sshconnect.c47
2 files changed, 37 insertions, 14 deletions
diff --git a/usr.bin/ssh/compat.c b/usr.bin/ssh/compat.c
index 13c0e4e71d3..23fc439e664 100644
--- a/usr.bin/ssh/compat.c
+++ b/usr.bin/ssh/compat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: compat.c,v 1.79 2011/09/23 07:45:05 markus Exp $ */
+/* $OpenBSD: compat.c,v 1.80 2012/08/17 01:30:00 djm Exp $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
@@ -43,6 +43,8 @@ int datafellows = 0;
void
enable_compat20(void)
{
+ if (compat20)
+ return;
debug("Enabling compatibility mode for protocol 2.0");
compat20 = 1;
}
diff --git a/usr.bin/ssh/sshconnect.c b/usr.bin/ssh/sshconnect.c
index 6f8646e2c9d..40609979a92 100644
--- a/usr.bin/ssh/sshconnect.c
+++ b/usr.bin/ssh/sshconnect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.234 2011/05/24 07:15:47 djm Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.235 2012/08/17 01:30:00 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -419,6 +419,26 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
return 0;
}
+static void
+send_client_banner(int connection_out, int minor1)
+{
+ char buf[256];
+
+ /* Send our own protocol version identification. */
+ if (compat20) {
+ xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n",
+ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION);
+ } else {
+ xasprintf(&client_version_string, "SSH-%d.%d-%.100s\n",
+ PROTOCOL_MAJOR_1, minor1, SSH_VERSION);
+ }
+ if (roaming_atomicio(vwrite, connection_out, client_version_string,
+ strlen(client_version_string)) != strlen(client_version_string))
+ fatal("write: %.100s", strerror(errno));
+ chop(client_version_string);
+ debug("Local version string %.100s", client_version_string);
+}
+
/*
* Waits for the server identification string, and sends our own
* identification string.
@@ -430,7 +450,7 @@ ssh_exchange_identification(int timeout_ms)
int remote_major, remote_minor, mismatch;
int connection_in = packet_get_connection_in();
int connection_out = packet_get_connection_out();
- int minor1 = PROTOCOL_MINOR_1;
+ int minor1 = PROTOCOL_MINOR_1, client_banner_sent = 0;
u_int i, n;
size_t len;
int fdsetsz, remaining, rc;
@@ -440,6 +460,16 @@ ssh_exchange_identification(int timeout_ms)
fdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask);
fdset = xcalloc(1, fdsetsz);
+ /*
+ * If we are SSH2-only then we can send the banner immediately and
+ * save a round-trip.
+ */
+ if (options.protocol == SSH_PROTO_2) {
+ enable_compat20();
+ send_client_banner(connection_out, 0);
+ client_banner_sent = 1;
+ }
+
/* Read other side's version identification. */
remaining = timeout_ms;
for (n = 0;;) {
@@ -542,18 +572,9 @@ ssh_exchange_identification(int timeout_ms)
fatal("Protocol major versions differ: %d vs. %d",
(options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
remote_major);
- /* Send our own protocol version identification. */
- snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s",
- compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
- compat20 ? PROTOCOL_MINOR_2 : minor1,
- SSH_VERSION, compat20 ? "\r\n" : "\n");
- if (roaming_atomicio(vwrite, connection_out, buf, strlen(buf))
- != strlen(buf))
- fatal("write: %.100s", strerror(errno));
- client_version_string = xstrdup(buf);
- chop(client_version_string);
+ if (!client_banner_sent)
+ send_client_banner(connection_out, minor1);
chop(server_version_string);
- debug("Local version string %.100s", client_version_string);
}
/* defaults to 'no' */