=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/ssh.c,v retrieving revision 1.526 retrieving revision 1.527 diff -u -r1.526 -r1.527 --- src/usr.bin/ssh/ssh.c 2020/04/03 06:07:57 1.526 +++ src/usr.bin/ssh/ssh.c 2020/04/10 00:52:07 1.527 @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.526 2020/04/03 06:07:57 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.527 2020/04/10 00:52:07 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -160,13 +160,6 @@ /* Various strings used to to percent_expand() arguments */ static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; static char uidstr[32], *host_arg, *conn_hash_hex; -#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS \ - "C", conn_hash_hex, \ - "L", shorthost, \ - "i", uidstr, \ - "l", thishost, \ - "n", host_arg, \ - "p", portstr /* socket address the host resolves to */ struct sockaddr_storage hostaddr; @@ -222,7 +215,35 @@ } } +#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS \ + "C", conn_hash_hex, \ + "L", shorthost, \ + "i", uidstr, \ + "l", thishost, \ + "n", host_arg, \ + "p", portstr + /* + * Expands the set of percent_expand options used by the majority of keywords + * in the client that support percent expansion. + * Caller must free returned string. + */ +static char * +default_client_percent_expand(const char *str, const char *homedir, + const char *remhost, const char *remuser, const char *locuser) +{ + return percent_expand(str, + /* values from statics above */ + DEFAULT_CLIENT_PERCENT_EXPAND_ARGS, + /* values from arguments */ + "d", homedir, + "h", remhost, + "r", remuser, + "u", locuser, + (char *)NULL); +} + +/* * Attempt to resolve a host name / port to a set of addresses and * optionally return any CNAMEs encountered along the way. * Returns NULL on failure. @@ -1324,13 +1345,8 @@ if (options.remote_command != NULL) { debug3("expanding RemoteCommand: %s", options.remote_command); cp = options.remote_command; - options.remote_command = percent_expand(cp, - DEFAULT_CLIENT_PERCENT_EXPAND_ARGS, - "d", pw->pw_dir, - "h", host, - "r", options.user, - "u", pw->pw_name, - (char *)NULL); + options.remote_command = default_client_percent_expand(cp, + pw->pw_dir, host, options.user, pw->pw_name); debug3("expanded RemoteCommand: %s", options.remote_command); free(cp); if ((r = sshbuf_put(command, options.remote_command, @@ -1341,25 +1357,15 @@ if (options.control_path != NULL) { cp = tilde_expand_filename(options.control_path, getuid()); free(options.control_path); - options.control_path = percent_expand(cp, - DEFAULT_CLIENT_PERCENT_EXPAND_ARGS, - "d", pw->pw_dir, - "h", host, - "r", options.user, - "u", pw->pw_name, - (char *)NULL); + options.control_path = default_client_percent_expand(cp, + pw->pw_dir, host, options.user, pw->pw_name); free(cp); } if (options.identity_agent != NULL) { p = tilde_expand_filename(options.identity_agent, getuid()); - cp = percent_expand(p, - DEFAULT_CLIENT_PERCENT_EXPAND_ARGS, - "d", pw->pw_dir, - "h", host, - "r", options.user, - "u", pw->pw_name, - (char *)NULL); + cp = default_client_percent_expand(p, + pw->pw_dir, host, options.user, pw->pw_name); free(p); free(options.identity_agent); options.identity_agent = cp; @@ -1368,18 +1374,59 @@ if (options.forward_agent_sock_path != NULL) { p = tilde_expand_filename(options.forward_agent_sock_path, getuid()); - cp = percent_expand(p, - DEFAULT_CLIENT_PERCENT_EXPAND_ARGS, - "d", pw->pw_dir, - "h", host, - "r", options.user, - "u", pw->pw_name, - (char *)NULL); + cp = default_client_percent_expand(p, + pw->pw_dir, host, options.user, pw->pw_name); free(p); free(options.forward_agent_sock_path); options.forward_agent_sock_path = cp; } + for (i = 0; i < options.num_local_forwards; i++) { + if (options.local_forwards[i].listen_path != NULL) { + cp = options.local_forwards[i].listen_path; + p = options.local_forwards[i].listen_path = + default_client_percent_expand(cp, + pw->pw_dir, host, options.user, pw->pw_name); + if (strcmp(cp, p) != 0) + debug3("expanded LocalForward listen path " + "'%s' -> '%s'", cp, p); + free(cp); + } + if (options.local_forwards[i].connect_path != NULL) { + cp = options.local_forwards[i].connect_path; + p = options.local_forwards[i].connect_path = + default_client_percent_expand(cp, + pw->pw_dir, host, options.user, pw->pw_name); + if (strcmp(cp, p) != 0) + debug3("expanded LocalForward connect path " + "'%s' -> '%s'", cp, p); + free(cp); + } + } + + for (i = 0; i < options.num_remote_forwards; i++) { + if (options.remote_forwards[i].listen_path != NULL) { + cp = options.remote_forwards[i].listen_path; + p = options.remote_forwards[i].listen_path = + default_client_percent_expand(cp, + pw->pw_dir, host, options.user, pw->pw_name); + if (strcmp(cp, p) != 0) + debug3("expanded RemoteForward listen path " + "'%s' -> '%s'", cp, p); + free(cp); + } + if (options.remote_forwards[i].connect_path != NULL) { + cp = options.remote_forwards[i].connect_path; + p = options.remote_forwards[i].connect_path = + default_client_percent_expand(cp, + pw->pw_dir, host, options.user, pw->pw_name); + if (strcmp(cp, p) != 0) + debug3("expanded RemoteForward connect path " + "'%s' -> '%s'", cp, p); + free(cp); + } + } + if (config_test) { dump_client_config(&options, host); exit(0); @@ -2127,13 +2174,8 @@ continue; } cp = tilde_expand_filename(options.identity_files[i], getuid()); - filename = percent_expand(cp, - DEFAULT_CLIENT_PERCENT_EXPAND_ARGS, - "d", pw->pw_dir, - "h", host, - "r", options.user, - "u", pw->pw_name, - (char *)NULL); + filename = default_client_percent_expand(cp, + pw->pw_dir, host, options.user, pw->pw_name); free(cp); check_load(sshkey_load_public(filename, &public, NULL), filename, "pubkey"); @@ -2182,13 +2224,8 @@ for (i = 0; i < options.num_certificate_files; i++) { cp = tilde_expand_filename(options.certificate_files[i], getuid()); - filename = percent_expand(cp, - DEFAULT_CLIENT_PERCENT_EXPAND_ARGS, - "d", pw->pw_dir, - "h", host, - "r", options.user, - "u", pw->pw_name, - (char *)NULL); + filename = default_client_percent_expand(cp, + pw->pw_dir, host, options.user, pw->pw_name); free(cp); check_load(sshkey_load_public(filename, &public, NULL),