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