version 1.220, 2014/07/15 15:54:14 |
version 1.221, 2014/10/08 22:20:25 |
|
|
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
#include <util.h> |
#include <util.h> |
|
#include <vis.h> |
|
|
#include "xmalloc.h" |
#include "xmalloc.h" |
#include "ssh.h" |
#include "ssh.h" |
|
|
#include "kex.h" |
#include "kex.h" |
#include "mac.h" |
#include "mac.h" |
#include "uidswap.h" |
#include "uidswap.h" |
|
#include "myproposal.h" |
|
|
/* Format of the configuration file: |
/* Format of the configuration file: |
|
|
|
|
oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, |
oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, |
oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, |
oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, |
oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, |
oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, |
oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, |
oPubkeyAuthentication, |
oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, |
oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, |
oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, |
oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, |
oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, |
oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, |
|
|
{ "globalknownhostsfile", oGlobalKnownHostsFile }, |
{ "globalknownhostsfile", oGlobalKnownHostsFile }, |
{ "globalknownhostsfile2", oDeprecated }, |
{ "globalknownhostsfile2", oDeprecated }, |
{ "userknownhostsfile", oUserKnownHostsFile }, |
{ "userknownhostsfile", oUserKnownHostsFile }, |
{ "userknownhostsfile2", oDeprecated }, |
{ "userknownhostsfile2", oDeprecated }, |
{ "connectionattempts", oConnectionAttempts }, |
{ "connectionattempts", oConnectionAttempts }, |
{ "batchmode", oBatchMode }, |
{ "batchmode", oBatchMode }, |
{ "checkhostip", oCheckHostIP }, |
{ "checkhostip", oCheckHostIP }, |
|
|
if (!WIFEXITED(status)) { |
if (!WIFEXITED(status)) { |
error("command '%.100s' exited abnormally", cmd); |
error("command '%.100s' exited abnormally", cmd); |
return -1; |
return -1; |
} |
} |
debug3("command returned status %d", WEXITSTATUS(status)); |
debug3("command returned status %d", WEXITSTATUS(status)); |
return WEXITSTATUS(status); |
return WEXITSTATUS(status); |
} |
} |
|
|
*/ |
*/ |
static int |
static int |
match_cfg_line(Options *options, char **condition, struct passwd *pw, |
match_cfg_line(Options *options, char **condition, struct passwd *pw, |
const char *host_arg, const char *filename, int linenum) |
const char *host_arg, const char *original_host, int post_canon, |
|
const char *filename, int linenum) |
{ |
{ |
char *arg, *attrib, *cmd, *cp = *condition, *host; |
char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; |
const char *ruser; |
const char *ruser; |
int r, port, result = 1, attributes = 0; |
int r, port, this_result, result = 1, attributes = 0, negate; |
size_t len; |
size_t len; |
char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; |
char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; |
|
|
|
|
} else |
} else |
host = xstrdup(host_arg); |
host = xstrdup(host_arg); |
|
|
debug3("checking match for '%s' host %s", cp, host); |
debug2("checking match for '%s' host %s originally %s", |
while ((attrib = strdelim(&cp)) && *attrib != '\0') { |
cp, host, original_host); |
attributes++; |
while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') { |
|
criteria = NULL; |
|
this_result = 1; |
|
if ((negate = attrib[0] == '!')) |
|
attrib++; |
|
/* criteria "all" and "canonical" have no argument */ |
if (strcasecmp(attrib, "all") == 0) { |
if (strcasecmp(attrib, "all") == 0) { |
if (attributes != 1 || |
if (attributes > 1 || |
((arg = strdelim(&cp)) != NULL && *arg != '\0')) { |
((arg = strdelim(&cp)) != NULL && *arg != '\0')) { |
error("'all' cannot be combined with other " |
error("%.200s line %d: '%s' cannot be combined " |
"Match attributes"); |
"with other Match attributes", |
|
filename, linenum, oattrib); |
result = -1; |
result = -1; |
goto out; |
goto out; |
} |
} |
*condition = cp; |
if (result) |
result = 1; |
result = negate ? 0 : 1; |
goto out; |
goto out; |
} |
} |
|
attributes++; |
|
if (strcasecmp(attrib, "canonical") == 0) { |
|
r = !!post_canon; /* force bitmask member to boolean */ |
|
if (r == (negate ? 1 : 0)) |
|
this_result = result = 0; |
|
debug3("%.200s line %d: %smatched '%s'", |
|
filename, linenum, |
|
this_result ? "" : "not ", oattrib); |
|
continue; |
|
} |
|
/* All other criteria require an argument */ |
if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { |
if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { |
error("Missing Match criteria for %s", attrib); |
error("Missing Match criteria for %s", attrib); |
result = -1; |
result = -1; |
|
|
} |
} |
len = strlen(arg); |
len = strlen(arg); |
if (strcasecmp(attrib, "host") == 0) { |
if (strcasecmp(attrib, "host") == 0) { |
if (match_hostname(host, arg, len) != 1) |
criteria = xstrdup(host); |
result = 0; |
r = match_hostname(host, arg, len) == 1; |
else |
if (r == (negate ? 1 : 0)) |
debug("%.200s line %d: matched 'Host %.100s' ", |
this_result = result = 0; |
filename, linenum, host); |
|
} else if (strcasecmp(attrib, "originalhost") == 0) { |
} else if (strcasecmp(attrib, "originalhost") == 0) { |
if (match_hostname(host_arg, arg, len) != 1) |
criteria = xstrdup(original_host); |
result = 0; |
r = match_hostname(original_host, arg, len) == 1; |
else |
if (r == (negate ? 1 : 0)) |
debug("%.200s line %d: matched " |
this_result = result = 0; |
"'OriginalHost %.100s' ", |
|
filename, linenum, host_arg); |
|
} else if (strcasecmp(attrib, "user") == 0) { |
} else if (strcasecmp(attrib, "user") == 0) { |
if (match_pattern_list(ruser, arg, len, 0) != 1) |
criteria = xstrdup(ruser); |
result = 0; |
r = match_pattern_list(ruser, arg, len, 0) == 1; |
else |
if (r == (negate ? 1 : 0)) |
debug("%.200s line %d: matched 'User %.100s' ", |
this_result = result = 0; |
filename, linenum, ruser); |
|
} else if (strcasecmp(attrib, "localuser") == 0) { |
} else if (strcasecmp(attrib, "localuser") == 0) { |
if (match_pattern_list(pw->pw_name, arg, len, 0) != 1) |
criteria = xstrdup(pw->pw_name); |
result = 0; |
r = match_pattern_list(pw->pw_name, arg, len, 0) == 1; |
else |
if (r == (negate ? 1 : 0)) |
debug("%.200s line %d: matched " |
this_result = result = 0; |
"'LocalUser %.100s' ", |
|
filename, linenum, pw->pw_name); |
|
} else if (strcasecmp(attrib, "exec") == 0) { |
} else if (strcasecmp(attrib, "exec") == 0) { |
if (gethostname(thishost, sizeof(thishost)) == -1) |
if (gethostname(thishost, sizeof(thishost)) == -1) |
fatal("gethostname: %s", strerror(errno)); |
fatal("gethostname: %s", strerror(errno)); |
|
|
"d", pw->pw_dir, |
"d", pw->pw_dir, |
"h", host, |
"h", host, |
"l", thishost, |
"l", thishost, |
"n", host_arg, |
"n", original_host, |
"p", portstr, |
"p", portstr, |
"r", ruser, |
"r", ruser, |
"u", pw->pw_name, |
"u", pw->pw_name, |
(char *)NULL); |
(char *)NULL); |
if (result != 1) { |
if (result != 1) { |
/* skip execution if prior predicate failed */ |
/* skip execution if prior predicate failed */ |
debug("%.200s line %d: skipped exec \"%.100s\"", |
debug3("%.200s line %d: skipped exec " |
filename, linenum, cmd); |
"\"%.100s\"", filename, linenum, cmd); |
} else { |
free(cmd); |
r = execute_in_shell(cmd); |
continue; |
if (r == -1) { |
|
fatal("%.200s line %d: match exec " |
|
"'%.100s' error", filename, |
|
linenum, cmd); |
|
} else if (r == 0) { |
|
debug("%.200s line %d: matched " |
|
"'exec \"%.100s\"'", filename, |
|
linenum, cmd); |
|
} else { |
|
debug("%.200s line %d: no match " |
|
"'exec \"%.100s\"'", filename, |
|
linenum, cmd); |
|
result = 0; |
|
} |
|
} |
} |
|
r = execute_in_shell(cmd); |
|
if (r == -1) { |
|
fatal("%.200s line %d: match exec " |
|
"'%.100s' error", filename, |
|
linenum, cmd); |
|
} |
|
criteria = xstrdup(cmd); |
free(cmd); |
free(cmd); |
|
/* Force exit status to boolean */ |
|
r = r == 0; |
|
if (r == (negate ? 1 : 0)) |
|
this_result = result = 0; |
} else { |
} else { |
error("Unsupported Match attribute %s", attrib); |
error("Unsupported Match attribute %s", attrib); |
result = -1; |
result = -1; |
goto out; |
goto out; |
} |
} |
|
debug3("%.200s line %d: %smatched '%s \"%.100s\"' ", |
|
filename, linenum, this_result ? "": "not ", |
|
oattrib, criteria); |
|
free(criteria); |
} |
} |
if (attributes == 0) { |
if (attributes == 0) { |
error("One or more attributes required for Match"); |
error("One or more attributes required for Match"); |
result = -1; |
result = -1; |
goto out; |
goto out; |
} |
} |
debug3("match %sfound", result ? "" : "not "); |
|
*condition = cp; |
|
out: |
out: |
|
if (result != -1) |
|
debug2("match %sfound", result ? "" : "not "); |
|
*condition = cp; |
free(host); |
free(host); |
return result; |
return result; |
} |
} |
|
|
#define WHITESPACE " \t\r\n" |
#define WHITESPACE " \t\r\n" |
int |
int |
process_config_line(Options *options, struct passwd *pw, const char *host, |
process_config_line(Options *options, struct passwd *pw, const char *host, |
char *line, const char *filename, int linenum, int *activep, int userconfig) |
const char *original_host, char *line, const char *filename, |
|
int linenum, int *activep, int flags) |
{ |
{ |
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; |
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; |
char **cpptr, fwdarg[256]; |
char **cpptr, fwdarg[256]; |
|
|
if (!arg || *arg == '\0') |
if (!arg || *arg == '\0') |
fatal("%s line %d: missing time value.", |
fatal("%s line %d: missing time value.", |
filename, linenum); |
filename, linenum); |
if ((value = convtime(arg)) == -1) |
if (strcmp(arg, "none") == 0) |
|
value = -1; |
|
else if ((value = convtime(arg)) == -1) |
fatal("%s line %d: invalid time value.", |
fatal("%s line %d: invalid time value.", |
filename, linenum); |
filename, linenum); |
if (*activep && *intptr == -1) |
if (*activep && *intptr == -1) |
|
|
case oForwardX11Trusted: |
case oForwardX11Trusted: |
intptr = &options->forward_x11_trusted; |
intptr = &options->forward_x11_trusted; |
goto parse_flag; |
goto parse_flag; |
|
|
case oForwardX11Timeout: |
case oForwardX11Timeout: |
intptr = &options->forward_x11_timeout; |
intptr = &options->forward_x11_timeout; |
goto parse_time; |
goto parse_time; |
|
|
if (*intptr >= SSH_MAX_IDENTITY_FILES) |
if (*intptr >= SSH_MAX_IDENTITY_FILES) |
fatal("%.200s line %d: Too many identity files specified (max %d).", |
fatal("%.200s line %d: Too many identity files specified (max %d).", |
filename, linenum, SSH_MAX_IDENTITY_FILES); |
filename, linenum, SSH_MAX_IDENTITY_FILES); |
add_identity_file(options, NULL, arg, userconfig); |
add_identity_file(options, NULL, |
|
arg, flags & SSHCONF_USERCONF); |
} |
} |
break; |
break; |
|
|
|
|
if (cmdline) |
if (cmdline) |
fatal("Host directive not supported as a command-line " |
fatal("Host directive not supported as a command-line " |
"option"); |
"option"); |
value = match_cfg_line(options, &s, pw, host, |
value = match_cfg_line(options, &s, pw, host, original_host, |
filename, linenum); |
flags & SSHCONF_POSTCANON, filename, linenum); |
if (value < 0) |
if (value < 0) |
fatal("%.200s line %d: Bad Match condition", filename, |
fatal("%.200s line %d: Bad Match condition", filename, |
linenum); |
linenum); |
|
|
return 0; |
return 0; |
|
|
default: |
default: |
fatal("process_config_line: Unimplemented opcode %d", opcode); |
fatal("%s: Unimplemented opcode %d", __func__, opcode); |
} |
} |
|
|
/* Check that there is no garbage at end of line. */ |
/* Check that there is no garbage at end of line. */ |
|
|
|
|
int |
int |
read_config_file(const char *filename, struct passwd *pw, const char *host, |
read_config_file(const char *filename, struct passwd *pw, const char *host, |
Options *options, int flags) |
const char *original_host, Options *options, int flags) |
{ |
{ |
FILE *f; |
FILE *f; |
char line[1024]; |
char line[1024]; |
|
|
while (fgets(line, sizeof(line), f)) { |
while (fgets(line, sizeof(line), f)) { |
/* Update line number counter. */ |
/* Update line number counter. */ |
linenum++; |
linenum++; |
if (process_config_line(options, pw, host, line, filename, |
if (process_config_line(options, pw, host, original_host, |
linenum, &active, flags & SSHCONF_USERCONF) != 0) |
line, filename, linenum, &active, flags) != 0) |
bad_options++; |
bad_options++; |
} |
} |
fclose(f); |
fclose(f); |
|
|
free(fwd->listen_path); |
free(fwd->listen_path); |
fwd->listen_path = NULL; |
fwd->listen_path = NULL; |
return (0); |
return (0); |
|
} |
|
|
|
/* XXX the following is a near-vebatim copy from servconf.c; refactor */ |
|
static const char * |
|
fmt_multistate_int(int val, const struct multistate *m) |
|
{ |
|
u_int i; |
|
|
|
for (i = 0; m[i].key != NULL; i++) { |
|
if (m[i].value == val) |
|
return m[i].key; |
|
} |
|
return "UNKNOWN"; |
|
} |
|
|
|
static const char * |
|
fmt_intarg(OpCodes code, int val) |
|
{ |
|
if (val == -1) |
|
return "unset"; |
|
switch (code) { |
|
case oAddressFamily: |
|
return fmt_multistate_int(val, multistate_addressfamily); |
|
case oVerifyHostKeyDNS: |
|
case oStrictHostKeyChecking: |
|
return fmt_multistate_int(val, multistate_yesnoask); |
|
case oControlMaster: |
|
return fmt_multistate_int(val, multistate_controlmaster); |
|
case oTunnel: |
|
return fmt_multistate_int(val, multistate_tunnel); |
|
case oRequestTTY: |
|
return fmt_multistate_int(val, multistate_requesttty); |
|
case oCanonicalizeHostname: |
|
return fmt_multistate_int(val, multistate_canonicalizehostname); |
|
case oProtocol: |
|
switch (val) { |
|
case SSH_PROTO_1: |
|
return "1"; |
|
case SSH_PROTO_2: |
|
return "2"; |
|
case (SSH_PROTO_1|SSH_PROTO_2): |
|
return "2,1"; |
|
default: |
|
return "UNKNOWN"; |
|
} |
|
default: |
|
switch (val) { |
|
case 0: |
|
return "no"; |
|
case 1: |
|
return "yes"; |
|
default: |
|
return "UNKNOWN"; |
|
} |
|
} |
|
} |
|
|
|
static const char * |
|
lookup_opcode_name(OpCodes code) |
|
{ |
|
u_int i; |
|
|
|
for (i = 0; keywords[i].name != NULL; i++) |
|
if (keywords[i].opcode == code) |
|
return(keywords[i].name); |
|
return "UNKNOWN"; |
|
} |
|
|
|
static void |
|
dump_cfg_int(OpCodes code, int val) |
|
{ |
|
printf("%s %d\n", lookup_opcode_name(code), val); |
|
} |
|
|
|
static void |
|
dump_cfg_fmtint(OpCodes code, int val) |
|
{ |
|
printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); |
|
} |
|
|
|
static void |
|
dump_cfg_string(OpCodes code, const char *val) |
|
{ |
|
if (val == NULL) |
|
return; |
|
printf("%s %s\n", lookup_opcode_name(code), val); |
|
} |
|
|
|
static void |
|
dump_cfg_strarray(OpCodes code, u_int count, char **vals) |
|
{ |
|
u_int i; |
|
|
|
for (i = 0; i < count; i++) |
|
printf("%s %s\n", lookup_opcode_name(code), vals[i]); |
|
} |
|
|
|
static void |
|
dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) |
|
{ |
|
u_int i; |
|
|
|
printf("%s", lookup_opcode_name(code)); |
|
for (i = 0; i < count; i++) |
|
printf(" %s", vals[i]); |
|
printf("\n"); |
|
} |
|
|
|
static void |
|
dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds) |
|
{ |
|
const struct Forward *fwd; |
|
u_int i; |
|
|
|
/* oDynamicForward */ |
|
for (i = 0; i < count; i++) { |
|
fwd = &fwds[i]; |
|
if (code == oDynamicForward && |
|
strcmp(fwd->connect_host, "socks") != 0) |
|
continue; |
|
if (code == oLocalForward && |
|
strcmp(fwd->connect_host, "socks") == 0) |
|
continue; |
|
printf("%s", lookup_opcode_name(code)); |
|
if (fwd->listen_port == PORT_STREAMLOCAL) |
|
printf(" %s", fwd->listen_path); |
|
else if (fwd->listen_host == NULL) |
|
printf(" %d", fwd->listen_port); |
|
else { |
|
printf(" [%s]:%d", |
|
fwd->listen_host, fwd->listen_port); |
|
} |
|
if (code != oDynamicForward) { |
|
if (fwd->connect_port == PORT_STREAMLOCAL) |
|
printf(" %s", fwd->connect_path); |
|
else if (fwd->connect_host == NULL) |
|
printf(" %d", fwd->connect_port); |
|
else { |
|
printf(" [%s]:%d", |
|
fwd->connect_host, fwd->connect_port); |
|
} |
|
} |
|
printf("\n"); |
|
} |
|
} |
|
|
|
void |
|
dump_client_config(Options *o, const char *host) |
|
{ |
|
int i; |
|
char vbuf[5]; |
|
|
|
/* Most interesting options first: user, host, port */ |
|
dump_cfg_string(oUser, o->user); |
|
dump_cfg_string(oHostName, host); |
|
dump_cfg_int(oPort, o->port); |
|
|
|
/* Flag options */ |
|
dump_cfg_fmtint(oAddressFamily, o->address_family); |
|
dump_cfg_fmtint(oBatchMode, o->batch_mode); |
|
dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local); |
|
dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname); |
|
dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication); |
|
dump_cfg_fmtint(oCheckHostIP, o->check_host_ip); |
|
dump_cfg_fmtint(oCompression, o->compression); |
|
dump_cfg_fmtint(oControlMaster, o->control_master); |
|
dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); |
|
dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); |
|
dump_cfg_fmtint(oForwardAgent, o->forward_agent); |
|
dump_cfg_fmtint(oForwardX11, o->forward_x11); |
|
dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); |
|
dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); |
|
#ifdef GSSAPI |
|
dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); |
|
dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds); |
|
#endif /* GSSAPI */ |
|
dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); |
|
dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); |
|
dump_cfg_fmtint(oIdentitiesOnly, o->identities_only); |
|
dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication); |
|
dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost); |
|
dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication); |
|
dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command); |
|
dump_cfg_fmtint(oProtocol, o->protocol); |
|
dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass); |
|
dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication); |
|
dump_cfg_fmtint(oRequestTTY, o->request_tty); |
|
dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication); |
|
dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication); |
|
dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); |
|
dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking); |
|
dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive); |
|
dump_cfg_fmtint(oTunnel, o->tun_open); |
|
dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port); |
|
dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns); |
|
dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); |
|
|
|
/* Integer options */ |
|
dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); |
|
dump_cfg_int(oCompressionLevel, o->compression_level); |
|
dump_cfg_int(oConnectionAttempts, o->connection_attempts); |
|
dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout); |
|
dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); |
|
dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max); |
|
dump_cfg_int(oServerAliveInterval, o->server_alive_interval); |
|
|
|
/* String options */ |
|
dump_cfg_string(oBindAddress, o->bind_address); |
|
dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT); |
|
dump_cfg_string(oControlPath, o->control_path); |
|
dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); |
|
dump_cfg_string(oHostKeyAlias, o->host_key_alias); |
|
dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); |
|
dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); |
|
dump_cfg_string(oLocalCommand, o->local_command); |
|
dump_cfg_string(oLogLevel, log_level_name(o->log_level)); |
|
dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC); |
|
dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); |
|
dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); |
|
dump_cfg_string(oProxyCommand, o->proxy_command); |
|
dump_cfg_string(oXAuthLocation, o->xauth_location); |
|
|
|
dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); |
|
dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards); |
|
dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards); |
|
|
|
/* String array options */ |
|
dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files); |
|
dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains); |
|
dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); |
|
dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); |
|
dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); |
|
|
|
/* Special cases */ |
|
|
|
/* oConnectTimeout */ |
|
if (o->connection_timeout == -1) |
|
printf("connecttimeout none\n"); |
|
else |
|
dump_cfg_int(oConnectTimeout, o->connection_timeout); |
|
|
|
/* oTunnelDevice */ |
|
printf("tunneldevice"); |
|
if (o->tun_local == SSH_TUNID_ANY) |
|
printf(" any"); |
|
else |
|
printf(" %d", o->tun_local); |
|
if (o->tun_remote == SSH_TUNID_ANY) |
|
printf(":any"); |
|
else |
|
printf(":%d", o->tun_remote); |
|
printf("\n"); |
|
|
|
/* oCanonicalizePermittedCNAMEs */ |
|
if ( o->num_permitted_cnames > 0) { |
|
printf("canonicalizePermittedcnames"); |
|
for (i = 0; i < o->num_permitted_cnames; i++) { |
|
printf(" %s:%s", o->permitted_cnames[i].source_list, |
|
o->permitted_cnames[i].target_list); |
|
} |
|
printf("\n"); |
|
} |
|
|
|
/* oCipher */ |
|
if (o->cipher != SSH_CIPHER_NOT_SET) |
|
printf("Cipher %s\n", cipher_name(o->cipher)); |
|
|
|
/* oControlPersist */ |
|
if (o->control_persist == 0 || o->control_persist_timeout == 0) |
|
dump_cfg_fmtint(oControlPersist, o->control_persist); |
|
else |
|
dump_cfg_int(oControlPersist, o->control_persist_timeout); |
|
|
|
/* oEscapeChar */ |
|
if (o->escape_char == SSH_ESCAPECHAR_NONE) |
|
printf("escapechar none\n"); |
|
else { |
|
vis(vbuf, o->escape_char, VIS_WHITE, 0); |
|
printf("escapechar %s\n", vbuf); |
|
} |
|
|
|
/* oIPQoS */ |
|
printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); |
|
printf("%s\n", iptos2str(o->ip_qos_bulk)); |
|
|
|
/* oRekeyLimit */ |
|
printf("rekeylimit %lld %d\n", |
|
(long long)o->rekey_limit, o->rekey_interval); |
|
|
|
/* oStreamLocalBindMask */ |
|
printf("streamlocalbindmask 0%o\n", |
|
o->fwd_opts.streamlocal_bind_mask); |
} |
} |