View | Details | Raw Unified | Return to bug 2468 | Differences between
and this patch

Collapse All | Expand All

(-)a/auth.c (-1 / +2 lines)
Lines 79-84 Link Here
79
79
80
/* import */
80
/* import */
81
extern ServerOptions options;
81
extern ServerOptions options;
82
extern struct include_list includes;
82
extern int use_privsep;
83
extern int use_privsep;
83
extern struct sshbuf *loginmsg;
84
extern struct sshbuf *loginmsg;
84
extern struct passwd *privsep_pw;
85
extern struct passwd *privsep_pw;
Lines 571-577 getpwnamallow(struct ssh *ssh, const char *user) Link Here
571
572
572
	ci = get_connection_info(ssh, 1, options.use_dns);
573
	ci = get_connection_info(ssh, 1, options.use_dns);
573
	ci->user = user;
574
	ci->user = user;
574
	parse_server_match_config(&options, ci);
575
	parse_server_match_config(&options, &includes, ci);
575
	log_change_level(options.log_level);
576
	log_change_level(options.log_level);
576
	process_permitopen(ssh, &options);
577
	process_permitopen(ssh, &options);
577
578
(-)a/regress/Makefile (-1 / +2 lines)
Lines 82-87 LTESTS= connect \ Link Here
82
		principals-command \
82
		principals-command \
83
		cert-file \
83
		cert-file \
84
		cfginclude \
84
		cfginclude \
85
		servcfginclude \
85
		allow-deny-users \
86
		allow-deny-users \
86
		authinfo
87
		authinfo
87
88
Lines 116-122 CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ Link Here
116
		sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \
117
		sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \
117
		ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \
118
		ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \
118
		ssh_proxy_envpass sshd.log sshd_config sshd_config_minimal \
119
		ssh_proxy_envpass sshd.log sshd_config sshd_config_minimal \
119
		sshd_config.orig sshd_proxy sshd_proxy.* sshd_proxy_bak \
120
		sshd_config.* sshd_proxy sshd_proxy.* sshd_proxy_bak \
120
		sshd_proxy_orig t10.out t10.out.pub t12.out t12.out.pub \
121
		sshd_proxy_orig t10.out t10.out.pub t12.out t12.out.pub \
121
		t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub \
122
		t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub \
122
		t8.out t8.out.pub t9.out t9.out.pub testdata \
123
		t8.out t8.out.pub t9.out t9.out.pub testdata \
(-)a/regress/servcfginclude.sh (+151 lines)
Line 0 Link Here
1
#	Placed in the Public Domain.
2
3
tid="server config include"
4
5
cat > $OBJ/sshd_config.i << _EOF
6
HostKey $OBJ/host.ssh-ed25519
7
Match host a
8
	Banner /aa
9
10
Match host b
11
	Banner /bb
12
	Include $OBJ/sshd_config.i.*
13
14
Match host c
15
	Include $OBJ/sshd_config.i.*
16
	Banner /cc
17
18
Match host m
19
	Include $OBJ/sshd_config.i.*
20
21
Match Host d
22
	Banner /dd
23
24
Match Host e
25
	Banner /ee
26
	Include $OBJ/sshd_config.i.*
27
28
Match Host f
29
	Include $OBJ/sshd_config.i.*
30
	Banner /ff
31
32
Match Host n
33
	Include $OBJ/sshd_config.i.*
34
_EOF
35
36
cat > $OBJ/sshd_config.i.0 << _EOF
37
Match host xxxxxx
38
_EOF
39
40
cat > $OBJ/sshd_config.i.1 << _EOF
41
Match host a
42
	Banner /aaa
43
44
Match host b
45
	Banner /bbb
46
47
Match host c
48
	Banner /ccc
49
50
Match Host d
51
	Banner /ddd
52
53
Match Host e
54
	Banner /eee
55
56
Match Host f
57
	Banner /fff
58
_EOF
59
60
cat > $OBJ/sshd_config.i.2 << _EOF
61
Match host a
62
	Banner /aaaa
63
64
Match host b
65
	Banner /bbbb
66
67
Match host c
68
	Banner /cccc
69
70
Match Host d
71
	Banner /dddd
72
73
Match Host e
74
	Banner /eeee
75
76
Match Host f
77
	Banner /ffff
78
79
Match all
80
	Banner /xxxx
