summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c158
1 files changed, 118 insertions, 40 deletions
diff --git a/sshd.c b/sshd.c
index efa3f4c13..be3b3b8bb 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
@@ -370,9 +373,6 @@ grace_alarm_handler(int sig)
370static void 373static void
371generate_ephemeral_server_key(void) 374generate_ephemeral_server_key(void)
372{ 375{
373 u_int32_t rnd = 0;
374 int i;
375
376 verbose("Generating %s%d bit RSA key.", 376 verbose("Generating %s%d bit RSA key.",
377 sensitive_data.server_key ? "new " : "", options.server_key_bits); 377 sensitive_data.server_key ? "new " : "", options.server_key_bits);
378 if (sensitive_data.server_key != NULL) 378 if (sensitive_data.server_key != NULL)
@@ -381,12 +381,7 @@ generate_ephemeral_server_key(void)
381 options.server_key_bits); 381 options.server_key_bits);
382 verbose("RSA key generation complete."); 382 verbose("RSA key generation complete.");
383 383
384 for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { 384 arc4random_buf(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH);
385 if (i % 4 == 0)
386 rnd = arc4random();
387 sensitive_data.ssh1_cookie[i] = rnd & 0xff;
388 rnd >>= 8;
389 }
390 arc4random_stir(); 385 arc4random_stir();
391} 386}
392 387
@@ -408,7 +403,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
408 int mismatch; 403 int mismatch;
409 int remote_major, remote_minor; 404 int remote_major, remote_minor;
410 int major, minor; 405 int major, minor;
411 char *s; 406 char *s, *newline = "\n";
412 char buf[256]; /* Must not be larger than remote_version. */ 407 char buf[256]; /* Must not be larger than remote_version. */
413 char remote_version[256]; /* Must be at least as big as buf. */ 408 char remote_version[256]; /* Must be at least as big as buf. */
414 409
@@ -419,11 +414,13 @@ sshd_exchange_identification(int sock_in, int sock_out)
419 } else if (options.protocol & SSH_PROTO_2) { 414 } else if (options.protocol & SSH_PROTO_2) {
420 major = PROTOCOL_MAJOR_2; 415 major = PROTOCOL_MAJOR_2;
421 minor = PROTOCOL_MINOR_2; 416 minor = PROTOCOL_MINOR_2;
417 newline = "\r\n";
422 } else { 418 } else {
423 major = PROTOCOL_MAJOR_1; 419 major = PROTOCOL_MAJOR_1;
424 minor = PROTOCOL_MINOR_1; 420 minor = PROTOCOL_MINOR_1;
425 } 421 }
426 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION); 422 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor,
423 SSH_VERSION, newline);
427 server_version_string = xstrdup(buf); 424 server_version_string = xstrdup(buf);
428 425
429 /* Send our protocol version identification. */ 426 /* Send our protocol version identification. */
@@ -585,15 +582,14 @@ demote_sensitive_data(void)
585static void 582static void
586privsep_preauth_child(void) 583privsep_preauth_child(void)
587{ 584{
588 u_int32_t rnd[256]; 585 u_int32_t rnd[256];
589 gid_t gidset[1]; 586 gid_t gidset[1];
590 int i;
591 587
592 /* Enable challenge-response authentication for privilege separation */ 588 /* Enable challenge-response authentication for privilege separation */
593 privsep_challenge_enable(); 589 privsep_challenge_enable();
594 590
595 for (i = 0; i < 256; i++) 591 arc4random_stir();
596 rnd[i] = arc4random(); 592 arc4random_buf(rnd, sizeof(rnd));
597 RAND_seed(rnd, sizeof(rnd)); 593 RAND_seed(rnd, sizeof(rnd));
598 594
599 /* Demote the private keys to public keys. */ 595 /* Demote the private keys to public keys. */
@@ -666,6 +662,8 @@ privsep_preauth(Authctxt *authctxt)
666static void 662static void
667privsep_postauth(Authctxt *authctxt) 663privsep_postauth(Authctxt *authctxt)
668{ 664{
665 u_int32_t rnd[256];
666
669#ifdef DISABLE_FD_PASSING 667#ifdef DISABLE_FD_PASSING
670 if (1) { 668 if (1) {
671#else 669#else
@@ -683,7 +681,7 @@ privsep_postauth(Authctxt *authctxt)
683 if (pmonitor->m_pid == -1) 681 if (pmonitor->m_pid == -1)
684 fatal("fork of unprivileged child failed"); 682 fatal("fork of unprivileged child failed");
685 else if (pmonitor->m_pid != 0) { 683 else if (pmonitor->m_pid != 0) {
686 debug2("User child is on pid %ld", (long)pmonitor->m_pid); 684 verbose("User child is on pid %ld", (long)pmonitor->m_pid);
687 close(pmonitor->m_recvfd); 685 close(pmonitor->m_recvfd);
688 buffer_clear(&loginmsg); 686 buffer_clear(&loginmsg);
689 monitor_child_postauth(pmonitor); 687 monitor_child_postauth(pmonitor);
@@ -697,6 +695,10 @@ privsep_postauth(Authctxt *authctxt)
697 /* Demote the private keys to public keys. */ 695 /* Demote the private keys to public keys. */
698 demote_sensitive_data(); 696 demote_sensitive_data();
699 697
698 arc4random_stir();
699 arc4random_buf(rnd, sizeof(rnd));
700 RAND_seed(rnd, sizeof(rnd));
701
700 /* Drop privileges */ 702 /* Drop privileges */
701 do_setusercontext(authctxt->pw); 703 do_setusercontext(authctxt->pw);
702 704
@@ -796,7 +798,7 @@ drop_connection(int startups)
796 p *= startups - options.max_startups_begin; 798 p *= startups - options.max_startups_begin;
797 p /= options.max_startups - options.max_startups_begin; 799 p /= options.max_startups - options.max_startups_begin;
798 p += options.max_startups_rate; 800 p += options.max_startups_rate;
799 r = arc4random() % 100; 801 r = arc4random_uniform(100);
800 802
801 debug("drop_connection: p %d, r %d", p, r); 803 debug("drop_connection: p %d, r %d", p, r);
802 return (r < p) ? 1 : 0; 804 return (r < p) ? 1 : 0;
@@ -808,8 +810,9 @@ usage(void)
808 fprintf(stderr, "%s, %s\n", 810 fprintf(stderr, "%s, %s\n",
809 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); 811 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
810 fprintf(stderr, 812 fprintf(stderr,
811"usage: sshd [-46Ddeiqt] [-b bits] [-f config_file] [-g login_grace_time]\n" 813"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-f config_file]\n"
812" [-h host_key_file] [-k key_gen_time] [-o option] [-p port] [-u len]\n" 814" [-g login_grace_time] [-h host_key_file] [-k key_gen_time]\n"
815" [-o option] [-p port] [-u len]\n"
813 ); 816 );
814 exit(1); 817 exit(1);
815} 818}
@@ -957,8 +960,7 @@ server_listen(void)
957 ntop, sizeof(ntop), strport, sizeof(strport), 960 ntop, sizeof(ntop), strport, sizeof(strport),
958 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { 961 NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
959 error("getnameinfo failed: %.100s", 962 error("getnameinfo failed: %.100s",
960 (ret != EAI_SYSTEM) ? gai_strerror(ret) : 963 ssh_gai_strerror(ret));
961 strerror(errno));
962 continue; 964 continue;
963 } 965 }
964 /* Create socket for listening. */ 966 /* Create socket for listening. */
@@ -981,6 +983,16 @@ server_listen(void)
981 &on, sizeof(on)) == -1) 983 &on, sizeof(on)) == -1)
982 error("setsockopt SO_REUSEADDR: %s", strerror(errno)); 984 error("setsockopt SO_REUSEADDR: %s", strerror(errno));
983 985
986#ifdef IPV6_V6ONLY
987 /* Only communicate in IPv6 over AF_INET6 sockets. */
988 if (ai->ai_family == AF_INET6) {
989 if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY,
990 &on, sizeof(on)) == -1)
991 error("setsockopt IPV6_V6ONLY: %s",
992 strerror(errno));
993 }
994#endif
995
984 debug("Bind to port %s on %s.", strport, ntop); 996 debug("Bind to port %s on %s.", strport, ntop);
985 997
986 /* Bind the socket to the desired port. */ 998 /* Bind the socket to the desired port. */
@@ -1088,7 +1100,8 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
1088 *newsock = accept(listen_socks[i], 1100 *newsock = accept(listen_socks[i],
1089 (struct sockaddr *)&from, &fromlen); 1101 (struct sockaddr *)&from, &fromlen);
1090 if (*newsock < 0) { 1102 if (*newsock < 0) {
1091 if (errno != EINTR && errno != EWOULDBLOCK) 1103 if (errno != EINTR && errno != EAGAIN &&
1104 errno != EWOULDBLOCK)
1092 error("accept: %.100s", strerror(errno)); 1105 error("accept: %.100s", strerror(errno));
1093 continue; 1106 continue;
1094 } 1107 }
@@ -1235,9 +1248,12 @@ main(int ac, char **av)
1235 int opt, i, on = 1; 1248 int opt, i, on = 1;
1236 int sock_in = -1, sock_out = -1, newsock = -1; 1249 int sock_in = -1, sock_out = -1, newsock = -1;
1237 const char *remote_ip; 1250 const char *remote_ip;
1251 char *test_user = NULL, *test_host = NULL, *test_addr = NULL;
1238 int remote_port; 1252 int remote_port;
1239 char *line; 1253 char *line, *p, *cp;
1240 int config_s[2] = { -1 , -1 }; 1254 int config_s[2] = { -1 , -1 };
1255 u_int64_t ibytes, obytes;
1256 mode_t new_umask;
1241 Key *key; 1257 Key *key;
1242 Authctxt *authctxt; 1258 Authctxt *authctxt;
1243 1259
@@ -1271,7 +1287,7 @@ main(int ac, char **av)
1271 initialize_server_options(&options); 1287 initialize_server_options(&options);
1272 1288
1273 /* Parse command-line arguments. */ 1289 /* Parse command-line arguments. */
1274 while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46")) != -1) { 1290 while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:dDeiqrtQRT46")) != -1) {
1275 switch (opt) { 1291 switch (opt) {
1276 case '4': 1292 case '4':
1277 options.address_family = AF_INET; 1293 options.address_family = AF_INET;
@@ -1349,6 +1365,25 @@ main(int ac, char **av)
1349 case 't': 1365 case 't':
1350 test_flag = 1; 1366 test_flag = 1;
1351 break; 1367 break;
1368 case 'T':
1369 test_flag = 2;
1370 break;
1371 case 'C':
1372 cp = optarg;
1373 while ((p = strsep(&cp, ",")) && *p != '\0') {
1374 if (strncmp(p, "addr=", 5) == 0)
1375 test_addr = xstrdup(p + 5);
1376 else if (strncmp(p, "host=", 5) == 0)
1377 test_host = xstrdup(p + 5);
1378 else if (strncmp(p, "user=", 5) == 0)
1379 test_user = xstrdup(p + 5);
1380 else {
1381 fprintf(stderr, "Invalid test "
1382 "mode specification %s\n", p);
1383 exit(1);
1384 }
1385 }
1386 break;
1352 case 'u': 1387 case 'u':
1353 utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL); 1388 utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL);
1354 if (utmp_len > MAXHOSTNAMELEN) { 1389 if (utmp_len > MAXHOSTNAMELEN) {
@@ -1371,7 +1406,7 @@ main(int ac, char **av)
1371 } 1406 }
1372 if (rexeced_flag || inetd_flag) 1407 if (rexeced_flag || inetd_flag)
1373 rexec_flag = 0; 1408 rexec_flag = 0;
1374 if (rexec_flag && (av[0] == NULL || *av[0] != '/')) 1409 if (!test_flag && (rexec_flag && (av[0] == NULL || *av[0] != '/')))
1375 fatal("sshd re-exec requires execution with an absolute path"); 1410 fatal("sshd re-exec requires execution with an absolute path");
1376 if (rexeced_flag) 1411 if (rexeced_flag)
1377 closefrom(REEXEC_MIN_FREE_FD); 1412 closefrom(REEXEC_MIN_FREE_FD);
@@ -1410,6 +1445,21 @@ main(int ac, char **av)
1410 sensitive_data.have_ssh1_key = 0; 1445 sensitive_data.have_ssh1_key = 0;
1411 sensitive_data.have_ssh2_key = 0; 1446 sensitive_data.have_ssh2_key = 0;
1412 1447
1448 /*
1449 * If we're doing an extended config test, make sure we have all of
1450 * the parameters we need. If we're not doing an extended test,
1451 * do not silently ignore connection test params.
1452 */
1453 if (test_flag >= 2 &&
1454 (test_user != NULL || test_host != NULL || test_addr != NULL)
1455 && (test_user == NULL || test_host == NULL || test_addr == NULL))
1456 fatal("user, host and addr are all required when testing "
1457 "Match configs");
1458 if (test_flag < 2 && (test_user != NULL || test_host != NULL ||
1459 test_addr != NULL))
1460 fatal("Config test connection parameter (-C) provided without "
1461 "test mode (-T)");
1462
1413 /* Fetch our configuration */ 1463 /* Fetch our configuration */
1414 buffer_init(&cfg); 1464 buffer_init(&cfg);
1415 if (rexeced_flag) 1465 if (rexeced_flag)
@@ -1541,6 +1591,13 @@ main(int ac, char **av)
1541 "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); 1591 "world-writable.", _PATH_PRIVSEP_CHROOT_DIR);
1542 } 1592 }
1543 1593
1594 if (test_flag > 1) {
1595 if (test_user != NULL && test_addr != NULL && test_host != NULL)
1596 parse_server_match_config(&options, test_user,
1597 test_host, test_addr);
1598 dump_config(&options);
1599 }
1600
1544 /* Configuration looks good, so exit if in test mode. */ 1601 /* Configuration looks good, so exit if in test mode. */
1545 if (test_flag) 1602 if (test_flag)
1546 exit(0); 1603 exit(0);
@@ -1565,6 +1622,10 @@ main(int ac, char **av)
1565 rexec_argv[rexec_argc + 1] = NULL; 1622 rexec_argv[rexec_argc + 1] = NULL;
1566 } 1623 }
1567 1624
1625 /* Ensure that umask disallows at least group and world write */
1626 new_umask = umask(0077) | 0022;
1627 (void) umask(new_umask);
1628
1568 /* Initialize the log (it is reinitialized below in case we forked). */ 1629 /* Initialize the log (it is reinitialized below in case we forked). */
1569 if (debug_flag && (!inetd_flag || rexeced_flag)) 1630 if (debug_flag && (!inetd_flag || rexeced_flag))
1570 log_stderr = 1; 1631 log_stderr = 1;
@@ -1607,10 +1668,6 @@ main(int ac, char **av)
1607 /* Get a connection, either from inetd or a listening TCP socket */ 1668 /* Get a connection, either from inetd or a listening TCP socket */
1608 if (inetd_flag) { 1669 if (inetd_flag) {
1609 server_accept_inetd(&sock_in, &sock_out); 1670 server_accept_inetd(&sock_in, &sock_out);
1610
1611 if ((options.protocol & SSH_PROTO_1) &&
1612 sensitive_data.server_key == NULL)
1613 generate_ephemeral_server_key();
1614 } else { 1671 } else {
1615 server_listen(); 1672 server_listen();
1616 1673
@@ -1747,6 +1804,8 @@ main(int ac, char **av)
1747 audit_connection_from(remote_ip, remote_port); 1804 audit_connection_from(remote_ip, remote_port);
1748#endif 1805#endif
1749#ifdef LIBWRAP 1806#ifdef LIBWRAP
1807 allow_severity = options.log_facility|LOG_INFO;
1808 deny_severity = options.log_facility|LOG_WARNING;
1750 /* Check whether logins are denied from this host. */ 1809 /* Check whether logins are denied from this host. */
1751 if (packet_connection_is_on_socket()) { 1810 if (packet_connection_is_on_socket()) {
1752 struct request_info req; 1811 struct request_info req;
@@ -1834,6 +1893,10 @@ main(int ac, char **av)
1834 1893
1835 sshd_exchange_identification(sock_in, sock_out); 1894 sshd_exchange_identification(sock_in, sock_out);
1836 1895
1896 /* In inetd mode, generate ephemeral key only for proto 1 connections */
1897 if (!compat20 && inetd_flag && sensitive_data.server_key == NULL)
1898 generate_ephemeral_server_key();
1899
1837 packet_set_nonblocking(); 1900 packet_set_nonblocking();
1838 1901
1839 /* allocate authentication context */ 1902 /* allocate authentication context */
@@ -1886,6 +1949,20 @@ main(int ac, char **av)
1886 audit_event(SSH_AUTH_SUCCESS); 1949 audit_event(SSH_AUTH_SUCCESS);
1887#endif 1950#endif
1888 1951
1952#ifdef GSSAPI
1953 if (options.gss_authentication) {
1954 temporarily_use_uid(authctxt->pw);
1955 ssh_gssapi_storecreds();
1956 restore_uid();
1957 }
1958#endif
1959#ifdef USE_PAM
1960 if (options.use_pam) {
1961 do_pam_setcred(1);
1962 do_pam_session();
1963 }
1964#endif
1965
1889 /* 1966 /*
1890 * In privilege separation, we fork another child and prepare 1967 * In privilege separation, we fork another child and prepare
1891 * file descriptor passing. 1968 * file descriptor passing.
@@ -1897,11 +1974,18 @@ main(int ac, char **av)
1897 destroy_sensitive_data(); 1974 destroy_sensitive_data();
1898 } 1975 }
1899 1976
1977 packet_set_timeout(options.client_alive_interval,
1978 options.client_alive_count_max);
1979
1900 /* Start session. */ 1980 /* Start session. */
1901 do_authenticated(authctxt); 1981 do_authenticated(authctxt);
1902 1982
1903 /* The connection has been terminated. */ 1983 /* The connection has been terminated. */
1904 verbose("Closing connection to %.100s", remote_ip); 1984 packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes);
1985 packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes);
1986 verbose("Transferred: sent %llu, received %llu bytes", obytes, ibytes);
1987
1988 verbose("Closing connection to %.500s port %d", remote_ip, remote_port);
1905 1989
1906#ifdef USE_PAM 1990#ifdef USE_PAM
1907 if (options.use_pam) 1991 if (options.use_pam)
@@ -1981,7 +2065,6 @@ do_ssh1_kex(void)
1981 u_char session_key[SSH_SESSION_KEY_LENGTH]; 2065 u_char session_key[SSH_SESSION_KEY_LENGTH];
1982 u_char cookie[8]; 2066 u_char cookie[8];
1983 u_int cipher_type, auth_mask, protocol_flags; 2067 u_int cipher_type, auth_mask, protocol_flags;
1984 u_int32_t rnd = 0;
1985 2068
1986 /* 2069 /*
1987 * Generate check bytes that the client must send back in the user 2070 * Generate check bytes that the client must send back in the user
@@ -1992,12 +2075,7 @@ do_ssh1_kex(void)
1992 * cookie. This only affects rhosts authentication, and this is one 2075 * cookie. This only affects rhosts authentication, and this is one
1993 * of the reasons why it is inherently insecure. 2076 * of the reasons why it is inherently insecure.
1994 */ 2077 */
1995 for (i = 0; i < 8; i++) { 2078 arc4random_buf(cookie, sizeof(cookie));
1996 if (i % 4 == 0)
1997 rnd = arc4random();
1998 cookie[i] = rnd & 0xff;
1999 rnd >>= 8;
2000 }
2001 2079
2002 /* 2080 /*
2003 * Send our public key. We include in the packet 64 bits of random 2081 * Send our public key. We include in the packet 64 bits of random