fix merge conflict

This commit is contained in:
Tess Gauthier 2024-03-04 12:13:33 -05:00
commit ed376e945e
10 changed files with 249 additions and 134 deletions

View File

@ -72,6 +72,7 @@ jobs:
- { target: fbsd14, config: pam, host: libvirt } - { target: fbsd14, config: pam, host: libvirt }
- { target: nbsd8, config: pam, host: libvirt } - { target: nbsd8, config: pam, host: libvirt }
- { target: nbsd9, config: pam, host: libvirt } - { target: nbsd9, config: pam, host: libvirt }
- { target: nbsd10, config: pam, host: libvirt }
# VMs with persistent disks that have their own runner. # VMs with persistent disks that have their own runner.
- { target: win10, config: default, host: win10 } - { target: win10, config: default, host: win10 }
- { target: win10, config: cygwin-release, host: win10 } - { target: win10, config: cygwin-release, host: win10 }

View File

@ -1,4 +1,4 @@
/* $OpenBSD: clientloop.c,v 1.402 2023/11/24 00:31:30 dtucker Exp $ */ /* $OpenBSD: clientloop.c,v 1.403 2024/02/21 05:57:34 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -525,7 +525,7 @@ send_chaff(struct ssh *ssh)
{ {
int r; int r;
if ((ssh->kex->flags & KEX_HAS_PING) == 0) if (ssh->kex == NULL || (ssh->kex->flags & KEX_HAS_PING) == 0)
return 0; return 0;
/* XXX probabilistically send chaff? */ /* XXX probabilistically send chaff? */
/* /*

View File

@ -3006,7 +3006,7 @@ if test "x$openssl" = "xyes" ; then
fi fi
# Check for OpenSSL without EVP_aes_{192,256}_cbc # Check for OpenSSL without EVP_aes_{192,256}_cbc
AC_MSG_CHECKING([whether OpenSSL has crippled AES support]) AC_MSG_CHECKING([whether OpenSSL lacks support for AES 192/256])
AC_LINK_IFELSE( AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[ [AC_LANG_PROGRAM([[
#include <stdlib.h> #include <stdlib.h>

15
misc.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: misc.c,v 1.189 2023/10/12 03:36:32 djm Exp $ */ /* $OpenBSD: misc.c,v 1.190 2024/03/04 02:16:11 djm Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005-2020 Damien Miller. All rights reserved. * Copyright (c) 2005-2020 Damien Miller. All rights reserved.
@ -2726,6 +2726,19 @@ opt_array_append(const char *file, const int line, const char *directive,
opt_array_append2(file, line, directive, array, NULL, lp, s, 0); opt_array_append2(file, line, directive, array, NULL, lp, s, 0);
} }
void
opt_array_free2(char **array, int **iarray, u_int l)
{
u_int i;
if (array == NULL || l == 0)
return;
for (i = 0; i < l; i++)
free(array[i]);
free(array);
free(iarray);
}
sshsig_t sshsig_t
ssh_signal(int signum, sshsig_t handler) ssh_signal(int signum, sshsig_t handler)
{ {

3
misc.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: misc.h,v 1.106 2023/10/11 22:42:26 djm Exp $ */ /* $OpenBSD: misc.h,v 1.107 2024/03/04 02:16:11 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -213,6 +213,7 @@ void opt_array_append(const char *file, const int line,
void opt_array_append2(const char *file, const int line, void opt_array_append2(const char *file, const int line,
const char *directive, char ***array, int **iarray, u_int *lp, const char *directive, char ***array, int **iarray, u_int *lp,
const char *s, int i); const char *s, int i);
void opt_array_free2(char **array, int **iarray, u_int l);
struct timespec; struct timespec;
void ptimeout_init(struct timespec *pt); void ptimeout_init(struct timespec *pt);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.c,v 1.384 2024/01/11 01:45:36 djm Exp $ */ /* $OpenBSD: readconf.c,v 1.386 2024/03/04 04:13:18 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -897,6 +897,20 @@ parse_token(const char *cp, const char *filename, int linenum,
return oBadOption; return oBadOption;
} }
static void
free_canon_cnames(struct allowed_cname *cnames, u_int n)
{
u_int i;
if (cnames == NULL || n == 0)
return;
for (i = 0; i < n; i++) {
free(cnames[i].source_list);
free(cnames[i].target_list);
}
free(cnames);
}
/* Multistate option parsing */ /* Multistate option parsing */
struct multistate { struct multistate {
char *key; char *key;
@ -1039,21 +1053,24 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,
{ {
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 *uintptr, uvalue, max_entries = 0; u_int *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, i; // fix CodeQL SM01735 size_t len, i; // fix CodeQL SM01735
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;
@ -1669,14 +1686,13 @@ parse_pubkey_algos:
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);
@ -1702,17 +1718,20 @@ parse_pubkey_algos:
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:
@ -1830,12 +1849,14 @@ parse_pubkey_algos:
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 == '-') {
@ -1847,27 +1868,38 @@ parse_pubkey_algos:
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;
@ -2080,52 +2112,46 @@ parse_pubkey_algos:
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) { if (nstrs == 0) {
error("%s line %d: too many hostname suffixes.", fatal("%s line %d: no %s specified",
filename, linenum); filename, linenum, keyword);
goto out; }
} if (found && *activep) {
options->canonical_domains[ options->canonical_domains = strs;
options->num_canonical_domains++] = xstrdup(arg); 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);
@ -2146,20 +2172,23 @@ parse_pubkey_algos:
*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);
goto out;
}
cname = options->permitted_cnames +
options->num_permitted_cnames++;
cname->source_list = xstrdup(arg);
cname->target_list = xstrdup(arg2);
} }
if (ncnames == 0) {
fatal("%s line %d: no %s specified",
filename, linenum, keyword);
}
if (found && *activep) {
options->permitted_cnames = cnames;
options->num_permitted_cnames = ncnames;
cnames = NULL; /* transferred */
ncnames = 0;
}
/* un-transferred cnames is cleaned up before exit */
break; break;
case oCanonicalizeHostname: case oCanonicalizeHostname:
@ -2340,12 +2369,11 @@ parse_pubkey_algos:
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);
@ -2356,11 +2384,18 @@ parse_pubkey_algos:
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;
@ -2392,6 +2427,8 @@ parse_pubkey_algos:
/* success */ /* success */
ret = 0; ret = 0;
out: out:
free_canon_cnames(cnames, ncnames);
opt_array_free2(strs, NULL, nstrs);
argv_free(oav, oac); argv_free(oav, oac);
return ret; return ret;
} }
@ -2430,7 +2467,7 @@ read_config_file_depth(const char *filename, struct passwd *pw,
if ((f = fopen(filename, "r")) == NULL) if ((f = fopen(filename, "r")) == NULL)
return 0; return 0;
if (flags & SSHCONF_CHECKPERM) { if (flags & SSHCONF_CHECKPERM) {
#if WINDOWS #if WINDOWS
/* /*
file permissions are designed differently on windows. file permissions are designed differently on windows.

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.h,v 1.155 2024/01/11 01:45:36 djm Exp $ */ /* $OpenBSD: readconf.h,v 1.156 2024/03/04 02:16:11 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -155,12 +155,12 @@ typedef struct {
int proxy_use_fdpass; int proxy_use_fdpass;
int num_canonical_domains; int num_canonical_domains;
char *canonical_domains[MAX_CANON_DOMAINS]; char **canonical_domains;
int canonicalize_hostname; int canonicalize_hostname;
int canonicalize_max_dots; int canonicalize_max_dots;
int canonicalize_fallback_local; int canonicalize_fallback_local;
int num_permitted_cnames; int num_permitted_cnames;
struct allowed_cname permitted_cnames[MAX_CANON_DOMAINS]; struct allowed_cname *permitted_cnames;
char *revoked_host_keys; char *revoked_host_keys;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.c,v 1.404 2024/02/20 04:10:03 djm Exp $ */ /* $OpenBSD: servconf.c,v 1.405 2024/03/04 02:16:11 djm Exp $ */
/* /*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved * All rights reserved
@ -1302,12 +1302,12 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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;
@ -1317,6 +1317,8 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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)
@ -1779,7 +1781,6 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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",
@ -1788,19 +1789,25 @@ process_server_config_line_depth(ServerOptions *options, char *line,
} }
/* 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;
@ -1826,16 +1833,22 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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:
@ -1846,16 +1859,22 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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:
@ -2039,7 +2058,7 @@ process_server_config_line_depth(ServerOptions *options, char *line,
* 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",
@ -2047,13 +2066,20 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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:
@ -2079,34 +2105,47 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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;
@ -2260,21 +2299,20 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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) {
/* /*
@ -2296,12 +2334,20 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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:
@ -2430,10 +2476,9 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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);
@ -2446,17 +2491,19 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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:
@ -2516,12 +2563,11 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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);
@ -2532,11 +2578,18 @@ process_server_config_line_depth(ServerOptions *options, char *line,
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;
@ -2576,6 +2629,7 @@ process_server_config_line_depth(ServerOptions *options, char *line,
/* 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;
} }

View File

@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.\" $OpenBSD: ssh_config.5,v 1.393 2024/01/10 06:33:13 jmc Exp $ .\" $OpenBSD: ssh_config.5,v 1.394 2024/02/21 06:01:13 djm Exp $
.Dd $Mdocdate: January 10 2024 $ .Dd $Mdocdate: February 21 2024 $
.Dt SSH_CONFIG 5 .Dt SSH_CONFIG 5
.Os .Os
.Sh NAME .Sh NAME
@ -144,7 +144,7 @@ The available criteria keywords are:
.Cm localnetwork , .Cm localnetwork ,
.Cm host , .Cm host ,
.Cm originalhost , .Cm originalhost ,
.Cm Tag , .Cm tagged ,
.Cm user , .Cm user ,
and and
.Cm localuser . .Cm localuser .

View File

@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.\" $OpenBSD: sshd_config.5,v 1.352 2024/01/10 06:33:13 jmc Exp $ .\" $OpenBSD: sshd_config.5,v 1.355 2024/02/21 06:17:29 djm Exp $
.Dd $Mdocdate: January 10 2024 $ .Dd $Mdocdate: February 21 2024 $
.Dt SSHD_CONFIG 5 .Dt SSHD_CONFIG 5
.Os .Os
.Sh NAME .Sh NAME
@ -485,7 +485,7 @@ to after authentication.
At session startup At session startup
.Xr sshd 8 .Xr sshd 8
checks that all components of the pathname are root-owned directories checks that all components of the pathname are root-owned directories
which are not writable by any other user or group. which are not writable by group or others.
After the chroot, After the chroot,
.Xr sshd 8 .Xr sshd 8
changes the working directory to the user's home directory. changes the working directory to the user's home directory.
@ -1126,7 +1126,8 @@ DEBUG and DEBUG1 are equivalent.
DEBUG2 and DEBUG3 each specify higher levels of debugging output. DEBUG2 and DEBUG3 each specify higher levels of debugging output.
Logging with a DEBUG level violates the privacy of users and is not recommended. Logging with a DEBUG level violates the privacy of users and is not recommended.
.It Cm LogVerbose .It Cm LogVerbose
Specify one or more overrides to LogLevel. Specify one or more overrides to
.Cm LogLevel .
An override consists of a pattern lists that matches the source file, function An override consists of a pattern lists that matches the source file, function
and line number to force detailed logging for. and line number to force detailed logging for.
For example, an override pattern of: For example, an override pattern of:
@ -1791,6 +1792,14 @@ implements an in-process SFTP server.
This may simplify configurations using This may simplify configurations using
.Cm ChrootDirectory .Cm ChrootDirectory
to force a different filesystem root on clients. to force a different filesystem root on clients.
It accepts the same command line arguments as
.Cm sftp-server
and even though it is in-process, settings such as
.Cm LogLevel
or
.Cm SyslogFacility
do not apply to it and must be set explicitly via
command line arguments.
.Pp .Pp
By default no subsystems are defined. By default no subsystems are defined.
.It Cm SyslogFacility .It Cm SyslogFacility