81
_EOF
82
83
trial() {
84
	_host="$1"
85
	_exp="$2"
86
	trace "Testing the match with host=$_host"
87
	${REAL_SSHD} -f $OBJ/sshd_config.i -T -C "host=$_host,user=test,addr=127.0.0.1" > $OBJ/sshd_config.out ||
88
		fatal "ssh config parse failed"
89
	_got=`grep -i '^banner ' $OBJ/sshd_config.out | awk '{print $2}'`
90
	if test "x$_exp" != "x$_got" ; then
91
		fail "host $_host include fail: expected $_exp got $_got"
92
	fi
93
}
94
95
trial a /aa
96
trial b /bb
97
trial c /ccc
98
trial d /dd
99
trial e /ee
100
trial f /fff
101
trial m /xxxx
102
trial n /xxxx
103
trial x none
104
105
# Prepare an included config with an error.
106
107
cat > $OBJ/sshd_config.i.3 << _EOF
108
Banner xxxx
109
	Junk
110
_EOF
111
112
${REAL_SSHD} -f $OBJ/sshd_config.i -C "host=a,user=test,addr=127.0.0.1" 2>/dev/null && \
113
	fail "sshd include allowed invalid config"
114
115
${REAL_SSHD} -f $OBJ/sshd_config.i -C "host=x,user=test,addr=127.0.0.1" 2>/dev/null && \
116
	fail "sshd include allowed invalid config"
117
118
rm -f $OBJ/sshd_config.i.*
119
120
# Ensure that a missing include is not fatal.
121
cat > $OBJ/sshd_config.i << _EOF
122
HostKey $OBJ/host.ssh-ed25519
123
Include $OBJ/sshd_config.i.*
124
Banner /aa
125
_EOF
126
127
trial a /aa
128
129
# Ensure that Match/Host in an included config does not affect parent.
130
cat > $OBJ/sshd_config.i.x << _EOF
131
Match host x
132
_EOF
133
134
trial a /aa
135
136
cat > $OBJ/sshd_config.i.x << _EOF
137
Match Host x
138
_EOF
139
140
trial a /aa
141
142
# Ensure the empty include directive is not accepted
143
cat > $OBJ/sshd_config.i.x << _EOF
144
Include
145
_EOF
146
147
${REAL_SSHD} -f $OBJ/sshd_config.i.x -C "host=x,user=test,addr=127.0.0.1" 2>/dev/null && \
148
	fail "sshd allowed empty Include option"
149
150
# cleanup
151
rm -f $OBJ/sshd_config.i $OBJ/sshd_config.i.* $OBJ/sshd_config.out
(-)a/regress/test-exec.sh (+1 lines)
Lines 224-229 echo "exec ${SSH} -E${TEST_SSH_LOGFILE} "'"$@"' >>$SSHLOGWRAP Link Here
224
224
225
chmod a+rx $OBJ/ssh-log-wrapper.sh
225
chmod a+rx $OBJ/ssh-log-wrapper.sh
226
REAL_SSH="$SSH"
226
REAL_SSH="$SSH"
227
REAL_SSHD="$SSHD"
227
SSH="$SSHLOGWRAP"
228
SSH="$SSHLOGWRAP"
228
229
229
# Some test data.  We make a copy because some tests will overwrite it.
230
# Some test data.  We make a copy because some tests will overwrite it.
(-)a/servconf.c (-12 / +148 lines)
Lines 40-45 Link Here
40
#ifdef HAVE_UTIL_H
40
#ifdef HAVE_UTIL_H
41
#include <util.h>
41
#include <util.h>
42
#endif
42
#endif
43
#ifdef USE_SYSTEM_GLOB
44
# include <glob.h>
45
#else
46
# include "openbsd-compat/glob.h"
47
#endif
43
48
44
#include "openbsd-compat/sys-queue.h"
49
#include "openbsd-compat/sys-queue.h"
45
#include "xmalloc.h"
50
#include "xmalloc.h"
Lines 74-79 static void add_one_listen_addr(ServerOptions *, const char *, Link Here
74
extern int use_privsep;
79
extern int use_privsep;
75
extern struct sshbuf *cfg;
80
extern struct sshbuf *cfg;
76
81
82
#define INCLUDE_LIST_APPEND(includes, item) \
83
	do { \
84
		if ((includes)->count >= UINT16_MAX) \
85
			fatal("%s: Too many included files", __func__); \
86
		(item)->next = NULL; \
87
		if ((includes)->start == NULL) { \
88
			(includes)->start = (item); \
89
		} else if ((includes)->end != NULL) { \
90
			(includes)->end->next = (item); \
91
		} \
92
		(includes)->end = (item); \
93
		(includes)->count++; \
94
	} while (0)
95
77
/* Initializes the server options to their default values. */
96
/* Initializes the server options to their default values. */
78
97
79
void
98
void
Lines 473-478 fill_default_server_options(ServerOptions *options) Link Here
473
492
474
}
493
}
475
494
495
int process_server_config_line_depth(ServerOptions *options, char *line,
496
    const char *filename, int linenum, int *activep,
497
    struct connection_info *connectinfo, int inc_flags, int depth,
498
    struct include_list *includes);
