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