diff options
author | Colin Watson <cjwatson@debian.org> | 2003-09-01 02:05:26 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2003-09-01 02:05:26 +0000 |
commit | 6d5a72bc1d98a42ba42f082e50a22e911c1d82d3 (patch) | |
tree | 1bf23174bdb6fc71e2846dda0eca195a418484e7 /sshd.c | |
parent | 2ee26b431f98cf1dc0e4fb9809ad1e0c879b8c08 (diff) | |
parent | 58657d96514cd6f16d82add8d6f4adbb36765758 (diff) |
Debian release 3.5p1-1.
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 93 |
1 files changed, 50 insertions, 43 deletions
@@ -42,7 +42,7 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include "includes.h" | 44 | #include "includes.h" |
45 | RCSID("$OpenBSD: sshd.c,v 1.251 2002/06/25 18:51:04 markus Exp $"); | 45 | RCSID("$OpenBSD: sshd.c,v 1.260 2002/09/27 10:42:09 mickey Exp $"); |
46 | 46 | ||
47 | #include <openssl/dh.h> | 47 | #include <openssl/dh.h> |
48 | #include <openssl/bn.h> | 48 | #include <openssl/bn.h> |
@@ -303,11 +303,8 @@ grace_alarm_handler(int sig) | |||
303 | { | 303 | { |
304 | /* XXX no idea how fix this signal handler */ | 304 | /* XXX no idea how fix this signal handler */ |
305 | 305 | ||
306 | /* Close the connection. */ | ||
307 | packet_close(); | ||
308 | |||
309 | /* Log error and exit. */ | 306 | /* Log error and exit. */ |
310 | fatal("Timeout before authentication for %s.", get_remote_ipaddr()); | 307 | fatal("Timeout before authentication for %s", get_remote_ipaddr()); |
311 | } | 308 | } |
312 | 309 | ||
313 | /* | 310 | /* |
@@ -320,7 +317,7 @@ grace_alarm_handler(int sig) | |||
320 | static void | 317 | static void |
321 | generate_ephemeral_server_key(void) | 318 | generate_ephemeral_server_key(void) |
322 | { | 319 | { |
323 | u_int32_t rand = 0; | 320 | u_int32_t rnd = 0; |
324 | int i; | 321 | int i; |
325 | 322 | ||
326 | verbose("Generating %s%d bit RSA key.", | 323 | verbose("Generating %s%d bit RSA key.", |
@@ -333,9 +330,9 @@ generate_ephemeral_server_key(void) | |||
333 | 330 | ||
334 | for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { | 331 | for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { |
335 | if (i % 4 == 0) | 332 | if (i % 4 == 0) |
336 | rand = arc4random(); | 333 | rnd = arc4random(); |
337 | sensitive_data.ssh1_cookie[i] = rand & 0xff; | 334 | sensitive_data.ssh1_cookie[i] = rnd & 0xff; |
338 | rand >>= 8; | 335 | rnd >>= 8; |
339 | } | 336 | } |
340 | arc4random_stir(); | 337 | arc4random_stir(); |
341 | } | 338 | } |
@@ -427,6 +424,12 @@ sshd_exchange_identification(int sock_in, int sock_out) | |||
427 | 424 | ||
428 | compat_datafellows(remote_version); | 425 | compat_datafellows(remote_version); |
429 | 426 | ||
427 | if (datafellows & SSH_BUG_PROBE) { | ||
428 | log("probed from %s with %s. Don't panic.", | ||
429 | get_remote_ipaddr(), client_version_string); | ||
430 | fatal_cleanup(); | ||
431 | } | ||
432 | |||
430 | if (datafellows & SSH_BUG_SCANNER) { | 433 | if (datafellows & SSH_BUG_SCANNER) { |
431 | log("scanned from %s with %s. Don't panic.", | 434 | log("scanned from %s with %s. Don't panic.", |
432 | get_remote_ipaddr(), client_version_string); | 435 | get_remote_ipaddr(), client_version_string); |
@@ -529,8 +532,8 @@ demote_sensitive_data(void) | |||
529 | static void | 532 | static void |
530 | privsep_preauth_child(void) | 533 | privsep_preauth_child(void) |
531 | { | 534 | { |
532 | u_int32_t rand[256]; | 535 | u_int32_t rnd[256]; |
533 | gid_t gidset[2]; | 536 | gid_t gidset[1]; |
534 | struct passwd *pw; | 537 | struct passwd *pw; |
535 | int i; | 538 | int i; |
536 | 539 | ||
@@ -538,8 +541,8 @@ privsep_preauth_child(void) | |||
538 | privsep_challenge_enable(); | 541 | privsep_challenge_enable(); |
539 | 542 | ||
540 | for (i = 0; i < 256; i++) | 543 | for (i = 0; i < 256; i++) |
541 | rand[i] = arc4random(); | 544 | rnd[i] = arc4random(); |
542 | RAND_seed(rand, sizeof(rand)); | 545 | RAND_seed(rnd, sizeof(rnd)); |
543 | 546 | ||
544 | /* Demote the private keys to public keys. */ | 547 | /* Demote the private keys to public keys. */ |
545 | demote_sensitive_data(); | 548 | demote_sensitive_data(); |
@@ -550,7 +553,7 @@ privsep_preauth_child(void) | |||
550 | memset(pw->pw_passwd, 0, strlen(pw->pw_passwd)); | 553 | memset(pw->pw_passwd, 0, strlen(pw->pw_passwd)); |
551 | endpwent(); | 554 | endpwent(); |
552 | 555 | ||
553 | /* Change our root directory*/ | 556 | /* Change our root directory */ |
554 | if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) | 557 | if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) |
555 | fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, | 558 | fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, |
556 | strerror(errno)); | 559 | strerror(errno)); |
@@ -573,7 +576,7 @@ privsep_preauth_child(void) | |||
573 | #endif | 576 | #endif |
574 | } | 577 | } |
575 | 578 | ||
576 | static Authctxt* | 579 | static Authctxt * |
577 | privsep_preauth(void) | 580 | privsep_preauth(void) |
578 | { | 581 | { |
579 | Authctxt *authctxt = NULL; | 582 | Authctxt *authctxt = NULL; |
@@ -589,6 +592,8 @@ privsep_preauth(void) | |||
589 | if (pid == -1) { | 592 | if (pid == -1) { |
590 | fatal("fork of unprivileged child failed"); | 593 | fatal("fork of unprivileged child failed"); |
591 | } else if (pid != 0) { | 594 | } else if (pid != 0) { |
595 | fatal_remove_cleanup((void (*) (void *)) packet_close, NULL); | ||
596 | |||
592 | debug2("Network child is on pid %ld", (long)pid); | 597 | debug2("Network child is on pid %ld", (long)pid); |
593 | 598 | ||
594 | close(pmonitor->m_recvfd); | 599 | close(pmonitor->m_recvfd); |
@@ -602,6 +607,10 @@ privsep_preauth(void) | |||
602 | while (waitpid(pid, &status, 0) < 0) | 607 | while (waitpid(pid, &status, 0) < 0) |
603 | if (errno != EINTR) | 608 | if (errno != EINTR) |
604 | break; | 609 | break; |
610 | |||
611 | /* Reinstall, since the child has finished */ | ||
612 | fatal_add_cleanup((void (*) (void *)) packet_close, NULL); | ||
613 | |||
605 | return (authctxt); | 614 | return (authctxt); |
606 | } else { | 615 | } else { |
607 | /* child */ | 616 | /* child */ |
@@ -624,7 +633,7 @@ privsep_postauth(Authctxt *authctxt) | |||
624 | /* XXX - Remote port forwarding */ | 633 | /* XXX - Remote port forwarding */ |
625 | x_authctxt = authctxt; | 634 | x_authctxt = authctxt; |
626 | 635 | ||
627 | #ifdef BROKEN_FD_PASSING | 636 | #ifdef DISABLE_FD_PASSING |
628 | if (1) { | 637 | if (1) { |
629 | #else | 638 | #else |
630 | if (authctxt->pw->pw_uid == 0 || options.use_login) { | 639 | if (authctxt->pw->pw_uid == 0 || options.use_login) { |
@@ -649,6 +658,8 @@ privsep_postauth(Authctxt *authctxt) | |||
649 | if (pmonitor->m_pid == -1) | 658 | if (pmonitor->m_pid == -1) |
650 | fatal("fork of unprivileged child failed"); | 659 | fatal("fork of unprivileged child failed"); |
651 | else if (pmonitor->m_pid != 0) { | 660 | else if (pmonitor->m_pid != 0) { |
661 | fatal_remove_cleanup((void (*) (void *)) packet_close, NULL); | ||
662 | |||
652 | debug2("User child is on pid %ld", (long)pmonitor->m_pid); | 663 | debug2("User child is on pid %ld", (long)pmonitor->m_pid); |
653 | close(pmonitor->m_recvfd); | 664 | close(pmonitor->m_recvfd); |
654 | monitor_child_postauth(pmonitor); | 665 | monitor_child_postauth(pmonitor); |
@@ -801,7 +812,6 @@ main(int ac, char **av) | |||
801 | const char *remote_ip; | 812 | const char *remote_ip; |
802 | int remote_port; | 813 | int remote_port; |
803 | FILE *f; | 814 | FILE *f; |
804 | struct linger linger; | ||
805 | struct addrinfo *ai; | 815 | struct addrinfo *ai; |
806 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; | 816 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
807 | int listen_sock, maxfd; | 817 | int listen_sock, maxfd; |
@@ -911,6 +921,10 @@ main(int ac, char **av) | |||
911 | break; | 921 | break; |
912 | case 'u': | 922 | case 'u': |
913 | utmp_len = atoi(optarg); | 923 | utmp_len = atoi(optarg); |
924 | if (utmp_len > MAXHOSTNAMELEN) { | ||
925 | fprintf(stderr, "Invalid utmp length.\n"); | ||
926 | exit(1); | ||
927 | } | ||
914 | break; | 928 | break; |
915 | case 'o': | 929 | case 'o': |
916 | if (process_server_config_line(&options, optarg, | 930 | if (process_server_config_line(&options, optarg, |
@@ -937,7 +951,7 @@ main(int ac, char **av) | |||
937 | SYSLOG_FACILITY_AUTH : options.log_facility, | 951 | SYSLOG_FACILITY_AUTH : options.log_facility, |
938 | !inetd_flag); | 952 | !inetd_flag); |
939 | 953 | ||
940 | #ifdef _CRAY | 954 | #ifdef _UNICOS |
941 | /* Cray can define user privs drop all prives now! | 955 | /* Cray can define user privs drop all prives now! |
942 | * Not needed on PRIV_SU systems! | 956 | * Not needed on PRIV_SU systems! |
943 | */ | 957 | */ |
@@ -961,7 +975,8 @@ main(int ac, char **av) | |||
961 | debug("sshd version %.100s", SSH_VERSION); | 975 | debug("sshd version %.100s", SSH_VERSION); |
962 | 976 | ||
963 | /* load private host keys */ | 977 | /* load private host keys */ |
964 | sensitive_data.host_keys = xmalloc(options.num_host_key_files*sizeof(Key*)); | 978 | sensitive_data.host_keys = xmalloc(options.num_host_key_files * |
979 | sizeof(Key *)); | ||
965 | for (i = 0; i < options.num_host_key_files; i++) | 980 | for (i = 0; i < options.num_host_key_files; i++) |
966 | sensitive_data.host_keys[i] = NULL; | 981 | sensitive_data.host_keys[i] = NULL; |
967 | sensitive_data.server_key = NULL; | 982 | sensitive_data.server_key = NULL; |
@@ -1040,7 +1055,14 @@ main(int ac, char **av) | |||
1040 | (S_ISDIR(st.st_mode) == 0)) | 1055 | (S_ISDIR(st.st_mode) == 0)) |
1041 | fatal("Missing privilege separation directory: %s", | 1056 | fatal("Missing privilege separation directory: %s", |
1042 | _PATH_PRIVSEP_CHROOT_DIR); | 1057 | _PATH_PRIVSEP_CHROOT_DIR); |
1058 | |||
1059 | #ifdef HAVE_CYGWIN | ||
1060 | if (check_ntsec(_PATH_PRIVSEP_CHROOT_DIR) && | ||
1061 | (st.st_uid != getuid () || | ||
1062 | (st.st_mode & (S_IWGRP|S_IWOTH)) != 0)) | ||
1063 | #else | ||
1043 | if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0) | 1064 | if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0) |
1065 | #endif | ||
1044 | fatal("Bad owner or mode for %s", | 1066 | fatal("Bad owner or mode for %s", |
1045 | _PATH_PRIVSEP_CHROOT_DIR); | 1067 | _PATH_PRIVSEP_CHROOT_DIR); |
1046 | } | 1068 | } |
@@ -1140,17 +1162,12 @@ main(int ac, char **av) | |||
1140 | continue; | 1162 | continue; |
1141 | } | 1163 | } |
1142 | /* | 1164 | /* |
1143 | * Set socket options. We try to make the port | 1165 | * Set socket options. |
1144 | * reusable and have it close as fast as possible | 1166 | * Allow local port reuse in TIME_WAIT. |
1145 | * without waiting in unnecessary wait states on | ||
1146 | * close. | ||
1147 | */ | 1167 | */ |
1148 | setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, | 1168 | if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, |
1149 | &on, sizeof(on)); | 1169 | &on, sizeof(on)) == -1) |
1150 | linger.l_onoff = 1; | 1170 | error("setsockopt SO_REUSEADDR: %s", strerror(errno)); |
1151 | linger.l_linger = 5; | ||
1152 | setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, | ||
1153 | &linger, sizeof(linger)); | ||
1154 | 1171 | ||
1155 | debug("Bind to port %s on %s.", strport, ntop); | 1172 | debug("Bind to port %s on %s.", strport, ntop); |
1156 | 1173 | ||
@@ -1399,16 +1416,6 @@ main(int ac, char **av) | |||
1399 | signal(SIGCHLD, SIG_DFL); | 1416 | signal(SIGCHLD, SIG_DFL); |
1400 | signal(SIGINT, SIG_DFL); | 1417 | signal(SIGINT, SIG_DFL); |
1401 | 1418 | ||
1402 | /* | ||
1403 | * Set socket options for the connection. We want the socket to | ||
1404 | * close as fast as possible without waiting for anything. If the | ||
1405 | * connection is not a socket, these will do nothing. | ||
1406 | */ | ||
1407 | /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ | ||
1408 | linger.l_onoff = 1; | ||
1409 | linger.l_linger = 5; | ||
1410 | setsockopt(sock_in, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)); | ||
1411 | |||
1412 | /* Set keepalives if requested. */ | 1419 | /* Set keepalives if requested. */ |
1413 | if (options.keepalives && | 1420 | if (options.keepalives && |
1414 | setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, | 1421 | setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, |
@@ -1596,7 +1603,7 @@ do_ssh1_kex(void) | |||
1596 | u_char session_key[SSH_SESSION_KEY_LENGTH]; | 1603 | u_char session_key[SSH_SESSION_KEY_LENGTH]; |
1597 | u_char cookie[8]; | 1604 | u_char cookie[8]; |
1598 | u_int cipher_type, auth_mask, protocol_flags; | 1605 | u_int cipher_type, auth_mask, protocol_flags; |
1599 | u_int32_t rand = 0; | 1606 | u_int32_t rnd = 0; |
1600 | 1607 | ||
1601 | /* | 1608 | /* |
1602 | * Generate check bytes that the client must send back in the user | 1609 | * Generate check bytes that the client must send back in the user |
@@ -1609,9 +1616,9 @@ do_ssh1_kex(void) | |||
1609 | */ | 1616 | */ |
1610 | for (i = 0; i < 8; i++) { | 1617 | for (i = 0; i < 8; i++) { |
1611 | if (i % 4 == 0) | 1618 | if (i % 4 == 0) |
1612 | rand = arc4random(); | 1619 | rnd = arc4random(); |
1613 | cookie[i] = rand & 0xff; | 1620 | cookie[i] = rnd & 0xff; |
1614 | rand >>= 8; | 1621 | rnd >>= 8; |
1615 | } | 1622 | } |
1616 | 1623 | ||
1617 | /* | 1624 | /* |