Skip to content

Commit ed833da

Browse files
daztuckerdjmdjm
authored andcommitted
upstream: Make with config keywords support which
percent_expansions more consistent. - %C is moved into its own function and added to Match Exec. - move the common (global) options into a macro. This is ugly but it's the least-ugly way I could come up with. - move IdentityAgent and ForwardAgent percent expansion to before the config dump to make it regression-testable. - document all of the above ok jmc@ for man page bits, "makes things less terrible" djm@ for the rest. OpenBSD-Commit-ID: 4b65664bd6d8ae2a9afaf1a2438ddd1b614b1d75
1 parent 6ec7457 commit ed833da

File tree

4 files changed

+92
-88
lines changed

4 files changed

+92
-88
lines changed

readconf.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: readconf.c,v 1.326 2020/02/06 22:46:31 djm Exp $ */
1+
/* $OpenBSD: readconf.c,v 1.327 2020/04/03 02:27:12 dtucker Exp $ */
22
/*
33
* Author: Tatu Ylonen <[email protected]>
44
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
@@ -324,6 +324,24 @@ kex_default_pk_alg(void)
324324
return kex_default_pk_alg_filtered;
325325
}
326326

327+
char *
328+
ssh_connection_hash(const char *thishost, const char *host, const char *portstr,
329+
const char *user)
330+
{
331+
struct ssh_digest_ctx *md;
332+
u_char conn_hash[SSH_DIGEST_MAX_LENGTH];
333+
334+
if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL ||
335+
ssh_digest_update(md, thishost, strlen(thishost)) < 0 ||
336+
ssh_digest_update(md, host, strlen(host)) < 0 ||
337+
ssh_digest_update(md, portstr, strlen(portstr)) < 0 ||
338+
ssh_digest_update(md, user, strlen(user)) < 0 ||
339+
ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0)
340+
fatal("%s: mux digest failed", __func__);
341+
ssh_digest_free(md);
342+
return tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
343+
}
344+
327345
/*
328346
* Adds a local TCP/IP port forward to options. Never returns if there is an
329347
* error.
@@ -646,15 +664,20 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
646664
if (r == (negate ? 1 : 0))
647665
this_result = result = 0;
648666
} else if (strcasecmp(attrib, "exec") == 0) {
667+
char *conn_hash_hex;
668+
649669
if (gethostname(thishost, sizeof(thishost)) == -1)
650670
fatal("gethostname: %s", strerror(errno));
651671
strlcpy(shorthost, thishost, sizeof(shorthost));
652672
shorthost[strcspn(thishost, ".")] = '\0';
653673
snprintf(portstr, sizeof(portstr), "%d", port);
654674
snprintf(uidstr, sizeof(uidstr), "%llu",
655675
(unsigned long long)pw->pw_uid);
676+
conn_hash_hex = ssh_connection_hash(thishost, host,
677+
portstr, pw->pw_name);
656678

657679
cmd = percent_expand(arg,
680+
"C", conn_hash_hex,
658681
"L", shorthost,
659682
"d", pw->pw_dir,
660683
"h", host,
@@ -665,6 +688,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
665688
"u", pw->pw_name,
666689
"i", uidstr,
667690
(char *)NULL);
691+
free(conn_hash_hex);
668692
if (result != 1) {
669693
/* skip execution if prior predicate failed */
670694
debug3("%.200s line %d: skipped exec "

readconf.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: readconf.h,v 1.132 2020/01/23 02:46:49 dtucker Exp $ */
1+
/* $OpenBSD: readconf.h,v 1.133 2020/04/03 02:27:12 dtucker Exp $ */
22

33
/*
44
* Author: Tatu Ylonen <[email protected]>
@@ -200,6 +200,8 @@ typedef struct {
200200
#define SSH_STRICT_HOSTKEY_ASK 3
201201

202202
const char *kex_default_pk_alg(void);
203+
char *ssh_connection_hash(const char *thishost, const char *host,
204+
const char *portstr, const char *user);
203205
void initialize_options(Options *);
204206
void fill_default_options(Options *);
205207
void fill_default_options_for_canonicalization(Options *);

ssh.c

Lines changed: 53 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: ssh.c,v 1.521 2020/03/06 18:20:02 markus Exp $ */
1+
/* $OpenBSD: ssh.c,v 1.522 2020/04/03 02:27:12 dtucker Exp $ */
22
/*
33
* Author: Tatu Ylonen <[email protected]>
44
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
@@ -86,7 +86,6 @@
8686
#include "canohost.h"
8787
#include "compat.h"
8888
#include "cipher.h"
89-
#include "digest.h"
9089
#include "packet.h"
9190
#include "sshbuf.h"
9291
#include "channels.h"
@@ -177,6 +176,13 @@ char *forward_agent_sock_path = NULL;
177176
/* Various strings used to to percent_expand() arguments */
178177
static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
179178
static char uidstr[32], *host_arg, *conn_hash_hex;
179+
#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS \
180+
"C", conn_hash_hex, \
181+
"L", shorthost, \
182+
"i", uidstr, \
183+
"l", thishost, \
184+
"n", host_arg, \
185+
"p", portstr
180186

181187
/* socket address the host resolves to */
182188
struct sockaddr_storage hostaddr;
@@ -601,8 +607,6 @@ main(int ac, char **av)
601607
extern char *optarg;
602608
struct Forward fwd;
603609
struct addrinfo *addrs = NULL;
604-
struct ssh_digest_ctx *md;
605-
u_char conn_hash[SSH_DIGEST_MAX_LENGTH];
606610
size_t n, len;
607611

608612
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
@@ -1330,15 +1334,8 @@ main(int ac, char **av)
13301334
snprintf(uidstr, sizeof(uidstr), "%llu",
13311335
(unsigned long long)pw->pw_uid);
13321336

1333-
if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL ||
1334-
ssh_digest_update(md, thishost, strlen(thishost)) < 0 ||
1335-
ssh_digest_update(md, host, strlen(host)) < 0 ||
1336-
ssh_digest_update(md, portstr, strlen(portstr)) < 0 ||
1337-
ssh_digest_update(md, options.user, strlen(options.user)) < 0 ||
1338-
ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0)
1339-
fatal("%s: mux digest failed", __func__);
1340-
ssh_digest_free(md);
1341-
conn_hash_hex = tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
1337+
conn_hash_hex = ssh_connection_hash(thishost, host, portstr,
1338+
options.user);
13421339

