diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 158 |
1 files changed, 118 insertions, 40 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 |
@@ -370,9 +373,6 @@ grace_alarm_handler(int sig) | |||
370 | static void | 373 | static void |
371 | generate_ephemeral_server_key(void) | 374 | generate_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) | |||
585 | static void | 582 | static void |
586 | privsep_preauth_child(void) | 583 | privsep_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) | |||
666 | static void | 662 | static void |
667 | privsep_postauth(Authctxt *authctxt) | 663 | privsep_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 |