diff options
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 108 |
1 files changed, 54 insertions, 54 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.465 2017/10/21 23:06:24 millert Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.466 2017/10/23 05:08:00 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 |
@@ -168,6 +168,10 @@ char *config = NULL; | |||
168 | */ | 168 | */ |
169 | char *host; | 169 | char *host; |
170 | 170 | ||
171 | /* Various strings used to to percent_expand() arguments */ | ||
172 | static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; | ||
173 | static char uidstr[32], *host_arg, *conn_hash_hex; | ||
174 | |||
171 | /* socket address the host resolves to */ | 175 | /* socket address the host resolves to */ |
172 | struct sockaddr_storage hostaddr; | 176 | struct sockaddr_storage hostaddr; |
173 | 177 | ||
@@ -208,8 +212,8 @@ usage(void) | |||
208 | exit(255); | 212 | exit(255); |
209 | } | 213 | } |
210 | 214 | ||
211 | static int ssh_session2(struct ssh *); | 215 | static int ssh_session2(struct ssh *, struct passwd *); |
212 | static void load_public_identity_files(void); | 216 | static void load_public_identity_files(struct passwd *); |
213 | static void main_sigchld_handler(int); | 217 | static void main_sigchld_handler(int); |
214 | 218 | ||
215 | /* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */ | 219 | /* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */ |
@@ -456,14 +460,14 @@ resolve_canonicalize(char **hostp, int port) | |||
456 | * file if the user specifies a config file on the command line. | 460 | * file if the user specifies a config file on the command line. |
457 | */ | 461 | */ |
458 | static void | 462 | static void |
459 | process_config_files(const char *host_arg, struct passwd *pw, int post_canon) | 463 | process_config_files(const char *host_name, struct passwd *pw, int post_canon) |
460 | { | 464 | { |
461 | char buf[PATH_MAX]; | 465 | char buf[PATH_MAX]; |
462 | int r; | 466 | int r; |
463 | 467 | ||
464 | if (config != NULL) { | 468 | if (config != NULL) { |
465 | if (strcasecmp(config, "none") != 0 && | 469 | if (strcasecmp(config, "none") != 0 && |
466 | !read_config_file(config, pw, host, host_arg, &options, | 470 | !read_config_file(config, pw, host, host_name, &options, |
467 | SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0))) | 471 | SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0))) |
468 | fatal("Can't open user config file %.100s: " | 472 | fatal("Can't open user config file %.100s: " |
469 | "%.100s", config, strerror(errno)); | 473 | "%.100s", config, strerror(errno)); |
@@ -471,13 +475,13 @@ process_config_files(const char *host_arg, struct passwd *pw, int post_canon) | |||
471 | r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, | 475 | r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, |
472 | _PATH_SSH_USER_CONFFILE); | 476 | _PATH_SSH_USER_CONFFILE); |
473 | if (r > 0 && (size_t)r < sizeof(buf)) | 477 | if (r > 0 && (size_t)r < sizeof(buf)) |
474 | (void)read_config_file(buf, pw, host, host_arg, | 478 | (void)read_config_file(buf, pw, host, host_name, |
475 | &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | | 479 | &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | |
476 | (post_canon ? SSHCONF_POSTCANON : 0)); | 480 | (post_canon ? SSHCONF_POSTCANON : 0)); |
477 | 481 | ||
478 | /* Read systemwide configuration file after user config. */ | 482 | /* Read systemwide configuration file after user config. */ |
479 | (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, | 483 | (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, |
480 | host, host_arg, &options, | 484 | host, host_name, &options, |
481 | post_canon ? SSHCONF_POSTCANON : 0); | 485 | post_canon ? SSHCONF_POSTCANON : 0); |
482 | } | 486 | } |
483 | } | 487 | } |
@@ -511,9 +515,8 @@ main(int ac, char **av) | |||
511 | struct ssh *ssh = NULL; | 515 | struct ssh *ssh = NULL; |
512 | int i, r, opt, exit_status, use_syslog, direct, timeout_ms; | 516 | int i, r, opt, exit_status, use_syslog, direct, timeout_ms; |
513 | int config_test = 0, opt_terminated = 0; | 517 | int config_test = 0, opt_terminated = 0; |
514 | char *p, *cp, *line, *argv0, buf[PATH_MAX], *host_arg, *logfile; | 518 | char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile; |
515 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; | 519 | char cname[NI_MAXHOST]; |
516 | char cname[NI_MAXHOST], uidstr[32], *conn_hash_hex; | ||
517 | struct stat st; | 520 | struct stat st; |
518 | struct passwd *pw; | 521 | struct passwd *pw; |
519 | extern int optind, optreset; | 522 | extern int optind, optreset; |
@@ -1203,6 +1206,7 @@ main(int ac, char **av) | |||
1203 | if (options.user == NULL) | 1206 | if (options.user == NULL) |
1204 | options.user = xstrdup(pw->pw_name); | 1207 | options.user = xstrdup(pw->pw_name); |
1205 | 1208 | ||
1209 | /* Set up strings used to percent_expand() arguments */ | ||
1206 | if (gethostname(thishost, sizeof(thishost)) == -1) | 1210 | if (gethostname(thishost, sizeof(thishost)) == -1) |
1207 | fatal("gethostname: %s", strerror(errno)); | 1211 | fatal("gethostname: %s", strerror(errno)); |
1208 | strlcpy(shorthost, thishost, sizeof(shorthost)); | 1212 | strlcpy(shorthost, thishost, sizeof(shorthost)); |
@@ -1220,24 +1224,11 @@ main(int ac, char **av) | |||
1220 | ssh_digest_free(md); | 1224 | ssh_digest_free(md); |
1221 | conn_hash_hex = tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1)); | 1225 | conn_hash_hex = tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1)); |
1222 | 1226 | ||
1223 | if (options.local_command != NULL) { | 1227 | /* |
1224 | debug3("expanding LocalCommand: %s", options.local_command); | 1228 | * Expand tokens in arguments. NB. LocalCommand is expanded later, |
1225 | cp = options.local_command; | 1229 | * after port-forwarding is set up, so it may pick up any local |
1226 | options.local_command = percent_expand(cp, | 1230 | * tunnel interface name allocated. |
1227 | "C", conn_hash_hex, | 1231 | */ |
1228 | "L", shorthost, | ||
1229 | "d", pw->pw_dir, | ||
1230 | "h", host, | ||
1231 | "l", thishost, | ||
1232 | "n", host_arg, | ||
1233 | "p", portstr, | ||
1234 | "r", options.user, | ||
1235 | "u", pw->pw_name, | ||
1236 | (char *)NULL); | ||
1237 | debug3("expanded LocalCommand: %s", options.local_command); | ||
1238 | free(cp); | ||
1239 | } | ||
1240 | |||
1241 | if (options.remote_command != NULL) { | 1232 | if (options.remote_command != NULL) { |
1242 | debug3("expanding RemoteCommand: %s", options.remote_command); | 1233 | debug3("expanding RemoteCommand: %s", options.remote_command); |
1243 | cp = options.remote_command; | 1234 | cp = options.remote_command; |
@@ -1256,7 +1247,6 @@ main(int ac, char **av) | |||
1256 | free(cp); | 1247 | free(cp); |
1257 | buffer_append(&command, options.remote_command, | 1248 | buffer_append(&command, options.remote_command, |
1258 | strlen(options.remote_command)); | 1249 | strlen(options.remote_command)); |
1259 | |||
1260 | } | 1250 | } |
1261 | 1251 | ||
1262 | if (options.control_path != NULL) { | 1252 | if (options.control_path != NULL) { |
@@ -1427,7 +1417,7 @@ main(int ac, char **av) | |||
1427 | } | 1417 | } |
1428 | } | 1418 | } |
1429 | /* load options.identity_files */ | 1419 | /* load options.identity_files */ |
1430 | load_public_identity_files(); | 1420 | load_public_identity_files(pw); |
1431 | 1421 | ||
1432 | /* optionally set the SSH_AUTHSOCKET_ENV_NAME varibale */ | 1422 | /* optionally set the SSH_AUTHSOCKET_ENV_NAME varibale */ |
1433 | if (options.identity_agent && | 1423 | if (options.identity_agent && |
@@ -1491,7 +1481,7 @@ main(int ac, char **av) | |||
1491 | } | 1481 | } |
1492 | 1482 | ||
1493 | skip_connect: | 1483 | skip_connect: |
1494 | exit_status = ssh_session2(ssh); | 1484 | exit_status = ssh_session2(ssh, pw); |
1495 | packet_close(); | 1485 | packet_close(); |
1496 | 1486 | ||
1497 | if (options.control_path != NULL && muxserver_sock != -1) | 1487 | if (options.control_path != NULL && muxserver_sock != -1) |
@@ -1650,7 +1640,7 @@ ssh_init_stdio_forwarding(struct ssh *ssh) | |||
1650 | } | 1640 | } |
1651 | 1641 | ||
1652 | static void | 1642 | static void |
1653 | ssh_init_forwarding(struct ssh *ssh) | 1643 | ssh_init_forwarding(struct ssh *ssh, char **ifname) |
1654 | { | 1644 | { |
1655 | int success = 0; | 1645 | int success = 0; |
1656 | int i; | 1646 | int i; |
@@ -1708,8 +1698,9 @@ ssh_init_forwarding(struct ssh *ssh) | |||
1708 | 1698 | ||
1709 | /* Initiate tunnel forwarding. */ | 1699 | /* Initiate tunnel forwarding. */ |
1710 | if (options.tun_open != SSH_TUNMODE_NO) { | 1700 | if (options.tun_open != SSH_TUNMODE_NO) { |
1711 | if (client_request_tun_fwd(ssh, options.tun_open, | 1701 | if ((*ifname = client_request_tun_fwd(ssh, |
1712 | options.tun_local, options.tun_remote) == -1) { | 1702 | options.tun_open, options.tun_local, |
1703 | options.tun_remote)) == NULL) { | ||
1713 | if (options.exit_on_forward_failure) | 1704 | if (options.exit_on_forward_failure) |
1714 | fatal("Could not request tunnel forwarding."); | 1705 | fatal("Could not request tunnel forwarding."); |
1715 | else | 1706 | else |
@@ -1824,14 +1815,35 @@ ssh_session2_open(struct ssh *ssh) | |||
1824 | } | 1815 | } |
1825 | 1816 | ||
1826 | static int | 1817 | static int |
1827 | ssh_session2(struct ssh *ssh) | 1818 | ssh_session2(struct ssh *ssh, struct passwd *pw) |
1828 | { | 1819 | { |
1829 | int id = -1; | 1820 | int id = -1; |
1821 | char *cp, *tun_fwd_ifname = NULL; | ||
1830 | 1822 | ||
1831 | /* XXX should be pre-session */ | 1823 | /* XXX should be pre-session */ |
1832 | if (!options.control_persist) | 1824 | if (!options.control_persist) |
1833 | ssh_init_stdio_forwarding(ssh); | 1825 | ssh_init_stdio_forwarding(ssh); |
1834 | ssh_init_forwarding(ssh); | 1826 | |
1827 | ssh_init_forwarding(ssh, &tun_fwd_ifname); | ||
1828 | |||
1829 | if (options.local_command != NULL) { | ||
1830 | debug3("expanding LocalCommand: %s", options.local_command); | ||
1831 | cp = options.local_command; | ||
1832 | options.local_command = percent_expand(cp, | ||
1833 | "C", conn_hash_hex, | ||
1834 | "L", shorthost, | ||
1835 | "d", pw->pw_dir, | ||
1836 | "h", host, | ||
1837 | "l", thishost, | ||
1838 | "n", host_arg, | ||
1839 | "p", portstr, | ||
1840 | "r", options.user, | ||
1841 | "u", pw->pw_name, | ||
1842 | "T", tun_fwd_ifname == NULL ? "NONE" : tun_fwd_ifname, | ||
1843 | (char *)NULL); | ||
1844 | debug3("expanded LocalCommand: %s", options.local_command); | ||
1845 | free(cp); | ||
1846 | } | ||
1835 | 1847 | ||
1836 | /* Start listening for multiplex clients */ | 1848 | /* Start listening for multiplex clients */ |
1837 | if (!packet_get_mux()) | 1849 | if (!packet_get_mux()) |
@@ -1907,12 +1919,10 @@ ssh_session2(struct ssh *ssh) | |||
1907 | 1919 | ||
1908 | /* Loads all IdentityFile and CertificateFile keys */ | 1920 | /* Loads all IdentityFile and CertificateFile keys */ |
1909 | static void | 1921 | static void |
1910 | load_public_identity_files(void) | 1922 | load_public_identity_files(struct passwd *pw) |
1911 | { | 1923 | { |
1912 | char *filename, *cp, thishost[NI_MAXHOST]; | 1924 | char *filename, *cp; |
1913 | char *pwdir = NULL, *pwname = NULL; | ||
1914 | struct sshkey *public; | 1925 | struct sshkey *public; |
1915 | struct passwd *pw; | ||
1916 | int i; | 1926 | int i; |
1917 | u_int n_ids, n_certs; | 1927 | u_int n_ids, n_certs; |
1918 | char *identity_files[SSH_MAX_IDENTITY_FILES]; | 1928 | char *identity_files[SSH_MAX_IDENTITY_FILES]; |
@@ -1951,11 +1961,6 @@ load_public_identity_files(void) | |||
1951 | #endif /* ENABLE_PKCS11 */ | 1961 | #endif /* ENABLE_PKCS11 */ |
1952 | if ((pw = getpwuid(original_real_uid)) == NULL) | 1962 | if ((pw = getpwuid(original_real_uid)) == NULL) |
1953 | fatal("load_public_identity_files: getpwuid failed"); | 1963 | fatal("load_public_identity_files: getpwuid failed"); |
1954 | pwname = xstrdup(pw->pw_name); | ||
1955 | pwdir = xstrdup(pw->pw_dir); | ||
1956 | if (gethostname(thishost, sizeof(thishost)) == -1) | ||
1957 | fatal("load_public_identity_files: gethostname: %s", | ||
1958 | strerror(errno)); | ||
1959 | for (i = 0; i < options.num_identity_files; i++) { | 1964 | for (i = 0; i < options.num_identity_files; i++) { |
1960 | if (n_ids >= SSH_MAX_IDENTITY_FILES || | 1965 | if (n_ids >= SSH_MAX_IDENTITY_FILES || |
1961 | strcasecmp(options.identity_files[i], "none") == 0) { | 1966 | strcasecmp(options.identity_files[i], "none") == 0) { |
@@ -1965,8 +1970,8 @@ load_public_identity_files(void) | |||
1965 | } | 1970 | } |
1966 | cp = tilde_expand_filename(options.identity_files[i], | 1971 | cp = tilde_expand_filename(options.identity_files[i], |
1967 | original_real_uid); | 1972 | original_real_uid); |
1968 | filename = percent_expand(cp, "d", pwdir, | 1973 | filename = percent_expand(cp, "d", pw->pw_dir, |
1969 | "u", pwname, "l", thishost, "h", host, | 1974 | "u", pw->pw_name, "l", thishost, "h", host, |
1970 | "r", options.user, (char *)NULL); | 1975 | "r", options.user, (char *)NULL); |
1971 | free(cp); | 1976 | free(cp); |
1972 | public = key_load_public(filename, NULL); | 1977 | public = key_load_public(filename, NULL); |
@@ -2011,8 +2016,8 @@ load_public_identity_files(void) | |||
2011 | for (i = 0; i < options.num_certificate_files; i++) { | 2016 | for (i = 0; i < options.num_certificate_files; i++) { |
2012 | cp = tilde_expand_filename(options.certificate_files[i], | 2017 | cp = tilde_expand_filename(options.certificate_files[i], |
2013 | original_real_uid); | 2018 | original_real_uid); |
2014 | filename = percent_expand(cp, "d", pwdir, | 2019 | filename = percent_expand(cp, "d", pw->pw_dir, |
2015 | "u", pwname, "l", thishost, "h", host, | 2020 | "u", pw->pw_name, "l", thishost, "h", host, |
2016 | "r", options.user, (char *)NULL); | 2021 | "r", options.user, (char *)NULL); |
2017 | free(cp); | 2022 | free(cp); |
2018 | 2023 | ||
@@ -2045,11 +2050,6 @@ load_public_identity_files(void) | |||
2045 | memcpy(options.certificate_files, | 2050 | memcpy(options.certificate_files, |
2046 | certificate_files, sizeof(certificate_files)); | 2051 | certificate_files, sizeof(certificate_files)); |
2047 | memcpy(options.certificates, certificates, sizeof(certificates)); | 2052 | memcpy(options.certificates, certificates, sizeof(certificates)); |
2048 | |||
2049 | explicit_bzero(pwname, strlen(pwname)); | ||
2050 | free(pwname); | ||
2051 | explicit_bzero(pwdir, strlen(pwdir)); | ||
2052 | free(pwdir); | ||
2053 | } | 2053 | } |
2054 | 2054 | ||
2055 | static void | 2055 | static void |