499
void parse_server_config_depth(ServerOptions *options, const char *filename,
500
    struct sshbuf *conf, struct include_list *includes,
501
    struct connection_info *connectinfo, int flags, int *activep, int depth);
502
476
/* Keyword tokens. */
503
/* Keyword tokens. */
477
typedef enum {
504
typedef enum {
478
	sBadOption,		/* == unknown option */
505
	sBadOption,		/* == unknown option */
Lines 502-508 typedef enum { Link Here
502
	sAcceptEnv, sSetEnv, sPermitTunnel,
529
	sAcceptEnv, sSetEnv, sPermitTunnel,
503
	sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
530
	sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
504
	sUsePrivilegeSeparation, sAllowAgentForwarding,
531
	sUsePrivilegeSeparation, sAllowAgentForwarding,
505
	sHostCertificate,
532
	sHostCertificate, sInclude,
506
	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
533
	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
507
	sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
534
	sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
508
	sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum,
535
	sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum,
Lines 518-523 typedef enum { Link Here
518
#define SSHCFG_MATCH	0x02	/* allowed inside a Match section */
545
#define SSHCFG_MATCH	0x02	/* allowed inside a Match section */
519
#define SSHCFG_ALL	(SSHCFG_GLOBAL|SSHCFG_MATCH)
546
#define SSHCFG_ALL	(SSHCFG_GLOBAL|SSHCFG_MATCH)
520
547
548
#define SSHCFG_NEVERMATCH 0x04  /* Match/Host never matches; internal only */
549
521
/* Textual representation of the tokens. */
550
/* Textual representation of the tokens. */
522
static struct {
551
static struct {
523
	const char *name;
552
	const char *name;
Lines 644-649 static struct { Link Here
644
	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
673
	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
645
	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
674
	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
646
	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
675
	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
676
	{ "include", sInclude, SSHCFG_ALL },
647
	{ "ipqos", sIPQoS, SSHCFG_ALL },
677
	{ "ipqos", sIPQoS, SSHCFG_ALL },
648
	{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
678
	{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
649
	{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
679
	{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
Lines 1217-1226 static const struct multistate multistate_tcpfwd[] = { Link Here
1217
int
1247
int
1218
process_server_config_line(ServerOptions *options, char *line,
1248
process_server_config_line(ServerOptions *options, char *line,
1219
    const char *filename, int linenum, int *activep,
1249
    const char *filename, int linenum, int *activep,
1220
    struct connection_info *connectinfo)
1250
    struct connection_info *connectinfo, struct include_list *includes)
1251
{
1252
	return process_server_config_line_depth(options, line, filename,
1253
	    linenum, activep, connectinfo, 0, 0, includes);
1254
}
1255
1256
int
1257
process_server_config_line_depth(ServerOptions *options, char *line,
1258
    const char *filename, int linenum, int *activep,
1259
    struct connection_info *connectinfo, int inc_flags, int depth,
1260
    struct include_list *includes)
1221
{
1261
{
1222
	char ch, *cp, ***chararrayptr, **charptr, *arg, *arg2, *p;
1262
	char ch, *cp, ***chararrayptr, **charptr, *arg, *arg2, *p;
1223
	int cmdline = 0, *intptr, value, value2, n, port;
1263
	int cmdline = 0, *intptr, value, value2, n, port, oactive;
1224
	SyslogFacility *log_facility_ptr;
1264
	SyslogFacility *log_facility_ptr;
1225
	LogLevel *log_level_ptr;
1265
	LogLevel *log_level_ptr;
1226
	ServerOpCodes opcode;
1266
	ServerOpCodes opcode;
Lines 1229-1234 process_server_config_line(ServerOptions *options, char *line, Link Here
1229
	long long val64;
1269
	long long val64;
1230
	const struct multistate *multistate_ptr;
1270
	const struct multistate *multistate_ptr;
1231
	const char *errstr;
1271
	const char *errstr;
1272
	struct include_item *item;
1273
	int found = 0;
1274
	glob_t gbuf;
1232
1275
1233
	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1276
	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1234
	if ((len = strlen(line)) == 0)
1277
	if ((len = strlen(line)) == 0)
Lines 1255-1261 process_server_config_line(ServerOptions *options, char *line, Link Here
1255
		cmdline = 1;
1298
		cmdline = 1;
1256
		activep = &cmdline;
1299
		activep = &cmdline;
1257
	}
1300
	}
1258
	if (*activep && opcode != sMatch)
1301
	if (*activep && opcode != sMatch && opcode != sInclude)
1259
		debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
1302
		debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
1260
	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
1303
	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
1261
		if (connectinfo == NULL) {
1304
		if (connectinfo == NULL) {
Lines 1906-1911 process_server_config_line(ServerOptions *options, char *line, Link Here
1906
			*intptr = value;
1949
			*intptr = value;
1907
		break;
1950
		break;
1908
1951
1952
	case sInclude:
1953
		if (cmdline)
1954
			fatal("Include directive not supported as a command-line "
1955
			   "option");
1956
1957
		value = 0;
1958
		while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1959
			value++;
1960
			found = 0;
1961
			if (*arg != '/' && *arg != '~') {
1962
				xasprintf(&arg2, "%s/%s",
1963
				    SSHDIR, arg);
1964
			} else
1965
				arg2 = xstrdup(arg);
1966
1967
			/*
1968
			 * don't let the Match in Included clobber
1969
			 * the containing file's Match state.
1970
			 */
1971
			oactive = *activep;
1972
			/* browse cached list of files */
1973
			for (item = includes->start; item != NULL; item = item->next) {
1974
				if (strcmp(item->selector, arg2) == 0) {
1975
					if (item->filename != NULL)
1976
						parse_server_config_depth(options,
1977
						    item->filename, item->buffer,
1978
						    includes, connectinfo,
1979
						    (oactive ? 0 : SSHCFG_NEVERMATCH),
1980
						    activep, depth + 1);
1981
					found = 1;
1982
					*activep = oactive;
1983
				}
1984
			}
1985
			if (found != 0) {
1986
				free(arg2);
1987
				continue;
1988
			}
1989
1990
			/* not in cache, a new glob */
1991
			debug3("Glob configuration file to include %s", arg2);
1992
			if (glob(arg2, 0, NULL, &gbuf) == 0) {
1993
				for (n = 0; n < gbuf.gl_pathc; n++) {
1994
					debug3("Including configuration file %s",
1995
						gbuf.gl_pathv[n]);
1996
					item = malloc(sizeof(struct include_item));
1997
					item->selector = strdup(arg2);
1998
					item->filename = strdup(gbuf.gl_pathv[n]);
1999
					item->buffer = sshbuf_new();
2000
					load_server_config(item->filename,
2001
					    item->buffer);
2002
					parse_server_config_depth(options,
2003
					    item->filename, item->buffer,
2004
					    includes, connectinfo,
2005
					    (oactive ? 0 : SSHCFG_NEVERMATCH),
2006
					    activep, depth + 1);
2007
2008
					/* append item to the end of the list */
2009
					INCLUDE_LIST_APPEND(includes, item);
2010
					*activep = oactive;
2011
				}
2012
			} else { /* no match or other error */
2013
				/* store placeholder to avoid aditional empty globs */
2014
				item = malloc(sizeof(struct include_item));
2015
				item->selector = strdup(arg2);
2016
				item->filename = NULL;
2017
				item->buffer = sshbuf_new();
2018
				/* append item to the end of the list */
2019
				INCLUDE_LIST_APPEND(includes, item);
2020
			}
2021
			globfree(&gbuf);
2022
			free(arg2);
2023
		}
2024
		if (value == 0)
2025
			fatal("%s line %d: missing argument - file to include",
2026
			    filename, linenum);
2027
		break;
2028
1909
	case sMatch:
2029
	case sMatch:
1910
		if (cmdline)
2030
		if (cmdline)
1911
			fatal("Match directive not supported as a command-line "
2031
			fatal("Match directive not supported as a command-line "
Lines 1914-1920 process_server_config_line(ServerOptions *options, char *line, Link Here
1914
		if (value < 0)
2034
		if (value < 0)
1915
			fatal("%s line %d: Bad Match condition", filename,
2035
			fatal("%s line %d: Bad Match condition", filename,
1916
			    linenum);
2036
			    linenum);
1917
		*activep = value;
2037
		*activep = (inc_flags & SSHCFG_NEVERMATCH) ? 0 : value;
1918
		break;
2038
		break;
1919
2039
1920
	case sPermitListen:
2040
	case sPermitListen:
Lines 2231-2242 load_server_config(const char *filename, struct sshbuf *conf) Link Here
2231
2351
2232
void
2352
void
2233
parse_server_match_config(ServerOptions *options,
2353
parse_server_match_config(ServerOptions *options,
2234
   struct connection_info *connectinfo)
2354
   struct include_list *includes, struct connection_info *connectinfo)
2235
{
2355
{
2236
	ServerOptions mo;
2356
	ServerOptions mo;
2237
2357
2238
	initialize_server_options(&mo);
2358
	initialize_server_options(&mo);
2239
	parse_server_config(&mo, "reprocess config", cfg, connectinfo);
2359
	parse_server_config(&mo, "reprocess config", cfg, includes,
2360
	    connectinfo);
2240
	copy_set_server_options(options, &mo, 0);
2361
	copy_set_server_options(options, &mo, 0);
2241
}
2362
}
2242
2363
Lines 2381-2400 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) Link Here
2381
2502
2382
void
2503
void
2383
parse_server_config(ServerOptions *options, const char *filename,
2504
parse_server_config(ServerOptions *options, const char *filename,
2384
    struct sshbuf *conf, struct connection_info *connectinfo)
2505
    struct sshbuf *conf, struct include_list *includes,
2506
    struct connection_info *connectinfo)
2507
{
2508
	int active = connectinfo ? 0 : 1;
2509
	parse_server_config_depth(options, filename, conf, includes,
2510
	    connectinfo, 0, &active, 0);
2511
}
2512
2513
#define SERVCONF_MAX_DEPTH	16
2514
2515
void
2516
parse_server_config_depth(ServerOptions *options, const char *filename,
2517
    struct sshbuf *conf, struct include_list *includes,
2518
    struct connection_info *connectinfo, int flags, int *activep, int depth)
2385
{
2519
{
2386
	int active, linenum, bad_options = 0;
2520
	int linenum, bad_options = 0;
2387
	char *cp, *obuf, *cbuf;
2521
	char *cp, *obuf, *cbuf;
2388
2522
2523
	if (depth < 0 || depth > SERVCONF_MAX_DEPTH)
2524
		fatal("Too many recursive configuration includes");
2525
2389
	debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf));
2526
	debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf));
2390
2527
2391
	if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
2528
	if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
2392
		fatal("%s: sshbuf_dup_string failed", __func__);
2529
		fatal("%s: sshbuf_dup_string failed", __func__);
2393
	active = connectinfo ? 0 : 1;
2394
	linenum = 1;
2530
	linenum = 1;
2395
	while ((cp = strsep(&cbuf, "\n")) != NULL) {
2531
	while ((cp = strsep(&cbuf, "\n")) != NULL) {
2396
		if (process_server_config_line(options, cp, filename,
2532
		if (process_server_config_line_depth(options, cp, filename,
2397
		    linenum++, &active, connectinfo) != 0)
2533
		    linenum++, activep, connectinfo, flags, depth, includes) != 0)
2398
			bad_options++;
2534
			bad_options++;
2399
	}
2535
	}
2400
	free(obuf);
2536
	free(obuf);
(-)a/servconf.h (-3 / +17 lines)
Lines 223-228 struct connection_info { Link Here
223
	const char *rdomain;	/* routing domain if available */
223
	const char *rdomain;	/* routing domain if available */
224
};
224
};
225
225
226
/* List of included files for re-exec from the parsed configuration */
227
struct include_item {
228
	char *selector;
229
	char *filename;
230
	struct sshbuf *buffer;
231
	struct include_item *next;
232
};
233
struct include_list {
234
	u_int16_t count;
235
	struct include_item *start;
236
	struct include_item *end;
237
};
238
226
239
227
/*
240
/*
228
 * These are string config options that must be copied between the
241
 * These are string config options that must be copied between the
Lines 262-273 struct connection_info *get_connection_info(struct ssh *, int, int); Link Here
262
void	 initialize_server_options(ServerOptions *);
275
void	 initialize_server_options(ServerOptions *);
263
void	 fill_default_server_options(ServerOptions *);
276
void	 fill_default_server_options(ServerOptions *);
264
int	 process_server_config_line(ServerOptions *, char *, const char *, int,
277
int	 process_server_config_line(ServerOptions *, char *, const char *, int,
265
	     int *, struct connection_info *);
278
	     int *, struct connection_info *, struct include_list *includes);
266
void	 process_permitopen(struct ssh *ssh, ServerOptions *options);
279
void	 process_permitopen(struct ssh *ssh, ServerOptions *options);
267
void	 load_server_config(const char *, struct sshbuf *);
280
void	 load_server_config(const char *, struct sshbuf *);
268
void	 parse_server_config(ServerOptions *, const char *, struct sshbuf *,
281
void	 parse_server_config(ServerOptions *, const char *, struct sshbuf *,
269
	     struct connection_info *);
282
	     struct include_list *includes, struct connection_info *);
270
void	 parse_server_match_config(ServerOptions *, struct connection_info *);
283
void	 parse_server_match_config(ServerOptions *,
284
	     struct include_list *includes, struct connection_info *);
271
int	 parse_server_match_testspec(struct connection_info *, char *);
285
int	 parse_server_match_testspec(struct connection_info *, char *);
272
int	 server_match_spec_complete(struct connection_info *);
286
int	 server_match_spec_complete(struct connection_info *);
273
void	 copy_set_server_options(ServerOptions *, ServerOptions *, int);
287
void	 copy_set_server_options(ServerOptions *, ServerOptions *, int);
(-)a/sshd.c (-5 / +40 lines)
Lines 250-255 struct sshauthopt *auth_opts = NULL; Link Here
250
/* sshd_config buffer */
250
/* sshd_config buffer */
251
struct sshbuf *cfg;
251
struct sshbuf *cfg;
252
252
253
/* Included files from the configuration file */
254
struct include_list includes = {
255
	.count = 0,
256
	.start = NULL,
257
	.end = NULL,
258
};
259
253
/* message to be displayed after login */
260
/* message to be displayed after login */
254
struct sshbuf *loginmsg;
261
struct sshbuf *loginmsg;
255
262
Lines 852-858 usage(void) Link Here
852
static void
859
static void
853
send_rexec_state(int fd, struct sshbuf *conf)
860
send_rexec_state(int fd, struct sshbuf *conf)
854
{
861
{
855
	struct sshbuf *m;
862
	struct sshbuf *m = NULL;
863
	struct include_item *item = NULL;
856
	int r;
864
	int r;
857
865
858
	debug3("%s: entering fd = %d config len %zu", __func__, fd,
866
	debug3("%s: entering fd = %d config len %zu", __func__, fd,
Lines 867-872 send_rexec_state(int fd, struct sshbuf *conf) Link Here
867
		fatal("%s: sshbuf_new failed", __func__);
875
		fatal("%s: sshbuf_new failed", __func__);
868
	if ((r = sshbuf_put_stringb(m, conf)) != 0)
876
	if ((r = sshbuf_put_stringb(m, conf)) != 0)
869
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
877
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
878
	if ((r = sshbuf_put_u16(m, includes.count)) != 0)
879
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
880
	for (item = includes.start; item != NULL; item = item->next) {
881
		if ((r = sshbuf_put_cstring(m, item->selector)) != 0 ||
882
		    (r = sshbuf_put_cstring(m, item->filename)) != 0 ||
883
		    (r = sshbuf_put_stringb(m, item->buffer)) != 0)
884
			fatal("%s: buffer error: %s", __func__, ssh_err(r));
885
	}
870
886
871
#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY)
887
#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY)
872
	rexec_send_rng_seed(m);
888
	rexec_send_rng_seed(m);
Lines 886-892 recv_rexec_state(int fd, struct sshbuf *conf) Link Here
886
	struct sshbuf *m;
902
	struct sshbuf *m;
887
	u_char *cp, ver;
903
	u_char *cp, ver;
888
	size_t len;
904
	size_t len;
889
	int r;
905
	int r, i;
890
906
891
	debug3("%s: entering fd = %d", __func__, fd);
907
	debug3("%s: entering fd = %d", __func__, fd);
892
908
Lines 905-910 recv_rexec_state(int fd, struct sshbuf *conf) Link Here
905
#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY)
921
#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY)
906
	rexec_recv_rng_seed(m);
922
	rexec_recv_rng_seed(m);
907
#endif
923
#endif
924
	if ((r = sshbuf_get_u16(m, &includes.count)) != 0)
925
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
926
	for (i = 0; i < includes.count; i++) {
927
		struct include_item *item = calloc(1, sizeof(struct include_item));
928
929
		if (item == NULL)
930
			fatal("%s: Failed to allocate memory.", __func__);
931
		if ((item->buffer = sshbuf_new()) == NULL)
932
			fatal("%s: sshbuf_new failed", __func__);
933
		if ((r = sshbuf_get_cstring(m, &item->selector, NULL)) != 0 ||
934
		    (r = sshbuf_get_cstring(m, &item->filename, NULL)) != 0 ||
935
		    (r = sshbuf_get_stringb(m, item->buffer)) != 0)
936
			fatal("%s: buffer error: %s", __func__, ssh_err(r));
937
		if (includes.start == NULL)
938
			includes.start = item;
939
		if (includes.end != NULL)
940
			includes.end->next = item;
941
		includes.end = item;
942
	}
908
943
909
	free(cp);
944
	free(cp);
910
	sshbuf_free(m);
945
	sshbuf_free(m);
Lines 1564-1570 main(int ac, char **av) Link Here
1564
		case 'o':
1599
		case 'o':
1565
			line = xstrdup(optarg);
1600
			line = xstrdup(optarg);
1566
			if (process_server_config_line(&options, line,
1601
			if (process_server_config_line(&options, line,
1567
			    "command-line", 0, NULL, NULL) != 0)
1602
			    "command-line", 0, NULL, NULL, &includes) != 0)
1568
				exit(1);
1603
				exit(1);
1569
			free(line);
1604
			free(line);
1570
			break;
1605
			break;
Lines 1633-1639 main(int ac, char **av) Link Here
1633
		load_server_config(config_file_name, cfg);
1668
		load_server_config(config_file_name, cfg);
1634
1669
1635
	parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
1670
	parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
1636
	    cfg, NULL);
1671
	    cfg, &includes, NULL);
1637
1672
1638
	/* Fill in default values for those options not explicitly set. */
1673
	/* Fill in default values for those options not explicitly set. */
1639
	fill_default_server_options(&options);
1674
	fill_default_server_options(&options);
Lines 1843-1849 main(int ac, char **av) Link Here
1843
		 */
1878
		 */
1844
		if (connection_info == NULL)
1879
		if (connection_info == NULL)
1845
			connection_info = get_connection_info(ssh, 0, 0);
1880
			connection_info = get_connection_info(ssh, 0, 0);
1846
		parse_server_match_config(&options, connection_info);
1881
		parse_server_match_config(&options, &includes, connection_info);
1847
		dump_config(&options);
1882
		dump_config(&options);
1848
	}
1883
	}
1849
1884
(-)a/sshd_config.5 (-1 / +13 lines)
Lines 794-800 during Link Here
794
and use only the system-wide known hosts file
794
and use only the system-wide known hosts file
795
.Pa /etc/ssh/known_hosts .
795
.Pa /etc/ssh/known_hosts .
796
The default is
796
The default is
797
.Cm no .
797
.Dq no .
798
.It Cm Include
799
Include the specified configuration file(s).
800
Multiple path names may be specified and each pathname may contain
801
.Xr glob 7
802
wildcards.
803
Files without absolute paths are assumed to be in
804
.Pa /etc/ssh .
805
.Cm Include
806
directive may appear inside a
807
.Cm Match
808
block
809
to perform conditional inclusion.
798
.It Cm IPQoS
810
.It Cm IPQoS
799
Specifies the IPv4 type-of-service or DSCP class for the connection.
811
Specifies the IPv4 type-of-service or DSCP class for the connection.
800
Accepted values are
812
Accepted values are

Return to bug 2468