version 1.355, 2021/06/08 07:02:46 |
version 1.356, 2021/06/08 07:07:15 |
|
|
debug2("checking match for '%s' host %s originally %s", |
debug2("checking match for '%s' host %s originally %s", |
cp, host, original_host); |
cp, host, original_host); |
while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') { |
while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') { |
criteria = NULL; |
/* Terminate on comment */ |
|
if (*attrib == '#') { |
|
cp = NULL; /* mark all arguments consumed */ |
|
break; |
|
} |
|
arg = criteria = NULL; |
this_result = 1; |
this_result = 1; |
if ((negate = attrib[0] == '!')) |
if ((negate = attrib[0] == '!')) |
attrib++; |
attrib++; |
/* criteria "all" and "canonical" have no argument */ |
/* Criterion "all" has no argument and must appear alone */ |
if (strcasecmp(attrib, "all") == 0) { |
if (strcasecmp(attrib, "all") == 0) { |
if (attributes > 1 || |
if (attributes > 1 || ((arg = strdelim(&cp)) != NULL && |
((arg = strdelim(&cp)) != NULL && *arg != '\0')) { |
*arg != '\0' && *arg != '#')) { |
error("%.200s line %d: '%s' cannot be combined " |
error("%.200s line %d: '%s' cannot be combined " |
"with other Match attributes", |
"with other Match attributes", |
filename, linenum, oattrib); |
filename, linenum, oattrib); |
result = -1; |
result = -1; |
goto out; |
goto out; |
} |
} |
|
if (arg != NULL && *arg == '#') |
|
cp = NULL; /* mark all arguments consumed */ |
if (result) |
if (result) |
result = negate ? 0 : 1; |
result = negate ? 0 : 1; |
goto out; |
goto out; |
} |
} |
attributes++; |
attributes++; |
|
/* criteria "final" and "canonical" have no argument */ |
if (strcasecmp(attrib, "canonical") == 0 || |
if (strcasecmp(attrib, "canonical") == 0 || |
strcasecmp(attrib, "final") == 0) { |
strcasecmp(attrib, "final") == 0) { |
/* |
/* |
|
|
continue; |
continue; |
} |
} |
/* All other criteria require an argument */ |
/* All other criteria require an argument */ |
if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { |
if ((arg = strdelim(&cp)) == NULL || |
|
*arg == '\0' || *arg == '#') { |
error("Missing Match criteria for %s", attrib); |
error("Missing Match criteria for %s", attrib); |
result = -1; |
result = -1; |
goto out; |
goto out; |
|
|
const char *original_host, char *line, const char *filename, |
const char *original_host, char *line, const char *filename, |
int linenum, int *activep, int flags, int *want_final_pass, int depth) |
int linenum, int *activep, int flags, int *want_final_pass, int depth) |
{ |
{ |
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, *p, ch; |
char *str, **charptr, *endofnumber, *keyword, *arg, *arg2, *p, ch; |
char **cpptr, ***cppptr, fwdarg[256]; |
char **cpptr, ***cppptr, fwdarg[256]; |
u_int i, *uintptr, uvalue, max_entries = 0; |
u_int i, *uintptr, uvalue, max_entries = 0; |
int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0; |
int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0; |
|
|
struct allowed_cname *cname; |
struct allowed_cname *cname; |
glob_t gl; |
glob_t gl; |
const char *errstr; |
const char *errstr; |
|
char **oav = NULL, **av; |
|
int oac = 0, ac; |
|
int ret = -1; |
|
|
if (activep == NULL) { /* We are processing a command line directive */ |
if (activep == NULL) { /* We are processing a command line directive */ |
cmdline = 1; |
cmdline = 1; |
|
|
line[len] = '\0'; |
line[len] = '\0'; |
} |
} |
|
|
s = line; |
str = line; |
/* Get the keyword. (Each line is supposed to begin with a keyword). */ |
/* Get the keyword. (Each line is supposed to begin with a keyword). */ |
if ((keyword = strdelim(&s)) == NULL) |
if ((keyword = strdelim(&str)) == NULL) |
return 0; |
return 0; |
/* Ignore leading whitespace. */ |
/* Ignore leading whitespace. */ |
if (*keyword == '\0') |
if (*keyword == '\0') |
keyword = strdelim(&s); |
keyword = strdelim(&str); |
if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') |
if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') |
return 0; |
return 0; |
/* Match lowercase keyword */ |
/* Match lowercase keyword */ |
lowercase(keyword); |
lowercase(keyword); |
|
|
|
/* Prepare to parse remainder of line */ |
|
if (str != NULL) |
|
str += strspn(str, WHITESPACE); |
|
if (str == NULL || *str == '\0') { |
|
error("%s line %d: no argument after keyword \"%s\"", |
|
filename, linenum, keyword); |
|
return -1; |
|
} |
opcode = parse_token(keyword, filename, linenum, |
opcode = parse_token(keyword, filename, linenum, |
options->ignored_unknown); |
options->ignored_unknown); |
|
if (argv_split(str, &oac, &oav, 1) != 0) { |
|
error("%s line %d: invalid quotes", filename, linenum); |
|
return -1; |
|
} |
|
ac = oac; |
|
av = oav; |
|
|
switch (opcode) { |
switch (opcode) { |
case oBadOption: |
case oBadOption: |
/* don't panic, but count bad options */ |
/* don't panic, but count bad options */ |
return -1; |
goto out; |
case oIgnore: |
case oIgnore: |
return 0; |
argv_consume(&ac); |
|
break; |
case oIgnoredUnknownOption: |
case oIgnoredUnknownOption: |
debug("%s line %d: Ignored unknown option \"%s\"", |
debug("%s line %d: Ignored unknown option \"%s\"", |
filename, linenum, keyword); |
filename, linenum, keyword); |
return 0; |
argv_consume(&ac); |
|
break; |
case oConnectTimeout: |
case oConnectTimeout: |
intptr = &options->connection_timeout; |
intptr = &options->connection_timeout; |
parse_time: |
parse_time: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%s line %d: missing time value.", |
error("%s line %d: missing time value.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (strcmp(arg, "none") == 0) |
if (strcmp(arg, "none") == 0) |
value = -1; |
value = -1; |
else if ((value = convtime(arg)) == -1) { |
else if ((value = convtime(arg)) == -1) { |
error("%s line %d: invalid time value.", |
error("%s line %d: invalid time value.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (*activep && *intptr == -1) |
if (*activep && *intptr == -1) |
*intptr = value; |
*intptr = value; |
|
|
case oForwardAgent: |
case oForwardAgent: |
intptr = &options->forward_agent; |
intptr = &options->forward_agent; |
|
|
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%s line %d: missing argument.", |
error("%s line %d: missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
|
|
value = -1; |
value = -1; |
|
|
parse_flag: |
parse_flag: |
multistate_ptr = multistate_flag; |
multistate_ptr = multistate_flag; |
parse_multistate: |
parse_multistate: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if ((value = parse_multistate_value(arg, filename, linenum, |
if ((value = parse_multistate_value(arg, filename, linenum, |
multistate_ptr)) == -1) { |
multistate_ptr)) == -1) { |
error("%s line %d: unsupported option \"%s\".", |
error("%s line %d: unsupported option \"%s\".", |
filename, linenum, arg); |
filename, linenum, arg); |
return -1; |
goto out; |
} |
} |
if (*activep && *intptr == -1) |
if (*activep && *intptr == -1) |
*intptr = value; |
*intptr = value; |
|
|
goto parse_int; |
goto parse_int; |
|
|
case oRekeyLimit: |
case oRekeyLimit: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing argument.", filename, |
error("%.200s line %d: Missing argument.", filename, |
linenum); |
linenum); |
return -1; |
goto out; |
} |
} |
if (strcmp(arg, "default") == 0) { |
if (strcmp(arg, "default") == 0) { |
val64 = 0; |
val64 = 0; |
|
|
if (scan_scaled(arg, &val64) == -1) { |
if (scan_scaled(arg, &val64) == -1) { |
error("%.200s line %d: Bad number '%s': %s", |
error("%.200s line %d: Bad number '%s': %s", |
filename, linenum, arg, strerror(errno)); |
filename, linenum, arg, strerror(errno)); |
return -1; |
goto out; |
} |
} |
if (val64 != 0 && val64 < 16) { |
if (val64 != 0 && val64 < 16) { |
error("%.200s line %d: RekeyLimit too small", |
error("%.200s line %d: RekeyLimit too small", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
} |
} |
if (*activep && options->rekey_limit == -1) |
if (*activep && options->rekey_limit == -1) |
options->rekey_limit = val64; |
options->rekey_limit = val64; |
if (s != NULL) { /* optional rekey interval present */ |
if (ac != 0) { /* optional rekey interval present */ |
if (strcmp(s, "none") == 0) { |
if (strcmp(av[0], "none") == 0) { |
(void)strdelim(&s); /* discard */ |
(void)argv_next(&ac, &av); /* discard */ |
break; |
break; |
} |
} |
intptr = &options->rekey_interval; |
intptr = &options->rekey_interval; |
|
|
break; |
break; |
|
|
case oIdentityFile: |
case oIdentityFile: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (*activep) { |
if (*activep) { |
intptr = &options->num_identity_files; |
intptr = &options->num_identity_files; |
|
|
error("%.200s line %d: Too many identity files " |
error("%.200s line %d: Too many identity files " |
"specified (max %d).", filename, linenum, |
"specified (max %d).", filename, linenum, |
SSH_MAX_IDENTITY_FILES); |
SSH_MAX_IDENTITY_FILES); |
return -1; |
goto out; |
} |
} |
add_identity_file(options, NULL, |
add_identity_file(options, NULL, |
arg, flags & SSHCONF_USERCONF); |
arg, flags & SSHCONF_USERCONF); |
|
|
break; |
break; |
|
|
case oCertificateFile: |
case oCertificateFile: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (*activep) { |
if (*activep) { |
intptr = &options->num_certificate_files; |
intptr = &options->num_certificate_files; |
|
|
"files specified (max %d).", |
"files specified (max %d).", |
filename, linenum, |
filename, linenum, |
SSH_MAX_CERTIFICATE_FILES); |
SSH_MAX_CERTIFICATE_FILES); |
return -1; |
goto out; |
} |
} |
add_certificate_file(options, arg, |
add_certificate_file(options, arg, |
flags & SSHCONF_USERCONF); |
flags & SSHCONF_USERCONF); |
|
|
case oUser: |
case oUser: |
charptr = &options->user; |
charptr = &options->user; |
parse_string: |
parse_string: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (*activep && *charptr == NULL) |
if (*activep && *charptr == NULL) |
*charptr = xstrdup(arg); |
*charptr = xstrdup(arg); |
|
|
uintptr = &options->num_system_hostfiles; |
uintptr = &options->num_system_hostfiles; |
max_entries = SSH_MAX_HOSTS_FILES; |
max_entries = SSH_MAX_HOSTS_FILES; |
parse_char_array: |
parse_char_array: |
if (*activep && *uintptr == 0) { |
i = 0; |
while ((arg = strdelim(&s)) != NULL && *arg != '\0') { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
|
if (*arg == '\0') { |
|
error("%s line %d: keyword %s empty argument", |
|
filename, linenum, keyword); |
|
goto out; |
|
} |
|
/* Allow "none" only in first position */ |
|
if (strcasecmp(arg, "none") == 0) { |
|
if (i > 0 || ac > 0) { |
|
error("%s line %d: keyword %s \"none\" " |
|
"argument must appear alone.", |
|
filename, linenum, keyword); |
|
goto out; |
|
} |
|
} |
|
i++; |
|
if (*activep && *uintptr == 0) { |
if ((*uintptr) >= max_entries) { |
if ((*uintptr) >= max_entries) { |
error("%s line %d: too many known " |
error("%s line %d: too many %s " |
"hosts files.", filename, linenum); |
"entries.", filename, linenum, |
return -1; |
keyword); |
|
goto out; |
} |
} |
cpptr[(*uintptr)++] = xstrdup(arg); |
cpptr[(*uintptr)++] = xstrdup(arg); |
} |
} |
} |
} |
return 0; |
break; |
|
|
case oUserKnownHostsFile: |
case oUserKnownHostsFile: |
cpptr = (char **)&options->user_hostfiles; |
cpptr = (char **)&options->user_hostfiles; |
|
|
if (options->jump_host != NULL) |
if (options->jump_host != NULL) |
charptr = &options->jump_host; /* Skip below */ |
charptr = &options->jump_host; /* Skip below */ |
parse_command: |
parse_command: |
if (s == NULL) { |
if (str == NULL) { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
len = strspn(s, WHITESPACE "="); |
len = strspn(str, WHITESPACE "="); |
if (*activep && *charptr == NULL) |
if (*activep && *charptr == NULL) |
*charptr = xstrdup(s + len); |
*charptr = xstrdup(str + len); |
return 0; |
argv_consume(&ac); |
|
break; |
|
|
case oProxyJump: |
case oProxyJump: |
if (s == NULL) { |
if (str == NULL) { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
len = strspn(s, WHITESPACE "="); |
len = strspn(str, WHITESPACE "="); |
if (parse_jump(s + len, options, *activep) == -1) { |
/* XXX use argv? */ |
|
if (parse_jump(str + len, options, *activep) == -1) { |
error("%.200s line %d: Invalid ProxyJump \"%s\"", |
error("%.200s line %d: Invalid ProxyJump \"%s\"", |
filename, linenum, s + len); |
filename, linenum, str + len); |
return -1; |
goto out; |
} |
} |
return 0; |
argv_consume(&ac); |
|
break; |
|
|
case oPort: |
case oPort: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
value = a2port(arg); |
value = a2port(arg); |
if (value <= 0) { |
if (value <= 0) { |
error("%.200s line %d: Bad port '%s'.", |
error("%.200s line %d: Bad port '%s'.", |
filename, linenum, arg); |
filename, linenum, arg); |
return -1; |
goto out; |
} |
} |
if (*activep && options->port == -1) |
if (*activep && options->port == -1) |
options->port = value; |
options->port = value; |
|
|
case oConnectionAttempts: |
case oConnectionAttempts: |
intptr = &options->connection_attempts; |
intptr = &options->connection_attempts; |
parse_int: |
parse_int: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if ((errstr = atoi_err(arg, &value)) != NULL) { |
if ((errstr = atoi_err(arg, &value)) != NULL) { |
error("%s line %d: integer value %s.", |
error("%s line %d: integer value %s.", |
filename, linenum, errstr); |
filename, linenum, errstr); |
return -1; |
goto out; |
} |
} |
if (*activep && *intptr == -1) |
if (*activep && *intptr == -1) |
*intptr = value; |
*intptr = value; |
break; |
break; |
|
|
case oCiphers: |
case oCiphers: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (*arg != '-' && |
if (*arg != '-' && |
!ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)){ |
!ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)){ |
error("%.200s line %d: Bad SSH2 cipher spec '%s'.", |
error("%.200s line %d: Bad SSH2 cipher spec '%s'.", |
filename, linenum, arg ? arg : "<NONE>"); |
filename, linenum, arg ? arg : "<NONE>"); |
return -1; |
goto out; |
} |
} |
if (*activep && options->ciphers == NULL) |
if (*activep && options->ciphers == NULL) |
options->ciphers = xstrdup(arg); |
options->ciphers = xstrdup(arg); |
break; |
break; |
|
|
case oMacs: |
case oMacs: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (*arg != '-' && |
if (*arg != '-' && |
!mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) { |
!mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) { |
error("%.200s line %d: Bad SSH2 MAC spec '%s'.", |
error("%.200s line %d: Bad SSH2 MAC spec '%s'.", |
filename, linenum, arg ? arg : "<NONE>"); |
filename, linenum, arg ? arg : "<NONE>"); |
return -1; |
goto out; |
} |
} |
if (*activep && options->macs == NULL) |
if (*activep && options->macs == NULL) |
options->macs = xstrdup(arg); |
options->macs = xstrdup(arg); |
break; |
break; |
|
|
case oKexAlgorithms: |
case oKexAlgorithms: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (*arg != '-' && |
if (*arg != '-' && |
!kex_names_valid(*arg == '+' || *arg == '^' ? |
!kex_names_valid(*arg == '+' || *arg == '^' ? |
arg + 1 : arg)) { |
arg + 1 : arg)) { |
error("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.", |
error("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.", |
filename, linenum, arg ? arg : "<NONE>"); |
filename, linenum, arg ? arg : "<NONE>"); |
return -1; |
goto out; |
} |
} |
if (*activep && options->kex_algorithms == NULL) |
if (*activep && options->kex_algorithms == NULL) |
options->kex_algorithms = xstrdup(arg); |
options->kex_algorithms = xstrdup(arg); |
|
|
case oHostKeyAlgorithms: |
case oHostKeyAlgorithms: |
charptr = &options->hostkeyalgorithms; |
charptr = &options->hostkeyalgorithms; |
parse_pubkey_algos: |
parse_pubkey_algos: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (*arg != '-' && |
if (*arg != '-' && |
!sshkey_names_valid2(*arg == '+' || *arg == '^' ? |
!sshkey_names_valid2(*arg == '+' || *arg == '^' ? |
arg + 1 : arg, 1)) { |
arg + 1 : arg, 1)) { |
error("%s line %d: Bad key types '%s'.", |
error("%s line %d: Bad key types '%s'.", |
filename, linenum, arg ? arg : "<NONE>"); |
filename, linenum, arg ? arg : "<NONE>"); |
return -1; |
goto out; |
} |
} |
if (*activep && *charptr == NULL) |
if (*activep && *charptr == NULL) |
*charptr = xstrdup(arg); |
*charptr = xstrdup(arg); |
|
|
|
|
case oLogLevel: |
case oLogLevel: |
log_level_ptr = &options->log_level; |
log_level_ptr = &options->log_level; |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
value = log_level_number(arg); |
value = log_level_number(arg); |
if (value == SYSLOG_LEVEL_NOT_SET) { |
if (value == SYSLOG_LEVEL_NOT_SET) { |
error("%.200s line %d: unsupported log level '%s'", |
error("%.200s line %d: unsupported log level '%s'", |
filename, linenum, arg ? arg : "<NONE>"); |
filename, linenum, arg ? arg : "<NONE>"); |
return -1; |
goto out; |
} |
} |
if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) |
if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) |
*log_level_ptr = (LogLevel) value; |
*log_level_ptr = (LogLevel) value; |
|
|
|
|
case oLogFacility: |
case oLogFacility: |
log_facility_ptr = &options->log_facility; |
log_facility_ptr = &options->log_facility; |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
value = log_facility_number(arg); |
value = log_facility_number(arg); |
if (value == SYSLOG_FACILITY_NOT_SET) { |
if (value == SYSLOG_FACILITY_NOT_SET) { |
error("%.200s line %d: unsupported log facility '%s'", |
error("%.200s line %d: unsupported log facility '%s'", |
filename, linenum, arg ? arg : "<NONE>"); |
filename, linenum, arg ? arg : "<NONE>"); |
return -1; |
goto out; |
} |
} |
if (*log_facility_ptr == -1) |
if (*log_facility_ptr == -1) |
*log_facility_ptr = (SyslogFacility) value; |
*log_facility_ptr = (SyslogFacility) value; |
|
|
case oLogVerbose: |
case oLogVerbose: |
cppptr = &options->log_verbose; |
cppptr = &options->log_verbose; |
uintptr = &options->num_log_verbose; |
uintptr = &options->num_log_verbose; |
if (*activep && *uintptr == 0) { |
i = 0; |
while ((arg = strdelim(&s)) != NULL && *arg != '\0') { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
|
if (*arg == '\0') { |
|
error("%s line %d: keyword %s empty argument", |
|
filename, linenum, keyword); |
|
goto out; |
|
} |
|
/* Allow "none" only in first position */ |
|
if (strcasecmp(arg, "none") == 0) { |
|
if (i > 0 || ac > 0) { |
|
error("%s line %d: keyword %s \"none\" " |
|
"argument must appear alone.", |
|
filename, linenum, keyword); |
|
goto out; |
|
} |
|
} |
|
i++; |
|
if (*activep && *uintptr == 0) { |
*cppptr = xrecallocarray(*cppptr, *uintptr, |
*cppptr = xrecallocarray(*cppptr, *uintptr, |
*uintptr + 1, sizeof(**cppptr)); |
*uintptr + 1, sizeof(**cppptr)); |
(*cppptr)[(*uintptr)++] = xstrdup(arg); |
(*cppptr)[(*uintptr)++] = xstrdup(arg); |
} |
} |
} |
} |
return 0; |
break; |
|
|
case oLocalForward: |
case oLocalForward: |
case oRemoteForward: |
case oRemoteForward: |
case oDynamicForward: |
case oDynamicForward: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
|
|
remotefwd = (opcode == oRemoteForward); |
remotefwd = (opcode == oRemoteForward); |
dynamicfwd = (opcode == oDynamicForward); |
dynamicfwd = (opcode == oDynamicForward); |
|
|
if (!dynamicfwd) { |
if (!dynamicfwd) { |
arg2 = strdelim(&s); |
arg2 = argv_next(&ac, &av); |
if (arg2 == NULL || *arg2 == '\0') { |
if (arg2 == NULL || *arg2 == '\0') { |
if (remotefwd) |
if (remotefwd) |
dynamicfwd = 1; |
dynamicfwd = 1; |
else { |
else { |
error("%.200s line %d: Missing target " |
error("%.200s line %d: Missing target " |
"argument.", filename, linenum); |
"argument.", filename, linenum); |
return -1; |
goto out; |
} |
} |
} else { |
} else { |
/* construct a string for parse_forward */ |
/* construct a string for parse_forward */ |
|
|
if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0) { |
if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0) { |
error("%.200s line %d: Bad forwarding specification.", |
error("%.200s line %d: Bad forwarding specification.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
|
|
if (*activep) { |
if (*activep) { |
|
|
case oPermitRemoteOpen: |
case oPermitRemoteOpen: |
uintptr = &options->num_permitted_remote_opens; |
uintptr = &options->num_permitted_remote_opens; |
cppptr = &options->permitted_remote_opens; |
cppptr = &options->permitted_remote_opens; |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') |
if (!arg || *arg == '\0') |
fatal("%s line %d: missing %s specification", |
fatal("%s line %d: missing %s specification", |
filename, linenum, lookup_opcode_name(opcode)); |
filename, linenum, lookup_opcode_name(opcode)); |
|
|
} |
} |
break; |
break; |
} |
} |
for (; arg != NULL && *arg != '\0'; arg = strdelim(&s)) { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
arg2 = xstrdup(arg); |
arg2 = xstrdup(arg); |
ch = '\0'; |
ch = '\0'; |
p = hpdelim2(&arg, &ch); |
p = hpdelim2(&arg, &ch); |
|
|
if (cmdline) { |
if (cmdline) { |
error("Host directive not supported as a command-line " |
error("Host directive not supported as a command-line " |
"option"); |
"option"); |
return -1; |
goto out; |
} |
} |
*activep = 0; |
*activep = 0; |
arg2 = NULL; |
arg2 = NULL; |
while ((arg = strdelim(&s)) != NULL && *arg != '\0') { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
if ((flags & SSHCONF_NEVERMATCH) != 0) |
if (*arg == '\0') { |
|
error("%s line %d: keyword %s empty argument", |
|
filename, linenum, keyword); |
|
goto out; |
|
} |
|
if ((flags & SSHCONF_NEVERMATCH) != 0) { |
|
argv_consume(&ac); |
break; |
break; |
|
} |
negated = *arg == '!'; |
negated = *arg == '!'; |
if (negated) |
if (negated) |
arg++; |
arg++; |
|
|
"for %.100s", filename, linenum, |
"for %.100s", filename, linenum, |
arg); |
arg); |
*activep = 0; |
*activep = 0; |
|
argv_consume(&ac); |
break; |
break; |
} |
} |
if (!*activep) |
if (!*activep) |
|
|
if (*activep) |
if (*activep) |
debug("%.200s line %d: Applying options for %.100s", |
debug("%.200s line %d: Applying options for %.100s", |
filename, linenum, arg2); |
filename, linenum, arg2); |
/* Avoid garbage check below, as strdelim is done. */ |
break; |
return 0; |
|
|
|
case oMatch: |
case oMatch: |
if (cmdline) { |
if (cmdline) { |
error("Host directive not supported as a command-line " |
error("Host directive not supported as a command-line " |
"option"); |
"option"); |
return -1; |
goto out; |
} |
} |
value = match_cfg_line(options, &s, pw, host, original_host, |
value = match_cfg_line(options, &str, pw, host, original_host, |
flags & SSHCONF_FINAL, want_final_pass, |
flags & SSHCONF_FINAL, want_final_pass, |
filename, linenum); |
filename, linenum); |
if (value < 0) { |
if (value < 0) { |
error("%.200s line %d: Bad Match condition", filename, |
error("%.200s line %d: Bad Match condition", filename, |
linenum); |
linenum); |
return -1; |
goto out; |
} |
} |
*activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value; |
*activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value; |
|
/* |
|
* If match_cfg_line() didn't consume all its arguments then |
|
* arrange for the extra arguments check below to fail. |
|
*/ |
|
|
|
if (str == NULL || *str == '\0') |
|
argv_consume(&ac); |
break; |
break; |
|
|
case oEscapeChar: |
case oEscapeChar: |
intptr = &options->escape_char; |
intptr = &options->escape_char; |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (strcmp(arg, "none") == 0) |
if (strcmp(arg, "none") == 0) |
value = SSH_ESCAPECHAR_NONE; |
value = SSH_ESCAPECHAR_NONE; |
|
|
else { |
else { |
error("%.200s line %d: Bad escape character.", |
error("%.200s line %d: Bad escape character.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (*activep && *intptr == -1) |
if (*activep && *intptr == -1) |
*intptr = value; |
*intptr = value; |
|
|
goto parse_int; |
goto parse_int; |
|
|
case oSendEnv: |
case oSendEnv: |
while ((arg = strdelim(&s)) != NULL && *arg != '\0') { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
if (strchr(arg, '=') != NULL) { |
if (*arg == '\0' || strchr(arg, '=') != NULL) { |
error("%s line %d: Invalid environment name.", |
error("%s line %d: Invalid environment name.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (!*activep) |
if (!*activep) |
continue; |
continue; |
|
|
if (options->num_send_env >= INT_MAX) { |
if (options->num_send_env >= INT_MAX) { |
error("%s line %d: too many send env.", |
error("%s line %d: too many send env.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
options->send_env = xrecallocarray( |
options->send_env = xrecallocarray( |
options->send_env, options->num_send_env, |
options->send_env, options->num_send_env, |
|
|
|
|
case oSetEnv: |
case oSetEnv: |
value = options->num_setenv; |
value = options->num_setenv; |
while ((arg = strdelimw(&s)) != NULL && *arg != '\0') { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
if (strchr(arg, '=') == NULL) { |
if (strchr(arg, '=') == NULL) { |
error("%s line %d: Invalid SetEnv.", |
error("%s line %d: Invalid SetEnv.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (!*activep || value != 0) |
if (!*activep || value != 0) |
continue; |
continue; |
|
|
if (options->num_setenv >= INT_MAX) { |
if (options->num_setenv >= INT_MAX) { |
error("%s line %d: too many SetEnv.", |
error("%s line %d: too many SetEnv.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
options->setenv = xrecallocarray( |
options->setenv = xrecallocarray( |
options->setenv, options->num_setenv, |
options->setenv, options->num_setenv, |
|
|
case oControlPersist: |
case oControlPersist: |
/* no/false/yes/true, or a time spec */ |
/* no/false/yes/true, or a time spec */ |
intptr = &options->control_persist; |
intptr = &options->control_persist; |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing ControlPersist" |
error("%.200s line %d: Missing ControlPersist" |
" argument.", filename, linenum); |
" argument.", filename, linenum); |
return -1; |
goto out; |
} |
} |
value = 0; |
value = 0; |
value2 = 0; /* timeout */ |
value2 = 0; /* timeout */ |
|
|
else { |
else { |
error("%.200s line %d: Bad ControlPersist argument.", |
error("%.200s line %d: Bad ControlPersist argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (*activep && *intptr == -1) { |
if (*activep && *intptr == -1) { |
*intptr = value; |
*intptr = value; |
|
|
goto parse_multistate; |
goto parse_multistate; |
|
|
case oTunnelDevice: |
case oTunnelDevice: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
value = a2tun(arg, &value2); |
value = a2tun(arg, &value2); |
if (value == SSH_TUNID_ERR) { |
if (value == SSH_TUNID_ERR) { |
error("%.200s line %d: Bad tun device.", |
error("%.200s line %d: Bad tun device.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (*activep && options->tun_local == -1) { |
if (*activep && options->tun_local == -1) { |
options->tun_local = value; |
options->tun_local = value; |
|
|
if (cmdline) { |
if (cmdline) { |
error("Include directive not supported as a " |
error("Include directive not supported as a " |
"command-line option"); |
"command-line option"); |
return -1; |
goto out; |
} |
} |
value = 0; |
value = 0; |
while ((arg = strdelim(&s)) != NULL && *arg != '\0') { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
|
if (*arg == '\0') { |
|
error("%s line %d: keyword %s empty argument", |
|
filename, linenum, keyword); |
|
goto out; |
|
} |
/* |
/* |
* Ensure all paths are anchored. User configuration |
* Ensure all paths are anchored. User configuration |
* files may begin with '~/' but system configurations |
* files may begin with '~/' but system configurations |
|
|
if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0) { |
if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0) { |
error("%.200s line %d: bad include path %s.", |
error("%.200s line %d: bad include path %s.", |
filename, linenum, arg); |
filename, linenum, arg); |
return -1; |
goto out; |
} |
} |
if (!path_absolute(arg) && *arg != '~') { |
if (!path_absolute(arg) && *arg != '~') { |
xasprintf(&arg2, "%s/%s", |
xasprintf(&arg2, "%s/%s", |
|
|
} else if (r != 0) { |
} else if (r != 0) { |
error("%.200s line %d: glob failed for %s.", |
error("%.200s line %d: glob failed for %s.", |
filename, linenum, arg2); |
filename, linenum, arg2); |
return -1; |
goto out; |
} |
} |
free(arg2); |
free(arg2); |
oactive = *activep; |
oactive = *activep; |
|
|
"%.100s: %.100s", gl.gl_pathv[i], |
"%.100s: %.100s", gl.gl_pathv[i], |
strerror(errno)); |
strerror(errno)); |
globfree(&gl); |
globfree(&gl); |
return -1; |
goto out; |
} |
} |
/* |
/* |
* don't let Match in includes clobber the |
* don't let Match in includes clobber the |
|
|
globfree(&gl); |
globfree(&gl); |
} |
} |
if (value != 0) |
if (value != 0) |
return value; |
ret = value; |
break; |
break; |
|
|
case oIPQoS: |
case oIPQoS: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if ((value = parse_ipqos(arg)) == -1) { |
if ((value = parse_ipqos(arg)) == -1) { |
error("%s line %d: Bad IPQoS value: %s", |
error("%s line %d: Bad IPQoS value: %s", |
filename, linenum, arg); |
filename, linenum, arg); |
return -1; |
goto out; |
} |
} |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (arg == NULL) |
if (arg == NULL) |
value2 = value; |
value2 = value; |
else if ((value2 = parse_ipqos(arg)) == -1) { |
else if ((value2 = parse_ipqos(arg)) == -1) { |
error("%s line %d: Bad IPQoS value: %s", |
error("%s line %d: Bad IPQoS value: %s", |
filename, linenum, arg); |
filename, linenum, arg); |
return -1; |
goto out; |
} |
} |
if (*activep && options->ip_qos_interactive == -1) { |
if (*activep && options->ip_qos_interactive == -1) { |
options->ip_qos_interactive = value; |
options->ip_qos_interactive = value; |
|
|
|
|
case oCanonicalDomains: |
case oCanonicalDomains: |
value = options->num_canonical_domains != 0; |
value = options->num_canonical_domains != 0; |
while ((arg = strdelim(&s)) != NULL && *arg != '\0') { |
i = 0; |
|
while ((arg = argv_next(&ac, &av)) != NULL) { |
|
if (*arg == '\0') { |
|
error("%s line %d: keyword %s empty argument", |
|
filename, linenum, keyword); |
|
goto out; |
|
} |
|
/* Allow "none" only in first position */ |
|
if (strcasecmp(arg, "none") == 0) { |
|
if (i > 0 || ac > 0) { |
|
error("%s line %d: keyword %s \"none\" " |
|
"argument must appear alone.", |
|
filename, linenum, keyword); |
|
goto out; |
|
} |
|
} |
|
i++; |
if (!valid_domain(arg, 1, &errstr)) { |
if (!valid_domain(arg, 1, &errstr)) { |
error("%s line %d: %s", filename, linenum, |
error("%s line %d: %s", filename, linenum, |
errstr); |
errstr); |
return -1; |
goto out; |
} |
} |
if (!*activep || value) |
if (!*activep || value) |
continue; |
continue; |
|
|
MAX_CANON_DOMAINS) { |
MAX_CANON_DOMAINS) { |
error("%s line %d: too many hostname suffixes.", |
error("%s line %d: too many hostname suffixes.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
options->canonical_domains[ |
options->canonical_domains[ |
options->num_canonical_domains++] = xstrdup(arg); |
options->num_canonical_domains++] = xstrdup(arg); |
|
|
|
|
case oCanonicalizePermittedCNAMEs: |
case oCanonicalizePermittedCNAMEs: |
value = options->num_permitted_cnames != 0; |
value = options->num_permitted_cnames != 0; |
while ((arg = strdelim(&s)) != NULL && *arg != '\0') { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
/* Either '*' for everything or 'list:list' */ |
/* Either '*' for everything or 'list:list' */ |
if (strcmp(arg, "*") == 0) |
if (strcmp(arg, "*") == 0) |
arg2 = arg; |
arg2 = arg; |
|
|
error("%s line %d: " |
error("%s line %d: " |
"Invalid permitted CNAME \"%s\"", |
"Invalid permitted CNAME \"%s\"", |
filename, linenum, arg); |
filename, linenum, arg); |
return -1; |
goto out; |
} |
} |
*arg2 = '\0'; |
*arg2 = '\0'; |
arg2++; |
arg2++; |
|
|
MAX_CANON_DOMAINS) { |
MAX_CANON_DOMAINS) { |
error("%s line %d: too many permitted CNAMEs.", |
error("%s line %d: too many permitted CNAMEs.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
cname = options->permitted_cnames + |
cname = options->permitted_cnames + |
options->num_permitted_cnames++; |
options->num_permitted_cnames++; |
|
|
goto parse_flag; |
goto parse_flag; |
|
|
case oStreamLocalBindMask: |
case oStreamLocalBindMask: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing StreamLocalBindMask " |
error("%.200s line %d: Missing StreamLocalBindMask " |
"argument.", filename, linenum); |
"argument.", filename, linenum); |
return -1; |
goto out; |
} |
} |
/* Parse mode in octal format */ |
/* Parse mode in octal format */ |
value = strtol(arg, &endofnumber, 8); |
value = strtol(arg, &endofnumber, 8); |
if (arg == endofnumber || value < 0 || value > 0777) { |
if (arg == endofnumber || value < 0 || value > 0777) { |
error("%.200s line %d: Bad mask.", filename, linenum); |
error("%.200s line %d: Bad mask.", filename, linenum); |
return -1; |
goto out; |
} |
} |
options->fwd_opts.streamlocal_bind_mask = (mode_t)value; |
options->fwd_opts.streamlocal_bind_mask = (mode_t)value; |
break; |
break; |
|
|
|
|
case oFingerprintHash: |
case oFingerprintHash: |
intptr = &options->fingerprint_hash; |
intptr = &options->fingerprint_hash; |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if ((value = ssh_digest_alg_by_name(arg)) == -1) { |
if ((value = ssh_digest_alg_by_name(arg)) == -1) { |
error("%.200s line %d: Invalid hash algorithm \"%s\".", |
error("%.200s line %d: Invalid hash algorithm \"%s\".", |
filename, linenum, arg); |
filename, linenum, arg); |
return -1; |
goto out; |
} |
} |
if (*activep && *intptr == -1) |
if (*activep && *intptr == -1) |
*intptr = value; |
*intptr = value; |
|
|
goto parse_pubkey_algos; |
goto parse_pubkey_algos; |
|
|
case oAddKeysToAgent: |
case oAddKeysToAgent: |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
arg2 = strdelim(&s); |
arg2 = argv_next(&ac, &av); |
value = parse_multistate_value(arg, filename, linenum, |
value = parse_multistate_value(arg, filename, linenum, |
multistate_yesnoaskconfirm); |
multistate_yesnoaskconfirm); |
value2 = 0; /* unlimited lifespan by default */ |
value2 = 0; /* unlimited lifespan by default */ |
|
|
value2 > INT_MAX) { |
value2 > INT_MAX) { |
error("%s line %d: invalid time value.", |
error("%s line %d: invalid time value.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
} else if (value == -1 && arg2 == NULL) { |
} else if (value == -1 && arg2 == NULL) { |
if ((value2 = convtime(arg)) == -1 || |
if ((value2 = convtime(arg)) == -1 || |
value2 > INT_MAX) { |
value2 > INT_MAX) { |
error("%s line %d: unsupported option", |
error("%s line %d: unsupported option", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
value = 1; /* yes */ |
value = 1; /* yes */ |
} else if (value == -1 || arg2 != NULL) { |
} else if (value == -1 || arg2 != NULL) { |
error("%s line %d: unsupported option", |
error("%s line %d: unsupported option", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
if (*activep && options->add_keys_to_agent == -1) { |
if (*activep && options->add_keys_to_agent == -1) { |
options->add_keys_to_agent = value; |
options->add_keys_to_agent = value; |
|
|
|
|
case oIdentityAgent: |
case oIdentityAgent: |
charptr = &options->identity_agent; |
charptr = &options->identity_agent; |
arg = strdelim(&s); |
arg = argv_next(&ac, &av); |
if (!arg || *arg == '\0') { |
if (!arg || *arg == '\0') { |
error("%.200s line %d: Missing argument.", |
error("%.200s line %d: Missing argument.", |
filename, linenum); |
filename, linenum); |
return -1; |
goto out; |
} |
} |
parse_agent_path: |
parse_agent_path: |
/* Extra validation if the string represents an env var. */ |
/* Extra validation if the string represents an env var. */ |
if ((arg2 = dollar_expand(&r, arg)) == NULL || r) { |
if ((arg2 = dollar_expand(&r, arg)) == NULL || r) { |
error("%.200s line %d: Invalid environment expansion " |
error("%.200s line %d: Invalid environment expansion " |
"%s.", filename, linenum, arg); |
"%s.", filename, linenum, arg); |
return -1; |
goto out; |
} |
} |
free(arg2); |
free(arg2); |
/* check for legacy environment format */ |
/* check for legacy environment format */ |
|
|
!valid_env_name(arg + 1)) { |
!valid_env_name(arg + 1)) { |
error("%.200s line %d: Invalid environment name %s.", |
error("%.200s line %d: Invalid environment name %s.", |
filename, linenum, arg); |
filename, linenum, arg); |
return -1; |
goto out; |
} |
} |
if (*activep && *charptr == NULL) |
if (*activep && *charptr == NULL) |
*charptr = xstrdup(arg); |
*charptr = xstrdup(arg); |
|
|
case oDeprecated: |
case oDeprecated: |
debug("%s line %d: Deprecated option \"%s\"", |
debug("%s line %d: Deprecated option \"%s\"", |
filename, linenum, keyword); |
filename, linenum, keyword); |
return 0; |
argv_consume(&ac); |
|
break; |
|
|
case oUnsupported: |
case oUnsupported: |
error("%s line %d: Unsupported option \"%s\"", |
error("%s line %d: Unsupported option \"%s\"", |
filename, linenum, keyword); |
filename, linenum, keyword); |
return 0; |
argv_consume(&ac); |
|
break; |
|
|
default: |
default: |
error("%s line %d: Unimplemented opcode %d", |
error("%s line %d: Unimplemented opcode %d", |
filename, linenum, opcode); |
filename, linenum, opcode); |
|
goto out; |
} |
} |
|
|
/* Check that there is no garbage at end of line. */ |
/* Check that there is no garbage at end of line. */ |
if ((arg = strdelim(&s)) != NULL && *arg != '\0') { |
if (ac > 0) { |
error("%.200s line %d: garbage at end of line; \"%.200s\".", |
error("%.200s line %d: keyword %s extra arguments " |
filename, linenum, arg); |
"at end of line", filename, linenum, keyword); |
return -1; |
goto out; |
} |
} |
return 0; |
|
|
/* success */ |
|
ret = 0; |
|
out: |
|
argv_free(oav, oac); |
|
return ret; |
} |
} |
|
|
/* |
/* |
|
|
int flags, int *activep, int *want_final_pass, int depth) |
int flags, int *activep, int *want_final_pass, int depth) |
{ |
{ |
FILE *f; |
FILE *f; |
char *cp, *line = NULL; |
char *line = NULL; |
size_t linesize = 0; |
size_t linesize = 0; |
int linenum; |
int linenum; |
int bad_options = 0; |
int bad_options = 0; |
|
|
* NB - preserve newlines, they are needed to reproduce |
* NB - preserve newlines, they are needed to reproduce |
* line numbers later for error messages. |
* line numbers later for error messages. |
*/ |
*/ |
if ((cp = strchr(line, '#')) != NULL) |
|
*cp = '\0'; |
|
if (process_config_line_depth(options, pw, host, original_host, |
if (process_config_line_depth(options, pw, host, original_host, |
line, filename, linenum, activep, flags, want_final_pass, |
line, filename, linenum, activep, flags, want_final_pass, |
depth) != 0) |
depth) != 0) |
|
|
if (fwd->connect_host != NULL && |
if (fwd->connect_host != NULL && |
strlen(fwd->connect_host) >= NI_MAXHOST) |
strlen(fwd->connect_host) >= NI_MAXHOST) |
goto fail_free; |
goto fail_free; |
/* XXX - if connecting to a remote socket, max sun len may not match this host */ |
/* |
|
* XXX - if connecting to a remote socket, max sun len may not |
|
* match this host |
|
*/ |
if (fwd->connect_path != NULL && |
if (fwd->connect_path != NULL && |
strlen(fwd->connect_path) >= PATH_MAX_SUN) |
strlen(fwd->connect_path) >= PATH_MAX_SUN) |
goto fail_free; |
goto fail_free; |
|
|
active &= o->proxy_command == NULL && o->jump_host == NULL; |
active &= o->proxy_command == NULL && o->jump_host == NULL; |
|
|
orig = sdup = xstrdup(s); |
orig = sdup = xstrdup(s); |
|
|
|
/* Remove comment and trailing whitespace */ |
|
if ((cp = strchr(orig, '#')) != NULL) |
|
*cp = '\0'; |
|
rtrim(orig); |
|
|
first = active; |
first = active; |
do { |
do { |
if (strcasecmp(s, "none") == 0) |
if (strcasecmp(s, "none") == 0) |
|
|
u_int i; |
u_int i; |
|
|
printf("%s", lookup_opcode_name(code)); |
printf("%s", lookup_opcode_name(code)); |
|
if (count == 0) |
|
printf(" none"); |
for (i = 0; i < count; i++) |
for (i = 0; i < count; i++) |
printf(" %s", vals[i]); |
printf(" %s", vals[i]); |
printf("\n"); |
printf("\n"); |