diff options
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 274 |
1 files changed, 167 insertions, 107 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.519 2020/02/07 03:54:44 dtucker Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.527 2020/04/10 00:52:07 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 |
@@ -86,7 +86,6 @@ | |||
86 | #include "canohost.h" | 86 | #include "canohost.h" |
87 | #include "compat.h" | 87 | #include "compat.h" |
88 | #include "cipher.h" | 88 | #include "cipher.h" |
89 | #include "digest.h" | ||
90 | #include "packet.h" | 89 | #include "packet.h" |
91 | #include "sshbuf.h" | 90 | #include "sshbuf.h" |
92 | #include "channels.h" | 91 | #include "channels.h" |
@@ -191,7 +190,7 @@ struct sshbuf *command; | |||
191 | int subsystem_flag = 0; | 190 | int subsystem_flag = 0; |
192 | 191 | ||
193 | /* # of replies received for global requests */ | 192 | /* # of replies received for global requests */ |
194 | static int remote_forward_confirms_received = 0; | 193 | static int forward_confirms_pending = -1; |
195 | 194 | ||
196 | /* mux.c */ | 195 | /* mux.c */ |
197 | extern int muxserver_sock; | 196 | extern int muxserver_sock; |
@@ -232,6 +231,34 @@ tilde_expand_paths(char **paths, u_int num_paths) | |||
232 | } | 231 | } |
233 | } | 232 | } |
234 | 233 | ||
234 | #define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS \ | ||
235 | "C", conn_hash_hex, \ | ||
236 | "L", shorthost, \ | ||
237 | "i", uidstr, \ | ||
238 | "l", thishost, \ | ||
239 | "n", host_arg, \ | ||
240 | "p", portstr | ||
241 | |||
242 | /* | ||
243 | * Expands the set of percent_expand options used by the majority of keywords | ||
244 | * in the client that support percent expansion. | ||
245 | * Caller must free returned string. | ||
246 | */ | ||
247 | static char * | ||
248 | default_client_percent_expand(const char *str, const char *homedir, | ||
249 | const char *remhost, const char *remuser, const char *locuser) | ||
250 | { | ||
251 | return percent_expand(str, | ||
252 | /* values from statics above */ | ||
253 | DEFAULT_CLIENT_PERCENT_EXPAND_ARGS, | ||
254 | /* values from arguments */ | ||
255 | "d", homedir, | ||
256 | "h", remhost, | ||
257 | "r", remuser, | ||
258 | "u", locuser, | ||
259 | (char *)NULL); | ||
260 | } | ||
261 | |||
235 | /* | 262 | /* |
236 | * Attempt to resolve a host name / port to a set of addresses and | 263 | * Attempt to resolve a host name / port to a set of addresses and |
237 | * optionally return any CNAMEs encountered along the way. | 264 | * optionally return any CNAMEs encountered along the way. |
@@ -248,6 +275,8 @@ resolve_host(const char *name, int port, int logerr, char *cname, size_t clen) | |||
248 | 275 | ||
249 | if (port <= 0) | 276 | if (port <= 0) |
250 | port = default_ssh_port(); | 277 | port = default_ssh_port(); |
278 | if (cname != NULL) | ||
279 | *cname = '\0'; | ||
251 | 280 | ||
252 | snprintf(strport, sizeof strport, "%d", port); | 281 | snprintf(strport, sizeof strport, "%d", port); |
253 | memset(&hints, 0, sizeof(hints)); | 282 | memset(&hints, 0, sizeof(hints)); |
@@ -477,7 +506,6 @@ resolve_canonicalize(char **hostp, int port) | |||
477 | } | 506 | } |
478 | /* Attempt each supplied suffix */ | 507 | /* Attempt each supplied suffix */ |
479 | for (i = 0; i < options.num_canonical_domains; i++) { | 508 | for (i = 0; i < options.num_canonical_domains; i++) { |
480 | *newname = '\0'; | ||
481 | xasprintf(&fullhost, "%s.%s.", *hostp, | 509 | xasprintf(&fullhost, "%s.%s.", *hostp, |
482 | options.canonical_domains[i]); | 510 | options.canonical_domains[i]); |
483 | debug3("%s: attempting \"%s\" => \"%s\"", __func__, | 511 | debug3("%s: attempting \"%s\" => \"%s\"", __func__, |
@@ -600,8 +628,6 @@ main(int ac, char **av) | |||
600 | extern char *optarg; | 628 | extern char *optarg; |
601 | struct Forward fwd; | 629 | struct Forward fwd; |
602 | struct addrinfo *addrs = NULL; | 630 | struct addrinfo *addrs = NULL; |
603 | struct ssh_digest_ctx *md; | ||
604 | u_char conn_hash[SSH_DIGEST_MAX_LENGTH]; | ||
605 | size_t n, len; | 631 | size_t n, len; |
606 | 632 | ||
607 | /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ | 633 | /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
@@ -1210,6 +1236,14 @@ main(int ac, char **av) | |||
1210 | if (options.jump_host != NULL) { | 1236 | if (options.jump_host != NULL) { |
1211 | char port_s[8]; | 1237 | char port_s[8]; |
1212 | const char *sshbin = argv0; | 1238 | const char *sshbin = argv0; |
1239 | int port = options.port, jumpport = options.jump_port; | ||
1240 | |||
1241 | if (port <= 0) | ||
1242 | port = default_ssh_port(); | ||
1243 | if (jumpport <= 0) | ||
1244 | jumpport = default_ssh_port(); | ||
1245 | if (strcmp(options.jump_host, host) == 0 && port == jumpport) | ||
1246 | fatal("jumphost loop via %s", options.jump_host); | ||
1213 | 1247 | ||
1214 | /* | 1248 | /* |
1215 | * Try to use SSH indicated by argv[0], but fall back to | 1249 | * Try to use SSH indicated by argv[0], but fall back to |
@@ -1323,15 +1357,8 @@ main(int ac, char **av) | |||
1323 | snprintf(uidstr, sizeof(uidstr), "%llu", | 1357 | snprintf(uidstr, sizeof(uidstr), "%llu", |
1324 | (unsigned long long)pw->pw_uid); | 1358 | (unsigned long long)pw->pw_uid); |
1325 | 1359 | ||
1326 | if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL || | 1360 | conn_hash_hex = ssh_connection_hash(thishost, host, portstr, |
1327 | ssh_digest_update(md, thishost, strlen(thishost)) < 0 || | 1361 | options.user); |
1328 | ssh_digest_update(md, host, strlen(host)) < 0 || | ||
1329 | ssh_digest_update(md, portstr, strlen(portstr)) < 0 || | ||
1330 | ssh_digest_update(md, options.user, strlen(options.user)) < 0 || | ||
1331 | ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0) | ||
1332 | fatal("%s: mux digest failed", __func__); | ||
1333 | ssh_digest_free(md); | ||
1334 | conn_hash_hex = tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1)); | ||
1335 | 1362 | ||
1336 | /* | 1363 | /* |
1337 | * Expand tokens in arguments. NB. LocalCommand is expanded later, | 1364 | * Expand tokens in arguments. NB. LocalCommand is expanded later, |
@@ -1341,18 +1368,8 @@ main(int ac, char **av) | |||
1341 | if (options.remote_command != NULL) { | 1368 | if (options.remote_command != NULL) { |
1342 | debug3("expanding RemoteCommand: %s", options.remote_command); | 1369 | debug3("expanding RemoteCommand: %s", options.remote_command); |
1343 | cp = options.remote_command; | 1370 | cp = options.remote_command; |
1344 | options.remote_command = percent_expand(cp, | 1371 | options.remote_command = default_client_percent_expand(cp, |
1345 | "C", conn_hash_hex, | 1372 | pw->pw_dir, host, options.user, pw->pw_name); |
1346 | "L", shorthost, | ||
1347 | "d", pw->pw_dir, | ||
1348 | "h", host, | ||
1349 | "i", uidstr, | ||
1350 | "l", thishost, | ||
1351 | "n", host_arg, | ||
1352 | "p", portstr, | ||
1353 | "r", options.user, | ||
1354 | "u", pw->pw_name, | ||
1355 | (char *)NULL); | ||
1356 | debug3("expanded RemoteCommand: %s", options.remote_command); | 1373 | debug3("expanded RemoteCommand: %s", options.remote_command); |
1357 | free(cp); | 1374 | free(cp); |
1358 | if ((r = sshbuf_put(command, options.remote_command, | 1375 | if ((r = sshbuf_put(command, options.remote_command, |
@@ -1363,21 +1380,76 @@ main(int ac, char **av) | |||
1363 | if (options.control_path != NULL) { | 1380 | if (options.control_path != NULL) { |
1364 | cp = tilde_expand_filename(options.control_path, getuid()); | 1381 | cp = tilde_expand_filename(options.control_path, getuid()); |
1365 | free(options.control_path); | 1382 | free(options.control_path); |
1366 | options.control_path = percent_expand(cp, | 1383 | options.control_path = default_client_percent_expand(cp, |
1367 | "C", conn_hash_hex, | 1384 | pw->pw_dir, host, options.user, pw->pw_name); |
1368 | "L", shorthost, | ||
1369 | "h", host, | ||
1370 | "i", uidstr, | ||
1371 | "l", thishost, | ||
1372 | "n", host_arg, | ||
1373 | "p", portstr, | ||
1374 | "r", options.user, | ||
1375 | "u", pw->pw_name, | ||
1376 | "i", uidstr, | ||
1377 | (char *)NULL); | ||
1378 | free(cp); | 1385 | free(cp); |
1379 | } | 1386 | } |
1380 | 1387 | ||
1388 | if (options.identity_agent != NULL) { | ||
1389 | p = tilde_expand_filename(options.identity_agent, getuid()); | ||
1390 | cp = default_client_percent_expand(p, | ||
1391 | pw->pw_dir, host, options.user, pw->pw_name); | ||
1392 | free(p); | ||
1393 | free(options.identity_agent); | ||
1394 | options.identity_agent = cp; | ||
1395 | } | ||
1396 | |||
1397 | if (options.forward_agent_sock_path != NULL) { | ||
1398 | p = tilde_expand_filename(options.forward_agent_sock_path, | ||
1399 | getuid()); | ||
1400 | cp = default_client_percent_expand(p, | ||
1401 | pw->pw_dir, host, options.user, pw->pw_name); | ||
1402 | free(p); | ||
1403 | free(options.forward_agent_sock_path); | ||
1404 | options.forward_agent_sock_path = cp; | ||
1405 | } | ||
1406 | |||
1407 | for (i = 0; i < options.num_local_forwards; i++) { | ||
1408 | if (options.local_forwards[i].listen_path != NULL) { | ||
1409 | cp = options.local_forwards[i].listen_path; | ||
1410 | p = options.local_forwards[i].listen_path = | ||
1411 | default_client_percent_expand(cp, | ||
1412 | pw->pw_dir, host, options.user, pw->pw_name); | ||
1413 | if (strcmp(cp, p) != 0) | ||
1414 | debug3("expanded LocalForward listen path " | ||
1415 | "'%s' -> '%s'", cp, p); | ||
1416 | free(cp); | ||
1417 | } | ||
1418 | if (options.local_forwards[i].connect_path != NULL) { | ||
1419 | cp = options.local_forwards[i].connect_path; | ||
1420 | p = options.local_forwards[i].connect_path = | ||
1421 | default_client_percent_expand(cp, | ||
1422 | pw->pw_dir, host, options.user, pw->pw_name); | ||
1423 | if (strcmp(cp, p) != 0) | ||
1424 | debug3("expanded LocalForward connect path " | ||
1425 | "'%s' -> '%s'", cp, p); | ||
1426 | free(cp); | ||
1427 | } | ||
1428 | } | ||
1429 | |||
1430 | for (i = 0; i < options.num_remote_forwards; i++) { | ||
1431 | if (options.remote_forwards[i].listen_path != NULL) { | ||
1432 | cp = options.remote_forwards[i].listen_path; | ||
1433 | p = options.remote_forwards[i].listen_path = | ||
1434 | default_client_percent_expand(cp, | ||
1435 | pw->pw_dir, host, options.user, pw->pw_name); | ||
1436 | if (strcmp(cp, p) != 0) | ||
1437 | debug3("expanded RemoteForward listen path " | ||
1438 | "'%s' -> '%s'", cp, p); | ||
1439 | free(cp); | ||
1440 | } | ||
1441 | if (options.remote_forwards[i].connect_path != NULL) { | ||
1442 | cp = options.remote_forwards[i].connect_path; | ||
1443 | p = options.remote_forwards[i].connect_path = | ||
1444 | default_client_percent_expand(cp, | ||
1445 | pw->pw_dir, host, options.user, pw->pw_name); | ||
1446 | if (strcmp(cp, p) != 0) | ||
1447 | debug3("expanded RemoteForward connect path " | ||
1448 | "'%s' -> '%s'", cp, p); | ||
1449 | free(cp); | ||
1450 | } | ||
1451 | } | ||
1452 | |||
1381 | if (config_test) { | 1453 | if (config_test) { |
1382 | dump_client_config(&options, host); | 1454 | dump_client_config(&options, host); |
1383 | exit(0); | 1455 | exit(0); |
@@ -1502,23 +1574,7 @@ main(int ac, char **av) | |||
1502 | if (strcmp(options.identity_agent, "none") == 0) { | 1574 | if (strcmp(options.identity_agent, "none") == 0) { |
1503 | unsetenv(SSH_AUTHSOCKET_ENV_NAME); | 1575 | unsetenv(SSH_AUTHSOCKET_ENV_NAME); |
1504 | } else { | 1576 | } else { |
1505 | p = tilde_expand_filename(options.identity_agent, | 1577 | cp = options.identity_agent; |
1506 | getuid()); | ||
1507 | cp = percent_expand(p, | ||
1508 | "d", pw->pw_dir, | ||
1509 | "h", host, | ||
1510 | "i", uidstr, | ||
1511 | "l", thishost, | ||
1512 | "r", options.user, | ||
1513 | "u", pw->pw_name, | ||
1514 | (char *)NULL); | ||
1515 | free(p); | ||
1516 | /* | ||
1517 | * If identity_agent represents an environment variable | ||
1518 | * then recheck that it is valid (since processing with | ||
1519 | * percent_expand() may have changed it) and substitute | ||
1520 | * its value. | ||
1521 | */ | ||
1522 | if (cp[0] == '$') { | 1578 | if (cp[0] == '$') { |
1523 | if (!valid_env_name(cp + 1)) { | 1579 | if (!valid_env_name(cp + 1)) { |
1524 | fatal("Invalid IdentityAgent " | 1580 | fatal("Invalid IdentityAgent " |
@@ -1532,22 +1588,11 @@ main(int ac, char **av) | |||
1532 | /* identity_agent specifies a path directly */ | 1588 | /* identity_agent specifies a path directly */ |
1533 | setenv(SSH_AUTHSOCKET_ENV_NAME, cp, 1); | 1589 | setenv(SSH_AUTHSOCKET_ENV_NAME, cp, 1); |
1534 | } | 1590 | } |
1535 | free(cp); | ||
1536 | } | 1591 | } |
1537 | } | 1592 | } |
1538 | 1593 | ||
1539 | if (options.forward_agent && (options.forward_agent_sock_path != NULL)) { | 1594 | if (options.forward_agent && options.forward_agent_sock_path != NULL) { |
1540 | p = tilde_expand_filename(options.forward_agent_sock_path, getuid()); | 1595 | cp = options.forward_agent_sock_path; |
1541 | cp = percent_expand(p, | ||
1542 | "d", pw->pw_dir, | ||
1543 | "h", host, | ||
1544 | "i", uidstr, | ||
1545 | "l", thishost, | ||
1546 | "r", options.user, | ||
1547 | "u", pw->pw_name, | ||
1548 | (char *)NULL); | ||
1549 | free(p); | ||
1550 | |||
1551 | if (cp[0] == '$') { | 1596 | if (cp[0] == '$') { |
1552 | if (!valid_env_name(cp + 1)) { | 1597 | if (!valid_env_name(cp + 1)) { |
1553 | fatal("Invalid ForwardAgent environment variable name %s", cp); | 1598 | fatal("Invalid ForwardAgent environment variable name %s", cp); |
@@ -1678,6 +1723,21 @@ fork_postauth(void) | |||
1678 | fatal("daemon() failed: %.200s", strerror(errno)); | 1723 | fatal("daemon() failed: %.200s", strerror(errno)); |
1679 | } | 1724 | } |
1680 | 1725 | ||
1726 | static void | ||
1727 | forwarding_success(void) | ||
1728 | { | ||
1729 | if (forward_confirms_pending == -1) | ||
1730 | return; | ||
1731 | if (--forward_confirms_pending == 0) { | ||
1732 | debug("%s: all expected forwarding replies received", __func__); | ||
1733 | if (fork_after_authentication_flag) | ||
1734 | fork_postauth(); | ||
1735 | } else { | ||
1736 | debug2("%s: %d expected forwarding replies remaining", | ||
1737 | __func__, forward_confirms_pending); | ||
1738 | } | ||
1739 | } | ||
1740 | |||
1681 | /* Callback for remote forward global requests */ | 1741 | /* Callback for remote forward global requests */ |
1682 | static void | 1742 | static void |
1683 | ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) | 1743 | ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) |
@@ -1737,11 +1797,7 @@ ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) | |||
1737 | "for listen port %d", rfwd->listen_port); | 1797 | "for listen port %d", rfwd->listen_port); |
1738 | } | 1798 | } |
1739 | } | 1799 | } |
1740 | if (++remote_forward_confirms_received == options.num_remote_forwards) { | 1800 | forwarding_success(); |
1741 | debug("All remote forwarding requests processed"); | ||
1742 | if (fork_after_authentication_flag) | ||
1743 | fork_postauth(); | ||
1744 | } | ||
1745 | } | 1801 | } |
1746 | 1802 | ||
1747 | static void | 1803 | static void |
@@ -1759,6 +1815,19 @@ ssh_stdio_confirm(struct ssh *ssh, int id, int success, void *arg) | |||
1759 | } | 1815 | } |
1760 | 1816 | ||
1761 | static void | 1817 | static void |
1818 | ssh_tun_confirm(struct ssh *ssh, int id, int success, void *arg) | ||
1819 | { | ||
1820 | if (!success) { | ||
1821 | error("Tunnel forwarding failed"); | ||
1822 | if (options.exit_on_forward_failure) | ||
1823 | cleanup_exit(255); | ||
1824 | } | ||
1825 | |||
1826 | debug("%s: tunnel forward established, id=%d", __func__, id); | ||
1827 | forwarding_success(); | ||
1828 | } | ||
1829 | |||
1830 | static void | ||
1762 | ssh_init_stdio_forwarding(struct ssh *ssh) | 1831 | ssh_init_stdio_forwarding(struct ssh *ssh) |
1763 | { | 1832 | { |
1764 | Channel *c; | 1833 | Channel *c; |
@@ -1786,6 +1855,8 @@ ssh_init_forwarding(struct ssh *ssh, char **ifname) | |||
1786 | int success = 0; | 1855 | int success = 0; |
1787 | int i; | 1856 | int i; |
1788 | 1857 | ||
1858 | if (options.exit_on_forward_failure) | ||
1859 | forward_confirms_pending = 0; /* track pending requests */ | ||
1789 | /* Initiate local TCP/IP port forwardings. */ | 1860 | /* Initiate local TCP/IP port forwardings. */ |
1790 | for (i = 0; i < options.num_local_forwards; i++) { | 1861 | for (i = 0; i < options.num_local_forwards; i++) { |
1791 | debug("Local connections to %.200s:%d forwarded to remote " | 1862 | debug("Local connections to %.200s:%d forwarded to remote " |
@@ -1821,32 +1892,33 @@ ssh_init_forwarding(struct ssh *ssh, char **ifname) | |||
1821 | options.remote_forwards[i].connect_path : | 1892 | options.remote_forwards[i].connect_path : |
1822 | options.remote_forwards[i].connect_host, | 1893 | options.remote_forwards[i].connect_host, |
1823 | options.remote_forwards[i].connect_port); | 1894 | options.remote_forwards[i].connect_port); |
1824 | options.remote_forwards[i].handle = | 1895 | if ((options.remote_forwards[i].handle = |
1825 | channel_request_remote_forwarding(ssh, | 1896 | channel_request_remote_forwarding(ssh, |
1826 | &options.remote_forwards[i]); | 1897 | &options.remote_forwards[i])) >= 0) { |
1827 | if (options.remote_forwards[i].handle < 0) { | ||
1828 | if (options.exit_on_forward_failure) | ||
1829 | fatal("Could not request remote forwarding."); | ||
1830 | else | ||
1831 | logit("Warning: Could not request remote " | ||
1832 | "forwarding."); | ||
1833 | } else { | ||
1834 | client_register_global_confirm( | 1898 | client_register_global_confirm( |
1835 | ssh_confirm_remote_forward, | 1899 | ssh_confirm_remote_forward, |
1836 | &options.remote_forwards[i]); | 1900 | &options.remote_forwards[i]); |
1837 | } | 1901 | forward_confirms_pending++; |
1902 | } else if (options.exit_on_forward_failure) | ||
1903 | fatal("Could not request remote forwarding."); | ||
1904 | else | ||
1905 | logit("Warning: Could not request remote forwarding."); | ||
1838 | } | 1906 | } |
1839 | 1907 | ||
1840 | /* Initiate tunnel forwarding. */ | 1908 | /* Initiate tunnel forwarding. */ |
1841 | if (options.tun_open != SSH_TUNMODE_NO) { | 1909 | if (options.tun_open != SSH_TUNMODE_NO) { |
1842 | if ((*ifname = client_request_tun_fwd(ssh, | 1910 | if ((*ifname = client_request_tun_fwd(ssh, |
1843 | options.tun_open, options.tun_local, | 1911 | options.tun_open, options.tun_local, |
1844 | options.tun_remote)) == NULL) { | 1912 | options.tun_remote, ssh_tun_confirm, NULL)) != NULL) |
1845 | if (options.exit_on_forward_failure) | 1913 | forward_confirms_pending++; |
1846 | fatal("Could not request tunnel forwarding."); | 1914 | else if (options.exit_on_forward_failure) |
1847 | else | 1915 | fatal("Could not request tunnel forwarding."); |
1848 | error("Could not request tunnel forwarding."); | 1916 | else |
1849 | } | 1917 | error("Could not request tunnel forwarding."); |
1918 | } | ||
1919 | if (forward_confirms_pending > 0) { | ||
1920 | debug("%s: expecting replies for %d forwards", __func__, | ||
1921 | forward_confirms_pending); | ||
1850 | } | 1922 | } |
1851 | } | 1923 | } |
1852 | 1924 | ||
@@ -1972,14 +2044,9 @@ ssh_session2(struct ssh *ssh, struct passwd *pw) | |||
1972 | debug3("expanding LocalCommand: %s", options.local_command); | 2044 | debug3("expanding LocalCommand: %s", options.local_command); |
1973 | cp = options.local_command; | 2045 | cp = options.local_command; |
1974 | options.local_command = percent_expand(cp, | 2046 | options.local_command = percent_expand(cp, |
1975 | "C", conn_hash_hex, | 2047 | DEFAULT_CLIENT_PERCENT_EXPAND_ARGS, |
1976 | "L", shorthost, | ||
1977 | "d", pw->pw_dir, | 2048 | "d", pw->pw_dir, |
1978 | "h", host, | 2049 | "h", host, |
1979 | "i", uidstr, | ||
1980 | "l", thishost, | ||
1981 | "n", host_arg, | ||
1982 | "p", portstr, | ||
1983 | "r", options.user, | 2050 | "r", options.user, |
1984 | "u", pw->pw_name, | 2051 | "u", pw->pw_name, |
1985 | "T", tun_fwd_ifname == NULL ? "NONE" : tun_fwd_ifname, | 2052 | "T", tun_fwd_ifname == NULL ? "NONE" : tun_fwd_ifname, |
@@ -2136,9 +2203,8 @@ load_public_identity_files(struct passwd *pw) | |||
2136 | continue; | 2203 | continue; |
2137 | } | 2204 | } |
2138 | cp = tilde_expand_filename(options.identity_files[i], getuid()); | 2205 | cp = tilde_expand_filename(options.identity_files[i], getuid()); |
2139 | filename = percent_expand(cp, "d", pw->pw_dir, | 2206 | filename = default_client_percent_expand(cp, |
2140 | "u", pw->pw_name, "l", thishost, "h", host, | 2207 | pw->pw_dir, host, options.user, pw->pw_name); |
2141 | "r", options.user, (char *)NULL); | ||
2142 | free(cp); | 2208 | free(cp); |
2143 | check_load(sshkey_load_public(filename, &public, NULL), | 2209 | check_load(sshkey_load_public(filename, &public, NULL), |
2144 | filename, "pubkey"); | 2210 | filename, "pubkey"); |
@@ -2187,14 +2253,8 @@ load_public_identity_files(struct passwd *pw) | |||
2187 | for (i = 0; i < options.num_certificate_files; i++) { | 2253 | for (i = 0; i < options.num_certificate_files; i++) { |
2188 | cp = tilde_expand_filename(options.certificate_files[i], | 2254 | cp = tilde_expand_filename(options.certificate_files[i], |
2189 | getuid()); | 2255 | getuid()); |
2190 | filename = percent_expand(cp, | 2256 | filename = default_client_percent_expand(cp, |
2191 | "d", pw->pw_dir, | 2257 | pw->pw_dir, host, options.user, pw->pw_name); |
2192 | "h", host, | ||
2193 | "i", uidstr, | ||
2194 | "l", thishost, | ||
2195 | "r", options.user, | ||
2196 | "u", pw->pw_name, | ||
2197 | (char *)NULL); | ||
2198 | free(cp); | 2258 | free(cp); |
2199 | 2259 | ||
2200 | check_load(sshkey_load_public(filename, &public, NULL), | 2260 | check_load(sshkey_load_public(filename, &public, NULL), |