diff options
author | Colin Watson <cjwatson@debian.org> | 2019-06-05 06:41:44 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2019-06-05 06:41:44 +0100 |
commit | 102062f825fb26a74295a1c089c00c4c4c76b68a (patch) | |
tree | 3db66bc8c8483cce66516dff36f6ef56065143d9 /ssh.c | |
parent | 3d246f10429fc9a37b98eabef94fe8dc7c61002b (diff) | |
parent | fd0fa130ecf06d7d092932adcd5d77f1549bfc8d (diff) |
Import openssh_8.0p1.orig.tar.gz
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 107 |
1 files changed, 63 insertions, 44 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; |
@@ -816,7 +819,7 @@ main(int ac, char **av) | |||
816 | fprintf(stderr, "%s, %s\n", | 819 | fprintf(stderr, "%s, %s\n", |
817 | SSH_RELEASE, | 820 | SSH_RELEASE, |
818 | #ifdef WITH_OPENSSL | 821 | #ifdef WITH_OPENSSL |
819 | SSLeay_version(SSLEAY_VERSION) | 822 | OpenSSL_version(OPENSSL_VERSION) |
820 | #else | 823 | #else |
821 | "without OpenSSL" | 824 | "without OpenSSL" |
822 | #endif | 825 | #endif |
@@ -1036,11 +1039,6 @@ main(int ac, char **av) | |||
1036 | 1039 | ||
1037 | host_arg = xstrdup(host); | 1040 | host_arg = xstrdup(host); |
1038 | 1041 | ||
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. */ | 1042 | /* Initialize the command to execute on remote host. */ |
1045 | if ((command = sshbuf_new()) == NULL) | 1043 | if ((command = sshbuf_new()) == NULL) |
1046 | fatal("sshbuf_new failed"); | 1044 | fatal("sshbuf_new failed"); |
@@ -1085,14 +1083,16 @@ main(int ac, char **av) | |||
1085 | if (debug_flag) | 1083 | if (debug_flag) |
1086 | logit("%s, %s", SSH_RELEASE, | 1084 | logit("%s, %s", SSH_RELEASE, |
1087 | #ifdef WITH_OPENSSL | 1085 | #ifdef WITH_OPENSSL |
1088 | SSLeay_version(SSLEAY_VERSION) | 1086 | OpenSSL_version(OPENSSL_VERSION) |
1089 | #else | 1087 | #else |
1090 | "without OpenSSL" | 1088 | "without OpenSSL" |
1091 | #endif | 1089 | #endif |
1092 | ); | 1090 | ); |
1093 | 1091 | ||
1094 | /* Parse the configuration files */ | 1092 | /* Parse the configuration files */ |
1095 | process_config_files(host_arg, pw, 0); | 1093 | process_config_files(host_arg, pw, 0, &want_final_pass); |
1094 | if (want_final_pass) | ||
1095 | debug("configuration requests final Match pass"); | ||
1096 | 1096 | ||
1097 | /* Hostname canonicalisation needs a few options filled. */ | 1097 | /* Hostname canonicalisation needs a few options filled. */ |
1098 | fill_default_options_for_canonicalization(&options); | 1098 | fill_default_options_for_canonicalization(&options); |
@@ -1149,12 +1149,17 @@ main(int ac, char **av) | |||
1149 | * If canonicalisation is enabled then re-parse the configuration | 1149 | * If canonicalisation is enabled then re-parse the configuration |
1150 | * files as new stanzas may match. | 1150 | * files as new stanzas may match. |
1151 | */ | 1151 | */ |
1152 | if (options.canonicalize_hostname != 0) { | 1152 | if (options.canonicalize_hostname != 0 && !want_final_pass) { |
1153 | debug("Re-reading configuration after hostname " | 1153 | debug("hostname canonicalisation enabled, " |
1154 | "canonicalisation"); | 1154 | "will re-parse configuration"); |
1155 | want_final_pass = 1; | ||
1156 | } | ||
1157 | |||
1158 | if (want_final_pass) { | ||
1159 | debug("re-parsing configuration"); | ||
1155 | free(options.hostname); | 1160 | free(options.hostname); |
1156 | options.hostname = xstrdup(host); | 1161 | options.hostname = xstrdup(host); |
1157 | process_config_files(host_arg, pw, 1); | 1162 | process_config_files(host_arg, pw, 1, NULL); |
1158 | /* | 1163 | /* |
1159 | * Address resolution happens early with canonicalisation | 1164 | * Address resolution happens early with canonicalisation |
1160 | * enabled and the port number may have changed since, so | 1165 | * enabled and the port number may have changed since, so |
@@ -1264,8 +1269,6 @@ main(int ac, char **av) | |||
1264 | tty_flag = 0; | 1269 | tty_flag = 0; |
1265 | } | 1270 | } |
1266 | 1271 | ||
1267 | seed_rng(); | ||
1268 | |||
1269 | if (options.user == NULL) | 1272 | if (options.user == NULL) |
1270 | options.user = xstrdup(pw->pw_name); | 1273 | options.user = xstrdup(pw->pw_name); |
1271 | 1274 | ||
@@ -1344,7 +1347,7 @@ main(int ac, char **av) | |||
1344 | int sock; | 1347 | int sock; |
1345 | if ((sock = muxclient(options.control_path)) >= 0) { | 1348 | if ((sock = muxclient(options.control_path)) >= 0) { |
1346 | ssh_packet_set_connection(ssh, sock, sock); | 1349 | ssh_packet_set_connection(ssh, sock, sock); |
1347 | packet_set_mux(); | 1350 | ssh_packet_set_mux(ssh); |
1348 | goto skip_connect; | 1351 | goto skip_connect; |
1349 | } | 1352 | } |
1350 | } | 1353 | } |
@@ -1371,11 +1374,9 @@ main(int ac, char **av) | |||
1371 | if (addrs != NULL) | 1374 | if (addrs != NULL) |
1372 | freeaddrinfo(addrs); | 1375 | freeaddrinfo(addrs); |
1373 | 1376 | ||
1374 | packet_set_timeout(options.server_alive_interval, | 1377 | ssh_packet_set_timeout(ssh, options.server_alive_interval, |
1375 | options.server_alive_count_max); | 1378 | options.server_alive_count_max); |
1376 | 1379 | ||
1377 | ssh = active_state; /* XXX */ | ||
1378 | |||
1379 | if (timeout_ms > 0) | 1380 | if (timeout_ms > 0) |
1380 | debug3("timeout: %d ms remain after connect", timeout_ms); | 1381 | debug3("timeout: %d ms remain after connect", timeout_ms); |
1381 | 1382 | ||
@@ -1486,10 +1487,10 @@ main(int ac, char **av) | |||
1486 | signal(SIGCHLD, main_sigchld_handler); | 1487 | signal(SIGCHLD, main_sigchld_handler); |
1487 | 1488 | ||
1488 | /* Log into the remote system. Never returns if the login fails. */ | 1489 | /* Log into the remote system. Never returns if the login fails. */ |
1489 | ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, | 1490 | ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr, |
1490 | options.port, pw, timeout_ms); | 1491 | options.port, pw, timeout_ms); |
1491 | 1492 | ||
1492 | if (packet_connection_is_on_socket()) { | 1493 | if (ssh_packet_connection_is_on_socket(ssh)) { |
1493 | verbose("Authenticated to %s ([%s]:%d).", host, | 1494 | verbose("Authenticated to %s ([%s]:%d).", host, |
1494 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); | 1495 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); |
1495 | } else { | 1496 | } else { |
@@ -1523,7 +1524,7 @@ main(int ac, char **av) | |||
1523 | 1524 | ||
1524 | skip_connect: | 1525 | skip_connect: |
1525 | exit_status = ssh_session2(ssh, pw); | 1526 | exit_status = ssh_session2(ssh, pw); |
1526 | packet_close(); | 1527 | ssh_packet_close(ssh); |
1527 | 1528 | ||
1528 | if (options.control_path != NULL && muxserver_sock != -1) | 1529 | if (options.control_path != NULL && muxserver_sock != -1) |
1529 | unlink(options.control_path); | 1530 | unlink(options.control_path); |
@@ -1598,6 +1599,8 @@ static void | |||
1598 | ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) | 1599 | ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) |
1599 | { | 1600 | { |
1600 | struct Forward *rfwd = (struct Forward *)ctxt; | 1601 | struct Forward *rfwd = (struct Forward *)ctxt; |
1602 | u_int port; | ||
1603 | int r; | ||
1601 | 1604 | ||
1602 | /* XXX verbose() on failure? */ | 1605 | /* XXX verbose() on failure? */ |
1603 | debug("remote forward %s for: listen %s%s%d, connect %s:%d", | 1606 | debug("remote forward %s for: listen %s%s%d, connect %s:%d", |
@@ -1609,12 +1612,25 @@ ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) | |||
1609 | rfwd->connect_host, rfwd->connect_port); | 1612 | rfwd->connect_host, rfwd->connect_port); |
1610 | if (rfwd->listen_path == NULL && rfwd->listen_port == 0) { | 1613 | if (rfwd->listen_path == NULL && rfwd->listen_port == 0) { |
1611 | if (type == SSH2_MSG_REQUEST_SUCCESS) { | 1614 | if (type == SSH2_MSG_REQUEST_SUCCESS) { |
1612 | rfwd->allocated_port = packet_get_int(); | 1615 | if ((r = sshpkt_get_u32(ssh, &port)) != 0) |
1613 | logit("Allocated port %u for remote forward to %s:%d", | 1616 | fatal("%s: %s", __func__, ssh_err(r)); |
1614 | rfwd->allocated_port, | 1617 | if (port > 65535) { |
1615 | rfwd->connect_host, rfwd->connect_port); | 1618 | error("Invalid allocated port %u for remote " |
1616 | channel_update_permission(ssh, | 1619 | "forward to %s:%d", port, |
1617 | rfwd->handle, rfwd->allocated_port); | 1620 | rfwd->connect_host, rfwd->connect_port); |
1621 | /* Ensure failure processing runs below */ | ||
1622 | type = SSH2_MSG_REQUEST_FAILURE; | ||
1623 | channel_update_permission(ssh, | ||
1624 | rfwd->handle, -1); | ||
1625 | } else { | ||
1626 | rfwd->allocated_port = (int)port; | ||
1627 | logit("Allocated port %u for remote " | ||
1628 | "forward to %s:%d", | ||
1629 | rfwd->allocated_port, rfwd->connect_host, | ||
1630 | rfwd->connect_port); | ||
1631 | channel_update_permission(ssh, | ||
1632 | rfwd->handle, rfwd->allocated_port); | ||
1633 | } | ||
1618 | } else { | 1634 | } else { |
1619 | channel_update_permission(ssh, rfwd->handle, -1); | 1635 | channel_update_permission(ssh, rfwd->handle, -1); |
1620 | } | 1636 | } |
@@ -1771,7 +1787,7 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg) | |||
1771 | { | 1787 | { |
1772 | extern char **environ; | 1788 | extern char **environ; |
1773 | const char *display; | 1789 | const char *display; |
1774 | int interactive = tty_flag; | 1790 | int r, interactive = tty_flag; |
1775 | char *proto = NULL, *data = NULL; | 1791 | char *proto = NULL, *data = NULL; |
1776 | 1792 | ||
1777 | if (!success) | 1793 | if (!success) |
@@ -1797,11 +1813,12 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg) | |||
1797 | if (options.forward_agent) { | 1813 | if (options.forward_agent) { |
1798 | debug("Requesting authentication agent forwarding."); | 1814 | debug("Requesting authentication agent forwarding."); |
1799 | channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0); | 1815 | channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0); |
1800 | packet_send(); | 1816 | if ((r = sshpkt_send(ssh)) != 0) |
1817 | fatal("%s: %s", __func__, ssh_err(r)); | ||
1801 | } | 1818 | } |
1802 | 1819 | ||
1803 | /* Tell the packet module whether this is an interactive session. */ | 1820 | /* Tell the packet module whether this is an interactive session. */ |
1804 | packet_set_interactive(interactive, | 1821 | ssh_packet_set_interactive(ssh, interactive, |
1805 | options.ip_qos_interactive, options.ip_qos_bulk); | 1822 | options.ip_qos_interactive, options.ip_qos_bulk); |
1806 | 1823 | ||
1807 | client_session2_setup(ssh, id, tty_flag, subsystem_flag, getenv("TERM"), | 1824 | client_session2_setup(ssh, id, tty_flag, subsystem_flag, getenv("TERM"), |
@@ -1858,7 +1875,7 @@ ssh_session2_open(struct ssh *ssh) | |||
1858 | static int | 1875 | static int |
1859 | ssh_session2(struct ssh *ssh, struct passwd *pw) | 1876 | ssh_session2(struct ssh *ssh, struct passwd *pw) |
1860 | { | 1877 | { |
1861 | int devnull, id = -1; | 1878 | int r, devnull, id = -1; |
1862 | char *cp, *tun_fwd_ifname = NULL; | 1879 | char *cp, *tun_fwd_ifname = NULL; |
1863 | 1880 | ||
1864 | /* XXX should be pre-session */ | 1881 | /* XXX should be pre-session */ |
@@ -1888,7 +1905,7 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) | |||
1888 | } | 1905 | } |
1889 | 1906 | ||
1890 | /* Start listening for multiplex clients */ | 1907 | /* Start listening for multiplex clients */ |
1891 | if (!packet_get_mux()) | 1908 | if (!ssh_packet_get_mux(ssh)) |
1892 | muxserver_listen(ssh); | 1909 | muxserver_listen(ssh); |
1893 | 1910 | ||
1894 | /* | 1911 | /* |
@@ -1922,7 +1939,7 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) | |||
1922 | if (!no_shell_flag) | 1939 | if (!no_shell_flag) |
1923 | id = ssh_session2_open(ssh); | 1940 | id = ssh_session2_open(ssh); |
1924 | else { | 1941 | else { |
1925 | packet_set_interactive( | 1942 | ssh_packet_set_interactive(ssh, |
1926 | options.control_master == SSHCTL_MASTER_NO, | 1943 | options.control_master == SSHCTL_MASTER_NO, |
1927 | options.ip_qos_interactive, options.ip_qos_bulk); | 1944 | options.ip_qos_interactive, options.ip_qos_bulk); |
1928 | } | 1945 | } |
@@ -1931,10 +1948,12 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) | |||
1931 | if (options.control_master == SSHCTL_MASTER_NO && | 1948 | if (options.control_master == SSHCTL_MASTER_NO && |
1932 | (datafellows & SSH_NEW_OPENSSH)) { | 1949 | (datafellows & SSH_NEW_OPENSSH)) { |
1933 | debug("Requesting no-more-sessions@openssh.com"); | 1950 | debug("Requesting no-more-sessions@openssh.com"); |
1934 | packet_start(SSH2_MSG_GLOBAL_REQUEST); | 1951 | if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 || |
1935 | packet_put_cstring("no-more-sessions@openssh.com"); | 1952 | (r = sshpkt_put_cstring(ssh, |
1936 | packet_put_char(0); | 1953 | "no-more-sessions@openssh.com")) != 0 || |
1937 | packet_send(); | 1954 | (r = sshpkt_put_u8(ssh, 0)) != 0 || |
1955 | (r = sshpkt_send(ssh)) != 0) | ||
1956 | fatal("%s: %s", __func__, ssh_err(r)); | ||
1938 | } | 1957 | } |
1939 | 1958 | ||
1940 | /* Execute a local command */ | 1959 | /* Execute a local command */ |