diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 75 |
1 files changed, 43 insertions, 32 deletions
@@ -42,7 +42,7 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include "includes.h" | 44 | #include "includes.h" |
45 | RCSID("$OpenBSD: sshd.c,v 1.301 2004/08/11 11:50:09 dtucker Exp $"); | 45 | RCSID("$OpenBSD: sshd.c,v 1.308 2005/02/08 22:24:57 dtucker Exp $"); |
46 | 46 | ||
47 | #include <openssl/dh.h> | 47 | #include <openssl/dh.h> |
48 | #include <openssl/bn.h> | 48 | #include <openssl/bn.h> |
@@ -112,12 +112,6 @@ ServerOptions options; | |||
112 | char *config_file_name = _PATH_SERVER_CONFIG_FILE; | 112 | char *config_file_name = _PATH_SERVER_CONFIG_FILE; |
113 | 113 | ||
114 | /* | 114 | /* |
115 | * Flag indicating whether IPv4 or IPv6. This can be set on the command line. | ||
116 | * Default value is AF_UNSPEC means both IPv4 and IPv6. | ||
117 | */ | ||
118 | int IPv4or6 = AF_UNSPEC; | ||
119 | |||
120 | /* | ||
121 | * Debug mode flag. This can be set on the command line. If debug | 115 | * Debug mode flag. This can be set on the command line. If debug |
122 | * mode is enabled, extra debugging output will be sent to the system | 116 | * mode is enabled, extra debugging output will be sent to the system |
123 | * log, the daemon will not go to background, and will exit after processing | 117 | * log, the daemon will not go to background, and will exit after processing |
@@ -750,7 +744,7 @@ get_hostkey_index(Key *key) | |||
750 | static int | 744 | static int |
751 | drop_connection(int startups) | 745 | drop_connection(int startups) |
752 | { | 746 | { |
753 | double p, r; | 747 | int p, r; |
754 | 748 | ||
755 | if (startups < options.max_startups_begin) | 749 | if (startups < options.max_startups_begin) |
756 | return 0; | 750 | return 0; |
@@ -761,12 +755,11 @@ drop_connection(int startups) | |||
761 | 755 | ||
762 | p = 100 - options.max_startups_rate; | 756 | p = 100 - options.max_startups_rate; |
763 | p *= startups - options.max_startups_begin; | 757 | p *= startups - options.max_startups_begin; |
764 | p /= (double) (options.max_startups - options.max_startups_begin); | 758 | p /= options.max_startups - options.max_startups_begin; |
765 | p += options.max_startups_rate; | 759 | p += options.max_startups_rate; |
766 | p /= 100.0; | 760 | r = arc4random() % 100; |
767 | r = arc4random() / (double) UINT_MAX; | ||
768 | 761 | ||
769 | debug("drop_connection: p %g, r %g", p, r); | 762 | debug("drop_connection: p %d, r %d", p, r); |
770 | return (r < p) ? 1 : 0; | 763 | return (r < p) ? 1 : 0; |
771 | } | 764 | } |
772 | 765 | ||
@@ -774,7 +767,7 @@ static void | |||
774 | usage(void) | 767 | usage(void) |
775 | { | 768 | { |
776 | fprintf(stderr, "%s, %s\n", | 769 | fprintf(stderr, "%s, %s\n", |
777 | SSH_VERSION, SSLeay_version(SSLEAY_VERSION)); | 770 | SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); |
778 | fprintf(stderr, | 771 | fprintf(stderr, |
779 | "usage: sshd [-46Ddeiqt] [-b bits] [-f config_file] [-g login_grace_time]\n" | 772 | "usage: sshd [-46Ddeiqt] [-b bits] [-f config_file] [-g login_grace_time]\n" |
780 | " [-h host_key_file] [-k key_gen_time] [-o option] [-p port] [-u len]\n" | 773 | " [-h host_key_file] [-k key_gen_time] [-o option] [-p port] [-u len]\n" |
@@ -884,7 +877,7 @@ main(int ac, char **av) | |||
884 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; | 877 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
885 | char *line; | 878 | char *line; |
886 | int listen_sock, maxfd; | 879 | int listen_sock, maxfd; |
887 | int startup_p[2], config_s[2]; | 880 | int startup_p[2] = { -1 , -1 }, config_s[2] = { -1 , -1 }; |
888 | int startups = 0; | 881 | int startups = 0; |
889 | Key *key; | 882 | Key *key; |
890 | Authctxt *authctxt; | 883 | Authctxt *authctxt; |
@@ -921,10 +914,10 @@ main(int ac, char **av) | |||
921 | while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46")) != -1) { | 914 | while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46")) != -1) { |
922 | switch (opt) { | 915 | switch (opt) { |
923 | case '4': | 916 | case '4': |
924 | IPv4or6 = AF_INET; | 917 | options.address_family = AF_INET; |
925 | break; | 918 | break; |
926 | case '6': | 919 | case '6': |
927 | IPv4or6 = AF_INET6; | 920 | options.address_family = AF_INET6; |
928 | break; | 921 | break; |
929 | case 'f': | 922 | case 'f': |
930 | config_file_name = optarg; | 923 | config_file_name = optarg; |
@@ -1030,7 +1023,6 @@ main(int ac, char **av) | |||
1030 | closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); | 1023 | closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); |
1031 | 1024 | ||
1032 | SSLeay_add_all_algorithms(); | 1025 | SSLeay_add_all_algorithms(); |
1033 | channel_set_af(IPv4or6); | ||
1034 | 1026 | ||
1035 | /* | 1027 | /* |
1036 | * Force logging to stderr until we have loaded the private host | 1028 | * Force logging to stderr until we have loaded the private host |
@@ -1043,13 +1035,13 @@ main(int ac, char **av) | |||
1043 | SYSLOG_FACILITY_AUTH : options.log_facility, | 1035 | SYSLOG_FACILITY_AUTH : options.log_facility, |
1044 | log_stderr || !inetd_flag); | 1036 | log_stderr || !inetd_flag); |
1045 | 1037 | ||
1046 | #ifdef _AIX | ||
1047 | /* | 1038 | /* |
1048 | * Unset KRB5CCNAME, otherwise the user's session may inherit it from | 1039 | * Unset KRB5CCNAME, otherwise the user's session may inherit it from |
1049 | * root's environment | 1040 | * root's environment |
1050 | */ | 1041 | */ |
1051 | unsetenv("KRB5CCNAME"); | 1042 | if (getenv("KRB5CCNAME") != NULL) |
1052 | #endif /* _AIX */ | 1043 | unsetenv("KRB5CCNAME"); |
1044 | |||
1053 | #ifdef _UNICOS | 1045 | #ifdef _UNICOS |
1054 | /* Cray can define user privs drop all privs now! | 1046 | /* Cray can define user privs drop all privs now! |
1055 | * Not needed on PRIV_SU systems! | 1047 | * Not needed on PRIV_SU systems! |
@@ -1080,13 +1072,16 @@ main(int ac, char **av) | |||
1080 | /* Fill in default values for those options not explicitly set. */ | 1072 | /* Fill in default values for those options not explicitly set. */ |
1081 | fill_default_server_options(&options); | 1073 | fill_default_server_options(&options); |
1082 | 1074 | ||
1075 | /* set default channel AF */ | ||
1076 | channel_set_af(options.address_family); | ||
1077 | |||
1083 | /* Check that there are no remaining arguments. */ | 1078 | /* Check that there are no remaining arguments. */ |
1084 | if (optind < ac) { | 1079 | if (optind < ac) { |
1085 | fprintf(stderr, "Extra argument %s.\n", av[optind]); | 1080 | fprintf(stderr, "Extra argument %s.\n", av[optind]); |
1086 | exit(1); | 1081 | exit(1); |
1087 | } | 1082 | } |
1088 | 1083 | ||
1089 | debug("sshd version %.100s", SSH_VERSION); | 1084 | debug("sshd version %.100s", SSH_RELEASE); |
1090 | 1085 | ||
1091 | /* load private host keys */ | 1086 | /* load private host keys */ |
1092 | sensitive_data.host_keys = xmalloc(options.num_host_key_files * | 1087 | sensitive_data.host_keys = xmalloc(options.num_host_key_files * |
@@ -1202,7 +1197,7 @@ main(int ac, char **av) | |||
1202 | } | 1197 | } |
1203 | 1198 | ||
1204 | /* Initialize the log (it is reinitialized below in case we forked). */ | 1199 | /* Initialize the log (it is reinitialized below in case we forked). */ |
1205 | if (debug_flag && !inetd_flag) | 1200 | if (debug_flag && (!inetd_flag || rexeced_flag)) |
1206 | log_stderr = 1; | 1201 | log_stderr = 1; |
1207 | log_init(__progname, options.log_level, options.log_facility, log_stderr); | 1202 | log_init(__progname, options.log_level, options.log_facility, log_stderr); |
1208 | 1203 | ||
@@ -1278,10 +1273,12 @@ main(int ac, char **av) | |||
1278 | if (num_listen_socks >= MAX_LISTEN_SOCKS) | 1273 | if (num_listen_socks >= MAX_LISTEN_SOCKS) |
1279 | fatal("Too many listen sockets. " | 1274 | fatal("Too many listen sockets. " |
1280 | "Enlarge MAX_LISTEN_SOCKS"); | 1275 | "Enlarge MAX_LISTEN_SOCKS"); |
1281 | if (getnameinfo(ai->ai_addr, ai->ai_addrlen, | 1276 | if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, |
1282 | ntop, sizeof(ntop), strport, sizeof(strport), | 1277 | ntop, sizeof(ntop), strport, sizeof(strport), |
1283 | NI_NUMERICHOST|NI_NUMERICSERV) != 0) { | 1278 | NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { |
1284 | error("getnameinfo failed"); | 1279 | error("getnameinfo failed: %.100s", |
1280 | (ret != EAI_SYSTEM) ? gai_strerror(ret) : | ||
1281 | strerror(errno)); | ||
1285 | continue; | 1282 | continue; |
1286 | } | 1283 | } |
1287 | /* Create socket for listening. */ | 1284 | /* Create socket for listening. */ |
@@ -1512,7 +1509,8 @@ main(int ac, char **av) | |||
1512 | sock_in = newsock; | 1509 | sock_in = newsock; |
1513 | sock_out = newsock; | 1510 | sock_out = newsock; |
1514 | log_init(__progname, options.log_level, options.log_facility, log_stderr); | 1511 | log_init(__progname, options.log_level, options.log_facility, log_stderr); |
1515 | close(config_s[0]); | 1512 | if (rexec_flag) |
1513 | close(config_s[0]); | ||
1516 | break; | 1514 | break; |
1517 | } | 1515 | } |
1518 | } | 1516 | } |
@@ -1637,6 +1635,9 @@ main(int ac, char **av) | |||
1637 | remote_port = get_remote_port(); | 1635 | remote_port = get_remote_port(); |
1638 | remote_ip = get_remote_ipaddr(); | 1636 | remote_ip = get_remote_ipaddr(); |
1639 | 1637 | ||
1638 | #ifdef SSH_AUDIT_EVENTS | ||
1639 | audit_connection_from(remote_ip, remote_port); | ||
1640 | #endif | ||
1640 | #ifdef LIBWRAP | 1641 | #ifdef LIBWRAP |
1641 | /* Check whether logins are denied from this host. */ | 1642 | /* Check whether logins are denied from this host. */ |
1642 | if (packet_connection_is_on_socket()) { | 1643 | if (packet_connection_is_on_socket()) { |
@@ -1673,9 +1674,6 @@ main(int ac, char **av) | |||
1673 | 1674 | ||
1674 | packet_set_nonblocking(); | 1675 | packet_set_nonblocking(); |
1675 | 1676 | ||
1676 | /* prepare buffers to collect authentication messages */ | ||
1677 | buffer_init(&loginmsg); | ||
1678 | |||
1679 | /* allocate authentication context */ | 1677 | /* allocate authentication context */ |
1680 | authctxt = xmalloc(sizeof(*authctxt)); | 1678 | authctxt = xmalloc(sizeof(*authctxt)); |
1681 | memset(authctxt, 0, sizeof(*authctxt)); | 1679 | memset(authctxt, 0, sizeof(*authctxt)); |
@@ -1683,13 +1681,13 @@ main(int ac, char **av) | |||
1683 | /* XXX global for cleanup, access from other modules */ | 1681 | /* XXX global for cleanup, access from other modules */ |
1684 | the_authctxt = authctxt; | 1682 | the_authctxt = authctxt; |
1685 | 1683 | ||
1684 | /* prepare buffer to collect messages to display to user after login */ | ||
1685 | buffer_init(&loginmsg); | ||
1686 | |||
1686 | if (use_privsep) | 1687 | if (use_privsep) |
1687 | if (privsep_preauth(authctxt) == 1) | 1688 | if (privsep_preauth(authctxt) == 1) |
1688 | goto authenticated; | 1689 | goto authenticated; |
1689 | 1690 | ||
1690 | /* prepare buffer to collect messages to display to user after login */ | ||
1691 | buffer_init(&loginmsg); | ||
1692 | |||
1693 | /* perform the key exchange */ | 1691 | /* perform the key exchange */ |
1694 | /* authenticate user and start session */ | 1692 | /* authenticate user and start session */ |
1695 | if (compat20) { | 1693 | if (compat20) { |
@@ -1709,6 +1707,10 @@ main(int ac, char **av) | |||
1709 | } | 1707 | } |
1710 | 1708 | ||
1711 | authenticated: | 1709 | authenticated: |
1710 | #ifdef SSH_AUDIT_EVENTS | ||
1711 | audit_event(SSH_AUTH_SUCCESS); | ||
1712 | #endif | ||
1713 | |||
1712 | /* | 1714 | /* |
1713 | * In privilege separation, we fork another child and prepare | 1715 | * In privilege separation, we fork another child and prepare |
1714 | * file descriptor passing. | 1716 | * file descriptor passing. |
@@ -1731,6 +1733,10 @@ main(int ac, char **av) | |||
1731 | finish_pam(); | 1733 | finish_pam(); |
1732 | #endif /* USE_PAM */ | 1734 | #endif /* USE_PAM */ |
1733 | 1735 | ||
1736 | #ifdef SSH_AUDIT_EVENTS | ||
1737 | PRIVSEP(audit_event(SSH_CONNECTION_CLOSE)); | ||
1738 | #endif | ||
1739 | |||
1734 | packet_close(); | 1740 | packet_close(); |
1735 | 1741 | ||
1736 | if (use_privsep) | 1742 | if (use_privsep) |
@@ -2022,5 +2028,10 @@ cleanup_exit(int i) | |||
2022 | { | 2028 | { |
2023 | if (the_authctxt) | 2029 | if (the_authctxt) |
2024 | do_cleanup(the_authctxt); | 2030 | do_cleanup(the_authctxt); |
2031 | #ifdef SSH_AUDIT_EVENTS | ||
2032 | /* done after do_cleanup so it can cancel the PAM auth 'thread' */ | ||
2033 | if (!use_privsep || mm_is_monitor()) | ||
2034 | audit_event(SSH_CONNECTION_ABANDON); | ||
2035 | #endif | ||
2025 | _exit(i); | 2036 | _exit(i); |
2026 | } | 2037 | } |