From bd30cf784d6e825ef71592fb723c41d4f2fd407b Mon Sep 17 00:00:00 2001 From: "dtucker@openbsd.org" Date: Sat, 1 Mar 2025 06:11:26 +0000 Subject: [PATCH] upstream: Allow %-token and environment variable expansion in User, 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 | 23 +++++++++++++++++++---- ssh_config.5 | 13 +++++++++++-- sshconnect.h | 14 +++++++++----- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/ssh.c b/ssh.c index ff6249273..f6505b03a 100644 --- 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 * Copyright (c) 1995 Tatu Ylonen , 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); diff --git a/ssh_config.5 b/ssh_config.5 index 5051d7b39..1c49ec7b8 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -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. diff --git a/sshconnect.h b/sshconnect.h index 8b0466f29..308270160 100644 --- a/sshconnect.h +++ b/sshconnect.h @@ -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); -- 2.47.3