diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 160 |
1 files changed, 119 insertions, 41 deletions
@@ -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> |
127 | int allow_severity = LOG_INFO; | 130 | int allow_severity; |
128 | int deny_severity = LOG_WARNING; | 131 | int 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) | |||
375 | static void | 378 | static void |
376 | generate_ephemeral_server_key(void) | 379 | generate_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) | |||
590 | static void | 587 | static void |
591 | privsep_preauth_child(void) | 588 | privsep_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) | |||
671 | static void | 667 | static void |
672 | privsep_postauth(Authctxt *authctxt) | 668 | privsep_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 |