]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream: Add TOKEN percent expansion to LocalFoward and RemoteForward
authordtucker@openbsd.org <dtucker@openbsd.org>
Fri, 10 Apr 2020 00:52:07 +0000 (00:52 +0000)
committerDarren Tucker <dtucker@dtucker.net>
Fri, 10 Apr 2020 01:47:19 +0000 (11:47 +1000)
when used for Unix domain socket forwarding.  Factor out the code for the
config keywords that use the most common subset of TOKENS into its own
function. bz#3014, ok jmc@ (man page bits) djm@

OpenBSD-Commit-ID: bffc9f7e7b5cf420309a057408bef55171fd0b97

ssh.c
ssh_config.5

diff --git a/ssh.c b/ssh.c
index 176085647b22f798701e2d4c4230978a3cda5fc5..98b6ce788a8182e7564609f5b255f64814f7ffc3 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -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 <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -176,13 +176,6 @@ char *forward_agent_sock_path = NULL;
 /* 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;
@@ -238,6 +231,34 @@ tilde_expand_paths(char **paths, u_int num_paths)
        }
 }
 
+#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.
@@ -1345,13 +1366,8 @@ main(int ac, char **av)
        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,
@@ -1362,25 +1378,15 @@ main(int ac, char **av)
        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;
@@ -1389,18 +1395,59 @@ main(int ac, char **av)
        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);
@@ -2154,13 +2201,8 @@ load_public_identity_files(struct passwd *pw)
                        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");
@@ -2209,13 +2251,8 @@ load_public_identity_files(struct passwd *pw)
        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),
index 9d89c13aa5cb4b5c701d4b1097c9e5ce94860ae9..7bbc76aa38af5614a60defc5c957d58a736ad5f5 100644 (file)
@@ -33,8 +33,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: ssh_config.5,v 1.323 2020/04/03 02:27:12 dtucker Exp $
-.Dd $Mdocdate: April 3 2020 $
+.\" $OpenBSD: ssh_config.5,v 1.324 2020/04/10 00:52:07 dtucker Exp $
+.Dd $Mdocdate: April 10 2020 $
 .Dt SSH_CONFIG 5
 .Os
 .Sh NAME
@@ -1125,12 +1125,15 @@ has been enabled.
 .It Cm LocalForward
 Specifies that a TCP port on the local machine be forwarded over
 the secure channel to the specified host and port from the remote machine.
-The first argument must be
+The first argument specifies the listener and may be
 .Sm off
 .Oo Ar bind_address : Oc Ar port
 .Sm on
-and the second argument must be
-.Ar host : Ns Ar hostport .
+or a Unix domain socket path.
+The second argument is the destination and may be
+.Ar host : Ns Ar hostport
+or a Unix domain socket path if the remote host supports it.
+.Pp
 IPv6 addresses can be specified by enclosing addresses in square brackets.
 Multiple forwardings may be specified, and additional forwardings can be
 given on the command line.
@@ -1149,6 +1152,9 @@ indicates that the listening port be bound for local use only, while an
 empty address or
 .Sq *
 indicates that the port should be available from all interfaces.
+Unix domain socket paths accept the tokens described in the
+.Sx TOKENS
+section.
 .It Cm LogLevel
 Gives the verbosity level that is used when logging messages from
 .Xr ssh 1 .
@@ -1401,12 +1407,14 @@ the secure channel.
 The remote port may either be forwarded to a specified host and port
 from the local machine, or may act as a SOCKS 4/5 proxy that allows a remote
 client to connect to arbitrary destinations from the local machine.
-The first argument must be
+The first argument is the listening specification and may be
 .Sm off
 .Oo Ar bind_address : Oc Ar port
 .Sm on
+or, if the remote host supports it, a Unix domain socket path.
 If forwarding to a specific destination then the second argument must be
-.Ar host : Ns Ar hostport ,
+.Ar host : Ns Ar hostport
+or a Unix domain socket path,
 otherwise if no destination argument is specified then the remote forwarding
 will be established as a SOCKS proxy.
 .Pp
@@ -1415,6 +1423,9 @@ Multiple forwardings may be specified, and additional
 forwardings can be given on the command line.
 Privileged ports can be forwarded only when
 logging in as root on the remote machine.
+Unix domain socket paths accept the tokens described in the
+.Sx TOKENS
+section.
 .Pp
 If the
 .Ar port
@@ -1845,13 +1856,15 @@ otherwise.
 The local username.
 .El
 .Pp
-.Cm Match exec ,
 .Cm CertificateFile ,
 .Cm ControlPath ,
 .Cm IdentityAgent ,
 .Cm IdentityFile ,
+.Cm LocalForward,
+.Cm Match exec ,
+.Cm RemoteCommand ,
 and
-.Cm RemoteCommand
+.Cm RemoteForward
 accept the tokens %%, %C, %d, %h, %i, %L, %l, %n, %p, %r, and %u.
 .Pp
 .Cm Hostname