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 d2d1877d4..fb9b7b7fb 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
@@ -840,7 +840,7 @@ notify_hostkeys(struct ssh *ssh)
840 * all connections are dropped for startups > max_startups 840 * all connections are dropped for startups > max_startups
841 */ 841 */
842static int 842static int
843drop_connection(int startups) 843should_drop_connection(int startups)
844{ 844{
845 int p, r; 845 int p, r;
846 846
@@ -857,10 +857,68 @@ drop_connection(int startups)
857 p += options.max_startups_rate; 857 p += options.max_startups_rate;
858 r = arc4random_uniform(100); 858 r = arc4random_uniform(100);
859 859
860 debug("drop_connection: p %d, r %d", p, r); 860 debug("%s: p %d, r %d", __func__, p, r);
861 return (r < p) ? 1 : 0; 861 return (r < p) ? 1 : 0;
862} 862}
863 863
864/*
865 * Check whether connection should be accepted by MaxStartups.
866 * Returns 0 if the connection is accepted. If the connection is refused,
867 * returns 1 and attempts to send notification to client.
868 * Logs when the MaxStartups condition is entered or exited, and periodically
869 * while in that state.
870 */
871static int
872drop_connection(int sock, int startups)
873{
874 char *laddr, *raddr;
875 const char msg[] = "Exceeded MaxStartups\r\n";
876 static time_t last_drop, first_drop;
877 static u_int ndropped;
878 LogLevel drop_level = SYSLOG_LEVEL_VERBOSE;
879 time_t now;
880
881 now = monotime();
882 if (!should_drop_connection(startups)) {
883 if (last_drop != 0 &&
884 startups < options.max_startups_begin - 1) {
885 /* XXX maybe need better hysteresis here */
886 logit("exited MaxStartups throttling after %s, "
887 "%u connections dropped",
888 fmt_timeframe(now - first_drop), ndropped);
889 last_drop = 0;
890 }
891 return 0;
892 }
893
894#define SSHD_MAXSTARTUPS_LOG_INTERVAL (5 * 60)
895 if (last_drop == 0) {
896 error("beginning MaxStartups throttling");
897 drop_level = SYSLOG_LEVEL_INFO;
898 first_drop = now;
899 ndropped = 0;
900 } else if (last_drop + SSHD_MAXSTARTUPS_LOG_INTERVAL < now) {
901 /* Periodic logs */
902 error("in MaxStartups throttling for %s, "
903 "%u connections dropped",
904 fmt_timeframe(now - first_drop), ndropped + 1);
905 drop_level = SYSLOG_LEVEL_INFO;
906 }
907 last_drop = now;
908 ndropped++;
909
910 laddr = get_local_ipaddr(sock);
911 raddr = get_peer_ipaddr(sock);
912 do_log2(drop_level, "drop connection #%d from [%s]:%d on [%s]:%d "
913 "past MaxStartups", startups, raddr, get_peer_port(sock),
914 laddr, get_local_port(sock));
915 free(laddr);
916 free(raddr);
917 /* best-effort notification to client */
918 (void)write(sock, msg, sizeof(msg) - 1);
919 return 1;
920}
921
864static void 922static void
865usage(void) 923usage(void)
866{ 924{
@@ -918,7 +976,7 @@ send_rexec_state(int fd, struct sshbuf *conf)
918 rexec_send_rng_seed(m); 976 rexec_send_rng_seed(m);
919#endif 977#endif
920 if (ssh_msg_send(fd, 0, m) == -1) 978 if (ssh_msg_send(fd, 0, m) == -1)
921 fatal("%s: ssh_msg_send failed", __func__); 979 error("%s: ssh_msg_send failed", __func__);
922 980
923 sshbuf_free(m); 981 sshbuf_free(m);
924 sshbuf_free(inc); 982 sshbuf_free(inc);
@@ -1217,27 +1275,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
1217 usleep(100 * 1000); 1275 usleep(100 * 1000);
1218 continue; 1276 continue;
1219 } 1277 }
1220 if (unset_nonblock(*newsock) == -1) { 1278 if (unset_nonblock(*newsock) == -1 ||
1221 close(*newsock); 1279 drop_connection(*newsock, startups) ||
1222 continue; 1280 pipe(startup_p) == -1) {
1223 }
1224 if (drop_connection(startups) == 1) {
1225 char *laddr = get_local_ipaddr(*newsock);
1226 char *raddr = get_peer_ipaddr(*newsock);
1227 char msg[] = "Exceeded MaxStartups\r\n";
1228
1229 verbose("drop connection #%d from [%s]:%d "
1230 "on [%s]:%d past MaxStartups", startups,
1231 raddr, get_peer_port(*newsock),
1232 laddr, get_local_port(*newsock));
1233 free(laddr);
1234 free(raddr);
1235 /* best-effort notification to client */
1236 (void)write(*newsock, msg, strlen(msg));
1237 close(*newsock);
1238 continue;
1239 }
1240 if (pipe(startup_p) == -1) {
1241 close(*newsock); 1281 close(*newsock);
1242 continue; 1282 continue;
1243 } 1283 }
@@ -1339,9 +1379,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
1339 close(startup_p[1]); 1379 close(startup_p[1]);
1340 1380
1341 if (rexec_flag) { 1381 if (rexec_flag) {
1382 close(config_s[1]);
1342 send_rexec_state(config_s[0], cfg); 1383 send_rexec_state(config_s[0], cfg);
1343 close(config_s[0]); 1384 close(config_s[0]);
1344 close(config_s[1]);
1345 } 1385 }
1346 close(*newsock); 1386 close(*newsock);
1347 1387
@@ -1697,6 +1737,7 @@ main(int ac, char **av)
1697 if ((cfg = sshbuf_new()) == NULL) 1737 if ((cfg = sshbuf_new()) == NULL)
1698 fatal("%s: sshbuf_new failed", __func__); 1738 fatal("%s: sshbuf_new failed", __func__);
1699 if (rexeced_flag) { 1739 if (rexeced_flag) {
1740 setproctitle("%s", "[rexeced]");
1700 recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg); 1741 recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg);
1701 if (!debug_flag) { 1742 if (!debug_flag) {
1702 startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); 1743 startup_pipe = dup(REEXEC_STARTUP_PIPE_FD);
@@ -1820,10 +1861,19 @@ main(int ac, char **av)
1820 &pubkey, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) 1861 &pubkey, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
1821 do_log2(ll, "Unable to load host key \"%s\": %s", 1862 do_log2(ll, "Unable to load host key \"%s\": %s",
1822 options.host_key_files[i], ssh_err(r)); 1863 options.host_key_files[i], ssh_err(r));
1823 if (pubkey == NULL && key != NULL) 1864 if (pubkey != NULL && key != NULL) {
1865 if (!sshkey_equal(pubkey, key)) {
1866 error("Public key for %s does not match "
1867 "private key", options.host_key_files[i]);
1868 sshkey_free(pubkey);
1869 pubkey = NULL;
1870 }
1871 }
1872 if (pubkey == NULL && key != NULL) {
1824 if ((r = sshkey_from_private(key, &pubkey)) != 0) 1873 if ((r = sshkey_from_private(key, &pubkey)) != 0)
1825 fatal("Could not demote key: \"%s\": %s", 1874 fatal("Could not demote key: \"%s\": %s",
1826 options.host_key_files[i], ssh_err(r)); 1875 options.host_key_files[i], ssh_err(r));
1876 }
1827 sensitive_data.host_keys[i] = key; 1877 sensitive_data.host_keys[i] = key;
1828 sensitive_data.host_pubkeys[i] = pubkey; 1878 sensitive_data.host_pubkeys[i] = pubkey;
1829 1879
@@ -2076,6 +2126,7 @@ main(int ac, char **av)
2076 dup2(config_s[1], REEXEC_CONFIG_PASS_FD); 2126 dup2(config_s[1], REEXEC_CONFIG_PASS_FD);
2077 close(config_s[1]); 2127 close(config_s[1]);
2078 2128
2129 ssh_signal(SIGHUP, SIG_IGN); /* avoid reset to SIG_DFL */
2079 execv(rexec_argv[0], rexec_argv); 2130 execv(rexec_argv[0], rexec_argv);
2080 2131
2081 /* Reexec has failed, fall back and continue */ 2132 /* Reexec has failed, fall back and continue */
@@ -2322,19 +2373,19 @@ sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey,
2322 if (use_privsep) { 2373 if (use_privsep) {
2323 if (privkey) { 2374 if (privkey) {
2324 if (mm_sshkey_sign(ssh, privkey, signature, slenp, 2375 if (mm_sshkey_sign(ssh, privkey, signature, slenp,
2325 data, dlen, alg, options.sk_provider, 2376 data, dlen, alg, options.sk_provider, NULL,
2326 ssh->compat) < 0) 2377 ssh->compat) < 0)
2327 fatal("%s: privkey sign failed", __func__); 2378 fatal("%s: privkey sign failed", __func__);
2328 } else { 2379 } else {
2329 if (mm_sshkey_sign(ssh, pubkey, signature, slenp, 2380 if (mm_sshkey_sign(ssh, pubkey, signature, slenp,
2330 data, dlen, alg, options.sk_provider, 2381 data, dlen, alg, options.sk_provider, NULL,
2331 ssh->compat) < 0) 2382 ssh->compat) < 0)
2332 fatal("%s: pubkey sign failed", __func__); 2383 fatal("%s: pubkey sign failed", __func__);
2333 } 2384 }
2334 } else { 2385 } else {
2335 if (privkey) { 2386 if (privkey) {
2336 if (sshkey_sign(privkey, signature, slenp, data, dlen, 2387 if (sshkey_sign(privkey, signature, slenp, data, dlen,
2337 alg, options.sk_provider, ssh->compat) < 0) 2388 alg, options.sk_provider, NULL, ssh->compat) < 0)
2338 fatal("%s: privkey sign failed", __func__); 2389 fatal("%s: privkey sign failed", __func__);
2339 } else { 2390 } else {
2340 if ((r = ssh_agent_sign(auth_sock, pubkey, 2391 if ((r = ssh_agent_sign(auth_sock, pubkey,
@@ -2460,10 +2511,11 @@ do_ssh2_kex(struct ssh *ssh)
2460 2511
2461#ifdef DEBUG_KEXDH 2512#ifdef DEBUG_KEXDH
2462 /* send 1st encrypted/maced/compressed message */ 2513 /* send 1st encrypted/maced/compressed message */
2463 packet_start(SSH2_MSG_IGNORE); 2514 if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
2464 packet_put_cstring("markus"); 2515 (r = sshpkt_put_cstring(ssh, "markus")) != 0 ||
2465 packet_send(); 2516 (r = sshpkt_send(ssh)) != 0 ||
2466 packet_write_wait(); 2517 (r = ssh_packet_write_wait(ssh)) != 0)
2518 fatal("%s: send test: %s", __func__, ssh_err(r));
2467#endif 2519#endif
2468 debug("KEX done"); 2520 debug("KEX done");
2469} 2521}