summaryrefslogtreecommitdiff
path: root/ssh.c
diff options
context:
space:
mode:
authordtucker@openbsd.org <dtucker@openbsd.org>2020-04-03 02:27:12 +0000
committerDamien Miller <djm@mindrot.org>2020-04-03 13:33:37 +1100
commited833da176611a39d3376d62154eb88eb440d31c (patch)
treef9fe72b08478c0ad599538f9dbfb94e582e93a93 /ssh.c
parent6ec7457171468da2bbd908b8cd63d298b0e049ea (diff)
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
Diffstat (limited to 'ssh.c')
-rw-r--r--ssh.c120
1 files changed, 53 insertions, 67 deletions
diff --git a/ssh.c b/ssh.c
index 9713b61e1..470d9b7e6 100644
--- a/ssh.c
+++ b/ssh.c
@@ -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 $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -86,7 +86,6 @@
86#include "canohost.h" 86#include "canohost.h"
87#include "compat.h" 87#include "compat.h"
88#include "cipher.h" 88#include "cipher.h"
89#include "digest.h"
90#include "packet.h" 89#include "packet.h"
91#include "sshbuf.h" 90#include "sshbuf.h"
92#include "channels.h" 91#include "channels.h"
@@ -177,6 +176,13 @@ char *forward_agent_sock_path = NULL;
177/* Various strings used to to percent_expand() arguments */ 176/* Various strings used to to percent_expand() arguments */
178static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; 177static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
179static char uidstr[32], *host_arg, *conn_hash_hex; 178static 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
180 186
181/* socket address the host resolves to */ 187/* socket address the host resolves to */
182struct sockaddr_storage hostaddr; 188struct sockaddr_storage hostaddr;
@@ -601,8 +607,6 @@ main(int ac, char **av)
601 extern char *optarg; 607 extern char *optarg;
602 struct Forward fwd; 608 struct Forward fwd;
603 struct addrinfo *addrs = NULL; 609 struct addrinfo *addrs = NULL;
604 struct ssh_digest_ctx *md;
605 u_char conn_hash[SSH_DIGEST_MAX_LENGTH];
606 size_t n, len; 610 size_t n, len;
607 611
608 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 612 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
@@ -1330,15 +1334,8 @@ main(int ac, char **av)
1330 snprintf(uidstr, sizeof(uidstr), "%llu", 1334 snprintf(uidstr, sizeof(uidstr), "%llu",
1331 (unsigned long long)pw->pw_uid); 1335 (unsigned long long)pw->pw_uid);
1332 1336
1333 if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL || 1337 conn_hash_hex = ssh_connection_hash(thishost, host, portstr,
1334 ssh_digest_update(md, thishost, strlen(thishost)) < 0 || 1338 options.user);
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));
1342 1339
1343 /* 1340 /*
1344 * Expand tokens in arguments. NB. LocalCommand is expanded later, 1341 * Expand tokens in arguments. NB. LocalCommand is expanded later,
@@ -1349,14 +1346,9 @@ main(int ac, char **av)
1349 debug3("expanding RemoteCommand: %s", options.remote_command); 1346 debug3("expanding RemoteCommand: %s", options.remote_command);
1350 cp = options.remote_command; 1347 cp = options.remote_command;
1351 options.remote_command = percent_expand(cp, 1348 options.remote_command = percent_expand(cp,
1352 "C", conn_hash_hex, 1349 DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
1353 "L", shorthost,
1354 "d", pw->pw_dir, 1350 "d", pw->pw_dir,
1355 "h", host, 1351 "h", host,
1356 "i", uidstr,
1357 "l", thishost,
1358 "n", host_arg,
1359 "p", portstr,
1360 "r", options.user, 1352 "r", options.user,
1361 "u", pw->pw_name, 1353 "u", pw->pw_name,
1362 (char *)NULL); 1354 (char *)NULL);
@@ -1371,20 +1363,44 @@ main(int ac, char **av)
1371 cp = tilde_expand_filename(options.control_path, getuid()); 1363 cp = tilde_expand_filename(options.control_path, getuid());
1372 free(options.control_path); 1364 free(options.control_path);
1373 options.control_path = percent_expand(cp, 1365 options.control_path = percent_expand(cp,
1374 "C", conn_hash_hex, 1366 DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
1375 "L", shorthost, 1367 "d", pw->pw_dir,
1376 "h", host, 1368 "h", host,
1377 "i", uidstr,
1378 "l", thishost,
1379 "n", host_arg,
1380 "p", portstr,
1381 "r", options.user, 1369 "r", options.user,
1382 "u", pw->pw_name, 1370 "u", pw->pw_name,
1383 "i", uidstr,
1384 (char *)NULL); 1371 (char *)NULL);
1385 free(cp); 1372 free(cp);
1386 } 1373 }
1387 1374
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
1388 if (config_test) { 1404 if (config_test) {
1389 dump_client_config(&options, host); 1405 dump_client_config(&options, host);
1390 exit(0); 1406 exit(0);
@@ -1509,23 +1525,7 @@ main(int ac, char **av)
1509 if (strcmp(options.identity_agent, "none") == 0) { 1525 if (strcmp(options.identity_agent, "none") == 0) {
1510 unsetenv(SSH_AUTHSOCKET_ENV_NAME); 1526 unsetenv(SSH_AUTHSOCKET_ENV_NAME);
1511 } else { 1527 } else {
1512 p = tilde_expand_filename(options.identity_agent, 1528 cp = 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 */
1529 if (cp[0] == '$') { 1529 if (cp[0] == '$') {
1530 if (!valid_env_name(cp + 1)) { 1530 if (!valid_env_name(cp + 1)) {
1531 fatal("Invalid IdentityAgent " 1531 fatal("Invalid IdentityAgent "
@@ -1539,22 +1539,10 @@ main(int ac, char **av)
1539 /* identity_agent specifies a path directly */ 1539 /* identity_agent specifies a path directly */
1540 setenv(SSH_AUTHSOCKET_ENV_NAME, cp, 1); 1540 setenv(SSH_AUTHSOCKET_ENV_NAME, cp, 1);
1541 } 1541 }
1542 free(cp);
1543 } 1542 }
1544 } 1543 }
1545 1544
1546 if (options.forward_agent && (options.forward_agent_sock_path != NULL)) { 1545 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
1558 if (cp[0] == '$') { 1546 if (cp[0] == '$') {
1559 if (!valid_env_name(cp + 1)) { 1547 if (!valid_env_name(cp + 1)) {
1560 fatal("Invalid ForwardAgent environment variable name %s", cp); 1548 fatal("Invalid ForwardAgent environment variable name %s", cp);
@@ -1979,14 +1967,9 @@ ssh_session2(struct ssh *ssh, struct passwd *pw)
1979 debug3("expanding LocalCommand: %s", options.local_command); 1967 debug3("expanding LocalCommand: %s", options.local_command);
1980 cp = options.local_command; 1968 cp = options.local_command;
1981 options.local_command = percent_expand(cp, 1969 options.local_command = percent_expand(cp,
1982 "C", conn_hash_hex, 1970 DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
1983 "L", shorthost,
1984 "d", pw->pw_dir, 1971 "d", pw->pw_dir,
1985 "h", host, 1972 "h", host,
1986 "i", uidstr,
1987 "l", thishost,
1988 "n", host_arg,
1989 "p", portstr,
1990 "r", options.user, 1973 "r", options.user,
1991 "u", pw->pw_name, 1974 "u", pw->pw_name,
1992 "T", tun_fwd_ifname == NULL ? "NONE" : tun_fwd_ifname, 1975 "T", tun_fwd_ifname == NULL ? "NONE" : tun_fwd_ifname,
@@ -2143,9 +2126,13 @@ load_public_identity_files(struct passwd *pw)
2143 continue; 2126 continue;
2144 } 2127 }
2145 cp = tilde_expand_filename(options.identity_files[i], getuid()); 2128 cp = tilde_expand_filename(options.identity_files[i], getuid());
2146 filename = percent_expand(cp, "d", pw->pw_dir, 2129 filename = percent_expand(cp,
2147 "u", pw->pw_name, "l", thishost, "h", host, 2130 DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
2148 "r", options.user, (char *)NULL); 2131 "d", pw->pw_dir,
2132 "h", host,
2133 "r", options.user,
2134 "u", pw->pw_name,
2135 (char *)NULL);
2149 free(cp); 2136 free(cp);
2150 check_load(sshkey_load_public(filename, &public, NULL), 2137 check_load(sshkey_load_public(filename, &public, NULL),
2151 filename, "pubkey"); 2138 filename, "pubkey");
@@ -2195,10 +2182,9 @@ load_public_identity_files(struct passwd *pw)
2195 cp = tilde_expand_filename(options.certificate_files[i], 2182 cp = tilde_expand_filename(options.certificate_files[i],
2196 getuid()); 2183 getuid());
2197 filename = percent_expand(cp, 2184 filename = percent_expand(cp,
2185 DEFAULT_CLIENT_PERCENT_EXPAND_ARGS,
2198 "d", pw->pw_dir, 2186 "d", pw->pw_dir,
2199 "h", host, 2187 "h", host,
2200 "i", uidstr,
2201 "l", thishost,
2202 "r", options.user, 2188 "r", options.user,
2203 "u", pw->pw_name, 2189 "u", pw->pw_name,
2204 (char *)NULL); 2190 (char *)NULL);