summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c120
1 files changed, 86 insertions, 34 deletions
diff --git a/sshd.c b/sshd.c
index 6f8f11a3b..8aa7f3df6 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.552 2020/03/13 04:01:57 djm Exp $ */ 1/* $OpenBSD: sshd.c,v 1.561 2020/08/27 01:06:19 djm 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
@@ -829,7 +829,7 @@ notify_hostkeys(struct ssh *ssh)
829 * all connections are dropped for startups > max_startups 829 * all connections are dropped for startups > max_startups
830 */ 830 */
831static int 831static int
832drop_connection(int startups) 832should_drop_connection(int startups)
833{ 833{
834 int p, r; 834 int p, r;
835 835
@@ -846,10 +846,68 @@ drop_connection(int startups)
846 p += options.max_startups_rate; 846 p += options.max_startups_rate;
847 r = arc4random_uniform(100); 847 r = arc4random_uniform(100);
848 848
849 debug("drop_connection: p %d, r %d", p, r); 849 debug("%s: p %d, r %d", __func__, p, r);
850 return (r < p) ? 1 : 0; 850 return (r < p) ? 1 : 0;
851} 851}
852 852
853/*
854 * Check whether connection should be accepted by MaxStartups.
855 * Returns 0 if the connection is accepted. If the connection is refused,
856 * returns 1 and attempts to send notification to client.
857 * Logs when the MaxStartups condition is entered or exited, and periodically
858 * while in that state.
859 */
860static int
861drop_connection(int sock, int startups)
862{
863 char *laddr, *raddr;
864 const char msg[] = "Exceeded MaxStartups\r\n";
865 static time_t last_drop, first_drop;
866 static u_int ndropped;
867 LogLevel drop_level = SYSLOG_LEVEL_VERBOSE;
868 time_t now;
869
870 now = monotime();
871 if (!should_drop_connection(startups)) {
872 if (last_drop != 0 &&
873 startups < options.max_startups_begin - 1) {
874 /* XXX maybe need better hysteresis here */
875 logit("exited MaxStartups throttling after %s, "
876 "%u connections dropped",
877 fmt_timeframe(now - first_drop), ndropped);
878 last_drop = 0;
879 }
880 return 0;
881 }
882
883#define SSHD_MAXSTARTUPS_LOG_INTERVAL (5 * 60)
884 if (last_drop == 0) {
885 error("beginning MaxStartups throttling");
886 drop_level = SYSLOG_LEVEL_INFO;
887 first_drop = now;
888 ndropped = 0;
889 } else if (last_drop + SSHD_MAXSTARTUPS_LOG_INTERVAL < now) {
890 /* Periodic logs */
891 error("in MaxStartups throttling for %s, "
892 "%u connections dropped",
893 fmt_timeframe(now - first_drop), ndropped + 1);
894 drop_level = SYSLOG_LEVEL_INFO;
895 }
896 last_drop = now;
897 ndropped++;
898
899 laddr = get_local_ipaddr(sock);
900 raddr = get_peer_ipaddr(sock);
901 do_log2(drop_level, "drop connection #%d from [%s]:%d on [%s]:%d "
902 "past MaxStartups", startups, raddr, get_peer_port(sock),
903 laddr, get_local_port(sock));
904 free(laddr);
905 free(raddr);
906 /* best-effort notification to client */
907 (void)write(sock, msg, sizeof(msg) - 1);
908 return 1;
909}
910
853static void 911static void
854usage(void) 912usage(void)
855{ 913{
@@ -907,7 +965,7 @@ send_rexec_state(int fd, struct sshbuf *conf)
907 rexec_send_rng_seed(m); 965 rexec_send_rng_seed(m);
908#endif 966#endif
909 if (ssh_msg_send(fd, 0, m) == -1) 967 if (ssh_msg_send(fd, 0, m) == -1)
910 fatal("%s: ssh_msg_send failed", __func__); 968 error("%s: ssh_msg_send failed", __func__);
911 969
912 sshbuf_free(m); 970 sshbuf_free(m);
913 sshbuf_free(inc); 971 sshbuf_free(inc);
@@ -1206,27 +1264,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
1206 usleep(100 * 1000); 1264 usleep(100 * 1000);
1207 continue; 1265 continue;
1208 } 1266 }
1209 if (unset_nonblock(*newsock) == -1) { 1267 if (unset_nonblock(*newsock) == -1 ||
1210 close(*newsock); 1268 drop_connection(*newsock, startups) ||
1211 continue; 1269 pipe(startup_p) == -1) {
1212 }
1213 if (drop_connection(startups) == 1) {
1214 char *laddr = get_local_ipaddr(*newsock);
1215 char *raddr = get_peer_ipaddr(*newsock);
1216 char msg[] = "Exceeded MaxStartups\r\n";
1217
1218 verbose("drop connection #%d from [%s]:%d "
1219 "on [%s]:%d past MaxStartups", startups,
1220 raddr, get_peer_port(*newsock),
1221 laddr, get_local_port(*newsock));
1222 free(laddr);
1223 free(raddr);
1224 /* best-effort notification to client */
1225 (void)write(*newsock, msg, strlen(msg));
1226 close(*newsock);
1227 continue;
1228 }
1229 if (pipe(startup_p) == -1) {
1230 close(*newsock); 1270 close(*newsock);
1231 continue; 1271 continue;
1232 } 1272 }
@@ -1328,9 +1368,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
1328 close(startup_p[1]); 1368 close(startup_p[1]);
1329 1369
1330 if (rexec_flag) { 1370 if (rexec_flag) {
1371 close(config_s[1]);
1331 send_rexec_state(config_s[0], cfg); 1372 send_rexec_state(config_s[0], cfg);
1332 close(config_s[0]); 1373 close(config_s[0]);
1333 close(config_s[1]);
1334 } 1374 }
1335 close(*newsock); 1375 close(*newsock);
1336 1376
@@ -1686,6 +1726,7 @@ main(int ac, char **av)
1686 if ((cfg = sshbuf_new()) == NULL) 1726 if ((cfg = sshbuf_new()) == NULL)
1687 fatal("%s: sshbuf_new failed", __func__); 1727 fatal("%s: sshbuf_new failed", __func__);
1688 if (rexeced_flag) { 1728 if (rexeced_flag) {
1729 setproctitle("%s", "[rexeced]");
1689 recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg); 1730 recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg);
1690 if (!debug_flag) { 1731 if (!debug_flag) {
1691 startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); 1732 startup_pipe = dup(REEXEC_STARTUP_PIPE_FD);
@@ -1809,10 +1850,19 @@ main(int ac, char **av)
1809 &pubkey, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) 1850 &pubkey, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
1810 do_log2(ll, "Unable to load host key \"%s\": %s", 1851 do_log2(ll, "Unable to load host key \"%s\": %s",
1811 options.host_key_files[i], ssh_err(r)); 1852 options.host_key_files[i], ssh_err(r));
1812 if (pubkey == NULL && key != NULL) 1853 if (pubkey != NULL && key != NULL) {
1854 if (!sshkey_equal(pubkey, key)) {
1855 error("Public key for %s does not match "
1856 "private key", options.host_key_files[i]);
1857 sshkey_free(pubkey);
1858 pubkey = NULL;
1859 }
1860 }
1861 if (pubkey == NULL && key != NULL) {
1813 if ((r = sshkey_from_private(key, &pubkey)) != 0) 1862 if ((r = sshkey_from_private(key, &pubkey)) != 0)
1814 fatal("Could not demote key: \"%s\": %s", 1863 fatal("Could not demote key: \"%s\": %s",
1815 options.host_key_files[i], ssh_err(r)); 1864 options.host_key_files[i], ssh_err(r));
1865 }
1816 sensitive_data.host_keys[i] = key; 1866 sensitive_data.host_keys[i] = key;
1817 sensitive_data.host_pubkeys[i] = pubkey; 1867 sensitive_data.host_pubkeys[i] = pubkey;
1818 1868
@@ -2059,6 +2109,7 @@ main(int ac, char **av)
2059 dup2(config_s[1], REEXEC_CONFIG_PASS_FD); 2109 dup2(config_s[1], REEXEC_CONFIG_PASS_FD);
2060 close(config_s[1]); 2110 close(config_s[1]);
2061 2111
2112 ssh_signal(SIGHUP, SIG_IGN); /* avoid reset to SIG_DFL */
2062 execv(rexec_argv[0], rexec_argv); 2113 execv(rexec_argv[0], rexec_argv);
2063 2114
2064 /* Reexec has failed, fall back and continue */ 2115 /* Reexec has failed, fall back and continue */
@@ -2287,19 +2338,19 @@ sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey,
2287 if (use_privsep) { 2338 if (use_privsep) {
2288 if (privkey) { 2339 if (privkey) {
2289 if (mm_sshkey_sign(ssh, privkey, signature, slenp, 2340 if (mm_sshkey_sign(ssh, privkey, signature, slenp,
2290 data, dlen, alg, options.sk_provider, 2341 data, dlen, alg, options.sk_provider, NULL,
2291 ssh->compat) < 0) 2342 ssh->compat) < 0)
2292 fatal("%s: privkey sign failed", __func__); 2343 fatal("%s: privkey sign failed", __func__);
2293 } else { 2344 } else {
2294 if (mm_sshkey_sign(ssh, pubkey, signature, slenp, 2345 if (mm_sshkey_sign(ssh, pubkey, signature, slenp,
2295 data, dlen, alg, options.sk_provider, 2346 data, dlen, alg, options.sk_provider, NULL,
2296 ssh->compat) < 0) 2347 ssh->compat) < 0)
2297 fatal("%s: pubkey sign failed", __func__); 2348 fatal("%s: pubkey sign failed", __func__);
2298 } 2349 }
2299 } else { 2350 } else {
2300 if (privkey) { 2351 if (privkey) {
2301 if (sshkey_sign(privkey, signature, slenp, data, dlen, 2352 if (sshkey_sign(privkey, signature, slenp, data, dlen,
2302 alg, options.sk_provider, ssh->compat) < 0) 2353 alg, options.sk_provider, NULL, ssh->compat) < 0)
2303 fatal("%s: privkey sign failed", __func__); 2354 fatal("%s: privkey sign failed", __func__);
2304 } else { 2355 } else {
2305 if ((r = ssh_agent_sign(auth_sock, pubkey, 2356 if ((r = ssh_agent_sign(auth_sock, pubkey,
@@ -2372,10 +2423,11 @@ do_ssh2_kex(struct ssh *ssh)
2372 2423
2373#ifdef DEBUG_KEXDH 2424#ifdef DEBUG_KEXDH
2374 /* send 1st encrypted/maced/compressed message */ 2425 /* send 1st encrypted/maced/compressed message */
2375 packet_start(SSH2_MSG_IGNORE); 2426 if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
2376 packet_put_cstring("markus"); 2427 (r = sshpkt_put_cstring(ssh, "markus")) != 0 ||
2377 packet_send(); 2428 (r = sshpkt_send(ssh)) != 0 ||
2378 packet_write_wait(); 2429 (r = ssh_packet_write_wait(ssh)) != 0)
2430 fatal("%s: send test: %s", __func__, ssh_err(r));
2379#endif 2431#endif
2380 debug("KEX done"); 2432 debug("KEX done");
2381} 2433}