summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c160
1 files changed, 119 insertions, 41 deletions
diff --git a/sshd.c b/sshd.c
index 9097d71ad..9e03cf3ef 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.351 2007/05/22 10:18:52 djm Exp $ */ 1/* $OpenBSD: sshd.c,v 1.364 2008/07/10 18:08:11 markus 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
@@ -54,6 +54,7 @@
54# include <sys/time.h> 54# include <sys/time.h>
55#endif 55#endif
56#include "openbsd-compat/sys-tree.h" 56#include "openbsd-compat/sys-tree.h"
57#include "openbsd-compat/sys-queue.h"
57#include <sys/wait.h> 58#include <sys/wait.h>
58 59
59#include <errno.h> 60#include <errno.h>
@@ -75,6 +76,8 @@
75#include <openssl/bn.h> 76#include <openssl/bn.h>
76#include <openssl/md5.h> 77#include <openssl/md5.h>
77#include <openssl/rand.h> 78#include <openssl/rand.h>
79#include "openbsd-compat/openssl-compat.h"
80
78#ifdef HAVE_SECUREWARE 81#ifdef HAVE_SECUREWARE
79#include <sys/security.h> 82#include <sys/security.h>
80#include <prot.h> 83#include <prot.h>
@@ -124,8 +127,8 @@
124#ifdef LIBWRAP 127#ifdef LIBWRAP
125#include <tcpd.h> 128#include <tcpd.h>
126#include <syslog.h> 129#include <syslog.h>
127int allow_severity = LOG_INFO; 130int allow_severity;
128int deny_severity = LOG_WARNING; 131int deny_severity;
129#endif /* LIBWRAP */ 132#endif /* LIBWRAP */
130 133
131#ifndef O_NOCTTY 134#ifndef O_NOCTTY
@@ -375,9 +378,6 @@ grace_alarm_handler(int sig)
375static void 378static void
376generate_ephemeral_server_key(void) 379generate_ephemeral_server_key(void)
377{ 380{
378 u_int32_t rnd = 0;
379 int i;
380
381 verbose("Generating %s%d bit RSA key.", 381 verbose("Generating %s%d bit RSA key.",
382 sensitive_data.server_key ? "new " : "", options.server_key_bits); 382 sensitive_data.server_key ? "new " : "", options.server_key_bits);
383 if (sensitive_data.server_key != NULL) 383 if (sensitive_data.server_key != NULL)
@@ -386,12 +386,7 @@ generate_ephemeral_server_key(void)
386 options.server_key_bits); 386 options.server_key_bits);
387 verbose("RSA key generation complete."); 387 verbose("RSA key generation complete.");
388 388
389 for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { 389 arc4random_buf(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH);
390 if (i % 4 == 0)
391 rnd = arc4random();
392 sensitive_data.ssh1_cookie[i] = rnd & 0xff;
393 rnd >>= 8;
394 }
395 arc4random_stir(); 390 arc4random_stir();
396} 391}
397 392
@@ -413,7 +408,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
413 int mismatch; 408 int mismatch;
414 int remote_major, remote_minor; 409 int remote_major, remote_minor;
415 int major, minor; 410 int major, minor;
416 char *s; 411 char *s, *newline = "\n";
417 char buf[256]; /* Must not be larger than remote_version. */ 412 char buf[256]; /* Must not be larger than remote_version. */
418 char remote_version[256]; /* Must be at least as big as buf. */ 413 char remote_version[256]; /* Must be at least as big as buf. */
419 414
@@ -424,11 +419,13 @@ sshd_exchange_identification(int sock_in, int sock_out)
424 } else if (options.protocol & SSH_PROTO_2) { 419 } else if (options.protocol & SSH_PROTO_2) {
425 major = PROTOCOL_MAJOR_2; 420 major = PROTOCOL_MAJOR_2;
426 minor = PROTOCOL_MINOR_2; 421 minor = PROTOCOL_MINOR_2;
422 newline = "\r\n";
427 } else { 423 } else {
428 major = PROTOCOL_MAJOR_1; 424 major = PROTOCOL_MAJOR_1;
429 minor = PROTOCOL_MINOR_1; 425 minor = PROTOCOL_MINOR_1;
430 } 426 }
431 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_RELEASE); 427 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor,
428 SSH_RELEASE, newline);
432 server_version_string = xstrdup(buf); 429 server_version_string = xstrdup(buf);
433 430
434 /* Send our protocol version identification. */ 431 /* Send our protocol version identification. */
@@ -590,15 +587,14 @@ demote_sensitive_data(void)
590static void 587static void
591privsep_preauth_child(void) 588privsep_preauth_child(void)
592{ 589{
593 u_int32_t rnd[256]; 590 u_int32_t rnd[256];
594 gid_t gidset[1]; 591 gid_t gidset[1];
595 int i;
596 592
597 /* Enable challenge-response authentication for privilege separation */ 593 /* Enable challenge-response authentication for privilege separation */
598 privsep_challenge_enable(); 594 privsep_challenge_enable();
599 595
600 for (i = 0; i < 256; i++) 596 arc4random_stir();
601 rnd[i] = arc4random(); 597 arc4random_buf(rnd, sizeof(rnd));
602 RAND_seed(rnd, sizeof(rnd)); 598 RAND_seed(rnd, sizeof(rnd));
603 599
604 /* Demote the private keys to public keys. */ 600 /* Demote the private keys to public keys. */
@@ -671,6 +667,8 @@ privsep_preauth(Authctxt *authctxt)
671static void 667static void
672privsep_postauth(Authctxt *authctxt) 668privsep_postauth(Authctxt *authctxt)
673{ 669{
670 u_int32_t rnd[256];
671
674#ifdef DISABLE_FD_PASSING 672#ifdef DISABLE_FD_PASSING
675 if (1) { 673 if (1) {
676#else 674#else
@@ -688,7 +686,7 @@ privsep_postauth(Authctxt *authctxt)
688 if (pmonitor->m_pid == -1) 686 if (pmonitor->m_pid == -1)
689 fatal("fork of unprivileged child failed"); 687 fatal("fork of unprivileged child failed");
690 else if (pmonitor->m_pid != 0) { 688 else if (pmonitor->m_pid != 0) {
691 debug2("User child is on pid %ld", (long)pmonitor->m_pid); 689 verbose("User child is on pid %ld", (long)pmonitor->m_pid);
692 close(pmonitor->m_recvfd); 690 close(pmonitor->m_recvfd);
693 buffer_clear(&loginmsg); 691 buffer_clear(&loginmsg);
694 monitor_child_postauth(pmonitor); 692 monitor_child_postauth(pmonitor);
@@ -702,6 +700,10 @@ privsep_postauth(Authctxt *authctxt)
702 /* Demote the private keys to public keys. */ 700 /* Demote the private keys to public keys. */
703 demote_sensitive_data(); 701 demote_sensitive_data();
704 702
703 arc4random_stir();
704 arc4random_buf(rnd, sizeof(rnd));
705 RAND_seed(rnd, sizeof(rnd));
706
705 /* Drop privileges */ 707 /* Drop privileges */
706 do_setusercontext(authctxt->pw); 708 do_setusercontext(authctxt->pw);
707 709
@@ -801,7 +803,7 @@ drop_connection(int startups)
801 p *= startups - options.max_startups_begin; 803 p *= startups - options.max_startups_begin;
802 p /= options.max_startups - options.max_startups_begin; 804 p /= options.max_startups - options.max_startups_begin;
803 p += options.max_startups_rate; 805 p += options.max_startups_rate;
804 r = arc4random() % 100; 806 r = arc4random_uniform(100);
805 807
806 debug("drop_connection: p %d, r %d", p, r); 808 debug("drop_connection: p %d, r %d", p, r);
807 return (r < p) ? 1 : 0; 809 return (r < p) ? 1 : 0;
@@ -813,8 +815,9 @@ usage(void)
813 fprintf(stderr, "%s, %s\n", 815 fprintf(stderr, "%s, %s\n",
814 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); 816 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
815 fprintf(stderr, 817 fprintf(stderr,
816"usage: sshd [-46Ddeiqt] [-b bits] [-f config_file] [-g login_grace_time]\n" 818"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-f config_file]\n"
817" [-h host_key_file] [-k key_gen_time] [-o option] [-p port] [-u len]\n" 819" [-g login_grace_time] [-h host_key_file] [-k key_gen_time]\n"
820" [-o option] [-p port] [-u len]\n"
818 ); 821 );
819 exit(1); 822 exit(1);
820} 823}
@@ -987,8 +990,7 @@ server_listen(void)
987 ntop, sizeof(ntop), strport, sizeof(strport), 990 ntop, sizeof(ntop), strport, sizeof(strport),
988 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { 991 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
989 error("getnameinfo failed: %.100s", 992 error("getnameinfo failed: %.100s",
990 (ret != EAI_SYSTEM) ? gai_strerror(ret) : 993 ssh_gai_strerror(ret));
991 strerror(errno));
992 continue; 994 continue;
993 } 995 }
994 /* Create socket for listening. */ 996 /* Create socket for listening. */
@@ -1011,6 +1013,16 @@ server_listen(void)
1011 &on, sizeof(on)) == -1) 1013 &on, sizeof(on)) == -1)
1012 error("setsockopt SO_REUSEADDR: %s", strerror(errno)); 1014 error("setsockopt SO_REUSEADDR: %s", strerror(errno));
1013 1015
1016#ifdef IPV6_V6ONLY
1017 /* Only communicate in IPv6 over AF_INET6 sockets. */
1018 if (ai->ai_family == AF_INET6) {
1019 if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY,
1020 &on, sizeof(on)) == -1)
1021 error("setsockopt IPV6_V6ONLY: %s",
1022 strerror(errno));
1023 }
1024#endif
1025
1014 debug("Bind to port %s on %s.", strport, ntop); 1026 debug("Bind to port %s on %s.", strport, ntop);
1015 1027
1016 /* Bind the socket to the desired port. */ 1028 /* Bind the socket to the desired port. */
@@ -1118,7 +1130,8 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
1118 *newsock = accept(listen_socks[i], 1130 *newsock = accept(listen_socks[i],
1119 (struct sockaddr *)&from, &fromlen); 1131 (struct sockaddr *)&from, &fromlen);
1120 if (*newsock < 0) { 1132 if (*newsock < 0) {
1121 if (errno != EINTR && errno != EWOULDBLOCK) 1133 if (errno != EINTR && errno != EAGAIN &&
1134 errno != EWOULDBLOCK)
1122 error("accept: %.100s", strerror(errno)); 1135 error("accept: %.100s", strerror(errno));
1123 continue; 1136 continue;
1124 } 1137 }
@@ -1265,9 +1278,12 @@ main(int ac, char **av)
1265 int opt, i, on = 1; 1278 int opt, i, on = 1;
1266 int sock_in = -1, sock_out = -1, newsock = -1; 1279 int sock_in = -1, sock_out = -1, newsock = -1;
1267 const char *remote_ip; 1280 const char *remote_ip;
1281 char *test_user = NULL, *test_host = NULL, *test_addr = NULL;
1268 int remote_port; 1282 int remote_port;
1269 char *line; 1283 char *line, *p, *cp;
1270 int config_s[2] = { -1 , -1 }; 1284 int config_s[2] = { -1 , -1 };
1285 u_int64_t ibytes, obytes;
1286 mode_t new_umask;
1271 Key *key; 1287 Key *key;
1272 Authctxt *authctxt; 1288 Authctxt *authctxt;
1273 1289
@@ -1301,7 +1317,7 @@ main(int ac, char **av)
1301 initialize_server_options(&options); 1317 initialize_server_options(&options);
1302 1318
1303 /* Parse command-line arguments. */ 1319 /* Parse command-line arguments. */
1304 while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46")) != -1) { 1320 while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:dDeiqrtQRT46")) != -1) {
1305 switch (opt) { 1321 switch (opt) {
1306 case '4': 1322 case '4':
1307 options.address_family = AF_INET; 1323 options.address_family = AF_INET;
@@ -1384,6 +1400,25 @@ main(int ac, char **av)
1384 case 't': 1400 case 't':
1385 test_flag = 1; 1401 test_flag = 1;
1386 break; 1402 break;
1403 case 'T':
1404 test_flag = 2;
1405 break;
1406 case 'C':
1407 cp = optarg;
1408 while ((p = strsep(&cp, ",")) && *p != '\0') {
1409 if (strncmp(p, "addr=", 5) == 0)
1410 test_addr = xstrdup(p + 5);
1411 else if (strncmp(p, "host=", 5) == 0)
1412 test_host = xstrdup(p + 5);
1413 else if (strncmp(p, "user=", 5) == 0)
1414 test_user = xstrdup(p + 5);
1415 else {
1416 fprintf(stderr, "Invalid test "
1417 "mode specification %s\n", p);
1418 exit(1);
1419 }
1420 }
1421 break;
1387 case 'u': 1422 case 'u':
1388 utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL); 1423 utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL);
1389 if (utmp_len > MAXHOSTNAMELEN) { 1424 if (utmp_len > MAXHOSTNAMELEN) {
@@ -1406,7 +1441,7 @@ main(int ac, char **av)
1406 } 1441 }
1407 if (rexeced_flag || inetd_flag) 1442 if (rexeced_flag || inetd_flag)
1408 rexec_flag = 0; 1443 rexec_flag = 0;
1409 if (rexec_flag && (av[0] == NULL || *av[0] != '/')) 1444 if (!test_flag && (rexec_flag && (av[0] == NULL || *av[0] != '/')))
1410 fatal("sshd re-exec requires execution with an absolute path"); 1445 fatal("sshd re-exec requires execution with an absolute path");
1411 if (rexeced_flag) 1446 if (rexeced_flag)
1412 closefrom(REEXEC_MIN_FREE_FD); 1447 closefrom(REEXEC_MIN_FREE_FD);
@@ -1445,6 +1480,21 @@ main(int ac, char **av)
1445 sensitive_data.have_ssh1_key = 0; 1480 sensitive_data.have_ssh1_key = 0;
1446 sensitive_data.have_ssh2_key = 0; 1481 sensitive_data.have_ssh2_key = 0;
1447 1482
1483 /*
1484 * If we're doing an extended config test, make sure we have all of
1485 * the parameters we need. If we're not doing an extended test,
1486 * do not silently ignore connection test params.
1487 */
1488 if (test_flag >= 2 &&
1489 (test_user != NULL || test_host != NULL || test_addr != NULL)
1490 && (test_user == NULL || test_host == NULL || test_addr == NULL))
1491 fatal("user, host and addr are all required when testing "
1492 "Match configs");
1493 if (test_flag < 2 && (test_user != NULL || test_host != NULL ||
1494 test_addr != NULL))
1495 fatal("Config test connection parameter (-C) provided without "
1496 "test mode (-T)");
1497
1448 /* Fetch our configuration */ 1498 /* Fetch our configuration */
1449 buffer_init(&cfg); 1499 buffer_init(&cfg);
1450 if (rexeced_flag) 1500 if (rexeced_flag)
@@ -1581,6 +1631,13 @@ main(int ac, char **av)
1581 "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); 1631 "world-writable.", _PATH_PRIVSEP_CHROOT_DIR);
1582 } 1632 }
1583 1633
1634 if (test_flag > 1) {
1635 if (test_user != NULL && test_addr != NULL && test_host != NULL)
1636 parse_server_match_config(&options, test_user,
1637 test_host, test_addr);
1638 dump_config(&options);
1639 }
1640
1584 /* Configuration looks good, so exit if in test mode. */ 1641 /* Configuration looks good, so exit if in test mode. */
1585 if (test_flag) 1642 if (test_flag)
1586 exit(0); 1643 exit(0);
@@ -1605,6 +1662,10 @@ main(int ac, char **av)
1605 rexec_argv[rexec_argc + 1] = NULL; 1662 rexec_argv[rexec_argc + 1] = NULL;
1606 } 1663 }
1607 1664
1665 /* Ensure that umask disallows at least group and world write */
1666 new_umask = umask(0077) | 0022;
1667 (void) umask(new_umask);
1668
1608 /* Initialize the log (it is reinitialized below in case we forked). */ 1669 /* Initialize the log (it is reinitialized below in case we forked). */
1609 if (debug_flag && (!inetd_flag || rexeced_flag)) 1670 if (debug_flag && (!inetd_flag || rexeced_flag))
1610 log_stderr = 1; 1671 log_stderr = 1;
@@ -1652,10 +1713,6 @@ main(int ac, char **av)
1652 /* Get a connection, either from inetd or a listening TCP socket */ 1713 /* Get a connection, either from inetd or a listening TCP socket */
1653 if (inetd_flag) { 1714 if (inetd_flag) {
1654 server_accept_inetd(&sock_in, &sock_out); 1715 server_accept_inetd(&sock_in, &sock_out);
1655
1656 if ((options.protocol & SSH_PROTO_1) &&
1657 sensitive_data.server_key == NULL)
1658 generate_ephemeral_server_key();
1659 } else { 1716 } else {
1660 server_listen(); 1717 server_listen();
1661 1718
@@ -1767,7 +1824,7 @@ main(int ac, char **av)
1767 * Register our connection. This turns encryption off because we do 1824 * Register our connection. This turns encryption off because we do
1768 * not have a key. 1825 * not have a key.
1769 */ 1826 */
1770 packet_set_connection(sock_in, sock_out, -1); 1827 packet_set_connection(sock_in, sock_out);
1771 packet_set_server(); 1828 packet_set_server();
1772 1829
1773 /* Set SO_KEEPALIVE if requested. */ 1830 /* Set SO_KEEPALIVE if requested. */
@@ -1796,6 +1853,8 @@ main(int ac, char **av)
1796 audit_connection_from(remote_ip, remote_port); 1853 audit_connection_from(remote_ip, remote_port);
1797#endif 1854#endif
1798#ifdef LIBWRAP 1855#ifdef LIBWRAP
1856 allow_severity = options.log_facility|LOG_INFO;
1857 deny_severity = options.log_facility|LOG_WARNING;
1799 /* Check whether logins are denied from this host. */ 1858 /* Check whether logins are denied from this host. */
1800 if (packet_connection_is_on_socket()) { 1859 if (packet_connection_is_on_socket()) {
1801 struct request_info req; 1860 struct request_info req;
@@ -1883,6 +1942,10 @@ main(int ac, char **av)
1883 1942
1884 sshd_exchange_identification(sock_in, sock_out); 1943 sshd_exchange_identification(sock_in, sock_out);
1885 1944
1945 /* In inetd mode, generate ephemeral key only for proto 1 connections */
1946 if (!compat20 && inetd_flag && sensitive_data.server_key == NULL)
1947 generate_ephemeral_server_key();
1948
1886 packet_set_nonblocking(); 1949 packet_set_nonblocking();
1887 1950
1888 /* allocate authentication context */ 1951 /* allocate authentication context */
@@ -1935,6 +1998,20 @@ main(int ac, char **av)
1935 audit_event(SSH_AUTH_SUCCESS); 1998 audit_event(SSH_AUTH_SUCCESS);
1936#endif 1999#endif
1937 2000
2001#ifdef GSSAPI
2002 if (options.gss_authentication) {
2003 temporarily_use_uid(authctxt->pw);
2004 ssh_gssapi_storecreds();
2005 restore_uid();
2006 }
2007#endif
2008#ifdef USE_PAM
2009 if (options.use_pam) {
2010 do_pam_setcred(1);
2011 do_pam_session();
2012 }
2013#endif
2014
1938 /* 2015 /*
1939 * In privilege separation, we fork another child and prepare 2016 * In privilege separation, we fork another child and prepare
1940 * file descriptor passing. 2017 * file descriptor passing.
@@ -1946,11 +2023,18 @@ main(int ac, char **av)
1946 destroy_sensitive_data(); 2023 destroy_sensitive_data();
1947 } 2024 }
1948 2025
2026 packet_set_timeout(options.client_alive_interval,
2027 options.client_alive_count_max);
2028
1949 /* Start session. */ 2029 /* Start session. */
1950 do_authenticated(authctxt); 2030 do_authenticated(authctxt);
1951 2031
1952 /* The connection has been terminated. */ 2032 /* The connection has been terminated. */
1953 verbose("Closing connection to %.100s", remote_ip); 2033 packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes);
2034 packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes);
2035 verbose("Transferred: sent %llu, received %llu bytes", obytes, ibytes);
2036
2037 verbose("Closing connection to %.500s port %d", remote_ip, remote_port);
1954 2038
1955#ifdef USE_PAM 2039#ifdef USE_PAM
1956 if (options.use_pam) 2040 if (options.use_pam)
@@ -2030,7 +2114,6 @@ do_ssh1_kex(void)
2030 u_char session_key[SSH_SESSION_KEY_LENGTH]; 2114 u_char session_key[SSH_SESSION_KEY_LENGTH];
2031 u_char cookie[8]; 2115 u_char cookie[8];
2032 u_int cipher_type, auth_mask, protocol_flags; 2116 u_int cipher_type, auth_mask, protocol_flags;
2033 u_int32_t rnd = 0;
2034 2117
2035 /* 2118 /*
2036 * Generate check bytes that the client must send back in the user 2119 * Generate check bytes that the client must send back in the user
@@ -2041,12 +2124,7 @@ do_ssh1_kex(void)
2041 * cookie. This only affects rhosts authentication, and this is one 2124 * cookie. This only affects rhosts authentication, and this is one
2042 * of the reasons why it is inherently insecure. 2125 * of the reasons why it is inherently insecure.
2043 */ 2126 */
2044 for (i = 0; i < 8; i++) { 2127 arc4random_buf(cookie, sizeof(cookie));
2045 if (i % 4 == 0)
2046 rnd = arc4random();
2047 cookie[i] = rnd & 0xff;
2048 rnd >>= 8;
2049 }
2050 2128
2051 /* 2129 /*
2052 * Send our public key. We include in the packet 64 bits of random 2130 * Send our public key. We include in the packet 64 bits of random