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