version 1.521, 2020/03/06 18:20:02 |
version 1.522, 2020/04/03 02:27:12 |
|
|
#include "canohost.h" |
#include "canohost.h" |
#include "compat.h" |
#include "compat.h" |
#include "cipher.h" |
#include "cipher.h" |
#include "digest.h" |
|
#include "packet.h" |
#include "packet.h" |
#include "sshbuf.h" |
#include "sshbuf.h" |
#include "channels.h" |
#include "channels.h" |
|
|
/* Various strings used to to percent_expand() arguments */ |
/* Various strings used to to percent_expand() arguments */ |
static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; |
static char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; |
static char uidstr[32], *host_arg, *conn_hash_hex; |
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 */ |
/* socket address the host resolves to */ |
struct sockaddr_storage hostaddr; |
struct sockaddr_storage hostaddr; |
|
|
extern char *optarg; |
extern char *optarg; |
struct Forward fwd; |
struct Forward fwd; |
struct addrinfo *addrs = NULL; |
struct addrinfo *addrs = NULL; |
struct ssh_digest_ctx *md; |
|
u_char conn_hash[SSH_DIGEST_MAX_LENGTH]; |
|
size_t n, len; |
size_t n, len; |
|
|
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
|
|
snprintf(uidstr, sizeof(uidstr), "%llu", |
snprintf(uidstr, sizeof(uidstr), "%llu", |
(unsigned long long)pw->pw_uid); |
(unsigned long long)pw->pw_uid); |
|
|
if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL || |
conn_hash_hex = ssh_connection_hash(thishost, host, portstr, |
ssh_digest_update(md, thishost, strlen(thishost)) < 0 || |
options.user); |
ssh_digest_update(md, host, strlen(host)) < 0 || |
|
ssh_digest_update(md, portstr, strlen(portstr)) < 0 || |
|
ssh_digest_update(md, options.user, strlen(options.user)) < 0 || |
|
ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0) |
|
fatal("%s: mux digest failed", __func__); |
|
ssh_digest_free(md); |
|
conn_hash_hex = tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1)); |
|
|
|
/* |
/* |
* Expand tokens in arguments. NB. LocalCommand is expanded later, |
* Expand tokens in arguments. NB. LocalCommand is expanded later, |
|
|
debug3("expanding RemoteCommand: %s", options.remote_command); |
debug3("expanding RemoteCommand: %s", options.remote_command); |
cp = options.remote_command; |
cp = options.remote_command; |
options.remote_command = percent_expand(cp, |
options.remote_command = percent_expand(cp, |
"C", conn_hash_hex, |
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS, |
"L", shorthost, |
|
"d", pw->pw_dir, |
"d", pw->pw_dir, |
"h", host, |
"h", host, |
"i", uidstr, |
|
"l", thishost, |
|
"n", host_arg, |
|
"p", portstr, |
|
"r", options.user, |
"r", options.user, |
"u", pw->pw_name, |
"u", pw->pw_name, |
(char *)NULL); |
(char *)NULL); |
|
|
cp = tilde_expand_filename(options.control_path, getuid()); |
cp = tilde_expand_filename(options.control_path, getuid()); |
free(options.control_path); |
free(options.control_path); |
options.control_path = percent_expand(cp, |
options.control_path = percent_expand(cp, |
"C", conn_hash_hex, |
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS, |
"L", shorthost, |
"d", pw->pw_dir, |
"h", host, |
"h", host, |
"i", uidstr, |
|
"l", thishost, |
|
"n", host_arg, |
|
"p", portstr, |
|
"r", options.user, |
"r", options.user, |
"u", pw->pw_name, |
"u", pw->pw_name, |
"i", uidstr, |
|
(char *)NULL); |
(char *)NULL); |
free(cp); |
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); |
|
free(p); |
|
free(options.identity_agent); |
|
options.identity_agent = cp; |
|
} |
|
|
|
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); |
|
free(p); |
|
free(options.forward_agent_sock_path); |
|
options.forward_agent_sock_path = cp; |
|
} |
|
|
if (config_test) { |
if (config_test) { |
dump_client_config(&options, host); |
dump_client_config(&options, host); |
exit(0); |
exit(0); |
|
|
if (strcmp(options.identity_agent, "none") == 0) { |
if (strcmp(options.identity_agent, "none") == 0) { |
unsetenv(SSH_AUTHSOCKET_ENV_NAME); |
unsetenv(SSH_AUTHSOCKET_ENV_NAME); |
} else { |
} else { |
p = tilde_expand_filename(options.identity_agent, |
cp = options.identity_agent; |
getuid()); |
|
cp = percent_expand(p, |
|
"d", pw->pw_dir, |
|
"h", host, |
|
"i", uidstr, |
|
"l", thishost, |
|
"r", options.user, |
|
"u", pw->pw_name, |
|
(char *)NULL); |
|
free(p); |
|
/* |
|
* If identity_agent represents an environment variable |
|
* then recheck that it is valid (since processing with |
|
* percent_expand() may have changed it) and substitute |
|
* its value. |
|
*/ |
|
if (cp[0] == '$') { |
if (cp[0] == '$') { |
if (!valid_env_name(cp + 1)) { |
if (!valid_env_name(cp + 1)) { |
fatal("Invalid IdentityAgent " |
fatal("Invalid IdentityAgent " |
|
|
/* identity_agent specifies a path directly */ |
/* identity_agent specifies a path directly */ |
setenv(SSH_AUTHSOCKET_ENV_NAME, cp, 1); |
setenv(SSH_AUTHSOCKET_ENV_NAME, cp, 1); |
} |
} |
free(cp); |
|
} |
} |
} |
} |
|
|
if (options.forward_agent && (options.forward_agent_sock_path != NULL)) { |
if (options.forward_agent && options.forward_agent_sock_path != NULL) { |
p = tilde_expand_filename(options.forward_agent_sock_path, getuid()); |
|
cp = percent_expand(p, |
|
"d", pw->pw_dir, |
|
"h", host, |
|
"i", uidstr, |
|
"l", thishost, |
|
"r", options.user, |
|
"u", pw->pw_name, |
|
(char *)NULL); |
|
free(p); |
|
|
|
if (cp[0] == '$') { |
if (cp[0] == '$') { |
if (!valid_env_name(cp + 1)) { |
if (!valid_env_name(cp + 1)) { |
fatal("Invalid ForwardAgent environment variable name %s", cp); |
fatal("Invalid ForwardAgent environment variable name %s", cp); |
|
|
debug3("expanding LocalCommand: %s", options.local_command); |
debug3("expanding LocalCommand: %s", options.local_command); |
cp = options.local_command; |
cp = options.local_command; |
options.local_command = percent_expand(cp, |
options.local_command = percent_expand(cp, |
"C", conn_hash_hex, |
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS, |
"L", shorthost, |
|
"d", pw->pw_dir, |
"d", pw->pw_dir, |
"h", host, |
"h", host, |
"i", uidstr, |
|
"l", thishost, |
|
"n", host_arg, |
|
"p", portstr, |
|
"r", options.user, |
"r", options.user, |
"u", pw->pw_name, |
"u", pw->pw_name, |
"T", tun_fwd_ifname == NULL ? "NONE" : tun_fwd_ifname, |
"T", tun_fwd_ifname == NULL ? "NONE" : tun_fwd_ifname, |
|
|
continue; |
continue; |
} |
} |
cp = tilde_expand_filename(options.identity_files[i], getuid()); |
cp = tilde_expand_filename(options.identity_files[i], getuid()); |
filename = percent_expand(cp, "d", pw->pw_dir, |
filename = percent_expand(cp, |
"u", pw->pw_name, "l", thishost, "h", host, |
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS, |
"r", options.user, (char *)NULL); |
"d", pw->pw_dir, |
|
"h", host, |
|
"r", options.user, |
|
"u", pw->pw_name, |
|
(char *)NULL); |
free(cp); |
free(cp); |
check_load(sshkey_load_public(filename, &public, NULL), |
check_load(sshkey_load_public(filename, &public, NULL), |
filename, "pubkey"); |
filename, "pubkey"); |
|
|
cp = tilde_expand_filename(options.certificate_files[i], |
cp = tilde_expand_filename(options.certificate_files[i], |
getuid()); |
getuid()); |
filename = percent_expand(cp, |
filename = percent_expand(cp, |
|
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS, |
"d", pw->pw_dir, |
"d", pw->pw_dir, |
"h", host, |
"h", host, |
"i", uidstr, |
|
"l", thishost, |
|
"r", options.user, |
"r", options.user, |
"u", pw->pw_name, |
"u", pw->pw_name, |
(char *)NULL); |
(char *)NULL); |