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; |
@@ -1025,7 +1018,6 @@ main(int ac, char **av) | |||
1025 | closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); | 1018 | closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); |
1026 | 1019 | ||
1027 | SSLeay_add_all_algorithms(); | 1020 | SSLeay_add_all_algorithms(); |
1028 | channel_set_af(IPv4or6); | ||
1029 | 1021 | ||
1030 | /* | 1022 | /* |
1031 | * Force logging to stderr until we have loaded the private host | 1023 | * Force logging to stderr until we have loaded the private host |
@@ -1038,13 +1030,13 @@ main(int ac, char **av) | |||
1038 | SYSLOG_FACILITY_AUTH : options.log_facility, | 1030 | SYSLOG_FACILITY_AUTH : options.log_facility, |
1039 | log_stderr || !inetd_flag); | 1031 | log_stderr || !inetd_flag); |
1040 | 1032 | ||
1041 | #ifdef _AIX | ||
1042 | /* | 1033 | /* |
1043 | * Unset KRB5CCNAME, otherwise the user's session may inherit it from | 1034 | * Unset KRB5CCNAME, otherwise the user's session may inherit it from |
1044 | * root's environment | 1035 | * root's environment |
1045 | */ | 1036 | */ |
1046 | unsetenv("KRB5CCNAME"); | 1037 | if (getenv("KRB5CCNAME") != NULL) |
1047 | #endif /* _AIX */ | 1038 | unsetenv("KRB5CCNAME"); |
1039 | |||
1048 | #ifdef _UNICOS | 1040 | #ifdef _UNICOS |
1049 | /* Cray can define user privs drop all privs now! | 1041 | /* Cray can define user privs drop all privs now! |
1050 | * Not needed on PRIV_SU systems! | 1042 | * Not needed on PRIV_SU systems! |
@@ -1075,13 +1067,16 @@ main(int ac, char **av) | |||
1075 | /* Fill in default values for those options not explicitly set. */ | 1067 | /* Fill in default values for those options not explicitly set. */ |
1076 | fill_default_server_options(&options); | 1068 | fill_default_server_options(&options); |
1077 | 1069 | ||
1070 | /* set default channel AF */ | ||
1071 | channel_set_af(options.address_family); | ||
1072 | |||
1078 | /* Check that there are no remaining arguments. */ | 1073 | /* Check that there are no remaining arguments. */ |
1079 | if (optind < ac) { | 1074 | if (optind < ac) { |
1080 | fprintf(stderr, "Extra argument %s.\n", av[optind]); | 1075 | fprintf(stderr, "Extra argument %s.\n", av[optind]); |
1081 | exit(1); | 1076 | exit(1); |
1082 | } | 1077 | } |
1083 | 1078 | ||
1084 | debug("sshd version %.100s", SSH_VERSION); | 1079 | debug("sshd version %.100s", SSH_RELEASE); |
1085 | 1080 | ||
1086 | /* load private host keys */ | 1081 | /* load private host keys */ |
1087 | sensitive_data.host_keys = xmalloc(options.num_host_key_files * | 1082 | sensitive_data.host_keys = xmalloc(options.num_host_key_files * |
@@ -1197,7 +1192,7 @@ main(int ac, char **av) | |||
1197 | } | 1192 | } |
1198 | 1193 | ||
1199 | /* Initialize the log (it is reinitialized below in case we forked). */ | 1194 | /* Initialize the log (it is reinitialized below in case we forked). */ |
1200 | if (debug_flag && !inetd_flag) | 1195 | if (debug_flag && (!inetd_flag || rexeced_flag)) |
1201 | log_stderr = 1; | 1196 | log_stderr = 1; |
1202 | log_init(__progname, options.log_level, options.log_facility, log_stderr); | 1197 | log_init(__progname, options.log_level, options.log_facility, log_stderr); |
1203 | 1198 | ||
@@ -1273,10 +1268,12 @@ main(int ac, char **av) | |||
1273 | if (num_listen_socks >= MAX_LISTEN_SOCKS) | 1268 | if (num_listen_socks >= MAX_LISTEN_SOCKS) |
1274 | fatal("Too many listen sockets. " | 1269 | fatal("Too many listen sockets. " |
1275 | "Enlarge MAX_LISTEN_SOCKS"); | 1270 | "Enlarge MAX_LISTEN_SOCKS"); |
1276 | if (getnameinfo(ai->ai_addr, ai->ai_addrlen, | 1271 | if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, |
1277 | ntop, sizeof(ntop), strport, sizeof(strport), | 1272 | ntop, sizeof(ntop), strport, sizeof(strport), |
1278 | NI_NUMERICHOST|NI_NUMERICSERV) != 0) { | 1273 | NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { |
1279 | error("getnameinfo failed"); | 1274 | error("getnameinfo failed: %.100s", |
1275 | (ret != EAI_SYSTEM) ? gai_strerror(ret) : | ||
1276 | strerror(errno)); | ||
1280 | continue; | 1277 | continue; |
1281 | } | 1278 | } |
1282 | /* Create socket for listening. */ | 1279 | /* Create socket for listening. */ |
@@ -1507,7 +1504,8 @@ main(int ac, char **av) | |||
1507 | sock_in = newsock; | 1504 | sock_in = newsock; |
1508 | sock_out = newsock; | 1505 | sock_out = newsock; |
1509 | log_init(__progname, options.log_level, options.log_facility, log_stderr); | 1506 | log_init(__progname, options.log_level, options.log_facility, log_stderr); |
1510 | close(config_s[0]); | 1507 | if (rexec_flag) |
1508 | close(config_s[0]); | ||
1511 | break; | 1509 | break; |
1512 | } | 1510 | } |
1513 | } | 1511 | } |
@@ -1632,6 +1630,9 @@ main(int ac, char **av) | |||
1632 | remote_port = get_remote_port(); | 1630 | remote_port = get_remote_port(); |
1633 | remote_ip = get_remote_ipaddr(); | 1631 | remote_ip = get_remote_ipaddr(); |
1634 | 1632 | ||
1633 | #ifdef SSH_AUDIT_EVENTS | ||
1634 | audit_connection_from(remote_ip, remote_port); | ||
1635 | #endif | ||
1635 | #ifdef LIBWRAP | 1636 | #ifdef LIBWRAP |
1636 | /* Check whether logins are denied from this host. */ | 1637 | /* Check whether logins are denied from this host. */ |
1637 | if (packet_connection_is_on_socket()) { | 1638 | if (packet_connection_is_on_socket()) { |
@@ -1668,9 +1669,6 @@ main(int ac, char **av) | |||
1668 | 1669 | ||
1669 | packet_set_nonblocking(); | 1670 | packet_set_nonblocking(); |
1670 | 1671 | ||
1671 | /* prepare buffers to collect authentication messages */ | ||
1672 | buffer_init(&loginmsg); | ||
1673 | |||
1674 | /* allocate authentication context */ | 1672 | /* allocate authentication context */ |
1675 | authctxt = xmalloc(sizeof(*authctxt)); | 1673 | authctxt = xmalloc(sizeof(*authctxt)); |
1676 | memset(authctxt, 0, sizeof(*authctxt)); | 1674 | memset(authctxt, 0, sizeof(*authctxt)); |
@@ -1678,13 +1676,13 @@ main(int ac, char **av) | |||
1678 | /* XXX global for cleanup, access from other modules */ | 1676 | /* XXX global for cleanup, access from other modules */ |
1679 | the_authctxt = authctxt; | 1677 | the_authctxt = authctxt; |
1680 | 1678 | ||
1679 | /* prepare buffer to collect messages to display to user after login */ | ||
1680 | buffer_init(&loginmsg); | ||
1681 | |||
1681 | if (use_privsep) | 1682 | if (use_privsep) |
1682 | if (privsep_preauth(authctxt) == 1) | 1683 | if (privsep_preauth(authctxt) == 1) |
1683 | goto authenticated; | 1684 | goto authenticated; |
1684 | 1685 | ||
1685 | /* prepare buffer to collect messages to display to user after login */ | ||
1686 | buffer_init(&loginmsg); | ||
1687 | |||
1688 | /* perform the key exchange */ | 1686 | /* perform the key exchange */ |
1689 | /* authenticate user and start session */ | 1687 | /* authenticate user and start session */ |
1690 | if (compat20) { | 1688 | if (compat20) { |
@@ -1704,6 +1702,10 @@ main(int ac, char **av) | |||
1704 | } | 1702 | } |
1705 | 1703 | ||
1706 | authenticated: | 1704 | authenticated: |
1705 | #ifdef SSH_AUDIT_EVENTS | ||
1706 | audit_event(SSH_AUTH_SUCCESS); | ||
1707 | #endif | ||
1708 | |||
1707 | /* | 1709 | /* |
1708 | * In privilege separation, we fork another child and prepare | 1710 | * In privilege separation, we fork another child and prepare |
1709 | * file descriptor passing. | 1711 | * file descriptor passing. |
@@ -1726,6 +1728,10 @@ main(int ac, char **av) | |||
1726 | finish_pam(); | 1728 | finish_pam(); |
1727 | #endif /* USE_PAM */ | 1729 | #endif /* USE_PAM */ |
1728 | 1730 | ||
1731 | #ifdef SSH_AUDIT_EVENTS | ||
1732 | PRIVSEP(audit_event(SSH_CONNECTION_CLOSE)); | ||
1733 | #endif | ||
1734 | |||
1729 | packet_close(); | 1735 | packet_close(); |
1730 | 1736 | ||
1731 | if (use_privsep) | 1737 | if (use_privsep) |
@@ -2017,5 +2023,10 @@ cleanup_exit(int i) | |||
2017 | { | 2023 | { |
2018 | if (the_authctxt) | 2024 | if (the_authctxt) |
2019 | do_cleanup(the_authctxt); | 2025 | do_cleanup(the_authctxt); |
2026 | #ifdef SSH_AUDIT_EVENTS | ||
2027 | /* done after do_cleanup so it can cancel the PAM auth 'thread' */ | ||
2028 | if (!use_privsep || mm_is_monitor()) | ||
2029 | audit_event(SSH_CONNECTION_ABANDON); | ||
2030 | #endif | ||
2020 | _exit(i); | 2031 | _exit(i); |
2021 | } | 2032 | } |