version 1.384, 2024/01/11 01:45:36 |
version 1.385, 2024/03/04 02:16:11 |
|
|
{ |
{ |
char *str, **charptr, *endofnumber, *keyword, *arg, *arg2, *p; |
char *str, **charptr, *endofnumber, *keyword, *arg, *arg2, *p; |
char **cpptr, ***cppptr, fwdarg[256]; |
char **cpptr, ***cppptr, fwdarg[256]; |
u_int i, *uintptr, uvalue, max_entries = 0; |
u_int i, *uintptr, max_entries = 0; |
int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0; |
int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0; |
int remotefwd, dynamicfwd, ca_only = 0; |
int remotefwd, dynamicfwd, ca_only = 0, found = 0; |
LogLevel *log_level_ptr; |
LogLevel *log_level_ptr; |
SyslogFacility *log_facility_ptr; |
SyslogFacility *log_facility_ptr; |
long long val64; |
long long val64; |
size_t len; |
size_t len; |
struct Forward fwd; |
struct Forward fwd; |
const struct multistate *multistate_ptr; |
const struct multistate *multistate_ptr; |
struct allowed_cname *cname; |
|
glob_t gl; |
glob_t gl; |
const char *errstr; |
const char *errstr; |
char **oav = NULL, **av; |
char **oav = NULL, **av; |
int oac = 0, ac; |
int oac = 0, ac; |
int ret = -1; |
int ret = -1; |
|
struct allowed_cname *cnames = NULL; |
|
u_int ncnames = 0; |
|
char **strs = NULL; /* string array arguments; freed implicitly */ |
|
u_int nstrs = 0; |
|
|
if (activep == NULL) { /* We are processing a command line directive */ |
if (activep == NULL) { /* We are processing a command line directive */ |
cmdline = 1; |
cmdline = 1; |
|
|
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; |
uvalue = *uintptr; /* modified later */ |
found = *uintptr == 0; |
i = 0; |
|
while ((arg = argv_next(&ac, &av)) != NULL) { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
arg2 = xstrdup(arg); |
arg2 = xstrdup(arg); |
/* Allow any/none only in first position */ |
/* Allow any/none only in first position */ |
if (strcasecmp(arg, "none") == 0 || |
if (strcasecmp(arg, "none") == 0 || |
strcasecmp(arg, "any") == 0) { |
strcasecmp(arg, "any") == 0) { |
if (i > 0 || ac > 0) { |
if (nstrs > 0 || ac > 0) { |
error("%s line %d: keyword %s \"%s\" " |
error("%s line %d: keyword %s \"%s\" " |
"argument must appear alone.", |
"argument must appear alone.", |
filename, linenum, keyword, arg); |
filename, linenum, keyword, arg); |
|
|
lookup_opcode_name(opcode)); |
lookup_opcode_name(opcode)); |
} |
} |
} |
} |
if (*activep && uvalue == 0) { |
opt_array_append(filename, linenum, |
opt_array_append(filename, linenum, |
lookup_opcode_name(opcode), |
lookup_opcode_name(opcode), |
&strs, &nstrs, arg2); |
cppptr, uintptr, arg2); |
|
} |
|
free(arg2); |
free(arg2); |
i++; |
|
} |
} |
if (i == 0) |
if (nstrs == 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)); |
|
if (found && *activep) { |
|
*cppptr = strs; |
|
*uintptr = nstrs; |
|
strs = NULL; /* transferred */ |
|
nstrs = 0; |
|
} |
break; |
break; |
|
|
case oClearAllForwardings: |
case oClearAllForwardings: |
|
|
goto parse_int; |
goto parse_int; |
|
|
case oSendEnv: |
case oSendEnv: |
|
/* XXX appends to list; doesn't respect first-match-wins */ |
while ((arg = argv_next(&ac, &av)) != NULL) { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
if (*arg == '\0' || 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); |
goto out; |
goto out; |
} |
} |
|
found = 1; |
if (!*activep) |
if (!*activep) |
continue; |
continue; |
if (*arg == '-') { |
if (*arg == '-') { |
|
|
lookup_opcode_name(opcode), |
lookup_opcode_name(opcode), |
&options->send_env, &options->num_send_env, arg); |
&options->send_env, &options->num_send_env, arg); |
} |
} |
|
if (!found) { |
|
fatal("%s line %d: no %s specified", |
|
filename, linenum, keyword); |
|
} |
break; |
break; |
|
|
case oSetEnv: |
case oSetEnv: |
value = options->num_setenv; |
found = options->num_setenv == 0; |
while ((arg = argv_next(&ac, &av)) != NULL) { |
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); |
goto out; |
goto out; |
} |
} |
if (!*activep || value != 0) |
if (lookup_setenv_in_list(arg, strs, nstrs) != NULL) { |
continue; |
|
if (lookup_setenv_in_list(arg, options->setenv, |
|
options->num_setenv) != NULL) { |
|
debug2("%s line %d: ignoring duplicate env " |
debug2("%s line %d: ignoring duplicate env " |
"name \"%.64s\"", filename, linenum, arg); |
"name \"%.64s\"", filename, linenum, arg); |
continue; |
continue; |
} |
} |
opt_array_append(filename, linenum, |
opt_array_append(filename, linenum, |
lookup_opcode_name(opcode), |
lookup_opcode_name(opcode), |
&options->setenv, &options->num_setenv, arg); |
&strs, &nstrs, arg); |
} |
} |
|
if (nstrs == 0) { |
|
fatal("%s line %d: no %s specified", |
|
filename, linenum, keyword); |
|
} |
|
if (found && *activep) { |
|
options->setenv = strs; |
|
options->num_setenv = nstrs; |
|
strs = NULL; /* transferred */ |
|
nstrs = 0; |
|
} |
break; |
break; |
|
|
case oControlPath: |
case oControlPath: |
|
|
goto parse_flag; |
goto parse_flag; |
|
|
case oCanonicalDomains: |
case oCanonicalDomains: |
value = options->num_canonical_domains != 0; |
found = options->num_canonical_domains == 0; |
i = 0; |
|
while ((arg = argv_next(&ac, &av)) != NULL) { |
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 */ |
/* Allow "none" only in first position */ |
if (strcasecmp(arg, "none") == 0) { |
if (strcasecmp(arg, "none") == 0) { |
if (i > 0 || ac > 0) { |
if (nstrs > 0 || ac > 0) { |
error("%s line %d: keyword %s \"none\" " |
error("%s line %d: keyword %s \"none\" " |
"argument must appear alone.", |
"argument must appear alone.", |
filename, linenum, keyword); |
filename, linenum, keyword); |
goto out; |
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); |
goto out; |
goto out; |
} |
} |
if (!*activep || value) |
opt_array_append(filename, linenum, keyword, |
continue; |
&strs, &nstrs, arg); |
if (options->num_canonical_domains >= |
|
MAX_CANON_DOMAINS) { |
|
error("%s line %d: too many hostname suffixes.", |
|
filename, linenum); |
|
goto out; |
|
} |
|
options->canonical_domains[ |
|
options->num_canonical_domains++] = xstrdup(arg); |
|
} |
} |
|
if (nstrs == 0) { |
|
fatal("%s line %d: no %s specified", |
|
filename, linenum, keyword); |
|
} |
|
if (found && *activep) { |
|
options->canonical_domains = strs; |
|
options->num_canonical_domains = nstrs; |
|
strs = NULL; /* transferred */ |
|
nstrs = 0; |
|
} |
break; |
break; |
|
|
case oCanonicalizePermittedCNAMEs: |
case oCanonicalizePermittedCNAMEs: |
value = options->num_permitted_cnames != 0; |
found = options->num_permitted_cnames == 0; |
i = 0; |
|
while ((arg = argv_next(&ac, &av)) != NULL) { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
/* |
/* |
* Either 'none' (only in first position), '*' for |
* Either 'none' (only in first position), '*' for |
* everything or 'list:list' |
* everything or 'list:list' |
*/ |
*/ |
if (strcasecmp(arg, "none") == 0) { |
if (strcasecmp(arg, "none") == 0) { |
if (i > 0 || ac > 0) { |
if (ncnames > 0 || ac > 0) { |
error("%s line %d: keyword %s \"none\" " |
error("%s line %d: keyword %s \"none\" " |
"argument must appear alone.", |
"argument must appear alone.", |
filename, linenum, keyword); |
filename, linenum, keyword); |
|
|
*arg2 = '\0'; |
*arg2 = '\0'; |
arg2++; |
arg2++; |
} |
} |
i++; |
cnames = xrecallocarray(cnames, ncnames, ncnames + 1, |
if (!*activep || value) |
sizeof(*cnames)); |
continue; |
cnames[ncnames].source_list = xstrdup(arg); |
if (options->num_permitted_cnames >= |
cnames[ncnames].target_list = xstrdup(arg2); |
MAX_CANON_DOMAINS) { |
ncnames++; |
error("%s line %d: too many permitted CNAMEs.", |
} |
filename, linenum); |
if (ncnames == 0) { |
goto out; |
fatal("%s line %d: no %s specified", |
|
filename, linenum, keyword); |
|
} |
|
if (found && *activep) { |
|
options->permitted_cnames = cnames; |
|
options->num_permitted_cnames = ncnames; |
|
} else { |
|
for (i = 0; i < ncnames; i++) { |
|
free(cnames[i].source_list); |
|
free(cnames[i].target_list); |
} |
} |
cname = options->permitted_cnames + |
free(cnames); |
options->num_permitted_cnames++; |
|
cname->source_list = xstrdup(arg); |
|
cname->target_list = xstrdup(arg2); |
|
} |
} |
break; |
break; |
|
|
|
|
break; |
break; |
|
|
case oChannelTimeout: |
case oChannelTimeout: |
uvalue = options->num_channel_timeouts; |
found = options->num_channel_timeouts == 0; |
i = 0; |
|
while ((arg = argv_next(&ac, &av)) != NULL) { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
/* Allow "none" only in first position */ |
/* Allow "none" only in first position */ |
if (strcasecmp(arg, "none") == 0) { |
if (strcasecmp(arg, "none") == 0) { |
if (i > 0 || ac > 0) { |
if (nstrs > 0 || ac > 0) { |
error("%s line %d: keyword %s \"none\" " |
error("%s line %d: keyword %s \"none\" " |
"argument must appear alone.", |
"argument must appear alone.", |
filename, linenum, keyword); |
filename, linenum, keyword); |
|
|
fatal("%s line %d: invalid channel timeout %s", |
fatal("%s line %d: invalid channel timeout %s", |
filename, linenum, arg); |
filename, linenum, arg); |
} |
} |
if (!*activep || uvalue != 0) |
|
continue; |
|
opt_array_append(filename, linenum, keyword, |
opt_array_append(filename, linenum, keyword, |
&options->channel_timeouts, |
&strs, &nstrs, arg); |
&options->num_channel_timeouts, arg); |
|
} |
} |
|
if (nstrs == 0) { |
|
fatal("%s line %d: no %s specified", |
|
filename, linenum, keyword); |
|
} |
|
if (found && *activep) { |
|
options->channel_timeouts = strs; |
|
options->num_channel_timeouts = nstrs; |
|
strs = NULL; /* transferred */ |
|
nstrs = 0; |
|
} |
break; |
break; |
|
|
case oDeprecated: |
case oDeprecated: |
|
|
/* success */ |
/* success */ |
ret = 0; |
ret = 0; |
out: |
out: |
|
opt_array_free2(strs, NULL, nstrs); |
argv_free(oav, oac); |
argv_free(oav, oac); |
return ret; |
return ret; |
} |
} |