version 1.404, 2024/02/20 04:10:03 |
version 1.405, 2024/03/04 02:16:11 |
|
|
struct include_list *includes) |
struct include_list *includes) |
{ |
{ |
char *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword; |
char *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword; |
int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found; |
int cmdline = 0, *intptr, value, value2, n, port, oactive, r; |
int ca_only = 0; |
int ca_only = 0, found = 0; |
SyslogFacility *log_facility_ptr; |
SyslogFacility *log_facility_ptr; |
LogLevel *log_level_ptr; |
LogLevel *log_level_ptr; |
ServerOpCodes opcode; |
ServerOpCodes opcode; |
u_int i, *uintptr, uvalue, flags = 0; |
u_int i, *uintptr, flags = 0; |
size_t len; |
size_t len; |
long long val64; |
long long val64; |
const struct multistate *multistate_ptr; |
const struct multistate *multistate_ptr; |
|
|
char **oav = NULL, **av; |
char **oav = NULL, **av; |
int oac = 0, ac; |
int oac = 0, ac; |
int ret = -1; |
int ret = -1; |
|
char **strs = NULL; /* string array arguments; freed implicitly */ |
|
u_int nstrs = 0; |
|
|
/* Strip trailing whitespace. Allow \f (form feed) at EOL only */ |
/* Strip trailing whitespace. Allow \f (form feed) at EOL only */ |
if ((len = strlen(line)) == 0) |
if ((len = strlen(line)) == 0) |
|
|
|
|
case sLogVerbose: |
case sLogVerbose: |
found = options->num_log_verbose == 0; |
found = options->num_log_verbose == 0; |
i = 0; |
|
while ((arg = argv_next(&ac, &av)) != NULL) { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
if (*arg == '\0') { |
if (*arg == '\0') { |
error("%s line %d: keyword %s empty argument", |
error("%s line %d: keyword %s empty argument", |
|
|
} |
} |
/* 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 (!found || !*activep) |
|
continue; |
|
opt_array_append(filename, linenum, keyword, |
opt_array_append(filename, linenum, keyword, |
&options->log_verbose, &options->num_log_verbose, |
&strs, &nstrs, arg); |
arg); |
|
} |
} |
|
if (nstrs == 0) { |
|
fatal("%s line %d: no %s specified", |
|
filename, linenum, keyword); |
|
} |
|
if (found && *activep) { |
|
options->log_verbose = strs; |
|
options->num_log_verbose = nstrs; |
|
strs = NULL; /* transferred */ |
|
nstrs = 0; |
|
} |
break; |
break; |
|
|
case sAllowTcpForwarding: |
case sAllowTcpForwarding: |
|
|
chararrayptr = &options->allow_users; |
chararrayptr = &options->allow_users; |
uintptr = &options->num_allow_users; |
uintptr = &options->num_allow_users; |
parse_allowdenyusers: |
parse_allowdenyusers: |
|
/* 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' || |
if (*arg == '\0' || |
match_user(NULL, NULL, NULL, arg) == -1) |
match_user(NULL, NULL, NULL, arg) == -1) |
fatal("%s line %d: invalid %s pattern: \"%s\"", |
fatal("%s line %d: invalid %s pattern: \"%s\"", |
filename, linenum, keyword, arg); |
filename, linenum, keyword, arg); |
|
found = 1; |
if (!*activep) |
if (!*activep) |
continue; |
continue; |
opt_array_append(filename, linenum, keyword, |
opt_array_append(filename, linenum, keyword, |
chararrayptr, uintptr, arg); |
chararrayptr, uintptr, arg); |
} |
} |
|
if (!found) { |
|
fatal("%s line %d: no %s specified", |
|
filename, linenum, keyword); |
|
} |
break; |
break; |
|
|
case sDenyUsers: |
case sDenyUsers: |
|
|
case sAllowGroups: |
case sAllowGroups: |
chararrayptr = &options->allow_groups; |
chararrayptr = &options->allow_groups; |
uintptr = &options->num_allow_groups; |
uintptr = &options->num_allow_groups; |
|
/* XXX appends to list; doesn't respect first-match-wins */ |
parse_allowdenygroups: |
parse_allowdenygroups: |
while ((arg = argv_next(&ac, &av)) != NULL) { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
if (*arg == '\0') |
if (*arg == '\0') |
fatal("%s line %d: empty %s pattern", |
fatal("%s line %d: empty %s pattern", |
filename, linenum, keyword); |
filename, linenum, keyword); |
|
found = 1; |
if (!*activep) |
if (!*activep) |
continue; |
continue; |
opt_array_append(filename, linenum, keyword, |
opt_array_append(filename, linenum, keyword, |
chararrayptr, uintptr, arg); |
chararrayptr, uintptr, arg); |
} |
} |
|
if (!found) { |
|
fatal("%s line %d: no %s specified", |
|
filename, linenum, keyword); |
|
} |
break; |
break; |
|
|
case sDenyGroups: |
case sDenyGroups: |
|
|
* AuthorizedKeysFile /etc/ssh_keys/%u |
* AuthorizedKeysFile /etc/ssh_keys/%u |
*/ |
*/ |
case sAuthorizedKeysFile: |
case sAuthorizedKeysFile: |
uvalue = options->num_authkeys_files; |
found = options->num_authkeys_files == 0; |
while ((arg = argv_next(&ac, &av)) != NULL) { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
if (*arg == '\0') { |
if (*arg == '\0') { |
error("%s line %d: keyword %s empty argument", |
error("%s line %d: keyword %s empty argument", |
|
|
goto out; |
goto out; |
} |
} |
arg2 = tilde_expand_filename(arg, getuid()); |
arg2 = tilde_expand_filename(arg, getuid()); |
if (*activep && uvalue == 0) { |
opt_array_append(filename, linenum, keyword, |
opt_array_append(filename, linenum, keyword, |
&strs, &nstrs, arg2); |
&options->authorized_keys_files, |
|
&options->num_authkeys_files, arg2); |
|
} |
|
free(arg2); |
free(arg2); |
} |
} |
|
if (nstrs == 0) { |
|
fatal("%s line %d: no %s specified", |
|
filename, linenum, keyword); |
|
} |
|
if (found && *activep) { |
|
options->authorized_keys_files = strs; |
|
options->num_authkeys_files = nstrs; |
|
strs = NULL; /* transferred */ |
|
nstrs = 0; |
|
} |
break; |
break; |
|
|
case sAuthorizedPrincipalsFile: |
case sAuthorizedPrincipalsFile: |
|
|
goto parse_int; |
goto parse_int; |
|
|
case sAcceptEnv: |
case sAcceptEnv: |
|
/* 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) |
fatal("%s line %d: Invalid environment name.", |
fatal("%s line %d: Invalid environment name.", |
filename, linenum); |
filename, linenum); |
|
found = 1; |
if (!*activep) |
if (!*activep) |
continue; |
continue; |
opt_array_append(filename, linenum, keyword, |
opt_array_append(filename, linenum, keyword, |
&options->accept_env, &options->num_accept_env, |
&options->accept_env, &options->num_accept_env, |
arg); |
arg); |
} |
} |
|
if (!found) { |
|
fatal("%s line %d: no %s specified", |
|
filename, linenum, keyword); |
|
} |
break; |
break; |
|
|
case sSetEnv: |
case sSetEnv: |
uvalue = options->num_setenv; |
found = options->num_setenv == 0; |
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) |
fatal("%s line %d: Invalid environment.", |
fatal("%s line %d: Invalid environment.", |
filename, linenum); |
filename, linenum); |
if (!*activep || uvalue != 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, keyword, |
opt_array_append(filename, linenum, keyword, |
&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 sPermitTunnel: |
case sPermitTunnel: |
|
|
uintptr = &options->num_permitted_opens; |
uintptr = &options->num_permitted_opens; |
chararrayptr = &options->permitted_opens; |
chararrayptr = &options->permitted_opens; |
} |
} |
arg = argv_next(&ac, &av); |
found = *uintptr == 0; |
if (!arg || *arg == '\0') |
while ((arg = argv_next(&ac, &av)) != NULL) { |
fatal("%s line %d: %s missing argument.", |
if (strcmp(arg, "any") == 0 || |
filename, linenum, keyword); |
strcmp(arg, "none") == 0) { |
uvalue = *uintptr; /* modified later */ |
if (nstrs != 0) { |
if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) { |
fatal("%s line %d: %s must appear " |
if (*activep && uvalue == 0) { |
"alone on a %s line.", |
*uintptr = 1; |
filename, linenum, arg, keyword); |
*chararrayptr = xcalloc(1, |
} |
sizeof(**chararrayptr)); |
opt_array_append(filename, linenum, keyword, |
(*chararrayptr)[0] = xstrdup(arg); |
&strs, &nstrs, arg); |
|
continue; |
} |
} |
break; |
|
} |
|
for (; arg != NULL && *arg != '\0'; arg = argv_next(&ac, &av)) { |
|
if (opcode == sPermitListen && |
if (opcode == sPermitListen && |
strchr(arg, ':') == NULL) { |
strchr(arg, ':') == NULL) { |
/* |
/* |
|
|
fatal("%s line %d: %s bad port number", |
fatal("%s line %d: %s bad port number", |
filename, linenum, keyword); |
filename, linenum, keyword); |
} |
} |
if (*activep && uvalue == 0) { |
opt_array_append(filename, linenum, keyword, |
opt_array_append(filename, linenum, keyword, |
&strs, &nstrs, arg2); |
chararrayptr, uintptr, arg2); |
|
} |
|
free(arg2); |
free(arg2); |
} |
} |
|
if (nstrs == 0) { |
|
fatal("%s line %d: %s missing argument.", |
|
filename, linenum, keyword); |
|
} |
|
if (found && *activep) { |
|
*chararrayptr = strs; |
|
*uintptr = nstrs; |
|
strs = NULL; /* transferred */ |
|
nstrs = 0; |
|
} |
break; |
break; |
|
|
case sForceCommand: |
case sForceCommand: |
|
|
case sAuthenticationMethods: |
case sAuthenticationMethods: |
found = options->num_auth_methods == 0; |
found = options->num_auth_methods == 0; |
value = 0; /* seen "any" pseudo-method */ |
value = 0; /* seen "any" pseudo-method */ |
value2 = 0; /* successfully parsed any method */ |
|
while ((arg = argv_next(&ac, &av)) != NULL) { |
while ((arg = argv_next(&ac, &av)) != NULL) { |
if (strcmp(arg, "any") == 0) { |
if (strcmp(arg, "any") == 0) { |
if (options->num_auth_methods > 0) { |
if (nstrs > 0) { |
fatal("%s line %d: \"any\" must " |
fatal("%s line %d: \"any\" must " |
"appear alone in %s", |
"appear alone in %s", |
filename, linenum, keyword); |
filename, linenum, keyword); |
|
|
fatal("%s line %d: invalid %s method list.", |
fatal("%s line %d: invalid %s method list.", |
filename, linenum, keyword); |
filename, linenum, keyword); |
} |
} |
value2 = 1; |
|
if (!found || !*activep) |
|
continue; |
|
opt_array_append(filename, linenum, keyword, |
opt_array_append(filename, linenum, keyword, |
&options->auth_methods, |
&strs, &nstrs, arg); |
&options->num_auth_methods, arg); |
|
} |
} |
if (value2 == 0) { |
if (nstrs == 0) { |
fatal("%s line %d: no %s specified", |
fatal("%s line %d: no %s specified", |
filename, linenum, keyword); |
filename, linenum, keyword); |
} |
} |
|
if (found && *activep) { |
|
options->auth_methods = strs; |
|
options->num_auth_methods = nstrs; |
|
strs = NULL; /* transferred */ |
|
nstrs = 0; |
|
} |
break; |
break; |
|
|
case sStreamLocalBindMask: |
case sStreamLocalBindMask: |
|
|
goto parse_int; |
goto parse_int; |
|
|
case sChannelTimeout: |
case sChannelTimeout: |
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 sUnusedConnectionTimeout: |
case sUnusedConnectionTimeout: |
|
|
/* 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; |
} |
} |