diff options
author | Colin Watson <cjwatson@debian.org> | 2019-06-05 06:41:44 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2019-06-09 22:09:07 +0100 |
commit | 865a97e05b6aab1619e1c8eeb33ccb8f9a9e48d3 (patch) | |
tree | 7bb2128eb663180bacfabca88f26d26bf0733824 /ssh.c | |
parent | ba627ba172d6649919baedff5ba2789610da382a (diff) | |
parent | 7d50f9e5be88179325983a1f58c9d51bb58f025a (diff) |
New upstream release (8.0p1)
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 111 |
1 files changed, 66 insertions, 45 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.494 2018/10/03 06:38:35 djm Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.500 2019/01/19 21:43:56 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 |
@@ -527,7 +527,8 @@ check_load(int r, const char *path, const char *message) | |||
527 | * file if the user specifies a config file on the command line. | 527 | * file if the user specifies a config file on the command line. |
528 | */ | 528 | */ |
529 | static void | 529 | static void |
530 | process_config_files(const char *host_name, struct passwd *pw, int post_canon) | 530 | process_config_files(const char *host_name, struct passwd *pw, int final_pass, |
531 | int *want_final_pass) | ||
531 | { | 532 | { |
532 | char buf[PATH_MAX]; | 533 | char buf[PATH_MAX]; |
533 | int r; | 534 | int r; |
@@ -535,7 +536,8 @@ process_config_files(const char *host_name, struct passwd *pw, int post_canon) | |||
535 | if (config != NULL) { | 536 | if (config != NULL) { |
536 | if (strcasecmp(config, "none") != 0 && | 537 | if (strcasecmp(config, "none") != 0 && |
537 | !read_config_file(config, pw, host, host_name, &options, | 538 | !read_config_file(config, pw, host, host_name, &options, |
538 | SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0))) | 539 | SSHCONF_USERCONF | (final_pass ? SSHCONF_FINAL : 0), |
540 | want_final_pass)) | ||
539 | fatal("Can't open user config file %.100s: " | 541 | fatal("Can't open user config file %.100s: " |
540 | "%.100s", config, strerror(errno)); | 542 | "%.100s", config, strerror(errno)); |
541 | } else { | 543 | } else { |
@@ -544,12 +546,12 @@ process_config_files(const char *host_name, struct passwd *pw, int post_canon) | |||
544 | if (r > 0 && (size_t)r < sizeof(buf)) | 546 | if (r > 0 && (size_t)r < sizeof(buf)) |
545 | (void)read_config_file(buf, pw, host, host_name, | 547 | (void)read_config_file(buf, pw, host, host_name, |
546 | &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | | 548 | &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | |
547 | (post_canon ? SSHCONF_POSTCANON : 0)); | 549 | (final_pass ? SSHCONF_FINAL : 0), want_final_pass); |
548 | 550 | ||
549 | /* Read systemwide configuration file after user config. */ | 551 | /* Read systemwide configuration file after user config. */ |
550 | (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, | 552 | (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, |
551 | host, host_name, &options, | 553 | host, host_name, &options, |
552 | post_canon ? SSHCONF_POSTCANON : 0); | 554 | final_pass ? SSHCONF_FINAL : 0, want_final_pass); |
553 | } | 555 | } |
554 | } | 556 | } |
555 | 557 | ||
@@ -581,7 +583,7 @@ main(int ac, char **av) | |||
581 | { | 583 | { |
582 | struct ssh *ssh = NULL; | 584 | struct ssh *ssh = NULL; |
583 | int i, r, opt, exit_status, use_syslog, direct, timeout_ms; | 585 | int i, r, opt, exit_status, use_syslog, direct, timeout_ms; |
584 | int was_addr, config_test = 0, opt_terminated = 0; | 586 | int was_addr, config_test = 0, opt_terminated = 0, want_final_pass = 0; |
585 | char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile; | 587 | char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile; |
586 | char cname[NI_MAXHOST]; | 588 | char cname[NI_MAXHOST]; |
587 | struct stat st; | 589 | struct stat st; |
@@ -610,6 +612,8 @@ main(int ac, char **av) | |||
610 | av = saved_av; | 612 | av = saved_av; |
611 | #endif | 613 | #endif |
612 | 614 | ||
615 | seed_rng(); | ||
616 | |||
613 | /* | 617 | /* |
614 | * Discard other fds that are hanging around. These can cause problem | 618 | * Discard other fds that are hanging around. These can cause problem |
615 | * with backgrounded ssh processes started by ControlPersist. | 619 | * with backgrounded ssh processes started by ControlPersist. |
@@ -647,7 +651,6 @@ main(int ac, char **av) | |||
647 | if ((ssh = ssh_alloc_session_state()) == NULL) | 651 | if ((ssh = ssh_alloc_session_state()) == NULL) |
648 | fatal("Couldn't allocate session state"); | 652 | fatal("Couldn't allocate session state"); |
649 | channel_init_channels(ssh); | 653 | channel_init_channels(ssh); |
650 | active_state = ssh; /* XXX legacy API compat */ | ||
651 | 654 | ||
652 | /* Parse command-line arguments. */ | 655 | /* Parse command-line arguments. */ |
653 | host = NULL; | 656 | host = NULL; |
@@ -733,6 +736,8 @@ main(int ac, char **av) | |||
733 | cp = mac_alg_list('\n'); | 736 | cp = mac_alg_list('\n'); |
734 | else if (strcmp(optarg, "kex") == 0) | 737 | else if (strcmp(optarg, "kex") == 0) |
735 | cp = kex_alg_list('\n'); | 738 | cp = kex_alg_list('\n'); |
739 | else if (strcmp(optarg, "kex-gss") == 0) | ||
740 | cp = kex_gss_alg_list('\n'); | ||
736 | else if (strcmp(optarg, "key") == 0) | 741 | else if (strcmp(optarg, "key") == 0) |
737 | cp = sshkey_alg_list(0, 0, 0, '\n'); | 742 | cp = sshkey_alg_list(0, 0, 0, '\n'); |
738 | else if (strcmp(optarg, "key-cert") == 0) | 743 | else if (strcmp(optarg, "key-cert") == 0) |
@@ -745,7 +750,7 @@ main(int ac, char **av) | |||
745 | cp = xstrdup("2"); | 750 | cp = xstrdup("2"); |
746 | else if (strcmp(optarg, "help") == 0) { | 751 | else if (strcmp(optarg, "help") == 0) { |
747 | cp = xstrdup( | 752 | cp = xstrdup( |
748 | "cipher\ncipher-auth\nkex\nkey\n" | 753 | "cipher\ncipher-auth\nkex\nkex-gss\nkey\n" |
749 | "key-cert\nkey-plain\nmac\n" | 754 | "key-cert\nkey-plain\nmac\n" |
750 | "protocol-version\nsig"); | 755 | "protocol-version\nsig"); |
751 | } | 756 | } |
@@ -816,7 +821,7 @@ main(int ac, char **av) | |||
816 | fprintf(stderr, "%s, %s\n", | 821 | fprintf(stderr, "%s, %s\n", |
817 | SSH_RELEASE, | 822 | SSH_RELEASE, |
818 | #ifdef WITH_OPENSSL | 823 | #ifdef WITH_OPENSSL |
819 | SSLeay_version(SSLEAY_VERSION) | 824 | OpenSSL_version(OPENSSL_VERSION) |
820 | #else | 825 | #else |
821 | "without OpenSSL" | 826 | "without OpenSSL" |
822 | #endif | 827 | #endif |
@@ -1036,11 +1041,6 @@ main(int ac, char **av) | |||
1036 | 1041 | ||
1037 | host_arg = xstrdup(host); | 1042 | host_arg = xstrdup(host); |
1038 | 1043 | ||
1039 | #ifdef WITH_OPENSSL | ||
1040 | OpenSSL_add_all_algorithms(); | ||
1041 | ERR_load_crypto_strings(); | ||
1042 | #endif | ||
1043 | |||
1044 | /* Initialize the command to execute on remote host. */ | 1044 | /* Initialize the command to execute on remote host. */ |
1045 | if ((command = sshbuf_new()) == NULL) | 1045 | if ((command = sshbuf_new()) == NULL) |
1046 | fatal("sshbuf_new failed"); | 1046 | fatal("sshbuf_new failed"); |
@@ -1085,14 +1085,16 @@ main(int ac, char **av) | |||
1085 | if (debug_flag) | 1085 | if (debug_flag) |
1086 | logit("%s, %s", SSH_RELEASE, | 1086 | logit("%s, %s", SSH_RELEASE, |
1087 | #ifdef WITH_OPENSSL | 1087 | #ifdef WITH_OPENSSL |
1088 | SSLeay_version(SSLEAY_VERSION) | 1088 | OpenSSL_version(OPENSSL_VERSION) |
1089 | #else | 1089 | #else |
1090 | "without OpenSSL" | 1090 | "without OpenSSL" |
1091 | #endif | 1091 | #endif |
1092 | ); | 1092 | ); |
1093 | 1093 | ||
1094 | /* Parse the configuration files */ | 1094 | /* Parse the configuration files */ |
1095 | process_config_files(host_arg, pw, 0); | 1095 | process_config_files(host_arg, pw, 0, &want_final_pass); |
1096 | if (want_final_pass) | ||
1097 | debug("configuration requests final Match pass"); | ||
1096 | 1098 | ||
1097 | /* Hostname canonicalisation needs a few options filled. */ | 1099 | /* Hostname canonicalisation needs a few options filled. */ |
1098 | fill_default_options_for_canonicalization(&options); | 1100 | fill_default_options_for_canonicalization(&options); |
@@ -1149,12 +1151,17 @@ main(int ac, char **av) | |||
1149 | * If canonicalisation is enabled then re-parse the configuration | 1151 | * If canonicalisation is enabled then re-parse the configuration |
1150 | * files as new stanzas may match. | 1152 | * files as new stanzas may match. |
1151 | */ | 1153 | */ |
1152 | if (options.canonicalize_hostname != 0) { | 1154 | if (options.canonicalize_hostname != 0 && !want_final_pass) { |
1153 | debug("Re-reading configuration after hostname " | 1155 | debug("hostname canonicalisation enabled, " |
1154 | "canonicalisation"); | 1156 | "will re-parse configuration"); |
1157 | want_final_pass = 1; | ||
1158 | } | ||
1159 | |||
1160 | if (want_final_pass) { | ||
1161 | debug("re-parsing configuration"); | ||
1155 | free(options.hostname); | 1162 | free(options.hostname); |
1156 | options.hostname = xstrdup(host); | 1163 | options.hostname = xstrdup(host); |
1157 | process_config_files(host_arg, pw, 1); | 1164 | process_config_files(host_arg, pw, 1, NULL); |
1158 | /* | 1165 | /* |
1159 | * Address resolution happens early with canonicalisation | 1166 | * Address resolution happens early with canonicalisation |
1160 | * enabled and the port number may have changed since, so | 1167 | * enabled and the port number may have changed since, so |
@@ -1264,8 +1271,6 @@ main(int ac, char **av) | |||
1264 | tty_flag = 0; | 1271 | tty_flag = 0; |
1265 | } | 1272 | } |
1266 | 1273 | ||
1267 | seed_rng(); | ||
1268 | |||
1269 | if (options.user == NULL) | 1274 | if (options.user == NULL) |
1270 | options.user = xstrdup(pw->pw_name); | 1275 | options.user = xstrdup(pw->pw_name); |
1271 | 1276 | ||
@@ -1344,7 +1349,7 @@ main(int ac, char **av) | |||
1344 | int sock; | 1349 | int sock; |
1345 | if ((sock = muxclient(options.control_path)) >= 0) { | 1350 | if ((sock = muxclient(options.control_path)) >= 0) { |
1346 | ssh_packet_set_connection(ssh, sock, sock); | 1351 | ssh_packet_set_connection(ssh, sock, sock); |
1347 | packet_set_mux(); | 1352 | ssh_packet_set_mux(ssh); |
1348 | goto skip_connect; | 1353 | goto skip_connect; |
1349 | } | 1354 | } |
1350 | } | 1355 | } |
@@ -1371,11 +1376,9 @@ main(int ac, char **av) | |||
1371 | if (addrs != NULL) | 1376 | if (addrs != NULL) |
1372 | freeaddrinfo(addrs); | 1377 | freeaddrinfo(addrs); |
1373 | 1378 | ||
1374 | packet_set_timeout(options.server_alive_interval, | 1379 | ssh_packet_set_timeout(ssh, options.server_alive_interval, |
1375 | options.server_alive_count_max); | 1380 | options.server_alive_count_max); |
1376 | 1381 | ||
1377 | ssh = active_state; /* XXX */ | ||
1378 | |||
1379 | if (timeout_ms > 0) | 1382 | if (timeout_ms > 0) |
1380 | debug3("timeout: %d ms remain after connect", timeout_ms); | 1383 | debug3("timeout: %d ms remain after connect", timeout_ms); |
1381 | 1384 | ||
@@ -1486,10 +1489,10 @@ main(int ac, char **av) | |||
1486 | signal(SIGCHLD, main_sigchld_handler); | 1489 | signal(SIGCHLD, main_sigchld_handler); |
1487 | 1490 | ||
1488 | /* Log into the remote system. Never returns if the login fails. */ | 1491 | /* Log into the remote system. Never returns if the login fails. */ |
1489 | ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, | 1492 | ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr, |
1490 | options.port, pw, timeout_ms); | 1493 | options.port, pw, timeout_ms); |
1491 | 1494 | ||
1492 | if (packet_connection_is_on_socket()) { | 1495 | if (ssh_packet_connection_is_on_socket(ssh)) { |
1493 | verbose("Authenticated to %s ([%s]:%d).", host, | 1496 | verbose("Authenticated to %s ([%s]:%d).", host, |
1494 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); | 1497 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); |
1495 | } else { | 1498 | } else { |
@@ -1523,7 +1526,7 @@ main(int ac, char **av) | |||
1523 | 1526 | ||
1524 | skip_connect: | 1527 | skip_connect: |
1525 | exit_status = ssh_session2(ssh, pw); | 1528 | exit_status = ssh_session2(ssh, pw); |
1526 | packet_close(); | 1529 | ssh_packet_close(ssh); |
1527 | 1530 | ||
1528 | if (options.control_path != NULL && muxserver_sock != -1) | 1531 | if (options.control_path != NULL && muxserver_sock != -1) |
1529 | unlink(options.control_path); | 1532 | unlink(options.control_path); |
@@ -1598,6 +1601,8 @@ static void | |||
1598 | ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) | 1601 | ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) |
1599 | { | 1602 | { |
1600 | struct Forward *rfwd = (struct Forward *)ctxt; | 1603 | struct Forward *rfwd = (struct Forward *)ctxt; |
1604 | u_int port; | ||
1605 | int r; | ||
1601 | 1606 | ||
1602 | /* XXX verbose() on failure? */ | 1607 | /* XXX verbose() on failure? */ |
1603 | debug("remote forward %s for: listen %s%s%d, connect %s:%d", | 1608 | debug("remote forward %s for: listen %s%s%d, connect %s:%d", |
@@ -1609,12 +1614,25 @@ ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) | |||
1609 | rfwd->connect_host, rfwd->connect_port); | 1614 | rfwd->connect_host, rfwd->connect_port); |
1610 | if (rfwd->listen_path == NULL && rfwd->listen_port == 0) { | 1615 | if (rfwd->listen_path == NULL && rfwd->listen_port == 0) { |
1611 | if (type == SSH2_MSG_REQUEST_SUCCESS) { | 1616 | if (type == SSH2_MSG_REQUEST_SUCCESS) { |
1612 | rfwd->allocated_port = packet_get_int(); | 1617 | if ((r = sshpkt_get_u32(ssh, &port)) != 0) |
1613 | logit("Allocated port %u for remote forward to %s:%d", | 1618 | fatal("%s: %s", __func__, ssh_err(r)); |
1614 | rfwd->allocated_port, | 1619 | if (port > 65535) { |
1615 | rfwd->connect_host, rfwd->connect_port); | 1620 | error("Invalid allocated port %u for remote " |
1616 | channel_update_permission(ssh, | 1621 | "forward to %s:%d", port, |
1617 | rfwd->handle, rfwd->allocated_port); | 1622 | rfwd->connect_host, rfwd->connect_port); |
1623 | /* Ensure failure processing runs below */ | ||
1624 | type = SSH2_MSG_REQUEST_FAILURE; | ||
1625 | channel_update_permission(ssh, | ||
1626 | rfwd->handle, -1); | ||
1627 | } else { | ||
1628 | rfwd->allocated_port = (int)port; | ||
1629 | logit("Allocated port %u for remote " | ||
1630 | "forward to %s:%d", | ||
1631 | rfwd->allocated_port, rfwd->connect_host, | ||
1632 | rfwd->connect_port); | ||
1633 | channel_update_permission(ssh, | ||
1634 | rfwd->handle, rfwd->allocated_port); | ||
1635 | } | ||
1618 | } else { | 1636 | } else { |
1619 | channel_update_permission(ssh, rfwd->handle, -1); | 1637 | channel_update_permission(ssh, rfwd->handle, -1); |
1620 | } | 1638 | } |
@@ -1771,7 +1789,7 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg) | |||
1771 | { | 1789 | { |
1772 | extern char **environ; | 1790 | extern char **environ; |
1773 | const char *display; | 1791 | const char *display; |
1774 | int interactive = tty_flag; | 1792 | int r, interactive = tty_flag; |
1775 | char *proto = NULL, *data = NULL; | 1793 | char *proto = NULL, *data = NULL; |
1776 | 1794 | ||
1777 | if (!success) | 1795 | if (!success) |
@@ -1797,11 +1815,12 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg) | |||
1797 | if (options.forward_agent) { | 1815 | if (options.forward_agent) { |
1798 | debug("Requesting authentication agent forwarding."); | 1816 | debug("Requesting authentication agent forwarding."); |
1799 | channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0); | 1817 | channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0); |
1800 | packet_send(); | 1818 | if ((r = sshpkt_send(ssh)) != 0) |
1819 | fatal("%s: %s", __func__, ssh_err(r)); | ||
1801 | } | 1820 | } |
1802 | 1821 | ||
1803 | /* Tell the packet module whether this is an interactive session. */ | 1822 | /* Tell the packet module whether this is an interactive session. */ |
1804 | packet_set_interactive(interactive, | 1823 | ssh_packet_set_interactive(ssh, interactive, |
1805 | options.ip_qos_interactive, options.ip_qos_bulk); | 1824 | options.ip_qos_interactive, options.ip_qos_bulk); |
1806 | 1825 | ||
1807 | client_session2_setup(ssh, id, tty_flag, subsystem_flag, getenv("TERM"), | 1826 | client_session2_setup(ssh, id, tty_flag, subsystem_flag, getenv("TERM"), |
@@ -1858,7 +1877,7 @@ ssh_session2_open(struct ssh *ssh) | |||
1858 | static int | 1877 | static int |
1859 | ssh_session2(struct ssh *ssh, struct passwd *pw) | 1878 | ssh_session2(struct ssh *ssh, struct passwd *pw) |
1860 | { | 1879 | { |
1861 | int devnull, id = -1; | 1880 | int r, devnull, id = -1; |
1862 | char *cp, *tun_fwd_ifname = NULL; | 1881 | char *cp, *tun_fwd_ifname = NULL; |
1863 | 1882 | ||
1864 | /* XXX should be pre-session */ | 1883 | /* XXX should be pre-session */ |
@@ -1888,7 +1907,7 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) | |||
1888 | } | 1907 | } |
1889 | 1908 | ||
1890 | /* Start listening for multiplex clients */ | 1909 | /* Start listening for multiplex clients */ |
1891 | if (!packet_get_mux()) | 1910 | if (!ssh_packet_get_mux(ssh)) |
1892 | muxserver_listen(ssh); | 1911 | muxserver_listen(ssh); |
1893 | 1912 | ||
1894 | /* | 1913 | /* |
@@ -1922,7 +1941,7 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) | |||
1922 | if (!no_shell_flag) | 1941 | if (!no_shell_flag) |
1923 | id = ssh_session2_open(ssh); | 1942 | id = ssh_session2_open(ssh); |
1924 | else { | 1943 | else { |
1925 | packet_set_interactive( | 1944 | ssh_packet_set_interactive(ssh, |
1926 | options.control_master == SSHCTL_MASTER_NO, | 1945 | options.control_master == SSHCTL_MASTER_NO, |
1927 | options.ip_qos_interactive, options.ip_qos_bulk); | 1946 | options.ip_qos_interactive, options.ip_qos_bulk); |
1928 | } | 1947 | } |
@@ -1931,10 +1950,12 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) | |||
1931 | if (options.control_master == SSHCTL_MASTER_NO && | 1950 | if (options.control_master == SSHCTL_MASTER_NO && |
1932 | (datafellows & SSH_NEW_OPENSSH)) { | 1951 | (datafellows & SSH_NEW_OPENSSH)) { |
1933 | debug("Requesting no-more-sessions@openssh.com"); | 1952 | debug("Requesting no-more-sessions@openssh.com"); |
1934 | packet_start(SSH2_MSG_GLOBAL_REQUEST); | 1953 | if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 || |
1935 | packet_put_cstring("no-more-sessions@openssh.com"); | 1954 | (r = sshpkt_put_cstring(ssh, |
1936 | packet_put_char(0); | 1955 | "no-more-sessions@openssh.com")) != 0 || |
1937 | packet_send(); | 1956 | (r = sshpkt_put_u8(ssh, 0)) != 0 || |
1957 | (r = sshpkt_send(ssh)) != 0) | ||
1958 | fatal("%s: %s", __func__, ssh_err(r)); | ||
1938 | } | 1959 | } |
1939 | 1960 | ||
1940 | /* Execute a local command */ | 1961 | /* Execute a local command */ |