xref: /titanic_44/usr/src/cmd/ssh/sshd/servconf.c (revision 8339b41da2395f0525c46ceedfeb01961893ec44)
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  */
14 
15 #include "includes.h"
16 RCSID("$OpenBSD: servconf.c,v 1.115 2002/09/04 18:52:42 stevesk Exp $");
17 
18 #ifdef HAVE_DEFOPEN
19 #include <deflt.h>
20 #endif /* HAVE_DEFOPEN */
21 
22 #if defined(KRB4)
23 #include <krb.h>
24 #endif
25 #if defined(KRB5)
26 #ifdef HEIMDAL
27 #include <krb.h>
28 #else
29 /* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V
30  * keytab */
31 #define KEYFILE "/etc/krb5.keytab"
32 #endif
33 #endif
34 #ifdef AFS
35 #include <kafs.h>
36 #endif
37 
38 #include "ssh.h"
39 #include "log.h"
40 #include "buffer.h"
41 #include "servconf.h"
42 #include "xmalloc.h"
43 #include "compat.h"
44 #include "pathnames.h"
45 #include "tildexpand.h"
46 #include "misc.h"
47 #include "cipher.h"
48 #include "kex.h"
49 #include "mac.h"
50 #include "auth.h"
51 #include "match.h"
52 #include "groupaccess.h"
53 
54 static void add_listen_addr(ServerOptions *, char *, u_short);
55 static void add_one_listen_addr(ServerOptions *, char *, u_short);
56 
57 extern Buffer cfg;
58 
59 /* AF_UNSPEC or AF_INET or AF_INET6 */
60 extern int IPv4or6;
61 
62 /*
63  * Initializes the server options to their initial (unset) values. Some of those
64  * that stay unset after the command line options and configuration files are
65  * read are set to their default values in fill_default_server_options().
66  */
67 void
68 initialize_server_options(ServerOptions *options)
69 {
70 	(void) memset(options, 0, sizeof(*options));
71 
72 	/* Portable-specific options */
73 	options->pam_authentication_via_kbd_int = -1;
74 
75 	/* Standard Options */
76 	options->num_ports = 0;
77 	options->ports_from_cmdline = 0;
78 	options->listen_addrs = NULL;
79 	options->num_host_key_files = 0;
80 	options->pid_file = NULL;
81 	options->server_key_bits = -1;
82 	options->login_grace_time = -1;
83 	options->key_regeneration_time = -1;
84 	options->permit_root_login = PERMIT_NOT_SET;
85 	options->ignore_rhosts = -1;
86 	options->ignore_user_known_hosts = -1;
87 	options->print_motd = -1;
88 	options->print_lastlog = -1;
89 	options->x11_forwarding = -1;
90 	options->x11_display_offset = -1;
91 	options->x11_use_localhost = -1;
92 	options->xauth_location = NULL;
93 	options->strict_modes = -1;
94 	options->keepalives = -1;
95 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
96 	options->log_level = SYSLOG_LEVEL_NOT_SET;
97 	options->rhosts_authentication = -1;
98 	options->rhosts_rsa_authentication = -1;
99 	options->hostbased_authentication = -1;
100 	options->hostbased_uses_name_from_packet_only = -1;
101 	options->rsa_authentication = -1;
102 	options->pubkey_authentication = -1;
103 #ifdef GSSAPI
104 	options->gss_authentication = -1;
105 	options->gss_keyex = -1;
106 	options->gss_store_creds = -1;
107 	options->gss_use_session_ccache = -1;
108 	options->gss_cleanup_creds = -1;
109 #endif
110 #if defined(KRB4) || defined(KRB5)
111 	options->kerberos_authentication = -1;
112 	options->kerberos_or_local_passwd = -1;
113 	options->kerberos_ticket_cleanup = -1;
114 #endif
115 #if defined(AFS) || defined(KRB5)
116 	options->kerberos_tgt_passing = -1;
117 #endif
118 #ifdef AFS
119 	options->afs_token_passing = -1;
120 #endif
121 	options->password_authentication = -1;
122 	options->kbd_interactive_authentication = -1;
123 	options->challenge_response_authentication = -1;
124 	options->permit_empty_passwd = -1;
125 	options->permit_user_env = -1;
126 	options->compression = -1;
127 	options->allow_tcp_forwarding = -1;
128 	options->num_allow_users = 0;
129 	options->num_deny_users = 0;
130 	options->num_allow_groups = 0;
131 	options->num_deny_groups = 0;
132 	options->ciphers = NULL;
133 	options->macs = NULL;
134 	options->protocol = SSH_PROTO_UNKNOWN;
135 	options->gateway_ports = -1;
136 	options->num_subsystems = 0;
137 	options->max_startups_begin = -1;
138 	options->max_startups_rate = -1;
139 	options->max_startups = -1;
140 	options->banner = NULL;
141 	options->verify_reverse_mapping = -1;
142 	options->client_alive_interval = -1;
143 	options->client_alive_count_max = -1;
144 	options->authorized_keys_file = NULL;
145 	options->authorized_keys_file2 = NULL;
146 
147 	options->max_auth_tries = -1;
148 	options->max_auth_tries_log = -1;
149 
150 	options->max_init_auth_tries = -1;
151 	options->max_init_auth_tries_log = -1;
152 
153 	options->lookup_client_hostnames = -1;
154 	options->use_openssl_engine = -1;
155 	options->chroot_directory = NULL;
156 	options->pre_userauth_hook = NULL;
157 	options->pam_service_name = NULL;
158 	options->pam_service_prefix = NULL;
159 }
160 
161 #ifdef HAVE_DEFOPEN
162 /*
163  * Reads /etc/default/login and defaults several ServerOptions:
164  *
165  * PermitRootLogin
166  * PermitEmptyPasswords
167  * LoginGraceTime
168  *
169  * CONSOLE=*      -> PermitRootLogin=without-password
170  * #CONSOLE=*     -> PermitRootLogin=yes
171  *
172  * PASSREQ=YES    -> PermitEmptyPasswords=no
173  * PASSREQ=NO     -> PermitEmptyPasswords=yes
174  * #PASSREQ=*     -> PermitEmptyPasswords=no
175  *
176  * TIMEOUT=<secs> -> LoginGraceTime=<secs>
177  * #TIMEOUT=<secs> -> LoginGraceTime=300
178  */
179 static
180 void
181 deflt_fill_default_server_options(ServerOptions *options)
182 {
183 	int	flags;
184 	char	*ptr;
185 
186 	if (defopen(_PATH_DEFAULT_LOGIN))
187 		return;
188 
189 	/* Ignore case */
190 	flags = defcntl(DC_GETFLAGS, 0);
191 	TURNOFF(flags, DC_CASE);
192 	(void) defcntl(DC_SETFLAGS, flags);
193 
194 	if (options->permit_root_login == PERMIT_NOT_SET &&
195 	    (ptr = defread("CONSOLE=")) != NULL)
196 		options->permit_root_login = PERMIT_NO_PASSWD;
197 
198 	if (options->permit_empty_passwd == -1 &&
199 	    (ptr = defread("PASSREQ=")) != NULL) {
200 		if (strcasecmp("YES", ptr) == 0)
201 			options->permit_empty_passwd = 0;
202 		else if (strcasecmp("NO", ptr) == 0)
203 			options->permit_empty_passwd = 1;
204 	}
205 
206 	if (options->max_init_auth_tries == -1 &&
207 	    (ptr = defread("RETRIES=")) != NULL) {
208 		options->max_init_auth_tries = atoi(ptr);
209 	}
210 
211 	if (options->max_init_auth_tries_log == -1 &&
212 	    (ptr = defread("SYSLOG_FAILED_LOGINS=")) != NULL) {
213 		options->max_init_auth_tries_log = atoi(ptr);
214 	}
215 
216 	if (options->login_grace_time == -1) {
217 		if ((ptr = defread("TIMEOUT=")) != NULL)
218 			options->login_grace_time = (unsigned)atoi(ptr);
219 		else
220 			options->login_grace_time = 300;
221 	}
222 
223 	(void) defopen((char *)NULL);
224 }
225 #endif /* HAVE_DEFOPEN */
226 
227 void
228 fill_default_server_options(ServerOptions *options)
229 {
230 
231 #ifdef HAVE_DEFOPEN
232 	deflt_fill_default_server_options(options);
233 #endif /* HAVE_DEFOPEN */
234 
235 	/* Portable-specific options */
236 	if (options->pam_authentication_via_kbd_int == -1)
237 		options->pam_authentication_via_kbd_int = 0;
238 
239 	/* Standard Options */
240 	if (options->protocol == SSH_PROTO_UNKNOWN)
241 		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
242 	if (options->num_host_key_files == 0) {
243 		/* fill default hostkeys for protocols */
244 		if (options->protocol & SSH_PROTO_1)
245 			options->host_key_files[options->num_host_key_files++] =
246 			    _PATH_HOST_KEY_FILE;
247 #ifndef GSSAPI
248 		/* With GSS keyex we can run v2 w/ no host keys */
249 		if (options->protocol & SSH_PROTO_2) {
250 			options->host_key_files[options->num_host_key_files++] =
251 			    _PATH_HOST_RSA_KEY_FILE;
252 			options->host_key_files[options->num_host_key_files++] =
253 			    _PATH_HOST_DSA_KEY_FILE;
254 		}
255 #endif /* GSSAPI */
256 	}
257 	if (options->num_ports == 0)
258 		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
259 	if (options->listen_addrs == NULL)
260 		add_listen_addr(options, NULL, 0);
261 	if (options->pid_file == NULL)
262 		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
263 	if (options->server_key_bits == -1)
264 		options->server_key_bits = 768;
265 	if (options->login_grace_time == -1)
266 		options->login_grace_time = 120;
267 	if (options->key_regeneration_time == -1)
268 		options->key_regeneration_time = 3600;
269 	if (options->permit_root_login == PERMIT_NOT_SET)
270 		options->permit_root_login = PERMIT_YES;
271 	if (options->ignore_rhosts == -1)
272 		options->ignore_rhosts = 1;
273 	if (options->ignore_user_known_hosts == -1)
274 		options->ignore_user_known_hosts = 0;
275 	if (options->print_motd == -1)
276 		options->print_motd = 1;
277 	if (options->print_lastlog == -1)
278 		options->print_lastlog = 1;
279 	if (options->x11_forwarding == -1)
280 		options->x11_forwarding = 1;
281 	if (options->x11_display_offset == -1)
282 		options->x11_display_offset = 10;
283 	if (options->x11_use_localhost == -1)
284 		options->x11_use_localhost = 1;
285 	if (options->xauth_location == NULL)
286 		options->xauth_location = _PATH_XAUTH;
287 	if (options->strict_modes == -1)
288 		options->strict_modes = 1;
289 	if (options->keepalives == -1)
290 		options->keepalives = 1;
291 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
292 		options->log_facility = SYSLOG_FACILITY_AUTH;
293 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
294 		options->log_level = SYSLOG_LEVEL_INFO;
295 	if (options->rhosts_authentication == -1)
296 		options->rhosts_authentication = 0;
297 	if (options->rhosts_rsa_authentication == -1)
298 		options->rhosts_rsa_authentication = 0;
299 	if (options->hostbased_authentication == -1)
300 		options->hostbased_authentication = 0;
301 	if (options->hostbased_uses_name_from_packet_only == -1)
302 		options->hostbased_uses_name_from_packet_only = 0;
303 	if (options->rsa_authentication == -1)
304 		options->rsa_authentication = 1;
305 	if (options->pubkey_authentication == -1)
306 		options->pubkey_authentication = 1;
307 #ifdef GSSAPI
308 	if (options->gss_authentication == -1)
309 		options->gss_authentication = 1;
310 	if (options->gss_keyex == -1)
311 		options->gss_keyex = 1;
312 	if (options->gss_store_creds == -1)
313 		options->gss_store_creds = 1;
314 	if (options->gss_use_session_ccache == -1)
315 		options->gss_use_session_ccache = 1;
316 	if (options->gss_cleanup_creds == -1)
317 		options->gss_cleanup_creds = 1;
318 #endif
319 #if defined(KRB4) || defined(KRB5)
320 	if (options->kerberos_authentication == -1)
321 		options->kerberos_authentication = 0;
322 	if (options->kerberos_or_local_passwd == -1)
323 		options->kerberos_or_local_passwd = 1;
324 	if (options->kerberos_ticket_cleanup == -1)
325 		options->kerberos_ticket_cleanup = 1;
326 #endif
327 #if defined(AFS) || defined(KRB5)
328 	if (options->kerberos_tgt_passing == -1)
329 		options->kerberos_tgt_passing = 0;
330 #endif
331 #ifdef AFS
332 	if (options->afs_token_passing == -1)
333 		options->afs_token_passing = 0;
334 #endif
335 	if (options->password_authentication == -1)
336 		options->password_authentication = 1;
337 	if (options->kbd_interactive_authentication == -1)
338 		options->kbd_interactive_authentication = 0;
339 	if (options->challenge_response_authentication == -1)
340 		options->challenge_response_authentication = 1;
341 	if (options->permit_empty_passwd == -1)
342 		options->permit_empty_passwd = 0;
343 	if (options->permit_user_env == -1)
344 		options->permit_user_env = 0;
345 	if (options->compression == -1)
346 		options->compression = 1;
347 	if (options->allow_tcp_forwarding == -1)
348 		options->allow_tcp_forwarding = 1;
349 	if (options->gateway_ports == -1)
350 		options->gateway_ports = 0;
351 	if (options->max_startups == -1)
352 		options->max_startups = 10;
353 	if (options->max_startups_rate == -1)
354 		options->max_startups_rate = 100;		/* 100% */
355 	if (options->max_startups_begin == -1)
356 		options->max_startups_begin = options->max_startups;
357 	if (options->verify_reverse_mapping == -1)
358 		options->verify_reverse_mapping = 0;
359 	if (options->client_alive_interval == -1)
360 		options->client_alive_interval = 0;
361 	if (options->client_alive_count_max == -1)
362 		options->client_alive_count_max = 3;
363 	if (options->authorized_keys_file2 == NULL) {
364 		/* authorized_keys_file2 falls back to authorized_keys_file */
365 		if (options->authorized_keys_file != NULL)
366 			options->authorized_keys_file2 = options->authorized_keys_file;
367 		else
368 			options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
369 	}
370 	if (options->authorized_keys_file == NULL)
371 		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
372 
373 	if (options->max_auth_tries == -1)
374 		options->max_auth_tries = AUTH_FAIL_MAX;
375 	if (options->max_auth_tries_log == -1)
376 		options->max_auth_tries_log = options->max_auth_tries / 2;
377 
378 	if (options->max_init_auth_tries == -1)
379 		options->max_init_auth_tries = AUTH_FAIL_MAX;
380 	if (options->max_init_auth_tries_log == -1)
381 		options->max_init_auth_tries_log = options->max_init_auth_tries / 2;
382 
383 	if (options->lookup_client_hostnames == -1)
384 		options->lookup_client_hostnames = 1;
385 	if (options->use_openssl_engine == -1)
386 		options->use_openssl_engine = 1;
387 	if (options->pam_service_prefix == NULL)
388 		options->pam_service_prefix = _SSH_PAM_SERVICE_PREFIX;
389 	if (options->pam_service_name == NULL)
390 		options->pam_service_name = NULL;
391 }
392 
393 /* Keyword tokens. */
394 typedef enum {
395 	sBadOption,		/* == unknown option */
396 	/* Portable-specific options */
397 	sPAMAuthenticationViaKbdInt,
398 	/* Standard Options */
399 	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
400 	sPermitRootLogin, sLogFacility, sLogLevel,
401 	sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
402 #ifdef GSSAPI
403 	sGssAuthentication, sGssKeyEx, sGssStoreDelegCreds,
404 	sGssUseSessionCredCache, sGssCleanupCreds,
405 #endif /* GSSAPI */
406 #if defined(KRB4) || defined(KRB5)
407 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
408 #endif
409 #if defined(AFS) || defined(KRB5)
410 	sKerberosTgtPassing,
411 #endif
412 #ifdef AFS
413 	sAFSTokenPassing,
414 #endif
415 	sChallengeResponseAuthentication,
416 	sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
417 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
418 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
419 	sStrictModes, sEmptyPasswd, sKeepAlives,
420 	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
421 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
422 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
423 	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
424 	sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
425 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
426 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
427 	sMaxAuthTries, sMaxAuthTriesLog, sUsePrivilegeSeparation,
428 	sLookupClientHostnames, sUseOpenSSLEngine, sChrootDirectory,
429 	sPreUserauthHook, sMatch, sPAMServicePrefix, sPAMServiceName,
430 	sDeprecated
431 } ServerOpCodes;
432 
433 #define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
434 #define SSHCFG_MATCH	0x02	/* allowed inside a Match section */
435 #define SSHCFG_ALL	(SSHCFG_GLOBAL|SSHCFG_MATCH)
436 
437 /* Textual representation of the tokens. */
438 static struct {
439 	const char *name;
440 	ServerOpCodes opcode;
441 	u_int flags;
442 } keywords[] = {
443 	/* Portable-specific options */
444 	{ "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt, SSHCFG_GLOBAL },
445 	/* Standard Options */
446 	{ "port", sPort, SSHCFG_GLOBAL },
447 	{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
448 	{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },			/* alias */
449 	{ "pidfile", sPidFile, SSHCFG_GLOBAL },
450 	{ "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
451 	{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
452 	{ "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
453 	{ "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
454 	{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
455 	{ "loglevel", sLogLevel, SSHCFG_GLOBAL },
456 	{ "rhostsauthentication", sRhostsAuthentication, SSHCFG_GLOBAL },
457 	{ "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
458 	{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
459 	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
460 	{ "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
461 	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
462 	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },	/* alias */
463 #ifdef GSSAPI
464 	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
465 	{ "gssapikeyexchange", sGssKeyEx,   SSHCFG_GLOBAL },
466 	{ "gssapistoredelegatedcredentials", sGssStoreDelegCreds, SSHCFG_GLOBAL },
467 	{ "gssauthentication", sGssAuthentication, SSHCFG_GLOBAL },	/* alias */
468 	{ "gsskeyex", sGssKeyEx, SSHCFG_GLOBAL },	/* alias */
469 	{ "gssstoredelegcreds", sGssStoreDelegCreds, SSHCFG_GLOBAL },	/* alias */
470 #ifndef SUNW_GSSAPI
471 	{ "gssusesessionccache", sGssUseSessionCredCache, SSHCFG_GLOBAL },
472 	{ "gssusesessioncredcache", sGssUseSessionCredCache, SSHCFG_GLOBAL },
473 	{ "gsscleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL },
474 #endif /* SUNW_GSSAPI */
475 #endif
476 #if defined(KRB4) || defined(KRB5)
477 	{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
478 	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
479 	{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
480 #endif
481 #if defined(AFS) || defined(KRB5)
482 	{ "kerberostgtpassing", sKerberosTgtPassing, SSHCFG_GLOBAL },
483 #endif
484 #ifdef AFS
485 	{ "afstokenpassing", sAFSTokenPassing, SSHCFG_GLOBAL },
486 #endif
487 	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
488 	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
489 	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
490 	{ "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
491 	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
492 	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
493 	{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
494 	{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
495 	{ "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
496 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
497 	{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
498 	{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
499 	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
500 	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
501 	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
502 	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
503 	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
504 	{ "uselogin", sUseLogin, SSHCFG_GLOBAL },
505 	{ "compression", sCompression, SSHCFG_GLOBAL },
506 	{ "keepalive", sKeepAlives, SSHCFG_GLOBAL },
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 		intptr = &options->pam_authentication_via_kbd_int;
774 		goto parse_flag;
775 
776 	/* Standard Options */
777 	case sBadOption:
778 		return -1;
779 	case sPort:
780 		/* ignore ports from configfile if cmdline specifies ports */
781 		if (options->ports_from_cmdline)
782 			return 0;
783 		if (options->listen_addrs != NULL)
784 			fatal("%s line %d: ports must be specified before "
785 			    "ListenAddress.", filename, linenum);
786 		if (options->num_ports >= MAX_PORTS)
787 			fatal("%s line %d: too many ports.",
788 			    filename, linenum);
789 		arg = strdelim(&cp);
790 		if (!arg || *arg == '\0')
791 			fatal("%s line %d: missing port number.",
792 			    filename, linenum);
793 		options->ports[options->num_ports++] = a2port(arg);
794 		if (options->ports[options->num_ports-1] == 0)
795 			fatal("%s line %d: Badly formatted port number.",
796 			    filename, linenum);
797 		break;
798 
799 	case sServerKeyBits:
800 		intptr = &options->server_key_bits;
801 parse_int:
802 		arg = strdelim(&cp);
803 		if (!arg || *arg == '\0')
804 			fatal("%s line %d: missing integer value.",
805 			    filename, linenum);
806 		value = atoi(arg);
807 		if (*activep && *intptr == -1)
808 			*intptr = value;
809 		break;
810 
811 	case sLoginGraceTime:
812 		intptr = &options->login_grace_time;
813 parse_time:
814 		arg = strdelim(&cp);
815 		if (!arg || *arg == '\0')
816 			fatal("%s line %d: missing time value.",
817 			    filename, linenum);
818 		if ((value = convtime(arg)) == -1)
819 			fatal("%s line %d: invalid time value.",
820 			    filename, linenum);
821 		if (*intptr == -1)
822 			*intptr = value;
823 		break;
824 
825 	case sKeyRegenerationTime:
826 		intptr = &options->key_regeneration_time;
827 		goto parse_time;
828 
829 	case sListenAddress:
830 		arg = strdelim(&cp);
831 		if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
832 			fatal("%s line %d: missing inet addr.",
833 			    filename, linenum);
834 		if (*arg == '[') {
835 			if ((p = strchr(arg, ']')) == NULL)
836 				fatal("%s line %d: bad ipv6 inet addr usage.",
837 				    filename, linenum);
838 			arg++;
839 			(void) memmove(p, p+1, strlen(p+1)+1);
840 		} else if (((p = strchr(arg, ':')) == NULL) ||
841 			    (strchr(p+1, ':') != NULL)) {
842 			add_listen_addr(options, arg, 0);
843 			break;
844 		}
845 		if (*p == ':') {
846 			u_short port;
847 
848 			p++;
849 			if (*p == '\0')
850 				fatal("%s line %d: bad inet addr:port usage.",
851 				    filename, linenum);
852 			else {
853 				*(p-1) = '\0';
854 				if ((port = a2port(p)) == 0)
855 					fatal("%s line %d: bad port number.",
856 					    filename, linenum);
857 				add_listen_addr(options, arg, port);
858 			}
859 		} else if (*p == '\0')
860 			add_listen_addr(options, arg, 0);
861 		else
862 			fatal("%s line %d: bad inet addr usage.",
863 			    filename, linenum);
864 		break;
865 
866 	case sHostKeyFile:
867 		intptr = &options->num_host_key_files;
868 		if (*intptr >= MAX_HOSTKEYS)
869 			fatal("%s line %d: too many host keys specified (max %d).",
870 			    filename, linenum, MAX_HOSTKEYS);
871 		charptr = &options->host_key_files[*intptr];
872 parse_filename:
873 		arg = strdelim(&cp);
874 		if (!arg || *arg == '\0')
875 			fatal("%s line %d: missing file name.",
876 			    filename, linenum);
877 		if (*activep && *charptr == NULL) {
878 			*charptr = tilde_expand_filename(arg, getuid());
879 			/* increase optional counter */
880 			if (intptr != NULL)
881 				*intptr = *intptr + 1;
882 		}
883 		break;
884 
885 	case sPidFile:
886 		charptr = &options->pid_file;
887 		goto parse_filename;
888 
889 	case sPermitRootLogin:
890 		intptr = &options->permit_root_login;
891 		arg = strdelim(&cp);
892 		if (!arg || *arg == '\0')
893 			fatal("%s line %d: missing yes/"
894 			    "without-password/forced-commands-only/no "
895 			    "argument.", filename, linenum);
896 		value = 0;	/* silence compiler */
897 		if (strcmp(arg, "without-password") == 0)
898 			value = PERMIT_NO_PASSWD;
899 		else if (strcmp(arg, "forced-commands-only") == 0)
900 			value = PERMIT_FORCED_ONLY;
901 		else if (strcmp(arg, "yes") == 0)
902 			value = PERMIT_YES;
903 		else if (strcmp(arg, "no") == 0)
904 			value = PERMIT_NO;
905 		else
906 			fatal("%s line %d: Bad yes/"
907 			    "without-password/forced-commands-only/no "
908 			    "argument: %s", filename, linenum, arg);
909 		if (*activep && *intptr == -1)
910 			*intptr = value;
911 		break;
912 
913 	case sIgnoreRhosts:
914 		intptr = &options->ignore_rhosts;
915 parse_flag:
916 		arg = strdelim(&cp);
917 		if (!arg || *arg == '\0')
918 			fatal("%s line %d: missing yes/no argument.",
919 			    filename, linenum);
920 		value = 0;	/* silence compiler */
921 		if (strcmp(arg, "yes") == 0)
922 			value = 1;
923 		else if (strcmp(arg, "no") == 0)
924 			value = 0;
925 		else
926 			fatal("%s line %d: Bad yes/no argument: %s",
927 				filename, linenum, arg);
928 		if (*activep && *intptr == -1)
929 			*intptr = value;
930 		break;
931 
932 	case sIgnoreUserKnownHosts:
933 		intptr = &options->ignore_user_known_hosts;
934 		goto parse_flag;
935 
936 	case sRhostsAuthentication:
937 		intptr = &options->rhosts_authentication;
938 		goto parse_flag;
939 
940 	case sRhostsRSAAuthentication:
941 		intptr = &options->rhosts_rsa_authentication;
942 		goto parse_flag;
943 
944 	case sHostbasedAuthentication:
945 		intptr = &options->hostbased_authentication;
946 		goto parse_flag;
947 
948 	case sHostbasedUsesNameFromPacketOnly:
949 		intptr = &options->hostbased_uses_name_from_packet_only;
950 		goto parse_flag;
951 
952 	case sRSAAuthentication:
953 		intptr = &options->rsa_authentication;
954 		goto parse_flag;
955 
956 	case sPubkeyAuthentication:
957 		intptr = &options->pubkey_authentication;
958 		goto parse_flag;
959 #ifdef GSSAPI
960 	case sGssAuthentication:
961 		intptr = &options->gss_authentication;
962 		goto parse_flag;
963 	case sGssKeyEx:
964 		intptr = &options->gss_keyex;
965 		goto parse_flag;
966 	case sGssStoreDelegCreds:
967 		intptr = &options->gss_keyex;
968 		goto parse_flag;
969 #ifndef SUNW_GSSAPI
970 	case sGssUseSessionCredCache:
971 		intptr = &options->gss_use_session_ccache;
972 		goto parse_flag;
973 	case sGssCleanupCreds:
974 		intptr = &options->gss_cleanup_creds;
975 		goto parse_flag;
976 #endif /* SUNW_GSSAPI */
977 #endif /* GSSAPI */
978 #if defined(KRB4) || defined(KRB5)
979 	case sKerberosAuthentication:
980 		intptr = &options->kerberos_authentication;
981 		goto parse_flag;
982 
983 	case sKerberosOrLocalPasswd:
984 		intptr = &options->kerberos_or_local_passwd;
985 		goto parse_flag;
986 
987 	case sKerberosTicketCleanup:
988 		intptr = &options->kerberos_ticket_cleanup;
989 		goto parse_flag;
990 #endif
991 #if defined(AFS) || defined(KRB5)
992 	case sKerberosTgtPassing:
993 		intptr = &options->kerberos_tgt_passing;
994 		goto parse_flag;
995 #endif
996 #ifdef AFS
997 	case sAFSTokenPassing:
998 		intptr = &options->afs_token_passing;
999 		goto parse_flag;
1000 #endif
1001 
1002 	case sPasswordAuthentication:
1003 		intptr = &options->password_authentication;
1004 		goto parse_flag;
1005 
1006 	case sKbdInteractiveAuthentication:
1007 		intptr = &options->kbd_interactive_authentication;
1008 		goto parse_flag;
1009 
1010 	case sChallengeResponseAuthentication:
1011 		intptr = &options->challenge_response_authentication;
1012 		goto parse_flag;
1013 
1014 	case sPrintMotd:
1015 		intptr = &options->print_motd;
1016 		goto parse_flag;
1017 
1018 	case sPrintLastLog:
1019 		intptr = &options->print_lastlog;
1020 		goto parse_flag;
1021 
1022 	case sX11Forwarding:
1023 		intptr = &options->x11_forwarding;
1024 		goto parse_flag;
1025 
1026 	case sX11DisplayOffset:
1027 		intptr = &options->x11_display_offset;
1028 		goto parse_int;
1029 
1030 	case sX11UseLocalhost:
1031 		intptr = &options->x11_use_localhost;
1032 		goto parse_flag;
1033 
1034 	case sXAuthLocation:
1035 		charptr = &options->xauth_location;
1036 		goto parse_filename;
1037 
1038 	case sStrictModes:
1039 		intptr = &options->strict_modes;
1040 		goto parse_flag;
1041 
1042 	case sKeepAlives:
1043 		intptr = &options->keepalives;
1044 		goto parse_flag;
1045 
1046 	case sEmptyPasswd:
1047 		intptr = &options->permit_empty_passwd;
1048 		goto parse_flag;
1049 
1050 	case sPermitUserEnvironment:
1051 		intptr = &options->permit_user_env;
1052 		goto parse_flag;
1053 
1054 	case sUseLogin:
1055 		log("%s line %d: ignoring UseLogin option value."
1056 		    " This option is always off.", filename, linenum);
1057 		while (arg)
1058 			arg = strdelim(&cp);
1059 		break;
1060 
1061 	case sCompression:
1062 		intptr = &options->compression;
1063 		goto parse_flag;
1064 
1065 	case sGatewayPorts:
1066 		intptr = &options->gateway_ports;
1067 		arg = strdelim(&cp);
1068 		if (!arg || *arg == '\0')
1069 			fatal("%s line %d: missing yes/no/clientspecified "
1070 			    "argument.", filename, linenum);
1071 		value = 0;	/* silence compiler */
1072 		if (strcmp(arg, "clientspecified") == 0)
1073 			value = 2;
1074 		else if (strcmp(arg, "yes") == 0)
1075 			value = 1;
1076 		else if (strcmp(arg, "no") == 0)
1077 			value = 0;
1078 		else
1079 			fatal("%s line %d: Bad yes/no/clientspecified "
1080 			    "argument: %s", filename, linenum, arg);
1081 		if (*activep && *intptr == -1)
1082 			*intptr = value;
1083 		break;
1084 
1085 	case sVerifyReverseMapping:
1086 		intptr = &options->verify_reverse_mapping;
1087 		goto parse_flag;
1088 
1089 	case sLogFacility:
1090 		intptr = (int *) &options->log_facility;
1091 		arg = strdelim(&cp);
1092 		value = log_facility_number(arg);
1093 		if (value == SYSLOG_FACILITY_NOT_SET)
1094 			fatal("%.200s line %d: unsupported log facility '%s'",
1095 			    filename, linenum, arg ? arg : "<NONE>");
1096 		if (*intptr == -1)
1097 			*intptr = (SyslogFacility) value;
1098 		break;
1099 
1100 	case sLogLevel:
1101 		intptr = (int *) &options->log_level;
1102 		arg = strdelim(&cp);
1103 		value = log_level_number(arg);
1104 		if (value == SYSLOG_LEVEL_NOT_SET)
1105 			fatal("%.200s line %d: unsupported log level '%s'",
1106 			    filename, linenum, arg ? arg : "<NONE>");
1107 		if (*intptr == -1)
1108 			*intptr = (LogLevel) value;
1109 		break;
1110 
1111 	case sAllowTcpForwarding:
1112 		intptr = &options->allow_tcp_forwarding;
1113 		goto parse_flag;
1114 
1115 	case sUsePrivilegeSeparation:
1116 		log("%s line %d: ignoring UsePrivilegeSeparation option value."
1117 		    " This option is always on.", filename, linenum);
1118 		while (arg)
1119 			arg = strdelim(&cp);
1120 		break;
1121 
1122 	case sAllowUsers:
1123 		while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') {
1124 			if (options->num_allow_users >= MAX_ALLOW_USERS)
1125 				fatal("%s line %d: too many allow users.",
1126 				    filename, linenum);
1127 			options->allow_users[options->num_allow_users++] =
1128 			    xstrdup(arg);
1129 		}
1130 		break;
1131 
1132 	case sDenyUsers:
1133 		while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') {
1134 			if (options->num_deny_users >= MAX_DENY_USERS)
1135 				fatal( "%s line %d: too many deny users.",
1136 				    filename, linenum);
1137 			options->deny_users[options->num_deny_users++] =
1138 			    xstrdup(arg);
1139 		}
1140 		break;
1141 
1142 	case sAllowGroups:
1143 		while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') {
1144 			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1145 				fatal("%s line %d: too many allow groups.",
1146 				    filename, linenum);
1147 			options->allow_groups[options->num_allow_groups++] =
1148 			    xstrdup(arg);
1149 		}
1150 		break;
1151 
1152 	case sDenyGroups:
1153 		while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') {
1154 			if (options->num_deny_groups >= MAX_DENY_GROUPS)
1155 				fatal("%s line %d: too many deny groups.",
1156 				    filename, linenum);
1157 			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1158 		}
1159 		break;
1160 
1161 	case sCiphers:
1162 		arg = strdelim(&cp);
1163 		if (!arg || *arg == '\0')
1164 			fatal("%s line %d: Missing argument.", filename, linenum);
1165 		if (!ciphers_valid(arg))
1166 			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1167 			    filename, linenum, arg ? arg : "<NONE>");
1168 		if (options->ciphers == NULL)
1169 			options->ciphers = xstrdup(arg);
1170 		break;
1171 
1172 	case sMacs:
1173 		arg = strdelim(&cp);
1174 		if (!arg || *arg == '\0')
1175 			fatal("%s line %d: Missing argument.", filename, linenum);
1176 		if (!mac_valid(arg))
1177 			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1178 			    filename, linenum, arg ? arg : "<NONE>");
1179 		if (options->macs == NULL)
1180 			options->macs = xstrdup(arg);
1181 		break;
1182 
1183 	case sProtocol:
1184 		intptr = &options->protocol;
1185 		arg = strdelim(&cp);
1186 		if (!arg || *arg == '\0')
1187 			fatal("%s line %d: Missing argument.", filename, linenum);
1188 		value = proto_spec(arg);
1189 		if (value == SSH_PROTO_UNKNOWN)
1190 			fatal("%s line %d: Bad protocol spec '%s'.",
1191 			    filename, linenum, arg ? arg : "<NONE>");
1192 		if (*intptr == SSH_PROTO_UNKNOWN)
1193 			*intptr = value;
1194 		break;
1195 
1196 	case sSubsystem:
1197 		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1198 			fatal("%s line %d: too many subsystems defined.",
1199 			    filename, linenum);
1200 		}
1201 		arg = strdelim(&cp);
1202 		if (!arg || *arg == '\0')
1203 			fatal("%s line %d: Missing subsystem name.",
1204 			    filename, linenum);
1205 		if (!*activep) {
1206 			arg = strdelim(&cp);
1207 			break;
1208 		}
1209 		for (i = 0; i < options->num_subsystems; i++)
1210 			if (strcmp(arg, options->subsystem_name[i]) == 0)
1211 				fatal("%s line %d: Subsystem '%s' already defined.",
1212 				    filename, linenum, arg);
1213 		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1214 		arg = strdelim(&cp);
1215 		if (!arg || *arg == '\0')
1216 			fatal("%s line %d: Missing subsystem command.",
1217 			    filename, linenum);
1218 		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1219 
1220 		/*
1221 		 * Collect arguments (separate to executable), including the
1222 		 * name of the executable, in a way that is easier to parse
1223 		 * later.
1224 		 */
1225 		p = xstrdup(arg);
1226 		len = strlen(p) + 1;
1227 		while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1228 			len += 1 + strlen(arg);
1229 			p = xrealloc(p, len);
1230 			strlcat(p, " ", len);
1231 			strlcat(p, arg, len);
1232 		}
1233 		options->subsystem_args[options->num_subsystems] = p;
1234 		options->num_subsystems++;
1235 		break;
1236 
1237 	case sMaxStartups:
1238 		arg = strdelim(&cp);
1239 		if (!arg || *arg == '\0')
1240 			fatal("%s line %d: Missing MaxStartups spec.",
1241 			    filename, linenum);
1242 		if ((n = sscanf(arg, "%d:%d:%d",
1243 		    &options->max_startups_begin,
1244 		    &options->max_startups_rate,
1245 		    &options->max_startups)) == 3) {
1246 			if (options->max_startups_begin >
1247 			    options->max_startups ||
1248 			    options->max_startups_rate > 100 ||
1249 			    options->max_startups_rate < 1)
1250 				fatal("%s line %d: Illegal MaxStartups spec.",
1251 				    filename, linenum);
1252 		} else if (n != 1)
1253 			fatal("%s line %d: Illegal MaxStartups spec.",
1254 			    filename, linenum);
1255 		else
1256 			options->max_startups = options->max_startups_begin;
1257 		break;
1258 
1259 	case sBanner:
1260 		charptr = &options->banner;
1261 		goto parse_filename;
1262 	/*
1263 	 * These options can contain %X options expanded at
1264 	 * connect time, so that you can specify paths like:
1265 	 *
1266 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
1267 	 */
1268 	case sAuthorizedKeysFile:
1269 	case sAuthorizedKeysFile2:
1270 		charptr = (opcode == sAuthorizedKeysFile) ?
1271 		    &options->authorized_keys_file :
1272 		    &options->authorized_keys_file2;
1273 		goto parse_filename;
1274 
1275 	case sClientAliveInterval:
1276 		intptr = &options->client_alive_interval;
1277 		goto parse_time;
1278 
1279 	case sClientAliveCountMax:
1280 		intptr = &options->client_alive_count_max;
1281 		goto parse_int;
1282 
1283 	case sMaxAuthTries:
1284 		intptr = &options->max_auth_tries;
1285 		goto parse_int;
1286 
1287 	case sMaxAuthTriesLog:
1288 		intptr = &options->max_auth_tries_log;
1289 		goto parse_int;
1290 
1291 	case sLookupClientHostnames:
1292 		intptr = &options->lookup_client_hostnames;
1293 		goto parse_flag;
1294 
1295 	case sUseOpenSSLEngine:
1296 		intptr = &options->use_openssl_engine;
1297 		goto parse_flag;
1298 
1299 	case sChrootDirectory:
1300 		charptr = &options->chroot_directory;
1301 
1302 		arg = strdelim(&cp);
1303 		if (arg == NULL || *arg == '\0')
1304 			fatal("%s line %d: missing directory name for "
1305 			    "ChrootDirectory.", filename, linenum);
1306 		if (*activep && *charptr == NULL)
1307 			*charptr = xstrdup(arg);
1308 		break;
1309 
1310 	case sPreUserauthHook:
1311 		charptr = &options->pre_userauth_hook;
1312 		goto parse_filename;
1313 
1314 	case sMatch:
1315 		if (cmdline)
1316 			fatal("Match directive not supported as a command-line "
1317 			   "option");
1318 		value = match_cfg_line(&cp, linenum, user, host, address);
1319 		if (value < 0)
1320 			fatal("%s line %d: Bad Match condition", filename,
1321 			    linenum);
1322 		*activep = value;
1323 		break;
1324 
1325 	case sDeprecated:
1326 		log("%s line %d: Deprecated option %s",
1327 		    filename, linenum, arg);
1328 		while (arg)
1329 		    arg = strdelim(&cp);
1330 		break;
1331 
1332 	case sPAMServicePrefix:
1333 		arg = strdelim(&cp);
1334 		if (!arg || *arg == '\0')
1335 			fatal("%s line %d: Missing argument.",
1336 			    filename, linenum);
1337 		if (options->pam_service_name != NULL)
1338 			fatal("%s line %d: PAMServiceName and PAMServicePrefix "
1339 			    "are mutually exclusive.", filename, linenum);
1340 		if (options->pam_service_prefix == NULL)
1341 			options->pam_service_prefix = xstrdup(arg);
1342 		break;
1343 
1344 	case sPAMServiceName:
1345 		arg = strdelim(&cp);
1346 		if (!arg || *arg == '\0')
1347 			fatal("%s line %d: Missing argument.",
1348 			    filename, linenum);
1349 		if (options->pam_service_prefix != NULL)
1350 			fatal("%s line %d: PAMServiceName and PAMServicePrefix "
1351 			    "are mutually exclusive.", filename, linenum);
1352 		if (options->pam_service_name == NULL)
1353 			options->pam_service_name = xstrdup(arg);
1354 		break;
1355 
1356 	default:
1357 		fatal("%s line %d: Missing handler for opcode %s (%d)",
1358 		    filename, linenum, arg, opcode);
1359 	}
1360 	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1361 		fatal("%s line %d: garbage at end of line; \"%.200s\".",
1362 		    filename, linenum, arg);
1363 	return 0;
1364 }
1365 
1366 
1367 /* Reads the server configuration file. */
1368 
1369 void
1370 load_server_config(const char *filename, Buffer *conf)
1371 {
1372 	char line[1024], *cp;
1373 	FILE *f;
1374 
1375 	debug2("%s: filename %s", __func__, filename);
1376 	if ((f = fopen(filename, "r")) == NULL) {
1377 		perror(filename);
1378 		exit(1);
1379 	}
1380 	buffer_clear(conf);
1381 	while (fgets(line, sizeof(line), f)) {
1382 		/*
1383 		 * Trim out comments and strip whitespace
1384 		 * NB - preserve newlines, they are needed to reproduce
1385 		 * line numbers later for error messages
1386 		 */
1387 		if ((cp = strchr(line, '#')) != NULL)
1388 			memcpy(cp, "\n", 2);
1389 		cp = line + strspn(line, " \t\r");
1390 
1391 		buffer_append(conf, cp, strlen(cp));
1392 	}
1393 	buffer_append(conf, "\0", 1);
1394 	fclose(f);
1395 	debug2("%s: done config len = %d", __func__, buffer_len(conf));
1396 }
1397 
1398 void
1399 parse_server_match_config(ServerOptions *options, const char *user,
1400     const char *host, const char *address)
1401 {
1402 	ServerOptions mo;
1403 
1404 	initialize_server_options(&mo);
1405 	parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1406 	copy_set_server_options(options, &mo, 0);
1407 }
1408 
1409 
1410 
1411 /* Helper macros */
1412 #define M_CP_INTOPT(n) do {\
1413 	if (src->n != -1) \
1414 		dst->n = src->n; \
1415 } while (0)
1416 #define M_CP_STROPT(n) do {\
1417 	if (src->n != NULL) { \
1418 		if (dst->n != NULL) \
1419 			xfree(dst->n); \
1420 		dst->n = src->n; \
1421 	} \
1422 } while(0)
1423 
1424 /*
1425  * Copy any supported values that are set.
1426  *
1427  * If the preauth flag is set, we do not bother copying the the string or
1428  * array values that are not used pre-authentication, because any that we
1429  * do use must be explictly sent in mm_getpwnamallow().
1430  */
1431 void
1432 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1433 {
1434 	M_CP_INTOPT(password_authentication);
1435 	M_CP_INTOPT(gss_authentication);
1436 	M_CP_INTOPT(rsa_authentication);
1437 	M_CP_INTOPT(pubkey_authentication);
1438 	M_CP_INTOPT(hostbased_authentication);
1439 	M_CP_INTOPT(kbd_interactive_authentication);
1440 	M_CP_INTOPT(permit_root_login);
1441 	M_CP_INTOPT(permit_empty_passwd);
1442 	M_CP_INTOPT(allow_tcp_forwarding);
1443 	M_CP_INTOPT(gateway_ports);
1444 	M_CP_INTOPT(x11_display_offset);
1445 	M_CP_INTOPT(x11_forwarding);
1446 	M_CP_INTOPT(x11_use_localhost);
1447 	M_CP_INTOPT(max_auth_tries);
1448 	M_CP_STROPT(banner);
1449 
1450 	if (preauth)
1451 		return;
1452 	M_CP_STROPT(chroot_directory);
1453 }
1454 
1455 #undef M_CP_INTOPT
1456 #undef M_CP_STROPT
1457 
1458 void
1459 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1460     const char *user, const char *host, const char *address)
1461 {
1462 	int active, linenum, bad_options = 0;
1463 	char *cp, *obuf, *cbuf;
1464 
1465 	debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1466 
1467 	obuf = cbuf = xstrdup(buffer_ptr(conf));
1468 	active = user ? 0 : 1;
1469 	linenum = 1;
1470 	while ((cp = strsep(&cbuf, "\n")) != NULL) {
1471 		if (process_server_config_line(options, cp, filename,
1472 		    linenum++, &active, user, host, address) != 0)
1473 			bad_options++;
1474 	}
1475 	xfree(obuf);
1476 	if (bad_options > 0)
1477 		fatal("%s: terminating, %d bad configuration options",
1478 		    filename, bad_options);
1479 }
1480 
1481 
1482 /*
1483  * Note that "none" is a special path having the same affect on sshd
1484  * configuration as not specifying ChrootDirectory at all.
1485  */
1486 int
1487 chroot_requested(char *chroot_directory)
1488 {
1489 	return (chroot_directory != NULL &&
1490 	    strcasecmp(chroot_directory, "none") != 0);
1491 }
1492