summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2020-02-21 11:57:14 +0000
committerColin Watson <cjwatson@debian.org>2020-02-21 14:27:02 +0000
commit886e47e745586c34e81cfd5c5fb9b5dbc8e84d04 (patch)
treedd6c3b4dc64a17c520af7aaf213163f8a0a63e56 /clientloop.c
parentac2b4c0697fcac554041ab95f81736887eadf6ec (diff)
parenta2dabf35ce0228c86a288d11cc847a9d9801604f (diff)
New upstream release (8.2p1)
Diffstat (limited to 'clientloop.c')
-rw-r--r--clientloop.c137
1 files changed, 99 insertions, 38 deletions
diff --git a/clientloop.c b/clientloop.c
index 9def2a1a9..1bdac6a46 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.327 2019/07/24 08:57:00 mestre Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.340 2020/02/02 09:45:34 dtucker 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
@@ -77,10 +77,10 @@
77#include <paths.h> 77#include <paths.h>
78#endif 78#endif
79#include <signal.h> 79#include <signal.h>
80#include <stdarg.h>
81#include <stdio.h> 80#include <stdio.h>
82#include <stdlib.h> 81#include <stdlib.h>
83#include <string.h> 82#include <string.h>
83#include <stdarg.h>
84#include <termios.h> 84#include <termios.h>
85#include <pwd.h> 85#include <pwd.h>
86#include <unistd.h> 86#include <unistd.h>
@@ -139,6 +139,12 @@ extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */
139extern char *host; 139extern char *host;
140 140
141/* 141/*
142 * If this field is not NULL, the ForwardAgent socket is this path and different
143 * instead of SSH_AUTH_SOCK.
144 */
145extern char *forward_agent_sock_path;
146
147/*
142 * Flag to indicate that we have received a window change signal which has 148 * Flag to indicate that we have received a window change signal which has
143 * not yet been processed. This will cause a message indicating the new 149 * not yet been processed. This will cause a message indicating the new
144 * window size to be sent to the server a little later. This is volatile 150 * window size to be sent to the server a little later. This is volatile
@@ -783,7 +789,7 @@ process_cmdline(struct ssh *ssh)
783 memset(&fwd, 0, sizeof(fwd)); 789 memset(&fwd, 0, sizeof(fwd));
784 790
785 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 791 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
786 handler = signal(SIGINT, SIG_IGN); 792 handler = ssh_signal(SIGINT, SIG_IGN);
787 cmd = s = read_passphrase("\r\nssh> ", RP_ECHO); 793 cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
788 if (s == NULL) 794 if (s == NULL)
789 goto out; 795 goto out;
@@ -881,7 +887,7 @@ process_cmdline(struct ssh *ssh)
881 } 887 }
882 888
883out: 889out:
884 signal(SIGINT, handler); 890 ssh_signal(SIGINT, handler);
885 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 891 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
886 free(cmd); 892 free(cmd);
887 free(fwd.listen_host); 893 free(fwd.listen_host);
@@ -1304,15 +1310,15 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1304 * Set signal handlers, (e.g. to restore non-blocking mode) 1310 * Set signal handlers, (e.g. to restore non-blocking mode)
1305 * but don't overwrite SIG_IGN, matches behaviour from rsh(1) 1311 * but don't overwrite SIG_IGN, matches behaviour from rsh(1)
1306 */ 1312 */
1307 if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 1313 if (ssh_signal(SIGHUP, SIG_IGN) != SIG_IGN)
1308 signal(SIGHUP, signal_handler); 1314 ssh_signal(SIGHUP, signal_handler);
1309 if (signal(SIGINT, SIG_IGN) != SIG_IGN) 1315 if (ssh_signal(SIGINT, SIG_IGN) != SIG_IGN)
1310 signal(SIGINT, signal_handler); 1316 ssh_signal(SIGINT, signal_handler);
1311 if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) 1317 if (ssh_signal(SIGQUIT, SIG_IGN) != SIG_IGN)
1312 signal(SIGQUIT, signal_handler); 1318 ssh_signal(SIGQUIT, signal_handler);
1313 if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 1319 if (ssh_signal(SIGTERM, SIG_IGN) != SIG_IGN)
1314 signal(SIGTERM, signal_handler); 1320 ssh_signal(SIGTERM, signal_handler);
1315 signal(SIGWINCH, window_change_handler); 1321 ssh_signal(SIGWINCH, window_change_handler);
1316 1322
1317 if (have_pty) 1323 if (have_pty)
1318 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 1324 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
@@ -1399,8 +1405,12 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1399 * Send as much buffered packet data as possible to the 1405 * Send as much buffered packet data as possible to the
1400 * sender. 1406 * sender.
1401 */ 1407 */
1402 if (FD_ISSET(connection_out, writeset)) 1408 if (FD_ISSET(connection_out, writeset)) {
1403 ssh_packet_write_poll(ssh); 1409 if ((r = ssh_packet_write_poll(ssh)) != 0) {
1410 sshpkt_fatal(ssh, r,
1411 "%s: ssh_packet_write_poll", __func__);
1412 }
1413 }
1404 1414
1405 /* 1415 /*
1406 * If we are a backgrounded control master, and the 1416 * If we are a backgrounded control master, and the
@@ -1420,7 +1430,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1420 /* Terminate the session. */ 1430 /* Terminate the session. */
1421 1431
1422 /* Stop watching for window change. */ 1432 /* Stop watching for window change. */
1423 signal(SIGWINCH, SIG_DFL); 1433 ssh_signal(SIGWINCH, SIG_DFL);
1424 1434
1425 if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 || 1435 if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||
1426 (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_BY_APPLICATION)) != 0 || 1436 (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_BY_APPLICATION)) != 0 ||
@@ -1631,7 +1641,12 @@ client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
1631 "malicious server."); 1641 "malicious server.");
1632 return NULL; 1642 return NULL;
1633 } 1643 }
1634 if ((r = ssh_get_authentication_socket(&sock)) != 0) { 1644 if (forward_agent_sock_path == NULL) {
1645 r = ssh_get_authentication_socket(&sock);
1646 } else {
1647 r = ssh_get_authentication_socket_path(forward_agent_sock_path, &sock);
1648 }
1649 if (r != 0) {
1635 if (r != SSH_ERR_AGENT_NOT_PRESENT) 1650 if (r != SSH_ERR_AGENT_NOT_PRESENT)
1636 debug("%s: ssh_get_authentication_socket: %s", 1651 debug("%s: ssh_get_authentication_socket: %s",
1637 __func__, ssh_err(r)); 1652 __func__, ssh_err(r));
@@ -1890,13 +1905,22 @@ hostkeys_find(struct hostkey_foreach_line *l, void *_ctx)
1890} 1905}
1891 1906
1892static void 1907static void
1908hostkey_change_preamble(LogLevel loglevel)
1909{
1910 do_log2(loglevel, "The server has updated its host keys.");
1911 do_log2(loglevel, "These changes were verified by the server's "
1912 "existing trusted key.");
1913}
1914
1915static void
1893update_known_hosts(struct hostkeys_update_ctx *ctx) 1916update_known_hosts(struct hostkeys_update_ctx *ctx)
1894{ 1917{
1895 int r, was_raw = 0; 1918 int r, was_raw = 0, first = 1;
1896 LogLevel loglevel = options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK ? 1919 int asking = options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK;
1897 SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_VERBOSE; 1920 LogLevel loglevel = asking ? SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_VERBOSE;
1898 char *fp, *response; 1921 char *fp, *response;
1899 size_t i; 1922 size_t i;
1923 struct stat sb;
1900 1924
1901 for (i = 0; i < ctx->nkeys; i++) { 1925 for (i = 0; i < ctx->nkeys; i++) {
1902 if (ctx->keys_seen[i] != 2) 1926 if (ctx->keys_seen[i] != 2)
@@ -1904,16 +1928,22 @@ update_known_hosts(struct hostkeys_update_ctx *ctx)
1904 if ((fp = sshkey_fingerprint(ctx->keys[i], 1928 if ((fp = sshkey_fingerprint(ctx->keys[i],
1905 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) 1929 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
1906 fatal("%s: sshkey_fingerprint failed", __func__); 1930 fatal("%s: sshkey_fingerprint failed", __func__);
1931 if (first && asking)
1932 hostkey_change_preamble(loglevel);
1907 do_log2(loglevel, "Learned new hostkey: %s %s", 1933 do_log2(loglevel, "Learned new hostkey: %s %s",
1908 sshkey_type(ctx->keys[i]), fp); 1934 sshkey_type(ctx->keys[i]), fp);
1935 first = 0;
1909 free(fp); 1936 free(fp);
1910 } 1937 }
1911 for (i = 0; i < ctx->nold; i++) { 1938 for (i = 0; i < ctx->nold; i++) {
1912 if ((fp = sshkey_fingerprint(ctx->old_keys[i], 1939 if ((fp = sshkey_fingerprint(ctx->old_keys[i],
1913 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) 1940 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
1914 fatal("%s: sshkey_fingerprint failed", __func__); 1941 fatal("%s: sshkey_fingerprint failed", __func__);
1942 if (first && asking)
1943 hostkey_change_preamble(loglevel);
1915 do_log2(loglevel, "Deprecating obsolete hostkey: %s %s", 1944 do_log2(loglevel, "Deprecating obsolete hostkey: %s %s",
1916 sshkey_type(ctx->old_keys[i]), fp); 1945 sshkey_type(ctx->old_keys[i]), fp);
1946 first = 0;
1917 free(fp); 1947 free(fp);
1918 } 1948 }
1919 if (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) { 1949 if (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) {
@@ -1943,19 +1973,37 @@ update_known_hosts(struct hostkeys_update_ctx *ctx)
1943 if (was_raw) 1973 if (was_raw)
1944 enter_raw_mode(1); 1974 enter_raw_mode(1);
1945 } 1975 }
1946 1976 if (options.update_hostkeys == 0)
1977 return;
1947 /* 1978 /*
1948 * Now that all the keys are verified, we can go ahead and replace 1979 * Now that all the keys are verified, we can go ahead and replace
1949 * them in known_hosts (assuming SSH_UPDATE_HOSTKEYS_ASK didn't 1980 * them in known_hosts (assuming SSH_UPDATE_HOSTKEYS_ASK didn't
1950 * cancel the operation). 1981 * cancel the operation).
1951 */ 1982 */
1952 if (options.update_hostkeys != 0 && 1983 for (i = 0; i < options.num_user_hostfiles; i++) {
1953 (r = hostfile_replace_entries(options.user_hostfiles[0], 1984 /*
1954 ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys, 1985 * NB. keys are only added to hostfiles[0], for the rest we
1955 options.hash_known_hosts, 0, 1986 * just delete the hostname entries.
1956 options.fingerprint_hash)) != 0) 1987 */
1957 error("%s: hostfile_replace_entries failed: %s", 1988 if (stat(options.user_hostfiles[i], &sb) != 0) {
1958 __func__, ssh_err(r)); 1989 if (errno == ENOENT) {
1990 debug("%s: known hosts file %s does not exist",
1991 __func__, strerror(errno));
1992 } else {
1993 error("%s: known hosts file %s inaccessible",
1994 __func__, strerror(errno));
1995 }
1996 continue;
1997 }
1998 if ((r = hostfile_replace_entries(options.user_hostfiles[i],
1999 ctx->host_str, ctx->ip_str,
2000 i == 0 ? ctx->keys : NULL, i == 0 ? ctx->nkeys : 0,
2001 options.hash_known_hosts, 0,
2002 options.fingerprint_hash)) != 0) {
2003 error("%s: hostfile_replace_entries failed for %s: %s",
2004 __func__, options.user_hostfiles[i], ssh_err(r));
2005 }
2006 }
1959} 2007}
1960 2008
1961static void 2009static void
@@ -2016,7 +2064,8 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
2016 sshkey_type_plain(ctx->keys[i]->type) == KEY_RSA; 2064 sshkey_type_plain(ctx->keys[i]->type) == KEY_RSA;
2017 if ((r = sshkey_verify(ctx->keys[i], sig, siglen, 2065 if ((r = sshkey_verify(ctx->keys[i], sig, siglen,
2018 sshbuf_ptr(signdata), sshbuf_len(signdata), 2066 sshbuf_ptr(signdata), sshbuf_len(signdata),
2019 use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0)) != 0) { 2067 use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0,
2068 NULL)) != 0) {
2020 error("%s: server gave bad signature for %s key %zu", 2069 error("%s: server gave bad signature for %s key %zu",
2021 __func__, sshkey_type(ctx->keys[i]), i); 2070 __func__, sshkey_type(ctx->keys[i]), i);
2022 goto out; 2071 goto out;
@@ -2047,8 +2096,7 @@ static int
2047key_accepted_by_hostkeyalgs(const struct sshkey *key) 2096key_accepted_by_hostkeyalgs(const struct sshkey *key)
2048{ 2097{
2049 const char *ktype = sshkey_ssh_name(key); 2098 const char *ktype = sshkey_ssh_name(key);
2050 const char *hostkeyalgs = options.hostkeyalgorithms != NULL ? 2099 const char *hostkeyalgs = options.hostkeyalgorithms;
2051 options.hostkeyalgorithms : KEX_DEFAULT_PK_ALG;
2052 2100
2053 if (key == NULL || key->type == KEY_UNSPEC) 2101 if (key == NULL || key->type == KEY_UNSPEC)
2054 return 0; 2102 return 0;
@@ -2095,8 +2143,10 @@ client_input_hostkeys(struct ssh *ssh)
2095 goto out; 2143 goto out;
2096 } 2144 }
2097 if ((r = sshkey_from_blob(blob, len, &key)) != 0) { 2145 if ((r = sshkey_from_blob(blob, len, &key)) != 0) {
2098 error("%s: parse key: %s", __func__, ssh_err(r)); 2146 do_log2(r == SSH_ERR_KEY_TYPE_UNKNOWN ?
2099 goto out; 2147 SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_ERROR,
2148 "%s: parse key: %s", __func__, ssh_err(r));
2149 continue;
2100 } 2150 }
2101 fp = sshkey_fingerprint(key, options.fingerprint_hash, 2151 fp = sshkey_fingerprint(key, options.fingerprint_hash,
2102 SSH_FP_DEFAULT); 2152 SSH_FP_DEFAULT);
@@ -2148,11 +2198,22 @@ client_input_hostkeys(struct ssh *ssh)
2148 options.check_host_ip ? &ctx->ip_str : NULL); 2198 options.check_host_ip ? &ctx->ip_str : NULL);
2149 2199
2150 /* Find which keys we already know about. */ 2200 /* Find which keys we already know about. */
2151 if ((r = hostkeys_foreach(options.user_hostfiles[0], hostkeys_find, 2201 for (i = 0; i < options.num_user_hostfiles; i++) {
2152 ctx, ctx->host_str, ctx->ip_str, 2202 debug("%s: searching %s for %s / %s", __func__,
2153 HKF_WANT_PARSE_KEY|HKF_WANT_MATCH)) != 0) { 2203 options.user_hostfiles[i], ctx->host_str,
2154 error("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); 2204 ctx->ip_str ? ctx->ip_str : "(none)");
2155 goto out; 2205 if ((r = hostkeys_foreach(options.user_hostfiles[i],
2206 hostkeys_find, ctx, ctx->host_str, ctx->ip_str,
2207 HKF_WANT_PARSE_KEY|HKF_WANT_MATCH)) != 0) {
2208 if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) {
2209 debug("%s: hostkeys file %s does not exist",
2210 __func__, options.user_hostfiles[i]);
2211 continue;
2212 }
2213 error("%s: hostkeys_foreach failed for %s: %s",
2214 __func__, options.user_hostfiles[i], ssh_err(r));
2215 goto out;
2216 }
2156 } 2217 }
2157 2218
2158 /* Figure out if we have any new keys to add */ 2219 /* Figure out if we have any new keys to add */