]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream: Allow %-token and environment variable expansion in User,
authordtucker@openbsd.org <dtucker@openbsd.org>
Sat, 1 Mar 2025 06:11:26 +0000 (06:11 +0000)
committerDamien Miller <djm@mindrot.org>
Sun, 2 Mar 2025 11:06:30 +0000 (22:06 +1100)
with the exception of %r and %C which are self-referential.  Requested in
bz#3477, ok djm@, man page improvements jmc@

OpenBSD-Commit-ID: caeb46251ee073662f6f5864c6f7b92d8ac80fa8

ssh.c
ssh_config.5
sshconnect.h

diff --git a/ssh.c b/ssh.c
index ff6249273da328ff04def71eb94e7cd4eca5e74b..f6505b03abd46ff462310a1a27a87e0a717e122c 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.605 2025/02/21 18:22:41 deraadt Exp $ */
+/* $OpenBSD: ssh.c,v 1.606 2025/03/01 06:11:26 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1163,8 +1163,6 @@ main(int ac, char **av)
 
        if (!valid_hostname(host))
                fatal("hostname contains invalid characters");
-       if (options.user != NULL && !valid_ruser(options.user))
-               fatal("remote username contains invalid characters");
        options.host_arg = xstrdup(host);
 
        /* Initialize the command to execute on remote host. */
@@ -1445,11 +1443,28 @@ main(int ac, char **av)
            options.host_key_alias : options.host_arg);
        cinfo->host_arg = xstrdup(options.host_arg);
        cinfo->remhost = xstrdup(host);
-       cinfo->remuser = xstrdup(options.user);
        cinfo->homedir = xstrdup(pw->pw_dir);
        cinfo->locuser = xstrdup(pw->pw_name);
        cinfo->jmphost = xstrdup(options.jump_host == NULL ?
            "" : options.jump_host);
+
+       /*
+        * Expand User. It cannot contain %r (itself) or %C since User is
+        * a component of the hash.
+        */
+       if (options.user != NULL) {
+               if ((p = percent_dollar_expand(options.user,
+                   DEFAULT_CLIENT_PERCENT_EXPAND_ARGS_NOUSER(cinfo),
+                   (char *)NULL)) == NULL)
+                       fatal("invalid environment variable expansion");
+               free(options.user);
+               options.user = p;
+               if (!valid_ruser(options.user))
+                       fatal("remote username contains invalid characters");
+       }
+
+       /* Now User is expanded, store it an calculate hash. */
+       cinfo->remuser = xstrdup(options.user);
        cinfo->conn_hash_hex = ssh_connection_hash(cinfo->thishost,
            cinfo->remhost, cinfo->portstr, cinfo->remuser, cinfo->jmphost);
 
index 5051d7b39edabdb927f52c6688cbc07a31e82bfe..1c49ec7b8f946a370bac405b1a2cba31cfa103ab 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.411 2025/02/15 06:48:56 jmc Exp $
-.Dd $Mdocdate: February 15 2025 $
+.\" $OpenBSD: ssh_config.5,v 1.412 2025/03/01 06:11:26 dtucker Exp $
+.Dd $Mdocdate: March 1 2025 $
 .Dt SSH_CONFIG 5
 .Os
 .Sh NAME
@@ -2148,6 +2148,15 @@ Specifies the user to log in as.
 This can be useful when a different user name is used on different machines.
 This saves the trouble of
 having to remember to give the user name on the command line.
+Arguments to
+.Cm User
+may use the tokens described in the
+.Sx TOKENS
+section
+(with the exception of %r and %C)
+and environment variables as described in the
+.Sx ENVIRONMENT VARIABLES
+section.
 .It Cm UserKnownHostsFile
 Specifies one or more files to use for the user
 host key database, separated by whitespace.
index 8b0466f299e36f33c0e6d9660898bf2025592392..3082701604055fff551c4b71b2bb17ff3542428b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.h,v 1.48 2024/04/30 02:10:49 djm Exp $ */
+/* $OpenBSD: sshconnect.h,v 1.49 2025/03/01 06:11:26 dtucker Exp $ */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -52,9 +52,8 @@ struct ssh;
 struct hostkeys;
 struct ssh_conn_info;
 
-/* default argument for client percent expansions */
-#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(conn_info) \
-       "C", conn_info->conn_hash_hex, \
+/* default argument for client percent expansions, minus remote user */
+#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS_NOUSER(conn_info) \
        "L", conn_info->shorthost, \
        "i", conn_info->uidstr, \
        "k", conn_info->keyalias, \
@@ -63,10 +62,15 @@ struct ssh_conn_info;
        "p", conn_info->portstr, \
        "d", conn_info->homedir, \
        "h", conn_info->remhost, \
-       "r", conn_info->remuser, \
        "u", conn_info->locuser, \
        "j", conn_info->jmphost
 
+/* same plus remote user and hash which has user as a component */
+#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(conn_info) \
+       DEFAULT_CLIENT_PERCENT_EXPAND_ARGS_NOUSER(conn_info), \
+       "C", conn_info->conn_hash_hex, \
+       "r", conn_info->remuser
+
 int     ssh_connect(struct ssh *, const char *, const char *,
            struct addrinfo *, struct sockaddr_storage *, u_short,
            int, int *, int);