xref: /openbsd-src/usr.bin/ssh/servconf.c (revision daf88648c0e349d5c02e1504293082072c981640)
1 /* $OpenBSD: servconf.c,v 1.167 2006/12/14 10:01:14 dtucker Exp $ */
2 /*
3  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4  *                    All rights reserved
5  *
6  * As far as I am concerned, the code I have written for this software
7  * can be used freely for any purpose.  Any derived versions of this
8  * software must be clearly marked as such, and if the derived work is
9  * incompatible with the protocol description in the RFC file, it must be
10  * called by a name other than "ssh" or "Secure Shell".
11  */
12 
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 
16 #include <netdb.h>
17 #include <pwd.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <signal.h>
22 #include <unistd.h>
23 #include <stdarg.h>
24 
25 #include "xmalloc.h"
26 #include "ssh.h"
27 #include "log.h"
28 #include "buffer.h"
29 #include "servconf.h"
30 #include "compat.h"
31 #include "pathnames.h"
32 #include "misc.h"
33 #include "cipher.h"
34 #include "key.h"
35 #include "kex.h"
36 #include "mac.h"
37 #include "match.h"
38 #include "channels.h"
39 #include "groupaccess.h"
40 
41 static void add_listen_addr(ServerOptions *, char *, u_short);
42 static void add_one_listen_addr(ServerOptions *, char *, u_short);
43 
44 /* Use of privilege separation or not */
45 extern int use_privsep;
46 extern Buffer cfg;
47 
48 /* Initializes the server options to their default values. */
49 
50 void
51 initialize_server_options(ServerOptions *options)
52 {
53 	memset(options, 0, sizeof(*options));
54 	options->num_ports = 0;
55 	options->ports_from_cmdline = 0;
56 	options->listen_addrs = NULL;
57 	options->address_family = -1;
58 	options->num_host_key_files = 0;
59 	options->pid_file = NULL;
60 	options->server_key_bits = -1;
61 	options->login_grace_time = -1;
62 	options->key_regeneration_time = -1;
63 	options->permit_root_login = PERMIT_NOT_SET;
64 	options->ignore_rhosts = -1;
65 	options->ignore_user_known_hosts = -1;
66 	options->print_motd = -1;
67 	options->print_lastlog = -1;
68 	options->x11_forwarding = -1;
69 	options->x11_display_offset = -1;
70 	options->x11_use_localhost = -1;
71 	options->xauth_location = NULL;
72 	options->strict_modes = -1;
73 	options->tcp_keep_alive = -1;
74 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
75 	options->log_level = SYSLOG_LEVEL_NOT_SET;
76 	options->rhosts_rsa_authentication = -1;
77 	options->hostbased_authentication = -1;
78 	options->hostbased_uses_name_from_packet_only = -1;
79 	options->rsa_authentication = -1;
80 	options->pubkey_authentication = -1;
81 	options->kerberos_authentication = -1;
82 	options->kerberos_or_local_passwd = -1;
83 	options->kerberos_ticket_cleanup = -1;
84 	options->kerberos_get_afs_token = -1;
85 	options->gss_authentication=-1;
86 	options->gss_cleanup_creds = -1;
87 	options->password_authentication = -1;
88 	options->kbd_interactive_authentication = -1;
89 	options->challenge_response_authentication = -1;
90 	options->permit_empty_passwd = -1;
91 	options->permit_user_env = -1;
92 	options->use_login = -1;
93 	options->compression = -1;
94 	options->allow_tcp_forwarding = -1;
95 	options->num_allow_users = 0;
96 	options->num_deny_users = 0;
97 	options->num_allow_groups = 0;
98 	options->num_deny_groups = 0;
99 	options->ciphers = NULL;
100 	options->macs = NULL;
101 	options->protocol = SSH_PROTO_UNKNOWN;
102 	options->gateway_ports = -1;
103 	options->num_subsystems = 0;
104 	options->max_startups_begin = -1;
105 	options->max_startups_rate = -1;
106 	options->max_startups = -1;
107 	options->max_authtries = -1;
108 	options->banner = NULL;
109 	options->use_dns = -1;
110 	options->client_alive_interval = -1;
111 	options->client_alive_count_max = -1;
112 	options->authorized_keys_file = NULL;
113 	options->authorized_keys_file2 = NULL;
114 	options->num_accept_env = 0;
115 	options->permit_tun = -1;
116 	options->num_permitted_opens = -1;
117 	options->adm_forced_command = NULL;
118 }
119 
120 void
121 fill_default_server_options(ServerOptions *options)
122 {
123 	if (options->protocol == SSH_PROTO_UNKNOWN)
124 		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
125 	if (options->num_host_key_files == 0) {
126 		/* fill default hostkeys for protocols */
127 		if (options->protocol & SSH_PROTO_1)
128 			options->host_key_files[options->num_host_key_files++] =
129 			    _PATH_HOST_KEY_FILE;
130 		if (options->protocol & SSH_PROTO_2) {
131 			options->host_key_files[options->num_host_key_files++] =
132 			    _PATH_HOST_RSA_KEY_FILE;
133 			options->host_key_files[options->num_host_key_files++] =
134 			    _PATH_HOST_DSA_KEY_FILE;
135 		}
136 	}
137 	if (options->num_ports == 0)
138 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
139 	if (options->listen_addrs == NULL)
140 		add_listen_addr(options, NULL, 0);
141 	if (options->pid_file == NULL)
142 		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
143 	if (options->server_key_bits == -1)
144 		options->server_key_bits = 768;
145 	if (options->login_grace_time == -1)
146 		options->login_grace_time = 120;
147 	if (options->key_regeneration_time == -1)
148 		options->key_regeneration_time = 3600;
149 	if (options->permit_root_login == PERMIT_NOT_SET)
150 		options->permit_root_login = PERMIT_YES;
151 	if (options->ignore_rhosts == -1)
152 		options->ignore_rhosts = 1;
153 	if (options->ignore_user_known_hosts == -1)
154 		options->ignore_user_known_hosts = 0;
155 	if (options->print_motd == -1)
156 		options->print_motd = 1;
157 	if (options->print_lastlog == -1)
158 		options->print_lastlog = 1;
159 	if (options->x11_forwarding == -1)
160 		options->x11_forwarding = 0;
161 	if (options->x11_display_offset == -1)
162 		options->x11_display_offset = 10;
163 	if (options->x11_use_localhost == -1)
164 		options->x11_use_localhost = 1;
165 	if (options->xauth_location == NULL)
166 		options->xauth_location = _PATH_XAUTH;
167 	if (options->strict_modes == -1)
168 		options->strict_modes = 1;
169 	if (options->tcp_keep_alive == -1)
170 		options->tcp_keep_alive = 1;
171 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
172 		options->log_facility = SYSLOG_FACILITY_AUTH;
173 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
174 		options->log_level = SYSLOG_LEVEL_INFO;
175 	if (options->rhosts_rsa_authentication == -1)
176 		options->rhosts_rsa_authentication = 0;
177 	if (options->hostbased_authentication == -1)
178 		options->hostbased_authentication = 0;
179 	if (options->hostbased_uses_name_from_packet_only == -1)
180 		options->hostbased_uses_name_from_packet_only = 0;
181 	if (options->rsa_authentication == -1)
182 		options->rsa_authentication = 1;
183 	if (options->pubkey_authentication == -1)
184 		options->pubkey_authentication = 1;
185 	if (options->kerberos_authentication == -1)
186 		options->kerberos_authentication = 0;
187 	if (options->kerberos_or_local_passwd == -1)
188 		options->kerberos_or_local_passwd = 1;
189 	if (options->kerberos_ticket_cleanup == -1)
190 		options->kerberos_ticket_cleanup = 1;
191 	if (options->kerberos_get_afs_token == -1)
192 		options->kerberos_get_afs_token = 0;
193 	if (options->gss_authentication == -1)
194 		options->gss_authentication = 0;
195 	if (options->gss_cleanup_creds == -1)
196 		options->gss_cleanup_creds = 1;
197 	if (options->password_authentication == -1)
198 		options->password_authentication = 1;
199 	if (options->kbd_interactive_authentication == -1)
200 		options->kbd_interactive_authentication = 0;
201 	if (options->challenge_response_authentication == -1)
202 		options->challenge_response_authentication = 1;
203 	if (options->permit_empty_passwd == -1)
204 		options->permit_empty_passwd = 0;
205 	if (options->permit_user_env == -1)
206 		options->permit_user_env = 0;
207 	if (options->use_login == -1)
208 		options->use_login = 0;
209 	if (options->compression == -1)
210 		options->compression = COMP_DELAYED;
211 	if (options->allow_tcp_forwarding == -1)
212 		options->allow_tcp_forwarding = 1;
213 	if (options->gateway_ports == -1)
214 		options->gateway_ports = 0;
215 	if (options->max_startups == -1)
216 		options->max_startups = 10;
217 	if (options->max_startups_rate == -1)
218 		options->max_startups_rate = 100;		/* 100% */
219 	if (options->max_startups_begin == -1)
220 		options->max_startups_begin = options->max_startups;
221 	if (options->max_authtries == -1)
222 		options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
223 	if (options->use_dns == -1)
224 		options->use_dns = 1;
225 	if (options->client_alive_interval == -1)
226 		options->client_alive_interval = 0;
227 	if (options->client_alive_count_max == -1)
228 		options->client_alive_count_max = 3;
229 	if (options->authorized_keys_file2 == NULL) {
230 		/* authorized_keys_file2 falls back to authorized_keys_file */
231 		if (options->authorized_keys_file != NULL)
232 			options->authorized_keys_file2 = options->authorized_keys_file;
233 		else
234 			options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
235 	}
236 	if (options->authorized_keys_file == NULL)
237 		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
238 	if (options->permit_tun == -1)
239 		options->permit_tun = SSH_TUNMODE_NO;
240 
241 	/* Turn privilege separation on by default */
242 	if (use_privsep == -1)
243 		use_privsep = 1;
244 }
245 
246 /* Keyword tokens. */
247 typedef enum {
248 	sBadOption,		/* == unknown option */
249 	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
250 	sPermitRootLogin, sLogFacility, sLogLevel,
251 	sRhostsRSAAuthentication, sRSAAuthentication,
252 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
253 	sKerberosGetAFSToken,
254 	sKerberosTgtPassing, sChallengeResponseAuthentication,
255 	sPasswordAuthentication, sKbdInteractiveAuthentication,
256 	sListenAddress, sAddressFamily,
257 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
258 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
259 	sStrictModes, sEmptyPasswd, sTCPKeepAlive,
260 	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
261 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
262 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
263 	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
264 	sMaxStartups, sMaxAuthTries,
265 	sBanner, sUseDNS, sHostbasedAuthentication,
266 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
267 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
268 	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
269 	sMatch, sPermitOpen, sForceCommand,
270 	sUsePrivilegeSeparation,
271 	sDeprecated, sUnsupported
272 } ServerOpCodes;
273 
274 #define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
275 #define SSHCFG_MATCH	0x02	/* allowed inside a Match section */
276 #define SSHCFG_ALL	(SSHCFG_GLOBAL|SSHCFG_MATCH)
277 
278 /* Textual representation of the tokens. */
279 static struct {
280 	const char *name;
281 	ServerOpCodes opcode;
282 	u_int flags;
283 } keywords[] = {
284 	{ "port", sPort, SSHCFG_GLOBAL },
285 	{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
286 	{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },		/* alias */
287 	{ "pidfile", sPidFile, SSHCFG_GLOBAL },
288 	{ "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
289 	{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
290 	{ "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
291 	{ "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
292 	{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
293 	{ "loglevel", sLogLevel, SSHCFG_GLOBAL },
294 	{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
295 	{ "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
296 	{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
297 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
298 	{ "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
299 	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
300 	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
301 #ifdef KRB5
302 	{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
303 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
304 	{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
305 	{ "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
306 #else
307 	{ "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
308 	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
309 	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
310 	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
311 #endif
312 	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
313 	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
314 #ifdef GSSAPI
315 	{ "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
316 	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
317 #else
318 	{ "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
319 	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
320 #endif
321 	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
322 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
323 	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
324 	{ "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
325 	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
326 	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
327 	{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
328 	{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
329 	{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
330 	{ "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
331 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
332 	{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
333 	{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
334 	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
335 	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
336 	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
337 	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
338 	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
339 	{ "uselogin", sUseLogin, SSHCFG_GLOBAL },
340 	{ "compression", sCompression, SSHCFG_GLOBAL },
341 	{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
342 	{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },	/* obsolete alias */
343 	{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
344 	{ "allowusers", sAllowUsers, SSHCFG_GLOBAL },
345 	{ "denyusers", sDenyUsers, SSHCFG_GLOBAL },
346 	{ "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
347 	{ "denygroups", sDenyGroups, SSHCFG_GLOBAL },
348 	{ "ciphers", sCiphers, SSHCFG_GLOBAL },
349 	{ "macs", sMacs, SSHCFG_GLOBAL },
350 	{ "protocol", sProtocol, SSHCFG_GLOBAL },
351 	{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
352 	{ "subsystem", sSubsystem, SSHCFG_GLOBAL },
353 	{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
354 	{ "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
355 	{ "banner", sBanner, SSHCFG_GLOBAL },
356 	{ "usedns", sUseDNS, SSHCFG_GLOBAL },
357 	{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
358 	{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
359 	{ "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
360 	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
361 	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
362 	{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
363 	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
364 	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
365 	{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
366 	{ "match", sMatch, SSHCFG_ALL },
367 	{ "permitopen", sPermitOpen, SSHCFG_ALL },
368 	{ "forcecommand", sForceCommand, SSHCFG_ALL },
369 	{ NULL, sBadOption, 0 }
370 };
371 
372 /*
373  * Returns the number of the token pointed to by cp or sBadOption.
374  */
375 
376 static ServerOpCodes
377 parse_token(const char *cp, const char *filename,
378 	    int linenum, u_int *flags)
379 {
380 	u_int i;
381 
382 	for (i = 0; keywords[i].name; i++)
383 		if (strcasecmp(cp, keywords[i].name) == 0) {
384 			*flags = keywords[i].flags;
385 			return keywords[i].opcode;
386 		}
387 
388 	error("%s: line %d: Bad configuration option: %s",
389 	    filename, linenum, cp);
390 	return sBadOption;
391 }
392 
393 static void
394 add_listen_addr(ServerOptions *options, char *addr, u_short port)
395 {
396 	u_int i;
397 
398 	if (options->num_ports == 0)
399 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
400 	if (options->address_family == -1)
401 		options->address_family = AF_UNSPEC;
402 	if (port == 0)
403 		for (i = 0; i < options->num_ports; i++)
404 			add_one_listen_addr(options, addr, options->ports[i]);
405 	else
406 		add_one_listen_addr(options, addr, port);
407 }
408 
409 static void
410 add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
411 {
412 	struct addrinfo hints, *ai, *aitop;
413 	char strport[NI_MAXSERV];
414 	int gaierr;
415 
416 	memset(&hints, 0, sizeof(hints));
417 	hints.ai_family = options->address_family;
418 	hints.ai_socktype = SOCK_STREAM;
419 	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
420 	snprintf(strport, sizeof strport, "%u", port);
421 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
422 		fatal("bad addr or host: %s (%s)",
423 		    addr ? addr : "<NULL>",
424 		    gai_strerror(gaierr));
425 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
426 		;
427 	ai->ai_next = options->listen_addrs;
428 	options->listen_addrs = aitop;
429 }
430 
431 /*
432  * The strategy for the Match blocks is that the config file is parsed twice.
433  *
434  * The first time is at startup.  activep is initialized to 1 and the
435  * directives in the global context are processed and acted on.  Hitting a
436  * Match directive unsets activep and the directives inside the block are
437  * checked for syntax only.
438  *
439  * The second time is after a connection has been established but before
440  * authentication.  activep is initialized to 2 and global config directives
441  * are ignored since they have already been processed.  If the criteria in a
442  * Match block is met, activep is set and the subsequent directives
443  * processed and actioned until EOF or another Match block unsets it.  Any
444  * options set are copied into the main server config.
445  *
446  * Potential additions/improvements:
447  *  - Add Match support for pre-kex directives, eg Protocol, Ciphers.
448  *
449  *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
450  *	Match Address 192.168.0.*
451  *		Tag trusted
452  *	Match Group wheel
453  *		Tag trusted
454  *	Match Tag trusted
455  *		AllowTcpForwarding yes
456  *		GatewayPorts clientspecified
457  *		[...]
458  *
459  *  - Add a PermittedChannelRequests directive
460  *	Match Group shell
461  *		PermittedChannelRequests session,forwarded-tcpip
462  */
463 
464 static int
465 match_cfg_line_group(const char *grps, int line, const char *user)
466 {
467 	int result = 0;
468 	u_int ngrps = 0;
469 	char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
470 	struct passwd *pw;
471 
472 	/*
473 	 * Even if we do not have a user yet, we still need to check for
474 	 * valid syntax.
475 	 */
476 	arg = cp = xstrdup(grps);
477 	while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
478 		if (ngrps >= MAX_MATCH_GROUPS) {
479 			error("line %d: too many groups in Match Group", line);
480 			result = -1;
481 			goto out;
482 		}
483 		grplist[ngrps++] = p;
484 	}
485 
486 	if (user == NULL)
487 		goto out;
488 
489 	if ((pw = getpwnam(user)) == NULL) {
490 		debug("Can't match group at line %d because user %.100s does "
491 		    "not exist", line, user);
492 	} else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
493 		debug("Can't Match group because user %.100s not in any group "
494 		    "at line %d", user, line);
495 	} else if (ga_match(grplist, ngrps) != 1) {
496 		debug("user %.100s does not match group %.100s at line %d",
497 		    user, arg, line);
498 	} else {
499 		debug("user %.100s matched group %.100s at line %d", user,
500 		    arg, line);
501 		result = 1;
502 	}
503 out:
504 	ga_free();
505 	xfree(arg);
506 	return result;
507 }
508 
509 static int
510 match_cfg_line(char **condition, int line, const char *user, const char *host,
511     const char *address)
512 {
513 	int result = 1;
514 	char *arg, *attrib, *cp = *condition;
515 	size_t len;
516 
517 	if (user == NULL)
518 		debug3("checking syntax for 'Match %s'", cp);
519 	else
520 		debug3("checking match for '%s' user %s host %s addr %s", cp,
521 		    user ? user : "(null)", host ? host : "(null)",
522 		    address ? address : "(null)");
523 
524 	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
525 		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
526 			error("Missing Match criteria for %s", attrib);
527 			return -1;
528 		}
529 		len = strlen(arg);
530 		if (strcasecmp(attrib, "user") == 0) {
531 			if (!user) {
532 				result = 0;
533 				continue;
534 			}
535 			if (match_pattern_list(user, arg, len, 0) != 1)
536 				result = 0;
537 			else
538 				debug("user %.100s matched 'User %.100s' at "
539 				    "line %d", user, arg, line);
540 		} else if (strcasecmp(attrib, "group") == 0) {
541 			switch (match_cfg_line_group(arg, line, user)) {
542 			case -1:
543 				return -1;
544 			case 0:
545 				result = 0;
546 			}
547 		} else if (strcasecmp(attrib, "host") == 0) {
548 			if (!host) {
549 				result = 0;
550 				continue;
551 			}
552 			if (match_hostname(host, arg, len) != 1)
553 				result = 0;
554 			else
555 				debug("connection from %.100s matched 'Host "
556 				    "%.100s' at line %d", host, arg, line);
557 		} else if (strcasecmp(attrib, "address") == 0) {
558 			debug("address '%s' arg '%s'", address, arg);
559 			if (!address) {
560 				result = 0;
561 				continue;
562 			}
563 			if (match_hostname(address, arg, len) != 1)
564 				result = 0;
565 			else
566 				debug("connection from %.100s matched 'Address "
567 				    "%.100s' at line %d", address, arg, line);
568 		} else {
569 			error("Unsupported Match attribute %s", attrib);
570 			return -1;
571 		}
572 	}
573 	if (user != NULL)
574 		debug3("match %sfound", result ? "" : "not ");
575 	*condition = cp;
576 	return result;
577 }
578 
579 #define WHITESPACE " \t\r\n"
580 
581 int
582 process_server_config_line(ServerOptions *options, char *line,
583     const char *filename, int linenum, int *activep, const char *user,
584     const char *host, const char *address)
585 {
586 	char *cp, **charptr, *arg, *p;
587 	int cmdline = 0, *intptr, value, n;
588 	ServerOpCodes opcode;
589 	u_short port;
590 	u_int i, flags = 0;
591 	size_t len;
592 
593 	cp = line;
594 	if ((arg = strdelim(&cp)) == NULL)
595 		return 0;
596 	/* Ignore leading whitespace */
597 	if (*arg == '\0')
598 		arg = strdelim(&cp);
599 	if (!arg || !*arg || *arg == '#')
600 		return 0;
601 	intptr = NULL;
602 	charptr = NULL;
603 	opcode = parse_token(arg, filename, linenum, &flags);
604 
605 	if (activep == NULL) { /* We are processing a command line directive */
606 		cmdline = 1;
607 		activep = &cmdline;
608 	}
609 	if (*activep && opcode != sMatch)
610 		debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
611 	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
612 		if (user == NULL) {
613 			fatal("%s line %d: Directive '%s' is not allowed "
614 			    "within a Match block", filename, linenum, arg);
615 		} else { /* this is a directive we have already processed */
616 			while (arg)
617 				arg = strdelim(&cp);
618 			return 0;
619 		}
620 	}
621 
622 	switch (opcode) {
623 	case sBadOption:
624 		return -1;
625 	case sPort:
626 		/* ignore ports from configfile if cmdline specifies ports */
627 		if (options->ports_from_cmdline)
628 			return 0;
629 		if (options->listen_addrs != NULL)
630 			fatal("%s line %d: ports must be specified before "
631 			    "ListenAddress.", filename, linenum);
632 		if (options->num_ports >= MAX_PORTS)
633 			fatal("%s line %d: too many ports.",
634 			    filename, linenum);
635 		arg = strdelim(&cp);
636 		if (!arg || *arg == '\0')
637 			fatal("%s line %d: missing port number.",
638 			    filename, linenum);
639 		options->ports[options->num_ports++] = a2port(arg);
640 		if (options->ports[options->num_ports-1] == 0)
641 			fatal("%s line %d: Badly formatted port number.",
642 			    filename, linenum);
643 		break;
644 
645 	case sServerKeyBits:
646 		intptr = &options->server_key_bits;
647 parse_int:
648 		arg = strdelim(&cp);
649 		if (!arg || *arg == '\0')
650 			fatal("%s line %d: missing integer value.",
651 			    filename, linenum);
652 		value = atoi(arg);
653 		if (*activep && *intptr == -1)
654 			*intptr = value;
655 		break;
656 
657 	case sLoginGraceTime:
658 		intptr = &options->login_grace_time;
659 parse_time:
660 		arg = strdelim(&cp);
661 		if (!arg || *arg == '\0')
662 			fatal("%s line %d: missing time value.",
663 			    filename, linenum);
664 		if ((value = convtime(arg)) == -1)
665 			fatal("%s line %d: invalid time value.",
666 			    filename, linenum);
667 		if (*intptr == -1)
668 			*intptr = value;
669 		break;
670 
671 	case sKeyRegenerationTime:
672 		intptr = &options->key_regeneration_time;
673 		goto parse_time;
674 
675 	case sListenAddress:
676 		arg = strdelim(&cp);
677 		if (arg == NULL || *arg == '\0')
678 			fatal("%s line %d: missing address",
679 			    filename, linenum);
680 		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
681 		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
682 		    && strchr(p+1, ':') != NULL) {
683 			add_listen_addr(options, arg, 0);
684 			break;
685 		}
686 		p = hpdelim(&arg);
687 		if (p == NULL)
688 			fatal("%s line %d: bad address:port usage",
689 			    filename, linenum);
690 		p = cleanhostname(p);
691 		if (arg == NULL)
692 			port = 0;
693 		else if ((port = a2port(arg)) == 0)
694 			fatal("%s line %d: bad port number", filename, linenum);
695 
696 		add_listen_addr(options, p, port);
697 
698 		break;
699 
700 	case sAddressFamily:
701 		arg = strdelim(&cp);
702 		if (!arg || *arg == '\0')
703 			fatal("%s line %d: missing address family.",
704 			    filename, linenum);
705 		intptr = &options->address_family;
706 		if (options->listen_addrs != NULL)
707 			fatal("%s line %d: address family must be specified before "
708 			    "ListenAddress.", filename, linenum);
709 		if (strcasecmp(arg, "inet") == 0)
710 			value = AF_INET;
711 		else if (strcasecmp(arg, "inet6") == 0)
712 			value = AF_INET6;
713 		else if (strcasecmp(arg, "any") == 0)
714 			value = AF_UNSPEC;
715 		else
716 			fatal("%s line %d: unsupported address family \"%s\".",
717 			    filename, linenum, arg);
718 		if (*intptr == -1)
719 			*intptr = value;
720 		break;
721 
722 	case sHostKeyFile:
723 		intptr = &options->num_host_key_files;
724 		if (*intptr >= MAX_HOSTKEYS)
725 			fatal("%s line %d: too many host keys specified (max %d).",
726 			    filename, linenum, MAX_HOSTKEYS);
727 		charptr = &options->host_key_files[*intptr];
728 parse_filename:
729 		arg = strdelim(&cp);
730 		if (!arg || *arg == '\0')
731 			fatal("%s line %d: missing file name.",
732 			    filename, linenum);
733 		if (*activep && *charptr == NULL) {
734 			*charptr = tilde_expand_filename(arg, getuid());
735 			/* increase optional counter */
736 			if (intptr != NULL)
737 				*intptr = *intptr + 1;
738 		}
739 		break;
740 
741 	case sPidFile:
742 		charptr = &options->pid_file;
743 		goto parse_filename;
744 
745 	case sPermitRootLogin:
746 		intptr = &options->permit_root_login;
747 		arg = strdelim(&cp);
748 		if (!arg || *arg == '\0')
749 			fatal("%s line %d: missing yes/"
750 			    "without-password/forced-commands-only/no "
751 			    "argument.", filename, linenum);
752 		value = 0;	/* silence compiler */
753 		if (strcmp(arg, "without-password") == 0)
754 			value = PERMIT_NO_PASSWD;
755 		else if (strcmp(arg, "forced-commands-only") == 0)
756 			value = PERMIT_FORCED_ONLY;
757 		else if (strcmp(arg, "yes") == 0)
758 			value = PERMIT_YES;
759 		else if (strcmp(arg, "no") == 0)
760 			value = PERMIT_NO;
761 		else
762 			fatal("%s line %d: Bad yes/"
763 			    "without-password/forced-commands-only/no "
764 			    "argument: %s", filename, linenum, arg);
765 		if (*intptr == -1)
766 			*intptr = value;
767 		break;
768 
769 	case sIgnoreRhosts:
770 		intptr = &options->ignore_rhosts;
771 parse_flag:
772 		arg = strdelim(&cp);
773 		if (!arg || *arg == '\0')
774 			fatal("%s line %d: missing yes/no argument.",
775 			    filename, linenum);
776 		value = 0;	/* silence compiler */
777 		if (strcmp(arg, "yes") == 0)
778 			value = 1;
779 		else if (strcmp(arg, "no") == 0)
780 			value = 0;
781 		else
782 			fatal("%s line %d: Bad yes/no argument: %s",
783 				filename, linenum, arg);
784 		if (*activep && *intptr == -1)
785 			*intptr = value;
786 		break;
787 
788 	case sIgnoreUserKnownHosts:
789 		intptr = &options->ignore_user_known_hosts;
790 		goto parse_flag;
791 
792 	case sRhostsRSAAuthentication:
793 		intptr = &options->rhosts_rsa_authentication;
794 		goto parse_flag;
795 
796 	case sHostbasedAuthentication:
797 		intptr = &options->hostbased_authentication;
798 		goto parse_flag;
799 
800 	case sHostbasedUsesNameFromPacketOnly:
801 		intptr = &options->hostbased_uses_name_from_packet_only;
802 		goto parse_flag;
803 
804 	case sRSAAuthentication:
805 		intptr = &options->rsa_authentication;
806 		goto parse_flag;
807 
808 	case sPubkeyAuthentication:
809 		intptr = &options->pubkey_authentication;
810 		goto parse_flag;
811 
812 	case sKerberosAuthentication:
813 		intptr = &options->kerberos_authentication;
814 		goto parse_flag;
815 
816 	case sKerberosOrLocalPasswd:
817 		intptr = &options->kerberos_or_local_passwd;
818 		goto parse_flag;
819 
820 	case sKerberosTicketCleanup:
821 		intptr = &options->kerberos_ticket_cleanup;
822 		goto parse_flag;
823 
824 	case sKerberosGetAFSToken:
825 		intptr = &options->kerberos_get_afs_token;
826 		goto parse_flag;
827 
828 	case sGssAuthentication:
829 		intptr = &options->gss_authentication;
830 		goto parse_flag;
831 
832 	case sGssCleanupCreds:
833 		intptr = &options->gss_cleanup_creds;
834 		goto parse_flag;
835 
836 	case sPasswordAuthentication:
837 		intptr = &options->password_authentication;
838 		goto parse_flag;
839 
840 	case sKbdInteractiveAuthentication:
841 		intptr = &options->kbd_interactive_authentication;
842 		goto parse_flag;
843 
844 	case sChallengeResponseAuthentication:
845 		intptr = &options->challenge_response_authentication;
846 		goto parse_flag;
847 
848 	case sPrintMotd:
849 		intptr = &options->print_motd;
850 		goto parse_flag;
851 
852 	case sPrintLastLog:
853 		intptr = &options->print_lastlog;
854 		goto parse_flag;
855 
856 	case sX11Forwarding:
857 		intptr = &options->x11_forwarding;
858 		goto parse_flag;
859 
860 	case sX11DisplayOffset:
861 		intptr = &options->x11_display_offset;
862 		goto parse_int;
863 
864 	case sX11UseLocalhost:
865 		intptr = &options->x11_use_localhost;
866 		goto parse_flag;
867 
868 	case sXAuthLocation:
869 		charptr = &options->xauth_location;
870 		goto parse_filename;
871 
872 	case sStrictModes:
873 		intptr = &options->strict_modes;
874 		goto parse_flag;
875 
876 	case sTCPKeepAlive:
877 		intptr = &options->tcp_keep_alive;
878 		goto parse_flag;
879 
880 	case sEmptyPasswd:
881 		intptr = &options->permit_empty_passwd;
882 		goto parse_flag;
883 
884 	case sPermitUserEnvironment:
885 		intptr = &options->permit_user_env;
886 		goto parse_flag;
887 
888 	case sUseLogin:
889 		intptr = &options->use_login;
890 		goto parse_flag;
891 
892 	case sCompression:
893 		intptr = &options->compression;
894 		arg = strdelim(&cp);
895 		if (!arg || *arg == '\0')
896 			fatal("%s line %d: missing yes/no/delayed "
897 			    "argument.", filename, linenum);
898 		value = 0;	/* silence compiler */
899 		if (strcmp(arg, "delayed") == 0)
900 			value = COMP_DELAYED;
901 		else if (strcmp(arg, "yes") == 0)
902 			value = COMP_ZLIB;
903 		else if (strcmp(arg, "no") == 0)
904 			value = COMP_NONE;
905 		else
906 			fatal("%s line %d: Bad yes/no/delayed "
907 			    "argument: %s", filename, linenum, arg);
908 		if (*intptr == -1)
909 			*intptr = value;
910 		break;
911 
912 	case sGatewayPorts:
913 		intptr = &options->gateway_ports;
914 		arg = strdelim(&cp);
915 		if (!arg || *arg == '\0')
916 			fatal("%s line %d: missing yes/no/clientspecified "
917 			    "argument.", filename, linenum);
918 		value = 0;	/* silence compiler */
919 		if (strcmp(arg, "clientspecified") == 0)
920 			value = 2;
921 		else if (strcmp(arg, "yes") == 0)
922 			value = 1;
923 		else if (strcmp(arg, "no") == 0)
924 			value = 0;
925 		else
926 			fatal("%s line %d: Bad yes/no/clientspecified "
927 			    "argument: %s", filename, linenum, arg);
928 		if (*intptr == -1)
929 			*intptr = value;
930 		break;
931 
932 	case sUseDNS:
933 		intptr = &options->use_dns;
934 		goto parse_flag;
935 
936 	case sLogFacility:
937 		intptr = (int *) &options->log_facility;
938 		arg = strdelim(&cp);
939 		value = log_facility_number(arg);
940 		if (value == SYSLOG_FACILITY_NOT_SET)
941 			fatal("%.200s line %d: unsupported log facility '%s'",
942 			    filename, linenum, arg ? arg : "<NONE>");
943 		if (*intptr == -1)
944 			*intptr = (SyslogFacility) value;
945 		break;
946 
947 	case sLogLevel:
948 		intptr = (int *) &options->log_level;
949 		arg = strdelim(&cp);
950 		value = log_level_number(arg);
951 		if (value == SYSLOG_LEVEL_NOT_SET)
952 			fatal("%.200s line %d: unsupported log level '%s'",
953 			    filename, linenum, arg ? arg : "<NONE>");
954 		if (*intptr == -1)
955 			*intptr = (LogLevel) value;
956 		break;
957 
958 	case sAllowTcpForwarding:
959 		intptr = &options->allow_tcp_forwarding;
960 		goto parse_flag;
961 
962 	case sUsePrivilegeSeparation:
963 		intptr = &use_privsep;
964 		goto parse_flag;
965 
966 	case sAllowUsers:
967 		while ((arg = strdelim(&cp)) && *arg != '\0') {
968 			if (options->num_allow_users >= MAX_ALLOW_USERS)
969 				fatal("%s line %d: too many allow users.",
970 				    filename, linenum);
971 			options->allow_users[options->num_allow_users++] =
972 			    xstrdup(arg);
973 		}
974 		break;
975 
976 	case sDenyUsers:
977 		while ((arg = strdelim(&cp)) && *arg != '\0') {
978 			if (options->num_deny_users >= MAX_DENY_USERS)
979 				fatal("%s line %d: too many deny users.",
980 				    filename, linenum);
981 			options->deny_users[options->num_deny_users++] =
982 			    xstrdup(arg);
983 		}
984 		break;
985 
986 	case sAllowGroups:
987 		while ((arg = strdelim(&cp)) && *arg != '\0') {
988 			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
989 				fatal("%s line %d: too many allow groups.",
990 				    filename, linenum);
991 			options->allow_groups[options->num_allow_groups++] =
992 			    xstrdup(arg);
993 		}
994 		break;
995 
996 	case sDenyGroups:
997 		while ((arg = strdelim(&cp)) && *arg != '\0') {
998 			if (options->num_deny_groups >= MAX_DENY_GROUPS)
999 				fatal("%s line %d: too many deny groups.",
1000 				    filename, linenum);
1001 			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1002 		}
1003 		break;
1004 
1005 	case sCiphers:
1006 		arg = strdelim(&cp);
1007 		if (!arg || *arg == '\0')
1008 			fatal("%s line %d: Missing argument.", filename, linenum);
1009 		if (!ciphers_valid(arg))
1010 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1011 			    filename, linenum, arg ? arg : "<NONE>");
1012 		if (options->ciphers == NULL)
1013 			options->ciphers = xstrdup(arg);
1014 		break;
1015 
1016 	case sMacs:
1017 		arg = strdelim(&cp);
1018 		if (!arg || *arg == '\0')
1019 			fatal("%s line %d: Missing argument.", filename, linenum);
1020 		if (!mac_valid(arg))
1021 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1022 			    filename, linenum, arg ? arg : "<NONE>");
1023 		if (options->macs == NULL)
1024 			options->macs = xstrdup(arg);
1025 		break;
1026 
1027 	case sProtocol:
1028 		intptr = &options->protocol;
1029 		arg = strdelim(&cp);
1030 		if (!arg || *arg == '\0')
1031 			fatal("%s line %d: Missing argument.", filename, linenum);
1032 		value = proto_spec(arg);
1033 		if (value == SSH_PROTO_UNKNOWN)
1034 			fatal("%s line %d: Bad protocol spec '%s'.",
1035 			    filename, linenum, arg ? arg : "<NONE>");
1036 		if (*intptr == SSH_PROTO_UNKNOWN)
1037 			*intptr = value;
1038 		break;
1039 
1040 	case sSubsystem:
1041 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1042 			fatal("%s line %d: too many subsystems defined.",
1043 			    filename, linenum);
1044 		}
1045 		arg = strdelim(&cp);
1046 		if (!arg || *arg == '\0')
1047 			fatal("%s line %d: Missing subsystem name.",
1048 			    filename, linenum);
1049 		if (!*activep) {
1050 			arg = strdelim(&cp);
1051 			break;
1052 		}
1053 		for (i = 0; i < options->num_subsystems; i++)
1054 			if (strcmp(arg, options->subsystem_name[i]) == 0)
1055 				fatal("%s line %d: Subsystem '%s' already defined.",
1056 				    filename, linenum, arg);
1057 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1058 		arg = strdelim(&cp);
1059 		if (!arg || *arg == '\0')
1060 			fatal("%s line %d: Missing subsystem command.",
1061 			    filename, linenum);
1062 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1063 
1064 		/* Collect arguments (separate to executable) */
1065 		p = xstrdup(arg);
1066 		len = strlen(p) + 1;
1067 		while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1068 			len += 1 + strlen(arg);
1069 			p = xrealloc(p, 1, len);
1070 			strlcat(p, " ", len);
1071 			strlcat(p, arg, len);
1072 		}
1073 		options->subsystem_args[options->num_subsystems] = p;
1074 		options->num_subsystems++;
1075 		break;
1076 
1077 	case sMaxStartups:
1078 		arg = strdelim(&cp);
1079 		if (!arg || *arg == '\0')
1080 			fatal("%s line %d: Missing MaxStartups spec.",
1081 			    filename, linenum);
1082 		if ((n = sscanf(arg, "%d:%d:%d",
1083 		    &options->max_startups_begin,
1084 		    &options->max_startups_rate,
1085 		    &options->max_startups)) == 3) {
1086 			if (options->max_startups_begin >
1087 			    options->max_startups ||
1088 			    options->max_startups_rate > 100 ||
1089 			    options->max_startups_rate < 1)
1090 				fatal("%s line %d: Illegal MaxStartups spec.",
1091 				    filename, linenum);
1092 		} else if (n != 1)
1093 			fatal("%s line %d: Illegal MaxStartups spec.",
1094 			    filename, linenum);
1095 		else
1096 			options->max_startups = options->max_startups_begin;
1097 		break;
1098 
1099 	case sMaxAuthTries:
1100 		intptr = &options->max_authtries;
1101 		goto parse_int;
1102 
1103 	case sBanner:
1104 		charptr = &options->banner;
1105 		goto parse_filename;
1106 	/*
1107 	 * These options can contain %X options expanded at
1108 	 * connect time, so that you can specify paths like:
1109 	 *
1110 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
1111 	 */
1112 	case sAuthorizedKeysFile:
1113 	case sAuthorizedKeysFile2:
1114 		charptr = (opcode == sAuthorizedKeysFile) ?
1115 		    &options->authorized_keys_file :
1116 		    &options->authorized_keys_file2;
1117 		goto parse_filename;
1118 
1119 	case sClientAliveInterval:
1120 		intptr = &options->client_alive_interval;
1121 		goto parse_time;
1122 
1123 	case sClientAliveCountMax:
1124 		intptr = &options->client_alive_count_max;
1125 		goto parse_int;
1126 
1127 	case sAcceptEnv:
1128 		while ((arg = strdelim(&cp)) && *arg != '\0') {
1129 			if (strchr(arg, '=') != NULL)
1130 				fatal("%s line %d: Invalid environment name.",
1131 				    filename, linenum);
1132 			if (options->num_accept_env >= MAX_ACCEPT_ENV)
1133 				fatal("%s line %d: too many allow env.",
1134 				    filename, linenum);
1135 			if (!*activep)
1136 				break;
1137 			options->accept_env[options->num_accept_env++] =
1138 			    xstrdup(arg);
1139 		}
1140 		break;
1141 
1142 	case sPermitTunnel:
1143 		intptr = &options->permit_tun;
1144 		arg = strdelim(&cp);
1145 		if (!arg || *arg == '\0')
1146 			fatal("%s line %d: Missing yes/point-to-point/"
1147 			    "ethernet/no argument.", filename, linenum);
1148 		value = 0;	/* silence compiler */
1149 		if (strcasecmp(arg, "ethernet") == 0)
1150 			value = SSH_TUNMODE_ETHERNET;
1151 		else if (strcasecmp(arg, "point-to-point") == 0)
1152 			value = SSH_TUNMODE_POINTOPOINT;
1153 		else if (strcasecmp(arg, "yes") == 0)
1154 			value = SSH_TUNMODE_YES;
1155 		else if (strcasecmp(arg, "no") == 0)
1156 			value = SSH_TUNMODE_NO;
1157 		else
1158 			fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1159 			    "no argument: %s", filename, linenum, arg);
1160 		if (*intptr == -1)
1161 			*intptr = value;
1162 		break;
1163 
1164 	case sMatch:
1165 		if (cmdline)
1166 			fatal("Match directive not supported as a command-line "
1167 			   "option");
1168 		value = match_cfg_line(&cp, linenum, user, host, address);
1169 		if (value < 0)
1170 			fatal("%s line %d: Bad Match condition", filename,
1171 			    linenum);
1172 		*activep = value;
1173 		break;
1174 
1175 	case sPermitOpen:
1176 		arg = strdelim(&cp);
1177 		if (!arg || *arg == '\0')
1178 			fatal("%s line %d: missing PermitOpen specification",
1179 			    filename, linenum);
1180 		n = options->num_permitted_opens;	/* modified later */
1181 		if (strcmp(arg, "any") == 0) {
1182 			if (*activep && n == -1) {
1183 				channel_clear_adm_permitted_opens();
1184 				options->num_permitted_opens = 0;
1185 			}
1186 			break;
1187 		}
1188 		if (*activep && n == -1)
1189 			channel_clear_adm_permitted_opens();
1190 		for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1191 			p = hpdelim(&arg);
1192 			if (p == NULL)
1193 				fatal("%s line %d: missing host in PermitOpen",
1194 				    filename, linenum);
1195 			p = cleanhostname(p);
1196 			if (arg == NULL || (port = a2port(arg)) == 0)
1197 				fatal("%s line %d: bad port number in "
1198 				    "PermitOpen", filename, linenum);
1199 			if (*activep && n == -1)
1200 				options->num_permitted_opens =
1201 				    channel_add_adm_permitted_opens(p, port);
1202 		}
1203 		break;
1204 
1205 	case sForceCommand:
1206 		if (cp == NULL)
1207 			fatal("%.200s line %d: Missing argument.", filename,
1208 			    linenum);
1209 		len = strspn(cp, WHITESPACE);
1210 		if (*activep && options->adm_forced_command == NULL)
1211 			options->adm_forced_command = xstrdup(cp + len);
1212 		return 0;
1213 
1214 	case sDeprecated:
1215 		logit("%s line %d: Deprecated option %s",
1216 		    filename, linenum, arg);
1217 		while (arg)
1218 		    arg = strdelim(&cp);
1219 		break;
1220 
1221 	case sUnsupported:
1222 		logit("%s line %d: Unsupported option %s",
1223 		    filename, linenum, arg);
1224 		while (arg)
1225 		    arg = strdelim(&cp);
1226 		break;
1227 
1228 	default:
1229 		fatal("%s line %d: Missing handler for opcode %s (%d)",
1230 		    filename, linenum, arg, opcode);
1231 	}
1232 	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1233 		fatal("%s line %d: garbage at end of line; \"%.200s\".",
1234 		    filename, linenum, arg);
1235 	return 0;
1236 }
1237 
1238 /* Reads the server configuration file. */
1239 
1240 void
1241 load_server_config(const char *filename, Buffer *conf)
1242 {
1243 	char line[1024], *cp;
1244 	FILE *f;
1245 
1246 	debug2("%s: filename %s", __func__, filename);
1247 	if ((f = fopen(filename, "r")) == NULL) {
1248 		perror(filename);
1249 		exit(1);
1250 	}
1251 	buffer_clear(conf);
1252 	while (fgets(line, sizeof(line), f)) {
1253 		/*
1254 		 * Trim out comments and strip whitespace
1255 		 * NB - preserve newlines, they are needed to reproduce
1256 		 * line numbers later for error messages
1257 		 */
1258 		if ((cp = strchr(line, '#')) != NULL)
1259 			memcpy(cp, "\n", 2);
1260 		cp = line + strspn(line, " \t\r");
1261 
1262 		buffer_append(conf, cp, strlen(cp));
1263 	}
1264 	buffer_append(conf, "\0", 1);
1265 	fclose(f);
1266 	debug2("%s: done config len = %d", __func__, buffer_len(conf));
1267 }
1268 
1269 void
1270 parse_server_match_config(ServerOptions *options, const char *user,
1271     const char *host, const char *address)
1272 {
1273 	ServerOptions mo;
1274 
1275 	initialize_server_options(&mo);
1276 	parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1277 	copy_set_server_options(options, &mo);
1278 }
1279 
1280 /* Copy any (supported) values that are set */
1281 void
1282 copy_set_server_options(ServerOptions *dst, ServerOptions *src)
1283 {
1284 	if (src->allow_tcp_forwarding != -1)
1285 		dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
1286 	if (src->gateway_ports != -1)
1287 		dst->gateway_ports = src->gateway_ports;
1288 	if (src->adm_forced_command != NULL) {
1289 		if (dst->adm_forced_command != NULL)
1290 			xfree(dst->adm_forced_command);
1291 		dst->adm_forced_command = src->adm_forced_command;
1292 	}
1293 	if (src->x11_display_offset != -1)
1294 		dst->x11_display_offset = src->x11_display_offset;
1295 	if (src->x11_forwarding != -1)
1296 		dst->x11_forwarding = src->x11_forwarding;
1297 	if (src->x11_use_localhost != -1)
1298 		dst->x11_use_localhost = src->x11_use_localhost;
1299 }
1300 
1301 void
1302 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1303     const char *user, const char *host, const char *address)
1304 {
1305 	int active, linenum, bad_options = 0;
1306 	char *cp, *obuf, *cbuf;
1307 
1308 	debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1309 
1310 	obuf = cbuf = xstrdup(buffer_ptr(conf));
1311 	active = user ? 0 : 1;
1312 	linenum = 1;
1313 	while ((cp = strsep(&cbuf, "\n")) != NULL) {
1314 		if (process_server_config_line(options, cp, filename,
1315 		    linenum++, &active, user, host, address) != 0)
1316 			bad_options++;
1317 	}
1318 	xfree(obuf);
1319 	if (bad_options > 0)
1320 		fatal("%s: terminating, %d bad configuration options",
1321 		    filename, bad_options);
1322 }
1323