summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2018-12-27 03:25:24 +0000
committerDamien Miller <djm@mindrot.org>2018-12-27 14:38:22 +1100
commit0a843d9a0e805f14653a555f5c7a8ba99d62c12d (patch)
tree481f36e9fd1918be5449e369a97c086a1a8d2432 /sshd.c
parent434b587afe41c19391821e7392005068fda76248 (diff)
upstream: move client/server SSH-* banners to buffers under
ssh->kex and factor out the banner exchange. This eliminates some common code from the client and server. Also be more strict about handling \r characters - these should only be accepted immediately before \n (pointed out by Jann Horn). Inspired by a patch from Markus Schmidt. (lots of) feedback and ok markus@ OpenBSD-Commit-ID: 1cc7885487a6754f63641d7d3279b0941890275b
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c118
1 files changed, 4 insertions, 114 deletions
diff --git a/sshd.c b/sshd.c
index fb9d9b60f..3461383a0 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.519 2018/11/19 04:12:32 djm Exp $ */ 1/* $OpenBSD: sshd.c,v 1.520 2018/12/27 03:25:25 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -180,13 +180,6 @@ char **rexec_argv;
180int listen_socks[MAX_LISTEN_SOCKS]; 180int listen_socks[MAX_LISTEN_SOCKS];
181int num_listen_socks = 0; 181int num_listen_socks = 0;
182 182
183/*
184 * the client's version string, passed by sshd2 in compat mode. if != NULL,
185 * sshd will skip the version-number exchange
186 */
187char *client_version_string = NULL;
188char *server_version_string = NULL;
189
190/* Daemon's agent connection */ 183/* Daemon's agent connection */
191int auth_sock = -1; 184int auth_sock = -1;
192int have_agent = 0; 185int have_agent = 0;
@@ -363,108 +356,6 @@ grace_alarm_handler(int sig)
363 ssh_remote_ipaddr(active_state), ssh_remote_port(active_state)); 356 ssh_remote_ipaddr(active_state), ssh_remote_port(active_state));
364} 357}
365 358
366static void
367sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out)
368{
369 u_int i;
370 int remote_major, remote_minor;
371 char *s;
372 char buf[256]; /* Must not be larger than remote_version. */
373 char remote_version[256]; /* Must be at least as big as buf. */
374
375 xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s\r\n",
376 PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION,
377 *options.version_addendum == '\0' ? "" : " ",
378 options.version_addendum);
379
380 /* Send our protocol version identification. */
381 if (atomicio(vwrite, sock_out, server_version_string,
382 strlen(server_version_string))
383 != strlen(server_version_string)) {
384 logit("Could not write ident string to %s port %d",
385 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
386 cleanup_exit(255);
387 }
388
389 /* Read other sides version identification. */
390 memset(buf, 0, sizeof(buf));
391 for (i = 0; i < sizeof(buf) - 1; i++) {
392 if (atomicio(read, sock_in, &buf[i], 1) != 1) {
393 logit("Did not receive identification string "
394 "from %s port %d",
395 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
396 cleanup_exit(255);
397 }
398 if (buf[i] == '\r') {
399 buf[i] = 0;
400 /* Kludge for F-Secure Macintosh < 1.0.2 */
401 if (i == 12 &&
402 strncmp(buf, "SSH-1.5-W1.0", 12) == 0)
403 break;
404 continue;
405 }
406 if (buf[i] == '\n') {
407 buf[i] = 0;
408 break;
409 }
410 }
411 buf[sizeof(buf) - 1] = 0;
412 client_version_string = xstrdup(buf);
413
414 /*
415 * Check that the versions match. In future this might accept
416 * several versions and set appropriate flags to handle them.
417 */
418 if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n",
419 &remote_major, &remote_minor, remote_version) != 3) {
420 s = "Protocol mismatch.\n";
421 (void) atomicio(vwrite, sock_out, s, strlen(s));
422 logit("Bad protocol version identification '%.100s' "
423 "from %s port %d", client_version_string,
424 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
425 close(sock_in);
426 close(sock_out);
427 cleanup_exit(255);
428 }
429 debug("Client protocol version %d.%d; client software version %.100s",
430 remote_major, remote_minor, remote_version);
431
432 ssh->compat = compat_datafellows(remote_version);
433
434 if ((ssh->compat & SSH_BUG_PROBE) != 0) {
435 logit("probed from %s port %d with %s. Don't panic.",
436 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
437 client_version_string);
438 cleanup_exit(255);
439 }
440 if ((ssh->compat & SSH_BUG_SCANNER) != 0) {
441 logit("scanned from %s port %d with %s. Don't panic.",
442 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
443 client_version_string);
444 cleanup_exit(255);
445 }
446 if ((ssh->compat & SSH_BUG_RSASIGMD5) != 0) {
447 logit("Client version \"%.100s\" uses unsafe RSA signature "
448 "scheme; disabling use of RSA keys", remote_version);
449 }
450
451 chop(server_version_string);
452 debug("Local version string %.200s", server_version_string);
453
454 if (remote_major != 2 &&
455 !(remote_major == 1 && remote_minor == 99)) {
456 s = "Protocol major versions differ.\n";
457 (void) atomicio(vwrite, sock_out, s, strlen(s));
458 close(sock_in);
459 close(sock_out);
460 logit("Protocol major versions differ for %s port %d: "
461 "%.200s vs. %.200s",
462 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
463 server_version_string, client_version_string);
464 cleanup_exit(255);
465 }
466}
467
468/* Destroy the host and server keys. They will no longer be needed. */ 359/* Destroy the host and server keys. They will no longer be needed. */
469void 360void
470destroy_sensitive_data(void) 361destroy_sensitive_data(void)
@@ -2115,7 +2006,9 @@ main(int ac, char **av)
2115 if (!debug_flag) 2006 if (!debug_flag)
2116 alarm(options.login_grace_time); 2007 alarm(options.login_grace_time);
2117 2008
2118 sshd_exchange_identification(ssh, sock_in, sock_out); 2009 if (kex_exchange_identification(ssh, -1, options.version_addendum) != 0)
2010 cleanup_exit(255); /* error already logged */
2011
2119 packet_set_nonblocking(); 2012 packet_set_nonblocking();
2120 2013
2121 /* allocate authentication context */ 2014 /* allocate authentication context */
@@ -2303,9 +2196,6 @@ do_ssh2_kex(void)
2303# endif 2196# endif
2304#endif 2197#endif
2305 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 2198 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
2306 kex->server = 1;
2307 kex->client_version_string=client_version_string;
2308 kex->server_version_string=server_version_string;
2309 kex->load_host_public_key=&get_hostkey_public_by_type; 2199 kex->load_host_public_key=&get_hostkey_public_by_type;
2310 kex->load_host_private_key=&get_hostkey_private_by_type; 2200 kex->load_host_private_key=&get_hostkey_private_by_type;
2311 kex->host_key_index=&get_hostkey_index; 2201 kex->host_key_index=&get_hostkey_index;