13431340
/*
13441341
* Expand tokens in arguments. NB. LocalCommand is expanded later,
@@ -1349,14 +1346,9 @@ main(int ac, char **av)
13491346
debug3("expanding RemoteCommand: %s", options.remote_command);
13501347
cp = options.remote_command;
13511348
options.remote_command = percent_expand(cp,
1352-
"C", conn_hash_hex,
1353-
"L", shorthost,
1349+
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
13541350
"d", pw->pw_dir,
13551351
"h", host,
1356-
"i", uidstr,
1357-
"l", thishost,
1358-
"n", host_arg,
1359-
"p", portstr,
13601352
"r", options.user,
13611353
"u", pw->pw_name,
13621354
(char *)NULL);
@@ -1371,20 +1363,44 @@ main(int ac, char **av)
13711363
cp = tilde_expand_filename(options.control_path, getuid());
13721364
free(options.control_path);
13731365
options.control_path = percent_expand(cp,
1374-
"C", conn_hash_hex,
1375-
"L", shorthost,
1366+
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
1367+
"d", pw->pw_dir,
13761368
"h", host,
1377-
"i", uidstr,
1378-
"l", thishost,
1379-
"n", host_arg,
1380-
"p", portstr,
13811369
"r", options.user,
13821370
"u", pw->pw_name,
1383-
"i", uidstr,
13841371
(char *)NULL);
13851372
free(cp);
13861373
}
13871374

1375+
if (options.identity_agent != NULL) {
1376+
p = tilde_expand_filename(options.identity_agent, getuid());
1377+
cp = percent_expand(p,
1378+
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
1379+
"d", pw->pw_dir,
1380+
"h", host,
1381+
"r", options.user,
1382+
"u", pw->pw_name,
1383+
(char *)NULL);
1384+
free(p);
1385+
free(options.identity_agent);
1386+
options.identity_agent = cp;
1387+
}
1388+
1389+
if (options.forward_agent_sock_path != NULL) {
1390+
p = tilde_expand_filename(options.forward_agent_sock_path,
1391+
getuid());
1392+
cp = percent_expand(p,
1393+
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
1394+
"d", pw->pw_dir,
1395+
"h", host,
1396+
"r", options.user,
1397+
"u", pw->pw_name,
1398+
(char *)NULL);
1399+
free(p);
1400+
free(options.forward_agent_sock_path);
1401+
options.forward_agent_sock_path = cp;
1402+
}
1403+
13881404
if (config_test) {
13891405
dump_client_config(&options, host);
13901406
exit(0);
@@ -1509,23 +1525,7 @@ main(int ac, char **av)
15091525
if (strcmp(options.identity_agent, "none") == 0) {
15101526
unsetenv(SSH_AUTHSOCKET_ENV_NAME);
15111527
} else {
1512-
p = tilde_expand_filename(options.identity_agent,
1513-
getuid());
1514-
cp = percent_expand(p,
1515-
"d", pw->pw_dir,
1516-
"h", host,
1517-
"i", uidstr,
1518-
"l", thishost,
1519-
"r", options.user,
1520-
"u", pw->pw_name,
1521-
(char *)NULL);
1522-
free(p);
1523-
/*
1524-
* If identity_agent represents an environment variable
1525-
* then recheck that it is valid (since processing with
1526-
* percent_expand() may have changed it) and substitute
1527-
* its value.
1528-
*/
1528+
cp = options.identity_agent;
15291529
if (cp[0] == '$') {
15301530
if (!valid_env_name(cp + 1)) {
15311531
fatal("Invalid IdentityAgent "
@@ -1539,22 +1539,10 @@ main(int ac, char **av)
15391539
/* identity_agent specifies a path directly */
15401540
setenv(SSH_AUTHSOCKET_ENV_NAME, cp, 1);
15411541
}
1542-
free(cp);
15431542
}
15441543
}
15451544

