version 1.206, 2013/10/14 22:22:02 |
version 1.207, 2013/10/14 23:28:23 |
|
|
return oBadOption; |
return oBadOption; |
} |
} |
|
|
|
/* Multistate option parsing */ |
|
struct multistate { |
|
char *key; |
|
int value; |
|
}; |
|
static const struct multistate multistate_flag[] = { |
|
{ "true", 1 }, |
|
{ "false", 0 }, |
|
{ "yes", 1 }, |
|
{ "no", 0 }, |
|
{ NULL, -1 } |
|
}; |
|
static const struct multistate multistate_yesnoask[] = { |
|
{ "true", 1 }, |
|
{ "false", 0 }, |
|
{ "yes", 1 }, |
|
{ "no", 0 }, |
|
{ "ask", 2 }, |
|
{ NULL, -1 } |
|
}; |
|
static const struct multistate multistate_addressfamily[] = { |
|
{ "inet", AF_INET }, |
|
{ "inet6", AF_INET6 }, |
|
{ "any", AF_UNSPEC }, |
|
{ NULL, -1 } |
|
}; |
|
static const struct multistate multistate_controlmaster[] = { |
|
{ "true", SSHCTL_MASTER_YES }, |
|
{ "yes", SSHCTL_MASTER_YES }, |
|
{ "false", SSHCTL_MASTER_NO }, |
|
{ "no", SSHCTL_MASTER_NO }, |
|
{ "auto", SSHCTL_MASTER_AUTO }, |
|
{ "ask", SSHCTL_MASTER_ASK }, |
|
{ "autoask", SSHCTL_MASTER_AUTO_ASK }, |
|
{ NULL, -1 } |
|
}; |
|
static const struct multistate multistate_tunnel[] = { |
|
{ "ethernet", SSH_TUNMODE_ETHERNET }, |
|
{ "point-to-point", SSH_TUNMODE_POINTOPOINT }, |
|
{ "true", SSH_TUNMODE_DEFAULT }, |
|
{ "yes", SSH_TUNMODE_DEFAULT }, |
|
{ "false", SSH_TUNMODE_NO }, |
|
{ "no", SSH_TUNMODE_NO }, |
|
{ NULL, -1 } |
|
}; |
|
static const struct multistate multistate_requesttty[] = { |
|
{ "true", REQUEST_TTY_YES }, |
|
{ "yes", REQUEST_TTY_YES }, |
|
{ "false", REQUEST_TTY_NO }, |
|
{ "no", REQUEST_TTY_NO }, |
|
{ "force", REQUEST_TTY_FORCE }, |
|
{ "auto", REQUEST_TTY_AUTO }, |
|
{ NULL, -1 } |
|
}; |
|
|
/* |
/* |
* Processes a single option line as used in the configuration files. This |
* Processes a single option line as used in the configuration files. This |
* only sets those values that have not already been set. |
* only sets those values that have not already been set. |
|
|
long long val64; |
long long val64; |
size_t len; |
size_t len; |
Forward fwd; |
Forward fwd; |
|
const struct multistate *multistate_ptr; |
|
|
if (activep == NULL) { /* We are processing a command line directive */ |
if (activep == NULL) { /* We are processing a command line directive */ |
cmdline = 1; |
cmdline = 1; |
|
|
if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') |
if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') |
return 0; |
return 0; |
/* Match lowercase keyword */ |
/* Match lowercase keyword */ |
for (i = 0; i < strlen(keyword); i++) |
lowercase(keyword); |
keyword[i] = tolower(keyword[i]); |
|
|
|
opcode = parse_token(keyword, filename, linenum, |
opcode = parse_token(keyword, filename, linenum, |
options->ignored_unknown); |
options->ignored_unknown); |
|
|
|
|
case oForwardAgent: |
case oForwardAgent: |
intptr = &options->forward_agent; |
intptr = &options->forward_agent; |
parse_flag: |
parse_flag: |
|
multistate_ptr = multistate_flag; |
|
parse_multistate: |
arg = strdelim(&s); |
arg = strdelim(&s); |
if (!arg || *arg == '\0') |
if (!arg || *arg == '\0') |
fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); |
fatal("%s line %d: missing argument.", |
value = 0; /* To avoid compiler warning... */ |
filename, linenum); |
if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) |
value = -1; |
value = 1; |
for (i = 0; multistate_ptr[i].key != NULL; i++) { |
else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) |
if (strcasecmp(arg, multistate_ptr[i].key) == 0) { |
value = 0; |
value = multistate_ptr[i].value; |
else |
break; |
fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); |
} |
|
} |
|
if (value == -1) |
|
fatal("%s line %d: unsupported option \"%s\".", |
|
filename, linenum, arg); |
if (*activep && *intptr == -1) |
if (*activep && *intptr == -1) |
*intptr = value; |
*intptr = value; |
break; |
break; |
|
|
|
|
case oVerifyHostKeyDNS: |
case oVerifyHostKeyDNS: |
intptr = &options->verify_host_key_dns; |
intptr = &options->verify_host_key_dns; |
goto parse_yesnoask; |
multistate_ptr = multistate_yesnoask; |
|
goto parse_multistate; |
|
|
case oStrictHostKeyChecking: |
case oStrictHostKeyChecking: |
intptr = &options->strict_host_key_checking; |
intptr = &options->strict_host_key_checking; |
parse_yesnoask: |
multistate_ptr = multistate_yesnoask; |
arg = strdelim(&s); |
goto parse_multistate; |
if (!arg || *arg == '\0') |
|
fatal("%.200s line %d: Missing yes/no/ask argument.", |
|
filename, linenum); |
|
value = 0; /* To avoid compiler warning... */ |
|
if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) |
|
value = 1; |
|
else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) |
|
value = 0; |
|
else if (strcmp(arg, "ask") == 0) |
|
value = 2; |
|
else |
|
fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); |
|
if (*activep && *intptr == -1) |
|
*intptr = value; |
|
break; |
|
|
|
case oCompression: |
case oCompression: |
intptr = &options->compression; |
intptr = &options->compression; |
|
|
break; |
break; |
|
|
case oAddressFamily: |
case oAddressFamily: |
arg = strdelim(&s); |
|
if (!arg || *arg == '\0') |
|
fatal("%s line %d: missing address family.", |
|
filename, linenum); |
|
intptr = &options->address_family; |
intptr = &options->address_family; |
if (strcasecmp(arg, "inet") == 0) |
multistate_ptr = multistate_addressfamily; |
value = AF_INET; |
goto parse_multistate; |
else if (strcasecmp(arg, "inet6") == 0) |
|
value = AF_INET6; |
|
else if (strcasecmp(arg, "any") == 0) |
|
value = AF_UNSPEC; |
|
else |
|
fatal("Unsupported AddressFamily \"%s\"", arg); |
|
if (*activep && *intptr == -1) |
|
*intptr = value; |
|
break; |
|
|
|
case oEnableSSHKeysign: |
case oEnableSSHKeysign: |
intptr = &options->enable_ssh_keysign; |
intptr = &options->enable_ssh_keysign; |
|
|
|
|
case oControlMaster: |
case oControlMaster: |
intptr = &options->control_master; |
intptr = &options->control_master; |
arg = strdelim(&s); |
multistate_ptr = multistate_controlmaster; |
if (!arg || *arg == '\0') |
goto parse_multistate; |
fatal("%.200s line %d: Missing ControlMaster argument.", |
|
filename, linenum); |
|
value = 0; /* To avoid compiler warning... */ |
|
if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) |
|
value = SSHCTL_MASTER_YES; |
|
else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) |
|
value = SSHCTL_MASTER_NO; |
|
else if (strcmp(arg, "auto") == 0) |
|
value = SSHCTL_MASTER_AUTO; |
|
else if (strcmp(arg, "ask") == 0) |
|
value = SSHCTL_MASTER_ASK; |
|
else if (strcmp(arg, "autoask") == 0) |
|
value = SSHCTL_MASTER_AUTO_ASK; |
|
else |
|
fatal("%.200s line %d: Bad ControlMaster argument.", |
|
filename, linenum); |
|
if (*activep && *intptr == -1) |
|
*intptr = value; |
|
break; |
|
|
|
case oControlPersist: |
case oControlPersist: |
/* no/false/yes/true, or a time spec */ |
/* no/false/yes/true, or a time spec */ |
|
|
|
|
case oTunnel: |
case oTunnel: |
intptr = &options->tun_open; |
intptr = &options->tun_open; |
arg = strdelim(&s); |
multistate_ptr = multistate_tunnel; |
if (!arg || *arg == '\0') |
goto parse_multistate; |
fatal("%s line %d: Missing yes/point-to-point/" |
|
"ethernet/no argument.", filename, linenum); |
|
value = 0; /* silence compiler */ |
|
if (strcasecmp(arg, "ethernet") == 0) |
|
value = SSH_TUNMODE_ETHERNET; |
|
else if (strcasecmp(arg, "point-to-point") == 0) |
|
value = SSH_TUNMODE_POINTOPOINT; |
|
else if (strcasecmp(arg, "yes") == 0) |
|
value = SSH_TUNMODE_DEFAULT; |
|
else if (strcasecmp(arg, "no") == 0) |
|
value = SSH_TUNMODE_NO; |
|
else |
|
fatal("%s line %d: Bad yes/point-to-point/ethernet/" |
|
"no argument: %s", filename, linenum, arg); |
|
if (*activep) |
|
*intptr = value; |
|
break; |
|
|
|
case oTunnelDevice: |
case oTunnelDevice: |
arg = strdelim(&s); |
arg = strdelim(&s); |
|
|
goto parse_flag; |
goto parse_flag; |
|
|
case oRequestTTY: |
case oRequestTTY: |
arg = strdelim(&s); |
|
if (!arg || *arg == '\0') |
|
fatal("%s line %d: missing argument.", |
|
filename, linenum); |
|
intptr = &options->request_tty; |
intptr = &options->request_tty; |
if (strcasecmp(arg, "yes") == 0) |
multistate_ptr = multistate_requesttty; |
value = REQUEST_TTY_YES; |
goto parse_multistate; |
else if (strcasecmp(arg, "no") == 0) |
|
value = REQUEST_TTY_NO; |
|
else if (strcasecmp(arg, "force") == 0) |
|
value = REQUEST_TTY_FORCE; |
|
else if (strcasecmp(arg, "auto") == 0) |
|
value = REQUEST_TTY_AUTO; |
|
else |
|
fatal("Unsupported RequestTTY \"%s\"", arg); |
|
if (*activep && *intptr == -1) |
|
*intptr = value; |
|
break; |
|
|
|
case oIgnoreUnknown: |
case oIgnoreUnknown: |
charptr = &options->ignored_unknown; |
charptr = &options->ignored_unknown; |
|
|
options->request_tty = REQUEST_TTY_AUTO; |
options->request_tty = REQUEST_TTY_AUTO; |
if (options->proxy_use_fdpass == -1) |
if (options->proxy_use_fdpass == -1) |
options->proxy_use_fdpass = 0; |
options->proxy_use_fdpass = 0; |
/* options->local_command should not be set by default */ |
#define CLEAR_ON_NONE(v) \ |
/* options->proxy_command should not be set by default */ |
do { \ |
|
if (v != NULL && strcasecmp(v, "none") == 0) { \ |
|
free(v); \ |
|
v = NULL; \ |
|
} \ |
|
} while(0) |
|
CLEAR_ON_NONE(options->local_command); |
|
CLEAR_ON_NONE(options->proxy_command); |
|
CLEAR_ON_NONE(options->control_path); |
/* options->user will be set in the main program if appropriate */ |
/* options->user will be set in the main program if appropriate */ |
/* options->hostname will be set in the main program if appropriate */ |
/* options->hostname will be set in the main program if appropriate */ |
/* options->host_key_alias should not be set by default */ |
/* options->host_key_alias should not be set by default */ |