1546-
if (options.forward_agent && (options.forward_agent_sock_path != NULL)) {
1547-
p = tilde_expand_filename(options.forward_agent_sock_path, getuid());
1548-
cp = percent_expand(p,
1549-
"d", pw->pw_dir,
1550-
"h", host,
1551-
"i", uidstr,
1552-
"l", thishost,
1553-
"r", options.user,
1554-
"u", pw->pw_name,
1555-
(char *)NULL);
1556-
free(p);
1557-
1545+
if (options.forward_agent && options.forward_agent_sock_path != NULL) {
15581546
if (cp[0] == '$') {
15591547
if (!valid_env_name(cp + 1)) {
15601548
fatal("Invalid ForwardAgent environment variable name %s", cp);
@@ -1979,14 +1967,9 @@ ssh_session2(struct ssh *ssh, struct passwd *pw)
19791967
debug3("expanding LocalCommand: %s", options.local_command);
19801968
cp = options.local_command;
19811969
options.local_command = percent_expand(cp,
1982-
"C", conn_hash_hex,
1983-
"L", shorthost,
1970+
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
19841971
"d", pw->pw_dir,
19851972
"h", host,
1986-
"i", uidstr,
1987-
"l", thishost,
1988-
"n", host_arg,
1989-
"p", portstr,
19901973
"r", options.user,
19911974
"u", pw->pw_name,
19921975
"T", tun_fwd_ifname == NULL ? "NONE" : tun_fwd_ifname,
@@ -2143,9 +2126,13 @@ load_public_identity_files(struct passwd *pw)
21432126
continue;
21442127
}
21452128
cp = tilde_expand_filename(options.identity_files[i], getuid());
2146-
filename = percent_expand(cp, "d", pw->pw_dir,
2147-
"u", pw->pw_name, "l", thishost, "h", host,
2148-
"r", options.user, (char *)NULL);
2129+
filename = percent_expand(cp,
2130+
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
2131+
"d", pw->pw_dir,
2132+
"h", host,
2133+
"r", options.user,
2134+
"u", pw->pw_name,
2135+
(char *)NULL);
21492136
free(cp);
21502137
check_load(sshkey_load_public(filename, &public, NULL),
21512138
filename, "pubkey");
@@ -2195,10 +2182,9 @@ load_public_identity_files(struct passwd *pw)
21952182
cp = tilde_expand_filename(options.certificate_files[i],
21962183
getuid());
21972184
filename = percent_expand(cp,
2185+
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
21982186
"d", pw->pw_dir,
21992187
"h", host,
2200-
"i", uidstr,
2201-
"l", thishost,
22022188
"r", options.user,
22032189
"u", pw->pw_name,
22042190
(char *)NULL);

ssh_config.5

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3434
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3535
.\"
36-
.\" $OpenBSD: ssh_config.5,v 1.322 2020/02/07 03:54:44 dtucker Exp $
37-
.Dd $Mdocdate: February 7 2020 $
36+
.\" $OpenBSD: ssh_config.5,v 1.323 2020/04/03 02:27:12 dtucker Exp $
37+
.Dd $Mdocdate: April 3 2020 $
3838
.Dt SSH_CONFIG 5
3939
.Os
4040
.Sh NAME
@@ -1845,31 +1845,23 @@ otherwise.
18451845
The local username.
18461846
.El
18471847
.Pp
1848-
.Cm Match exec
1849-
accepts the tokens %%, %h, %i, %L, %l, %n, %p, %r, and %u.
1850-
.Pp
1851-
.Cm CertificateFile
1852-
accepts the tokens %%, %d, %h, %i, %l, %r, and %u.
1853-
.Pp
1854-
.Cm ControlPath
1855-
accepts the tokens %%, %C, %h, %i, %L, %l, %n, %p, %r, and %u.
1848+
.Cm Match exec ,
1849+
.Cm CertificateFile ,
1850+
.Cm ControlPath ,
1851+
.Cm IdentityAgent ,
1852+
.Cm IdentityFile ,
1853+
and
1854+
.Cm RemoteCommand
1855+
accept the tokens %%, %C, %d, %h, %i, %L, %l, %n, %p, %r, and %u.
18561856
.Pp
18571857
.Cm Hostname
18581858
accepts the tokens %% and %h.
18591859
.Pp
1860-
.Cm IdentityAgent
1861-
and
1862-
.Cm IdentityFile
1863-
accept the tokens %%, %d, %h, %i, %l, %r, and %u.
1864-
.Pp
18651860
.Cm LocalCommand
1866-
accepts the tokens %%, %C, %d, %h, %i, %l, %n, %p, %r, %T, and %u.
1861+
accepts all tokens.
18671862
.Pp
18681863
.Cm ProxyCommand
18691864
accepts the tokens %%, %h, %n, %p, and %r.
1870-
.Pp
1871-
.Cm RemoteCommand
1872-
accepts the tokens %%, %C, %d, %h, %i, %l, %n, %p, %r, and %u.
18731865
.Sh FILES
18741866
.Bl -tag -width Ds
18751867
.It Pa ~/.ssh/config

0 commit comments

Comments
 (0)