1
2/* $OpenBSD: servconf.c,v 1.342 2018/09/20 23:40:16 djm Exp $ */
3/*
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 *                    All rights reserved
6 *
7 * As far as I am concerned, the code I have written for this software
8 * can be used freely for any purpose.  Any derived versions of this
9 * software must be clearly marked as such, and if the derived work is
10 * incompatible with the protocol description in the RFC file, it must be
11 * called by a name other than "ssh" or "Secure Shell".
12 */
13
14#include "includes.h"
15__RCSID("$FreeBSD$");
16
17#include <sys/types.h>
18#include <sys/socket.h>
19#ifdef HAVE_SYS_SYSCTL_H
20#include <sys/sysctl.h>
21#endif
22
23#include <netinet/in.h>
24#include <netinet/in_systm.h>
25#include <netinet/ip.h>
26#ifdef HAVE_NET_ROUTE_H
27#include <net/route.h>
28#endif
29
30#include <ctype.h>
31#include <netdb.h>
32#include <pwd.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <signal.h>
37#include <unistd.h>
38#include <limits.h>
39#include <stdarg.h>
40#include <errno.h>
41#ifdef HAVE_UTIL_H
42#include <util.h>
43#endif
44
45#include "openbsd-compat/sys-queue.h"
46#include "xmalloc.h"
47#include "ssh.h"
48#include "log.h"
49#include "sshbuf.h"
50#include "misc.h"
51#include "servconf.h"
52#include "compat.h"
53#include "pathnames.h"
54#include "cipher.h"
55#include "sshkey.h"
56#include "kex.h"
57#include "mac.h"
58#include "match.h"
59#include "channels.h"
60#include "groupaccess.h"
61#include "canohost.h"
62#include "packet.h"
63#include "ssherr.h"
64#include "hostfile.h"
65#include "auth.h"
66#include "myproposal.h"
67#include "digest.h"
68#include "version.h"
69
70static void add_listen_addr(ServerOptions *, const char *,
71    const char *, int);
72static void add_one_listen_addr(ServerOptions *, const char *,
73    const char *, int);
74
75/* Use of privilege separation or not */
76extern int use_privsep;
77extern struct sshbuf *cfg;
78
79/* Initializes the server options to their default values. */
80
81void
82initialize_server_options(ServerOptions *options)
83{
84	memset(options, 0, sizeof(*options));
85
86	/* Portable-specific options */
87	options->use_pam = -1;
88
89	/* Standard Options */
90	options->num_ports = 0;
91	options->ports_from_cmdline = 0;
92	options->queued_listen_addrs = NULL;
93	options->num_queued_listens = 0;
94	options->listen_addrs = NULL;
95	options->num_listen_addrs = 0;
96	options->address_family = -1;
97	options->routing_domain = NULL;
98	options->num_host_key_files = 0;
99	options->num_host_cert_files = 0;
100	options->host_key_agent = NULL;
101	options->pid_file = NULL;
102	options->login_grace_time = -1;
103	options->permit_root_login = PERMIT_NOT_SET;
104	options->ignore_rhosts = -1;
105	options->ignore_user_known_hosts = -1;
106	options->print_motd = -1;
107	options->print_lastlog = -1;
108	options->x11_forwarding = -1;
109	options->x11_display_offset = -1;
110	options->x11_use_localhost = -1;
111	options->permit_tty = -1;
112	options->permit_user_rc = -1;
113	options->xauth_location = NULL;
114	options->strict_modes = -1;
115	options->tcp_keep_alive = -1;
116	options->log_facility = SYSLOG_FACILITY_NOT_SET;
117	options->log_level = SYSLOG_LEVEL_NOT_SET;
118	options->hostbased_authentication = -1;
119	options->hostbased_uses_name_from_packet_only = -1;
120	options->hostbased_key_types = NULL;
121	options->hostkeyalgorithms = NULL;
122	options->pubkey_authentication = -1;
123	options->pubkey_key_types = NULL;
124	options->kerberos_authentication = -1;
125	options->kerberos_or_local_passwd = -1;
126	options->kerberos_ticket_cleanup = -1;
127	options->kerberos_get_afs_token = -1;
128	options->gss_authentication=-1;
129	options->gss_cleanup_creds = -1;
130	options->gss_strict_acceptor = -1;
131	options->password_authentication = -1;
132	options->kbd_interactive_authentication = -1;
133	options->challenge_response_authentication = -1;
134	options->permit_empty_passwd = -1;
135	options->permit_user_env = -1;
136	options->permit_user_env_whitelist = NULL;
137	options->compression = -1;
138	options->rekey_limit = -1;
139	options->rekey_interval = -1;
140	options->allow_tcp_forwarding = -1;
141	options->allow_streamlocal_forwarding = -1;
142	options->allow_agent_forwarding = -1;
143	options->num_allow_users = 0;
144	options->num_deny_users = 0;
145	options->num_allow_groups = 0;
146	options->num_deny_groups = 0;
147	options->ciphers = NULL;
148	options->macs = NULL;
149	options->kex_algorithms = NULL;
150	options->ca_sign_algorithms = NULL;
151	options->fwd_opts.gateway_ports = -1;
152	options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
153	options->fwd_opts.streamlocal_bind_unlink = -1;
154	options->num_subsystems = 0;
155	options->max_startups_begin = -1;
156	options->max_startups_rate = -1;
157	options->max_startups = -1;
158	options->max_authtries = -1;
159	options->max_sessions = -1;
160	options->banner = NULL;
161	options->use_dns = -1;
162	options->client_alive_interval = -1;
163	options->client_alive_count_max = -1;
164	options->num_authkeys_files = 0;
165	options->num_accept_env = 0;
166	options->num_setenv = 0;
167	options->permit_tun = -1;
168	options->permitted_opens = NULL;
169	options->permitted_listens = NULL;
170	options->adm_forced_command = NULL;
171	options->chroot_directory = NULL;
172	options->authorized_keys_command = NULL;
173	options->authorized_keys_command_user = NULL;
174	options->revoked_keys_file = NULL;
175	options->trusted_user_ca_keys = NULL;
176	options->authorized_principals_file = NULL;
177	options->authorized_principals_command = NULL;
178	options->authorized_principals_command_user = NULL;
179	options->ip_qos_interactive = -1;
180	options->ip_qos_bulk = -1;
181	options->version_addendum = NULL;
182	options->fingerprint_hash = -1;
183	options->disable_forwarding = -1;
184	options->expose_userauth_info = -1;
185	options->use_blacklist = -1;
186}
187
188/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
189static int
190option_clear_or_none(const char *o)
191{
192	return o == NULL || strcasecmp(o, "none") == 0;
193}
194
195static void
196assemble_algorithms(ServerOptions *o)
197{
198	char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
199	int r;
200
201	all_cipher = cipher_alg_list(',', 0);
202	all_mac = mac_alg_list(',');
203	all_kex = kex_alg_list(',');
204	all_key = sshkey_alg_list(0, 0, 1, ',');
205	all_sig = sshkey_alg_list(0, 1, 1, ',');
206#define ASSEMBLE(what, defaults, all) \
207	do { \
208		if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
209			fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \
210	} while (0)
211	ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher);
212	ASSEMBLE(macs, KEX_SERVER_MAC, all_mac);
213	ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex);
214	ASSEMBLE(hostkeyalgorithms, KEX_DEFAULT_PK_ALG, all_key);
215	ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
216	ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
217	ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
218#undef ASSEMBLE
219	free(all_cipher);
220	free(all_mac);
221	free(all_kex);
222	free(all_key);
223	free(all_sig);
224}
225
226static void
227array_append(const char *file, const int line, const char *directive,
228    char ***array, u_int *lp, const char *s)
229{
230
231	if (*lp >= INT_MAX)
232		fatal("%s line %d: Too many %s entries", file, line, directive);
233
234	*array = xrecallocarray(*array, *lp, *lp + 1, sizeof(**array));
235	(*array)[*lp] = xstrdup(s);
236	(*lp)++;
237}
238
239static const char *defaultkey = "[default]";
240
241void
242servconf_add_hostkey(const char *file, const int line,
243    ServerOptions *options, const char *path)
244{
245	char *apath = derelativise_path(path);
246
247	if (file == defaultkey && access(path, R_OK) != 0)
248		return;
249	array_append(file, line, "HostKey",
250	    &options->host_key_files, &options->num_host_key_files, apath);
251	free(apath);
252}
253
254void
255servconf_add_hostcert(const char *file, const int line,
256    ServerOptions *options, const char *path)
257{
258	char *apath = derelativise_path(path);
259
260	array_append(file, line, "HostCertificate",
261	    &options->host_cert_files, &options->num_host_cert_files, apath);
262	free(apath);
263}
264
265void
266fill_default_server_options(ServerOptions *options)
267{
268	u_int i;
269
270	/* Portable-specific options */
271	if (options->use_pam == -1)
272		options->use_pam = 1;
273
274	/* Standard Options */
275	if (options->num_host_key_files == 0) {
276		/* fill default hostkeys for protocols */
277		servconf_add_hostkey(defaultkey, 0, options,
278		    _PATH_HOST_RSA_KEY_FILE);
279		servconf_add_hostkey(defaultkey, 0, options,
280		    _PATH_HOST_DSA_KEY_FILE);
281#ifdef OPENSSL_HAS_ECC
282		servconf_add_hostkey(defaultkey, 0, options,
283		    _PATH_HOST_ECDSA_KEY_FILE);
284#endif
285		servconf_add_hostkey(defaultkey, 0, options,
286		    _PATH_HOST_ED25519_KEY_FILE);
287#ifdef WITH_XMSS
288		servconf_add_hostkey(defaultkey, 0, options,
289		    _PATH_HOST_XMSS_KEY_FILE);
290#endif /* WITH_XMSS */
291	}
292	if (options->num_host_key_files == 0)
293		fatal("No host key files found");
294	/* No certificates by default */
295	if (options->num_ports == 0)
296		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
297	if (options->address_family == -1)
298		options->address_family = AF_UNSPEC;
299	if (options->listen_addrs == NULL)
300		add_listen_addr(options, NULL, NULL, 0);
301	if (options->pid_file == NULL)
302		options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
303	if (options->login_grace_time == -1)
304		options->login_grace_time = 120;
305	if (options->permit_root_login == PERMIT_NOT_SET)
306		options->permit_root_login = PERMIT_NO;
307	if (options->ignore_rhosts == -1)
308		options->ignore_rhosts = 1;
309	if (options->ignore_user_known_hosts == -1)
310		options->ignore_user_known_hosts = 0;
311	if (options->print_motd == -1)
312		options->print_motd = 1;
313	if (options->print_lastlog == -1)
314		options->print_lastlog = 1;
315	if (options->x11_forwarding == -1)
316		options->x11_forwarding = 1;
317	if (options->x11_display_offset == -1)
318		options->x11_display_offset = 10;
319	if (options->x11_use_localhost == -1)
320		options->x11_use_localhost = 1;
321	if (options->xauth_location == NULL)
322		options->xauth_location = xstrdup(_PATH_XAUTH);
323	if (options->permit_tty == -1)
324		options->permit_tty = 1;
325	if (options->permit_user_rc == -1)
326		options->permit_user_rc = 1;
327	if (options->strict_modes == -1)
328		options->strict_modes = 1;
329	if (options->tcp_keep_alive == -1)
330		options->tcp_keep_alive = 1;
331	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
332		options->log_facility = SYSLOG_FACILITY_AUTH;
333	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
334		options->log_level = SYSLOG_LEVEL_INFO;
335	if (options->hostbased_authentication == -1)
336		options->hostbased_authentication = 0;
337	if (options->hostbased_uses_name_from_packet_only == -1)
338		options->hostbased_uses_name_from_packet_only = 0;
339	if (options->pubkey_authentication == -1)
340		options->pubkey_authentication = 1;
341	if (options->kerberos_authentication == -1)
342		options->kerberos_authentication = 0;
343	if (options->kerberos_or_local_passwd == -1)
344		options->kerberos_or_local_passwd = 1;
345	if (options->kerberos_ticket_cleanup == -1)
346		options->kerberos_ticket_cleanup = 1;
347	if (options->kerberos_get_afs_token == -1)
348		options->kerberos_get_afs_token = 0;
349	if (options->gss_authentication == -1)
350		options->gss_authentication = 0;
351	if (options->gss_cleanup_creds == -1)
352		options->gss_cleanup_creds = 1;
353	if (options->gss_strict_acceptor == -1)
354		options->gss_strict_acceptor = 1;
355	if (options->password_authentication == -1)
356		options->password_authentication = 0;
357	if (options->kbd_interactive_authentication == -1)
358		options->kbd_interactive_authentication = 0;
359	if (options->challenge_response_authentication == -1)
360		options->challenge_response_authentication = 1;
361	if (options->permit_empty_passwd == -1)
362		options->permit_empty_passwd = 0;
363	if (options->permit_user_env == -1) {
364		options->permit_user_env = 0;
365		options->permit_user_env_whitelist = NULL;
366	}
367	if (options->compression == -1)
368		options->compression = COMP_DELAYED;
369	if (options->rekey_limit == -1)
370		options->rekey_limit = 0;
371	if (options->rekey_interval == -1)
372		options->rekey_interval = 0;
373	if (options->allow_tcp_forwarding == -1)
374		options->allow_tcp_forwarding = FORWARD_ALLOW;
375	if (options->allow_streamlocal_forwarding == -1)
376		options->allow_streamlocal_forwarding = FORWARD_ALLOW;
377	if (options->allow_agent_forwarding == -1)
378		options->allow_agent_forwarding = 1;
379	if (options->fwd_opts.gateway_ports == -1)
380		options->fwd_opts.gateway_ports = 0;
381	if (options->max_startups == -1)
382		options->max_startups = 100;
383	if (options->max_startups_rate == -1)
384		options->max_startups_rate = 30;		/* 30% */
385	if (options->max_startups_begin == -1)
386		options->max_startups_begin = 10;
387	if (options->max_authtries == -1)
388		options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
389	if (options->max_sessions == -1)
390		options->max_sessions = DEFAULT_SESSIONS_MAX;
391	if (options->use_dns == -1)
392		options->use_dns = 1;
393	if (options->client_alive_interval == -1)
394		options->client_alive_interval = 0;
395	if (options->client_alive_count_max == -1)
396		options->client_alive_count_max = 3;
397	if (options->num_authkeys_files == 0) {
398		array_append(defaultkey, 0, "AuthorizedKeysFiles",
399		    &options->authorized_keys_files,
400		    &options->num_authkeys_files,
401		    _PATH_SSH_USER_PERMITTED_KEYS);
402		array_append(defaultkey, 0, "AuthorizedKeysFiles",
403		    &options->authorized_keys_files,
404		    &options->num_authkeys_files,
405		    _PATH_SSH_USER_PERMITTED_KEYS2);
406	}
407	if (options->permit_tun == -1)
408		options->permit_tun = SSH_TUNMODE_NO;
409	if (options->ip_qos_interactive == -1)
410		options->ip_qos_interactive = IPTOS_DSCP_AF21;
411	if (options->ip_qos_bulk == -1)
412		options->ip_qos_bulk = IPTOS_DSCP_CS1;
413	if (options->version_addendum == NULL)
414		options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
415	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
416		options->fwd_opts.streamlocal_bind_mask = 0177;
417	if (options->fwd_opts.streamlocal_bind_unlink == -1)
418		options->fwd_opts.streamlocal_bind_unlink = 0;
419	if (options->fingerprint_hash == -1)
420		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
421	if (options->disable_forwarding == -1)
422		options->disable_forwarding = 0;
423	if (options->expose_userauth_info == -1)
424		options->expose_userauth_info = 0;
425	if (options->use_blacklist == -1)
426		options->use_blacklist = 0;
427
428	assemble_algorithms(options);
429
430	/* Turn privilege separation and sandboxing on by default */
431	if (use_privsep == -1)
432		use_privsep = PRIVSEP_ON;
433
434#define CLEAR_ON_NONE(v) \
435	do { \
436		if (option_clear_or_none(v)) { \
437			free(v); \
438			v = NULL; \
439		} \
440	} while(0)
441	CLEAR_ON_NONE(options->pid_file);
442	CLEAR_ON_NONE(options->xauth_location);
443	CLEAR_ON_NONE(options->banner);
444	CLEAR_ON_NONE(options->trusted_user_ca_keys);
445	CLEAR_ON_NONE(options->revoked_keys_file);
446	CLEAR_ON_NONE(options->authorized_principals_file);
447	CLEAR_ON_NONE(options->adm_forced_command);
448	CLEAR_ON_NONE(options->chroot_directory);
449	CLEAR_ON_NONE(options->routing_domain);
450	for (i = 0; i < options->num_host_key_files; i++)
451		CLEAR_ON_NONE(options->host_key_files[i]);
452	for (i = 0; i < options->num_host_cert_files; i++)
453		CLEAR_ON_NONE(options->host_cert_files[i]);
454#undef CLEAR_ON_NONE
455
456	/* Similar handling for AuthenticationMethods=any */
457	if (options->num_auth_methods == 1 &&
458	    strcmp(options->auth_methods[0], "any") == 0) {
459		free(options->auth_methods[0]);
460		options->auth_methods[0] = NULL;
461		options->num_auth_methods = 0;
462	}
463
464#ifndef HAVE_MMAP
465	if (use_privsep && options->compression == 1) {
466		error("This platform does not support both privilege "
467		    "separation and compression");
468		error("Compression disabled");
469		options->compression = 0;
470	}
471#endif
472
473}
474
475/* Keyword tokens. */
476typedef enum {
477	sBadOption,		/* == unknown option */
478	/* Portable-specific options */
479	sUsePAM,
480	/* Standard Options */
481	sPort, sHostKeyFile, sLoginGraceTime,
482	sPermitRootLogin, sLogFacility, sLogLevel,
483	sRhostsRSAAuthentication, sRSAAuthentication,
484	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
485	sKerberosGetAFSToken, sChallengeResponseAuthentication,
486	sPasswordAuthentication, sKbdInteractiveAuthentication,
487	sListenAddress, sAddressFamily,
488	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
489	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
490	sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
491	sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
492	sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
493	sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile,
494	sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes,
495	sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
496	sBanner, sUseDNS, sHostbasedAuthentication,
497	sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes,
498	sHostKeyAlgorithms,
499	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
500	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
501	sAcceptEnv, sSetEnv, sPermitTunnel,
502	sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
503	sUsePrivilegeSeparation, sAllowAgentForwarding,
504	sHostCertificate,
505	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
506	sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
507	sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum,
508	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
509	sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
510	sStreamLocalBindMask, sStreamLocalBindUnlink,
511	sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
512	sExposeAuthInfo, sRDomain,
513	sUseBlacklist,
514	sDeprecated, sIgnore, sUnsupported
515} ServerOpCodes;
516
517#define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
518#define SSHCFG_MATCH	0x02	/* allowed inside a Match section */
519#define SSHCFG_ALL	(SSHCFG_GLOBAL|SSHCFG_MATCH)
520
521/* Textual representation of the tokens. */
522static struct {
523	const char *name;
524	ServerOpCodes opcode;
525	u_int flags;
526} keywords[] = {
527	/* Portable-specific options */
528#ifdef USE_PAM
529	{ "usepam", sUsePAM, SSHCFG_GLOBAL },
530#else
531	{ "usepam", sUnsupported, SSHCFG_GLOBAL },
532#endif
533	{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
534	/* Standard Options */
535	{ "port", sPort, SSHCFG_GLOBAL },
536	{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
537	{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },		/* alias */
538	{ "hostkeyagent", sHostKeyAgent, SSHCFG_GLOBAL },
539	{ "pidfile", sPidFile, SSHCFG_GLOBAL },
540	{ "serverkeybits", sDeprecated, SSHCFG_GLOBAL },
541	{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
542	{ "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL },
543	{ "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
544	{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
545	{ "loglevel", sLogLevel, SSHCFG_ALL },
546	{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
547	{ "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL },
548	{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
549	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
550	{ "hostbasedacceptedkeytypes", sHostbasedAcceptedKeyTypes, SSHCFG_ALL },
551	{ "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL },
552	{ "rsaauthentication", sDeprecated, SSHCFG_ALL },
553	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
554	{ "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL },
555	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
556#ifdef KRB5
557	{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
558	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
559	{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
560#ifdef USE_AFS
561	{ "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
562#else
563	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
564#endif
565#else
566	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
567	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
568	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
569	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
570#endif
571	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
572	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
573#ifdef GSSAPI
574	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
575	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
576	{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
577#else
578	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
579	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
580	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
581#endif
582	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
583	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
584	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
585	{ "skeyauthentication", sDeprecated, SSHCFG_GLOBAL },
586	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
587	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
588	{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
589	{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
590#ifdef DISABLE_LASTLOG
591	{ "printlastlog", sUnsupported, SSHCFG_GLOBAL },
592#else
593	{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
594#endif
595	{ "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
596	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
597	{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
598	{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
599	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
600	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
601	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
602	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
603	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
604	{ "uselogin", sDeprecated, SSHCFG_GLOBAL },
605	{ "compression", sCompression, SSHCFG_GLOBAL },
606	{ "rekeylimit", sRekeyLimit, SSHCFG_ALL },
607	{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
608	{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },	/* obsolete alias */
609	{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
610	{ "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
611	{ "allowusers", sAllowUsers, SSHCFG_ALL },
612	{ "denyusers", sDenyUsers, SSHCFG_ALL },
613	{ "allowgroups", sAllowGroups, SSHCFG_ALL },
614	{ "denygroups", sDenyGroups, SSHCFG_ALL },
615	{ "ciphers", sCiphers, SSHCFG_GLOBAL },
616	{ "macs", sMacs, SSHCFG_GLOBAL },
617	{ "protocol", sIgnore, SSHCFG_GLOBAL },
618	{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
619	{ "subsystem", sSubsystem, SSHCFG_GLOBAL },
620	{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
621	{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
622	{ "maxsessions", sMaxSessions, SSHCFG_ALL },
623	{ "banner", sBanner, SSHCFG_ALL },
624	{ "usedns", sUseDNS, SSHCFG_GLOBAL },
625	{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
626	{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
627	{ "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL },
628	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL },
629	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
630	{ "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
631	{ "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL},
632	{ "acceptenv", sAcceptEnv, SSHCFG_ALL },
633	{ "setenv", sSetEnv, SSHCFG_ALL },
634	{ "permittunnel", sPermitTunnel, SSHCFG_ALL },
635	{ "permittty", sPermitTTY, SSHCFG_ALL },
636	{ "permituserrc", sPermitUserRC, SSHCFG_ALL },
637	{ "match", sMatch, SSHCFG_ALL },
638	{ "permitopen", sPermitOpen, SSHCFG_ALL },
639	{ "permitlisten", sPermitListen, SSHCFG_ALL },
640	{ "forcecommand", sForceCommand, SSHCFG_ALL },
641	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
642	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
643	{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
644	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
645	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
646	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
647	{ "ipqos", sIPQoS, SSHCFG_ALL },
648	{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
649	{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
650	{ "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL },
651	{ "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL },
652	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
653	{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
654	{ "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
655	{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
656	{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
657	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
658	{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
659	{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
660	{ "rdomain", sRDomain, SSHCFG_ALL },
661	{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
662	{ "useblacklist", sUseBlacklist, SSHCFG_GLOBAL },
663	{ "useblocklist", sUseBlacklist, SSHCFG_GLOBAL }, /* alias */
664	{ "noneenabled", sUnsupported, SSHCFG_ALL },
665	{ "hpndisabled", sDeprecated, SSHCFG_ALL },
666	{ "hpnbuffersize", sDeprecated, SSHCFG_ALL },
667	{ "tcprcvbufpoll", sDeprecated, SSHCFG_ALL },
668	{ NULL, sBadOption, 0 }
669};
670
671static struct {
672	int val;
673	char *text;
674} tunmode_desc[] = {
675	{ SSH_TUNMODE_NO, "no" },
676	{ SSH_TUNMODE_POINTOPOINT, "point-to-point" },
677	{ SSH_TUNMODE_ETHERNET, "ethernet" },
678	{ SSH_TUNMODE_YES, "yes" },
679	{ -1, NULL }
680};
681
682/* Returns an opcode name from its number */
683
684static const char *
685lookup_opcode_name(ServerOpCodes code)
686{
687	u_int i;
688
689	for (i = 0; keywords[i].name != NULL; i++)
690		if (keywords[i].opcode == code)
691			return(keywords[i].name);
692	return "UNKNOWN";
693}
694
695
696/*
697 * Returns the number of the token pointed to by cp or sBadOption.
698 */
699
700static ServerOpCodes
701parse_token(const char *cp, const char *filename,
702	    int linenum, u_int *flags)
703{
704	u_int i;
705
706	for (i = 0; keywords[i].name; i++)
707		if (strcasecmp(cp, keywords[i].name) == 0) {
708			*flags = keywords[i].flags;
709			return keywords[i].opcode;
710		}
711
712	error("%s: line %d: Bad configuration option: %s",
713	    filename, linenum, cp);
714	return sBadOption;
715}
716
717char *
718derelativise_path(const char *path)
719{
720	char *expanded, *ret, cwd[PATH_MAX];
721
722	if (strcasecmp(path, "none") == 0)
723		return xstrdup("none");
724	expanded = tilde_expand_filename(path, getuid());
725	if (*expanded == '/')
726		return expanded;
727	if (getcwd(cwd, sizeof(cwd)) == NULL)
728		fatal("%s: getcwd: %s", __func__, strerror(errno));
729	xasprintf(&ret, "%s/%s", cwd, expanded);
730	free(expanded);
731	return ret;
732}
733
734static void
735add_listen_addr(ServerOptions *options, const char *addr,
736    const char *rdomain, int port)
737{
738	u_int i;
739
740	if (port > 0)
741		add_one_listen_addr(options, addr, rdomain, port);
742	else {
743		for (i = 0; i < options->num_ports; i++) {
744			add_one_listen_addr(options, addr, rdomain,
745			    options->ports[i]);
746		}
747	}
748}
749
750static void
751add_one_listen_addr(ServerOptions *options, const char *addr,
752    const char *rdomain, int port)
753{
754	struct addrinfo hints, *ai, *aitop;
755	char strport[NI_MAXSERV];
756	int gaierr;
757	u_int i;
758
759	/* Find listen_addrs entry for this rdomain */
760	for (i = 0; i < options->num_listen_addrs; i++) {
761		if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
762			break;
763		if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
764			continue;
765		if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
766			break;
767	}
768	if (i >= options->num_listen_addrs) {
769		/* No entry for this rdomain; allocate one */
770		if (i >= INT_MAX)
771			fatal("%s: too many listen addresses", __func__);
772		options->listen_addrs = xrecallocarray(options->listen_addrs,
773		    options->num_listen_addrs, options->num_listen_addrs + 1,
774		    sizeof(*options->listen_addrs));
775		i = options->num_listen_addrs++;
776		if (rdomain != NULL)
777			options->listen_addrs[i].rdomain = xstrdup(rdomain);
778	}
779	/* options->listen_addrs[i] points to the addresses for this rdomain */
780
781	memset(&hints, 0, sizeof(hints));
782	hints.ai_family = options->address_family;
783	hints.ai_socktype = SOCK_STREAM;
784	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
785	snprintf(strport, sizeof strport, "%d", port);
786	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
787		fatal("bad addr or host: %s (%s)",
788		    addr ? addr : "<NULL>",
789		    ssh_gai_strerror(gaierr));
790	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
791		;
792	ai->ai_next = options->listen_addrs[i].addrs;
793	options->listen_addrs[i].addrs = aitop;
794}
795
796/* Returns nonzero if the routing domain name is valid */
797static int
798valid_rdomain(const char *name)
799{
800#if defined(HAVE_SYS_VALID_RDOMAIN)
801	return sys_valid_rdomain(name);
802#elif defined(__OpenBSD__)
803	const char *errstr;
804	long long num;
805	struct rt_tableinfo info;
806	int mib[6];
807	size_t miblen = sizeof(mib);
808
809	if (name == NULL)
810		return 1;
811
812	num = strtonum(name, 0, 255, &errstr);
813	if (errstr != NULL)
814		return 0;
815
816	/* Check whether the table actually exists */
817	memset(mib, 0, sizeof(mib));
818	mib[0] = CTL_NET;
819	mib[1] = PF_ROUTE;
820	mib[4] = NET_RT_TABLE;
821	mib[5] = (int)num;
822	if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
823		return 0;
824
825	return 1;
826#else /* defined(__OpenBSD__) */
827	error("Routing domains are not supported on this platform");
828	return 0;
829#endif
830}
831
832/*
833 * Queue a ListenAddress to be processed once we have all of the Ports
834 * and AddressFamily options.
835 */
836static void
837queue_listen_addr(ServerOptions *options, const char *addr,
838    const char *rdomain, int port)
839{
840	struct queued_listenaddr *qla;
841
842	options->queued_listen_addrs = xrecallocarray(
843	    options->queued_listen_addrs,
844	    options->num_queued_listens, options->num_queued_listens + 1,
845	    sizeof(*options->queued_listen_addrs));
846	qla = &options->queued_listen_addrs[options->num_queued_listens++];
847	qla->addr = xstrdup(addr);
848	qla->port = port;
849	qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
850}
851
852/*
853 * Process queued (text) ListenAddress entries.
854 */
855static void
856process_queued_listen_addrs(ServerOptions *options)
857{
858	u_int i;
859	struct queued_listenaddr *qla;
860
861	if (options->num_ports == 0)
862		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
863	if (options->address_family == -1)
864		options->address_family = AF_UNSPEC;
865
866	for (i = 0; i < options->num_queued_listens; i++) {
867		qla = &options->queued_listen_addrs[i];
868		add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
869		free(qla->addr);
870		free(qla->rdomain);
871	}
872	free(options->queued_listen_addrs);
873	options->queued_listen_addrs = NULL;
874	options->num_queued_listens = 0;
875}
876
877/*
878 * Inform channels layer of permitopen options for a single forwarding
879 * direction (local/remote).
880 */
881static void
882process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode,
883    char **opens, u_int num_opens)
884{
885	u_int i;
886	int port;
887	char *host, *arg, *oarg;
888	int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE;
889	const char *what = lookup_opcode_name(opcode);
890
891	channel_clear_permission(ssh, FORWARD_ADM, where);
892	if (num_opens == 0)
893		return; /* permit any */
894
895	/* handle keywords: "any" / "none" */
896	if (num_opens == 1 && strcmp(opens[0], "any") == 0)
897		return;
898	if (num_opens == 1 && strcmp(opens[0], "none") == 0) {
899		channel_disable_admin(ssh, where);
900		return;
901	}
902	/* Otherwise treat it as a list of permitted host:port */
903	for (i = 0; i < num_opens; i++) {
904		oarg = arg = xstrdup(opens[i]);
905		host = hpdelim(&arg);
906		if (host == NULL)
907			fatal("%s: missing host in %s", __func__, what);
908		host = cleanhostname(host);
909		if (arg == NULL || ((port = permitopen_port(arg)) < 0))
910			fatal("%s: bad port number in %s", __func__, what);
911		/* Send it to channels layer */
912		channel_add_permission(ssh, FORWARD_ADM,
913		    where, host, port);
914		free(oarg);
915	}
916}
917
918/*
919 * Inform channels layer of permitopen options from configuration.
920 */
921void
922process_permitopen(struct ssh *ssh, ServerOptions *options)
923{
924	process_permitopen_list(ssh, sPermitOpen,
925	    options->permitted_opens, options->num_permitted_opens);
926	process_permitopen_list(ssh, sPermitListen,
927	    options->permitted_listens,
928	    options->num_permitted_listens);
929}
930
931struct connection_info *
932get_connection_info(int populate, int use_dns)
933{
934	struct ssh *ssh = active_state; /* XXX */
935	static struct connection_info ci;
936
937	if (!populate)
938		return &ci;
939	ci.host = auth_get_canonical_hostname(ssh, use_dns);
940	ci.address = ssh_remote_ipaddr(ssh);
941	ci.laddress = ssh_local_ipaddr(ssh);
942	ci.lport = ssh_local_port(ssh);
943	ci.rdomain = ssh_packet_rdomain_in(ssh);
944	return &ci;
945}
946
947/*
948 * The strategy for the Match blocks is that the config file is parsed twice.
949 *
950 * The first time is at startup.  activep is initialized to 1 and the
951 * directives in the global context are processed and acted on.  Hitting a
952 * Match directive unsets activep and the directives inside the block are
953 * checked for syntax only.
954 *
955 * The second time is after a connection has been established but before
956 * authentication.  activep is initialized to 2 and global config directives
957 * are ignored since they have already been processed.  If the criteria in a
958 * Match block is met, activep is set and the subsequent directives
959 * processed and actioned until EOF or another Match block unsets it.  Any
960 * options set are copied into the main server config.
961 *
962 * Potential additions/improvements:
963 *  - Add Match support for pre-kex directives, eg. Ciphers.
964 *
965 *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
966 *	Match Address 192.168.0.*
967 *		Tag trusted
968 *	Match Group wheel
969 *		Tag trusted
970 *	Match Tag trusted
971 *		AllowTcpForwarding yes
972 *		GatewayPorts clientspecified
973 *		[...]
974 *
975 *  - Add a PermittedChannelRequests directive
976 *	Match Group shell
977 *		PermittedChannelRequests session,forwarded-tcpip
978 */
979
980static int
981match_cfg_line_group(const char *grps, int line, const char *user)
982{
983	int result = 0;
984	struct passwd *pw;
985
986	if (user == NULL)
987		goto out;
988
989	if ((pw = getpwnam(user)) == NULL) {
990		debug("Can't match group at line %d because user %.100s does "
991		    "not exist", line, user);
992	} else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
993		debug("Can't Match group because user %.100s not in any group "
994		    "at line %d", user, line);
995	} else if (ga_match_pattern_list(grps) != 1) {
996		debug("user %.100s does not match group list %.100s at line %d",
997		    user, grps, line);
998	} else {
999		debug("user %.100s matched group list %.100s at line %d", user,
1000		    grps, line);
1001		result = 1;
1002	}
1003out:
1004	ga_free();
1005	return result;
1006}
1007
1008static void
1009match_test_missing_fatal(const char *criteria, const char *attrib)
1010{
1011	fatal("'Match %s' in configuration but '%s' not in connection "
1012	    "test specification.", criteria, attrib);
1013}
1014
1015/*
1016 * All of the attributes on a single Match line are ANDed together, so we need
1017 * to check every attribute and set the result to zero if any attribute does
1018 * not match.
1019 */
1020static int
1021match_cfg_line(char **condition, int line, struct connection_info *ci)
1022{
1023	int result = 1, attributes = 0, port;
1024	char *arg, *attrib, *cp = *condition;
1025
1026	if (ci == NULL)
1027		debug3("checking syntax for 'Match %s'", cp);
1028	else
1029		debug3("checking match for '%s' user %s host %s addr %s "
1030		    "laddr %s lport %d", cp, ci->user ? ci->user : "(null)",
1031		    ci->host ? ci->host : "(null)",
1032		    ci->address ? ci->address : "(null)",
1033		    ci->laddress ? ci->laddress : "(null)", ci->lport);
1034
1035	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
1036		attributes++;
1037		if (strcasecmp(attrib, "all") == 0) {
1038			if (attributes != 1 ||
1039			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
1040				error("'all' cannot be combined with other "
1041				    "Match attributes");
1042				return -1;
1043			}
1044			*condition = cp;
1045			return 1;
1046		}
1047		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
1048			error("Missing Match criteria for %s", attrib);
1049			return -1;
1050		}
1051		if (strcasecmp(attrib, "user") == 0) {
1052			if (ci == NULL) {
1053				result = 0;
1054				continue;
1055			}
1056			if (ci->user == NULL)
1057				match_test_missing_fatal("User", "user");
1058			if (match_pattern_list(ci->user, arg, 0) != 1)
1059				result = 0;
1060			else
1061				debug("user %.100s matched 'User %.100s' at "
1062				    "line %d", ci->user, arg, line);
1063		} else if (strcasecmp(attrib, "group") == 0) {
1064			if (ci == NULL) {
1065				result = 0;
1066				continue;
1067			}
1068			if (ci->user == NULL)
1069				match_test_missing_fatal("Group", "user");
1070			switch (match_cfg_line_group(arg, line, ci->user)) {
1071			case -1:
1072				return -1;
1073			case 0:
1074				result = 0;
1075			}
1076		} else if (strcasecmp(attrib, "host") == 0) {
1077			if (ci == NULL) {
1078				result = 0;
1079				continue;
1080			}
1081			if (ci->host == NULL)
1082				match_test_missing_fatal("Host", "host");
1083			if (match_hostname(ci->host, arg) != 1)
1084				result = 0;
1085			else
1086				debug("connection from %.100s matched 'Host "
1087				    "%.100s' at line %d", ci->host, arg, line);
1088		} else if (strcasecmp(attrib, "address") == 0) {
1089			if (ci == NULL) {
1090				result = 0;
1091				continue;
1092			}
1093			if (ci->address == NULL)
1094				match_test_missing_fatal("Address", "addr");
1095			switch (addr_match_list(ci->address, arg)) {
1096			case 1:
1097				debug("connection from %.100s matched 'Address "
1098				    "%.100s' at line %d", ci->address, arg, line);
1099				break;
1100			case 0:
1101			case -1:
1102				result = 0;
1103				break;
1104			case -2:
1105				return -1;
1106			}
1107		} else if (strcasecmp(attrib, "localaddress") == 0){
1108			if (ci == NULL) {
1109				result = 0;
1110				continue;
1111			}
1112			if (ci->laddress == NULL)
1113				match_test_missing_fatal("LocalAddress",
1114				    "laddr");
1115			switch (addr_match_list(ci->laddress, arg)) {
1116			case 1:
1117				debug("connection from %.100s matched "
1118				    "'LocalAddress %.100s' at line %d",
1119				    ci->laddress, arg, line);
1120				break;
1121			case 0:
1122			case -1:
1123				result = 0;
1124				break;
1125			case -2:
1126				return -1;
1127			}
1128		} else if (strcasecmp(attrib, "localport") == 0) {
1129			if ((port = a2port(arg)) == -1) {
1130				error("Invalid LocalPort '%s' on Match line",
1131				    arg);
1132				return -1;
1133			}
1134			if (ci == NULL) {
1135				result = 0;
1136				continue;
1137			}
1138			if (ci->lport == 0)
1139				match_test_missing_fatal("LocalPort", "lport");
1140			/* TODO support port lists */
1141			if (port == ci->lport)
1142				debug("connection from %.100s matched "
1143				    "'LocalPort %d' at line %d",
1144				    ci->laddress, port, line);
1145			else
1146				result = 0;
1147		} else if (strcasecmp(attrib, "rdomain") == 0) {
1148			if (ci == NULL || ci->rdomain == NULL) {
1149				result = 0;
1150				continue;
1151			}
1152			if (match_pattern_list(ci->rdomain, arg, 0) != 1)
1153				result = 0;
1154			else
1155				debug("user %.100s matched 'RDomain %.100s' at "
1156				    "line %d", ci->rdomain, arg, line);
1157		} else {
1158			error("Unsupported Match attribute %s", attrib);
1159			return -1;
1160		}
1161	}
1162	if (attributes == 0) {
1163		error("One or more attributes required for Match");
1164		return -1;
1165	}
1166	if (ci != NULL)
1167		debug3("match %sfound", result ? "" : "not ");
1168	*condition = cp;
1169	return result;
1170}
1171
1172#define WHITESPACE " \t\r\n"
1173
1174/* Multistate option parsing */
1175struct multistate {
1176	char *key;
1177	int value;
1178};
1179static const struct multistate multistate_flag[] = {
1180	{ "yes",			1 },
1181	{ "no",				0 },
1182	{ NULL, -1 }
1183};
1184static const struct multistate multistate_addressfamily[] = {
1185	{ "inet",			AF_INET },
1186	{ "inet6",			AF_INET6 },
1187	{ "any",			AF_UNSPEC },
1188	{ NULL, -1 }
1189};
1190static const struct multistate multistate_permitrootlogin[] = {
1191	{ "without-password",		PERMIT_NO_PASSWD },
1192	{ "prohibit-password",		PERMIT_NO_PASSWD },
1193	{ "forced-commands-only",	PERMIT_FORCED_ONLY },
1194	{ "yes",			PERMIT_YES },
1195	{ "no",				PERMIT_NO },
1196	{ NULL, -1 }
1197};
1198static const struct multistate multistate_compression[] = {
1199	{ "yes",			COMP_DELAYED },
1200	{ "delayed",			COMP_DELAYED },
1201	{ "no",				COMP_NONE },
1202	{ NULL, -1 }
1203};
1204static const struct multistate multistate_gatewayports[] = {
1205	{ "clientspecified",		2 },
1206	{ "yes",			1 },
1207	{ "no",				0 },
1208	{ NULL, -1 }
1209};
1210static const struct multistate multistate_tcpfwd[] = {
1211	{ "yes",			FORWARD_ALLOW },
1212	{ "all",			FORWARD_ALLOW },
1213	{ "no",				FORWARD_DENY },
1214	{ "remote",			FORWARD_REMOTE },
1215	{ "local",			FORWARD_LOCAL },
1216	{ NULL, -1 }
1217};
1218
1219int
1220process_server_config_line(ServerOptions *options, char *line,
1221    const char *filename, int linenum, int *activep,
1222    struct connection_info *connectinfo)
1223{
1224	char *cp, ***chararrayptr, **charptr, *arg, *arg2, *p;
1225	int cmdline = 0, *intptr, value, value2, n, port;
1226	SyslogFacility *log_facility_ptr;
1227	LogLevel *log_level_ptr;
1228	ServerOpCodes opcode;
1229	u_int i, *uintptr, uvalue, flags = 0;
1230	size_t len;
1231	long long val64;
1232	const struct multistate *multistate_ptr;
1233	const char *errstr;
1234
1235	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
1236	if ((len = strlen(line)) == 0)
1237		return 0;
1238	for (len--; len > 0; len--) {
1239		if (strchr(WHITESPACE "\f", line[len]) == NULL)
1240			break;
1241		line[len] = '\0';
1242	}
1243
1244	cp = line;
1245	if ((arg = strdelim(&cp)) == NULL)
1246		return 0;
1247	/* Ignore leading whitespace */
1248	if (*arg == '\0')
1249		arg = strdelim(&cp);
1250	if (!arg || !*arg || *arg == '#')
1251		return 0;
1252	intptr = NULL;
1253	charptr = NULL;
1254	opcode = parse_token(arg, filename, linenum, &flags);
1255
1256	if (activep == NULL) { /* We are processing a command line directive */
1257		cmdline = 1;
1258		activep = &cmdline;
1259	}
1260	if (*activep && opcode != sMatch)
1261		debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
1262	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
1263		if (connectinfo == NULL) {
1264			fatal("%s line %d: Directive '%s' is not allowed "
1265			    "within a Match block", filename, linenum, arg);
1266		} else { /* this is a directive we have already processed */
1267			while (arg)
1268				arg = strdelim(&cp);
1269			return 0;
1270		}
1271	}
1272
1273	switch (opcode) {
1274	/* Portable-specific options */
1275	case sUsePAM:
1276		intptr = &options->use_pam;
1277		goto parse_flag;
1278
1279	/* Standard Options */
1280	case sBadOption:
1281		return -1;
1282	case sPort:
1283		/* ignore ports from configfile if cmdline specifies ports */
1284		if (options->ports_from_cmdline)
1285			return 0;
1286		if (options->num_ports >= MAX_PORTS)
1287			fatal("%s line %d: too many ports.",
1288			    filename, linenum);
1289		arg = strdelim(&cp);
1290		if (!arg || *arg == '\0')
1291			fatal("%s line %d: missing port number.",
1292			    filename, linenum);
1293		options->ports[options->num_ports++] = a2port(arg);
1294		if (options->ports[options->num_ports-1] <= 0)
1295			fatal("%s line %d: Badly formatted port number.",
1296			    filename, linenum);
1297		break;
1298
1299	case sLoginGraceTime:
1300		intptr = &options->login_grace_time;
1301 parse_time:
1302		arg = strdelim(&cp);
1303		if (!arg || *arg == '\0')
1304			fatal("%s line %d: missing time value.",
1305			    filename, linenum);
1306		if ((value = convtime(arg)) == -1)
1307			fatal("%s line %d: invalid time value.",
1308			    filename, linenum);
1309		if (*activep && *intptr == -1)
1310			*intptr = value;
1311		break;
1312
1313	case sListenAddress:
1314		arg = strdelim(&cp);
1315		if (arg == NULL || *arg == '\0')
1316			fatal("%s line %d: missing address",
1317			    filename, linenum);
1318		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
1319		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
1320		    && strchr(p+1, ':') != NULL) {
1321			port = 0;
1322			p = arg;
1323		} else {
1324			p = hpdelim(&arg);
1325			if (p == NULL)
1326				fatal("%s line %d: bad address:port usage",
1327				    filename, linenum);
1328			p = cleanhostname(p);
1329			if (arg == NULL)
1330				port = 0;
1331			else if ((port = a2port(arg)) <= 0)
1332				fatal("%s line %d: bad port number",
1333				    filename, linenum);
1334		}
1335		/* Optional routing table */
1336		arg2 = NULL;
1337		if ((arg = strdelim(&cp)) != NULL) {
1338			if (strcmp(arg, "rdomain") != 0 ||
1339			    (arg2 = strdelim(&cp)) == NULL)
1340				fatal("%s line %d: bad ListenAddress syntax",
1341				    filename, linenum);
1342			if (!valid_rdomain(arg2))
1343				fatal("%s line %d: bad routing domain",
1344				    filename, linenum);
1345		}
1346
1347		queue_listen_addr(options, p, arg2, port);
1348
1349		break;
1350
1351	case sAddressFamily:
1352		intptr = &options->address_family;
1353		multistate_ptr = multistate_addressfamily;
1354 parse_multistate:
1355		arg = strdelim(&cp);
1356		if (!arg || *arg == '\0')
1357			fatal("%s line %d: missing argument.",
1358			    filename, linenum);
1359		value = -1;
1360		for (i = 0; multistate_ptr[i].key != NULL; i++) {
1361			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
1362				value = multistate_ptr[i].value;
1363				break;
1364			}
1365		}
1366		if (value == -1)
1367			fatal("%s line %d: unsupported option \"%s\".",
1368			    filename, linenum, arg);
1369		if (*activep && *intptr == -1)
1370			*intptr = value;
1371		break;
1372
1373	case sHostKeyFile:
1374		arg = strdelim(&cp);
1375		if (!arg || *arg == '\0')
1376			fatal("%s line %d: missing file name.",
1377			    filename, linenum);
1378		if (*activep)
1379			servconf_add_hostkey(filename, linenum, options, arg);
1380		break;
1381
1382	case sHostKeyAgent:
1383		charptr = &options->host_key_agent;
1384		arg = strdelim(&cp);
1385		if (!arg || *arg == '\0')
1386			fatal("%s line %d: missing socket name.",
1387			    filename, linenum);
1388		if (*activep && *charptr == NULL)
1389			*charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ?
1390			    xstrdup(arg) : derelativise_path(arg);
1391		break;
1392
1393	case sHostCertificate:
1394		arg = strdelim(&cp);
1395		if (!arg || *arg == '\0')
1396			fatal("%s line %d: missing file name.",
1397			    filename, linenum);
1398		if (*activep)
1399			servconf_add_hostcert(filename, linenum, options, arg);
1400		break;
1401
1402	case sPidFile:
1403		charptr = &options->pid_file;
1404 parse_filename:
1405		arg = strdelim(&cp);
1406		if (!arg || *arg == '\0')
1407			fatal("%s line %d: missing file name.",
1408			    filename, linenum);
1409		if (*activep && *charptr == NULL) {
1410			*charptr = derelativise_path(arg);
1411			/* increase optional counter */
1412			if (intptr != NULL)
1413				*intptr = *intptr + 1;
1414		}
1415		break;
1416
1417	case sPermitRootLogin:
1418		intptr = &options->permit_root_login;
1419		multistate_ptr = multistate_permitrootlogin;
1420		goto parse_multistate;
1421
1422	case sIgnoreRhosts:
1423		intptr = &options->ignore_rhosts;
1424 parse_flag:
1425		multistate_ptr = multistate_flag;
1426		goto parse_multistate;
1427
1428	case sIgnoreUserKnownHosts:
1429		intptr = &options->ignore_user_known_hosts;
1430		goto parse_flag;
1431
1432	case sHostbasedAuthentication:
1433		intptr = &options->hostbased_authentication;
1434		goto parse_flag;
1435
1436	case sHostbasedUsesNameFromPacketOnly:
1437		intptr = &options->hostbased_uses_name_from_packet_only;
1438		goto parse_flag;
1439
1440	case sHostbasedAcceptedKeyTypes:
1441		charptr = &options->hostbased_key_types;
1442 parse_keytypes:
1443		arg = strdelim(&cp);
1444		if (!arg || *arg == '\0')
1445			fatal("%s line %d: Missing argument.",
1446			    filename, linenum);
1447		if (*arg != '-' &&
1448		    !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1449			fatal("%s line %d: Bad key types '%s'.",
1450			    filename, linenum, arg ? arg : "<NONE>");
1451		if (*activep && *charptr == NULL)
1452			*charptr = xstrdup(arg);
1453		break;
1454
1455	case sHostKeyAlgorithms:
1456		charptr = &options->hostkeyalgorithms;
1457		goto parse_keytypes;
1458
1459	case sCASignatureAlgorithms:
1460		charptr = &options->ca_sign_algorithms;
1461		goto parse_keytypes;
1462
1463	case sPubkeyAuthentication:
1464		intptr = &options->pubkey_authentication;
1465		goto parse_flag;
1466
1467	case sPubkeyAcceptedKeyTypes:
1468		charptr = &options->pubkey_key_types;
1469		goto parse_keytypes;
1470
1471	case sKerberosAuthentication:
1472		intptr = &options->kerberos_authentication;
1473		goto parse_flag;
1474
1475	case sKerberosOrLocalPasswd:
1476		intptr = &options->kerberos_or_local_passwd;
1477		goto parse_flag;
1478
1479	case sKerberosTicketCleanup:
1480		intptr = &options->kerberos_ticket_cleanup;
1481		goto parse_flag;
1482
1483	case sKerberosGetAFSToken:
1484		intptr = &options->kerberos_get_afs_token;
1485		goto parse_flag;
1486
1487	case sGssAuthentication:
1488		intptr = &options->gss_authentication;
1489		goto parse_flag;
1490
1491	case sGssCleanupCreds:
1492		intptr = &options->gss_cleanup_creds;
1493		goto parse_flag;
1494
1495	case sGssStrictAcceptor:
1496		intptr = &options->gss_strict_acceptor;
1497		goto parse_flag;
1498
1499	case sPasswordAuthentication:
1500		intptr = &options->password_authentication;
1501		goto parse_flag;
1502
1503	case sKbdInteractiveAuthentication:
1504		intptr = &options->kbd_interactive_authentication;
1505		goto parse_flag;
1506
1507	case sChallengeResponseAuthentication:
1508		intptr = &options->challenge_response_authentication;
1509		goto parse_flag;
1510
1511	case sPrintMotd:
1512		intptr = &options->print_motd;
1513		goto parse_flag;
1514
1515	case sPrintLastLog:
1516		intptr = &options->print_lastlog;
1517		goto parse_flag;
1518
1519	case sX11Forwarding:
1520		intptr = &options->x11_forwarding;
1521		goto parse_flag;
1522
1523	case sX11DisplayOffset:
1524		intptr = &options->x11_display_offset;
1525 parse_int:
1526		arg = strdelim(&cp);
1527		if ((errstr = atoi_err(arg, &value)) != NULL)
1528			fatal("%s line %d: integer value %s.",
1529			    filename, linenum, errstr);
1530		if (*activep && *intptr == -1)
1531			*intptr = value;
1532		break;
1533
1534	case sX11UseLocalhost:
1535		intptr = &options->x11_use_localhost;
1536		goto parse_flag;
1537
1538	case sXAuthLocation:
1539		charptr = &options->xauth_location;
1540		goto parse_filename;
1541
1542	case sPermitTTY:
1543		intptr = &options->permit_tty;
1544		goto parse_flag;
1545
1546	case sPermitUserRC:
1547		intptr = &options->permit_user_rc;
1548		goto parse_flag;
1549
1550	case sStrictModes:
1551		intptr = &options->strict_modes;
1552		goto parse_flag;
1553
1554	case sTCPKeepAlive:
1555		intptr = &options->tcp_keep_alive;
1556		goto parse_flag;
1557
1558	case sEmptyPasswd:
1559		intptr = &options->permit_empty_passwd;
1560		goto parse_flag;
1561
1562	case sPermitUserEnvironment:
1563		intptr = &options->permit_user_env;
1564		charptr = &options->permit_user_env_whitelist;
1565		arg = strdelim(&cp);
1566		if (!arg || *arg == '\0')
1567			fatal("%s line %d: missing argument.",
1568			    filename, linenum);
1569		value = 0;
1570		p = NULL;
1571		if (strcmp(arg, "yes") == 0)
1572			value = 1;
1573		else if (strcmp(arg, "no") == 0)
1574			value = 0;
1575		else {
1576			/* Pattern-list specified */
1577			value = 1;
1578			p = xstrdup(arg);
1579		}
1580		if (*activep && *intptr == -1) {
1581			*intptr = value;
1582			*charptr = p;
1583			p = NULL;
1584		}
1585		free(p);
1586		break;
1587
1588	case sCompression:
1589		intptr = &options->compression;
1590		multistate_ptr = multistate_compression;
1591		goto parse_multistate;
1592
1593	case sRekeyLimit:
1594		arg = strdelim(&cp);
1595		if (!arg || *arg == '\0')
1596			fatal("%.200s line %d: Missing argument.", filename,
1597			    linenum);
1598		if (strcmp(arg, "default") == 0) {
1599			val64 = 0;
1600		} else {
1601			if (scan_scaled(arg, &val64) == -1)
1602				fatal("%.200s line %d: Bad number '%s': %s",
1603				    filename, linenum, arg, strerror(errno));
1604			if (val64 != 0 && val64 < 16)
1605				fatal("%.200s line %d: RekeyLimit too small",
1606				    filename, linenum);
1607		}
1608		if (*activep && options->rekey_limit == -1)
1609			options->rekey_limit = val64;
1610		if (cp != NULL) { /* optional rekey interval present */
1611			if (strcmp(cp, "none") == 0) {
1612				(void)strdelim(&cp);	/* discard */
1613				break;
1614			}
1615			intptr = &options->rekey_interval;
1616			goto parse_time;
1617		}
1618		break;
1619
1620	case sGatewayPorts:
1621		intptr = &options->fwd_opts.gateway_ports;
1622		multistate_ptr = multistate_gatewayports;
1623		goto parse_multistate;
1624
1625	case sUseDNS:
1626		intptr = &options->use_dns;
1627		goto parse_flag;
1628
1629	case sLogFacility:
1630		log_facility_ptr = &options->log_facility;
1631		arg = strdelim(&cp);
1632		value = log_facility_number(arg);
1633		if (value == SYSLOG_FACILITY_NOT_SET)
1634			fatal("%.200s line %d: unsupported log facility '%s'",
1635			    filename, linenum, arg ? arg : "<NONE>");
1636		if (*log_facility_ptr == -1)
1637			*log_facility_ptr = (SyslogFacility) value;
1638		break;
1639
1640	case sLogLevel:
1641		log_level_ptr = &options->log_level;
1642		arg = strdelim(&cp);
1643		value = log_level_number(arg);
1644		if (value == SYSLOG_LEVEL_NOT_SET)
1645			fatal("%.200s line %d: unsupported log level '%s'",
1646			    filename, linenum, arg ? arg : "<NONE>");
1647		if (*activep && *log_level_ptr == -1)
1648			*log_level_ptr = (LogLevel) value;
1649		break;
1650
1651	case sAllowTcpForwarding:
1652		intptr = &options->allow_tcp_forwarding;
1653		multistate_ptr = multistate_tcpfwd;
1654		goto parse_multistate;
1655
1656	case sAllowStreamLocalForwarding:
1657		intptr = &options->allow_streamlocal_forwarding;
1658		multistate_ptr = multistate_tcpfwd;
1659		goto parse_multistate;
1660
1661	case sAllowAgentForwarding:
1662		intptr = &options->allow_agent_forwarding;
1663		goto parse_flag;
1664
1665	case sDisableForwarding:
1666		intptr = &options->disable_forwarding;
1667		goto parse_flag;
1668
1669	case sAllowUsers:
1670		while ((arg = strdelim(&cp)) && *arg != '\0') {
1671			if (match_user(NULL, NULL, NULL, arg) == -1)
1672				fatal("%s line %d: invalid AllowUsers pattern: "
1673				    "\"%.100s\"", filename, linenum, arg);
1674			if (!*activep)
1675				continue;
1676			array_append(filename, linenum, "AllowUsers",
1677			    &options->allow_users, &options->num_allow_users,
1678			    arg);
1679		}
1680		break;
1681
1682	case sDenyUsers:
1683		while ((arg = strdelim(&cp)) && *arg != '\0') {
1684			if (match_user(NULL, NULL, NULL, arg) == -1)
1685				fatal("%s line %d: invalid DenyUsers pattern: "
1686				    "\"%.100s\"", filename, linenum, arg);
1687			if (!*activep)
1688				continue;
1689			array_append(filename, linenum, "DenyUsers",
1690			    &options->deny_users, &options->num_deny_users,
1691			    arg);
1692		}
1693		break;
1694
1695	case sAllowGroups:
1696		while ((arg = strdelim(&cp)) && *arg != '\0') {
1697			if (!*activep)
1698				continue;
1699			array_append(filename, linenum, "AllowGroups",
1700			    &options->allow_groups, &options->num_allow_groups,
1701			    arg);
1702		}
1703		break;
1704
1705	case sDenyGroups:
1706		while ((arg = strdelim(&cp)) && *arg != '\0') {
1707			if (!*activep)
1708				continue;
1709			array_append(filename, linenum, "DenyGroups",
1710			    &options->deny_groups, &options->num_deny_groups,
1711			    arg);
1712		}
1713		break;
1714
1715	case sCiphers:
1716		arg = strdelim(&cp);
1717		if (!arg || *arg == '\0')
1718			fatal("%s line %d: Missing argument.", filename, linenum);
1719		if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))
1720			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1721			    filename, linenum, arg ? arg : "<NONE>");
1722		if (options->ciphers == NULL)
1723			options->ciphers = xstrdup(arg);
1724		break;
1725
1726	case sMacs:
1727		arg = strdelim(&cp);
1728		if (!arg || *arg == '\0')
1729			fatal("%s line %d: Missing argument.", filename, linenum);
1730		if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))
1731			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1732			    filename, linenum, arg ? arg : "<NONE>");
1733		if (options->macs == NULL)
1734			options->macs = xstrdup(arg);
1735		break;
1736
1737	case sKexAlgorithms:
1738		arg = strdelim(&cp);
1739		if (!arg || *arg == '\0')
1740			fatal("%s line %d: Missing argument.",
1741			    filename, linenum);
1742		if (*arg != '-' &&
1743		    !kex_names_valid(*arg == '+' ? arg + 1 : arg))
1744			fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
1745			    filename, linenum, arg ? arg : "<NONE>");
1746		if (options->kex_algorithms == NULL)
1747			options->kex_algorithms = xstrdup(arg);
1748		break;
1749
1750	case sSubsystem:
1751		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1752			fatal("%s line %d: too many subsystems defined.",
1753			    filename, linenum);
1754		}
1755		arg = strdelim(&cp);
1756		if (!arg || *arg == '\0')
1757			fatal("%s line %d: Missing subsystem name.",
1758			    filename, linenum);
1759		if (!*activep) {
1760			arg = strdelim(&cp);
1761			break;
1762		}
1763		for (i = 0; i < options->num_subsystems; i++)
1764			if (strcmp(arg, options->subsystem_name[i]) == 0)
1765				fatal("%s line %d: Subsystem '%s' already defined.",
1766				    filename, linenum, arg);
1767		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1768		arg = strdelim(&cp);
1769		if (!arg || *arg == '\0')
1770			fatal("%s line %d: Missing subsystem command.",
1771			    filename, linenum);
1772		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1773
1774		/* Collect arguments (separate to executable) */
1775		p = xstrdup(arg);
1776		len = strlen(p) + 1;
1777		while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1778			len += 1 + strlen(arg);
1779			p = xreallocarray(p, 1, len);
1780			strlcat(p, " ", len);
1781			strlcat(p, arg, len);
1782		}
1783		options->subsystem_args[options->num_subsystems] = p;
1784		options->num_subsystems++;
1785		break;
1786
1787	case sMaxStartups:
1788		arg = strdelim(&cp);
1789		if (!arg || *arg == '\0')
1790			fatal("%s line %d: Missing MaxStartups spec.",
1791			    filename, linenum);
1792		if ((n = sscanf(arg, "%d:%d:%d",
1793		    &options->max_startups_begin,
1794		    &options->max_startups_rate,
1795		    &options->max_startups)) == 3) {
1796			if (options->max_startups_begin >
1797			    options->max_startups ||
1798			    options->max_startups_rate > 100 ||
1799			    options->max_startups_rate < 1)
1800				fatal("%s line %d: Illegal MaxStartups spec.",
1801				    filename, linenum);
1802		} else if (n != 1)
1803			fatal("%s line %d: Illegal MaxStartups spec.",
1804			    filename, linenum);
1805		else
1806			options->max_startups = options->max_startups_begin;
1807		break;
1808
1809	case sMaxAuthTries:
1810		intptr = &options->max_authtries;
1811		goto parse_int;
1812
1813	case sMaxSessions:
1814		intptr = &options->max_sessions;
1815		goto parse_int;
1816
1817	case sBanner:
1818		charptr = &options->banner;
1819		goto parse_filename;
1820
1821	/*
1822	 * These options can contain %X options expanded at
1823	 * connect time, so that you can specify paths like:
1824	 *
1825	 * AuthorizedKeysFile	/etc/ssh_keys/%u
1826	 */
1827	case sAuthorizedKeysFile:
1828		if (*activep && options->num_authkeys_files == 0) {
1829			while ((arg = strdelim(&cp)) && *arg != '\0') {
1830				arg = tilde_expand_filename(arg, getuid());
1831				array_append(filename, linenum,
1832				    "AuthorizedKeysFile",
1833				    &options->authorized_keys_files,
1834				    &options->num_authkeys_files, arg);
1835				free(arg);
1836			}
1837		}
1838		return 0;
1839
1840	case sAuthorizedPrincipalsFile:
1841		charptr = &options->authorized_principals_file;
1842		arg = strdelim(&cp);
1843		if (!arg || *arg == '\0')
1844			fatal("%s line %d: missing file name.",
1845			    filename, linenum);
1846		if (*activep && *charptr == NULL) {
1847			*charptr = tilde_expand_filename(arg, getuid());
1848			/* increase optional counter */
1849			if (intptr != NULL)
1850				*intptr = *intptr + 1;
1851		}
1852		break;
1853
1854	case sClientAliveInterval:
1855		intptr = &options->client_alive_interval;
1856		goto parse_time;
1857
1858	case sClientAliveCountMax:
1859		intptr = &options->client_alive_count_max;
1860		goto parse_int;
1861
1862	case sAcceptEnv:
1863		while ((arg = strdelim(&cp)) && *arg != '\0') {
1864			if (strchr(arg, '=') != NULL)
1865				fatal("%s line %d: Invalid environment name.",
1866				    filename, linenum);
1867			if (!*activep)
1868				continue;
1869			array_append(filename, linenum, "AcceptEnv",
1870			    &options->accept_env, &options->num_accept_env,
1871			    arg);
1872		}
1873		break;
1874
1875	case sSetEnv:
1876		uvalue = options->num_setenv;
1877		while ((arg = strdelimw(&cp)) && *arg != '\0') {
1878			if (strchr(arg, '=') == NULL)
1879				fatal("%s line %d: Invalid environment.",
1880				    filename, linenum);
1881			if (!*activep || uvalue != 0)
1882				continue;
1883			array_append(filename, linenum, "SetEnv",
1884			    &options->setenv, &options->num_setenv, arg);
1885		}
1886		break;
1887
1888	case sPermitTunnel:
1889		intptr = &options->permit_tun;
1890		arg = strdelim(&cp);
1891		if (!arg || *arg == '\0')
1892			fatal("%s line %d: Missing yes/point-to-point/"
1893			    "ethernet/no argument.", filename, linenum);
1894		value = -1;
1895		for (i = 0; tunmode_desc[i].val != -1; i++)
1896			if (strcmp(tunmode_desc[i].text, arg) == 0) {
1897				value = tunmode_desc[i].val;
1898				break;
1899			}
1900		if (value == -1)
1901			fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1902			    "no argument: %s", filename, linenum, arg);
1903		if (*activep && *intptr == -1)
1904			*intptr = value;
1905		break;
1906
1907	case sMatch:
1908		if (cmdline)
1909			fatal("Match directive not supported as a command-line "
1910			   "option");
1911		value = match_cfg_line(&cp, linenum, connectinfo);
1912		if (value < 0)
1913			fatal("%s line %d: Bad Match condition", filename,
1914			    linenum);
1915		*activep = value;
1916		break;
1917
1918	case sPermitListen:
1919	case sPermitOpen:
1920		if (opcode == sPermitListen) {
1921			uintptr = &options->num_permitted_listens;
1922			chararrayptr = &options->permitted_listens;
1923		} else {
1924			uintptr = &options->num_permitted_opens;
1925			chararrayptr = &options->permitted_opens;
1926		}
1927		arg = strdelim(&cp);
1928		if (!arg || *arg == '\0')
1929			fatal("%s line %d: missing %s specification",
1930			    filename, linenum, lookup_opcode_name(opcode));
1931		uvalue = *uintptr;	/* modified later */
1932		if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
1933			if (*activep && uvalue == 0) {
1934				*uintptr = 1;
1935				*chararrayptr = xcalloc(1,
1936				    sizeof(**chararrayptr));
1937				(*chararrayptr)[0] = xstrdup(arg);
1938			}
1939			break;
1940		}
1941		for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1942			if (opcode == sPermitListen &&
1943			    strchr(arg, ':') == NULL) {
1944				/*
1945				 * Allow bare port number for PermitListen
1946				 * to indicate a wildcard listen host.
1947				 */
1948				xasprintf(&arg2, "*:%s", arg);
1949			} else {
1950				arg2 = xstrdup(arg);
1951				p = hpdelim(&arg);
1952				if (p == NULL) {
1953					fatal("%s line %d: missing host in %s",
1954					    filename, linenum,
1955					    lookup_opcode_name(opcode));
1956				}
1957				p = cleanhostname(p);
1958			}
1959			if (arg == NULL ||
1960			    ((port = permitopen_port(arg)) < 0)) {
1961				fatal("%s line %d: bad port number in %s",
1962				    filename, linenum,
1963				    lookup_opcode_name(opcode));
1964			}
1965			if (*activep && uvalue == 0) {
1966				array_append(filename, linenum,
1967				    lookup_opcode_name(opcode),
1968				    chararrayptr, uintptr, arg2);
1969			}
1970			free(arg2);
1971		}
1972		break;
1973
1974	case sForceCommand:
1975		if (cp == NULL || *cp == '\0')
1976			fatal("%.200s line %d: Missing argument.", filename,
1977			    linenum);
1978		len = strspn(cp, WHITESPACE);
1979		if (*activep && options->adm_forced_command == NULL)
1980			options->adm_forced_command = xstrdup(cp + len);
1981		return 0;
1982
1983	case sChrootDirectory:
1984		charptr = &options->chroot_directory;
1985
1986		arg = strdelim(&cp);
1987		if (!arg || *arg == '\0')
1988			fatal("%s line %d: missing file name.",
1989			    filename, linenum);
1990		if (*activep && *charptr == NULL)
1991			*charptr = xstrdup(arg);
1992		break;
1993
1994	case sTrustedUserCAKeys:
1995		charptr = &options->trusted_user_ca_keys;
1996		goto parse_filename;
1997
1998	case sRevokedKeys:
1999		charptr = &options->revoked_keys_file;
2000		goto parse_filename;
2001
2002	case sIPQoS:
2003		arg = strdelim(&cp);
2004		if ((value = parse_ipqos(arg)) == -1)
2005			fatal("%s line %d: Bad IPQoS value: %s",
2006			    filename, linenum, arg);
2007		arg = strdelim(&cp);
2008		if (arg == NULL)
2009			value2 = value;
2010		else if ((value2 = parse_ipqos(arg)) == -1)
2011			fatal("%s line %d: Bad IPQoS value: %s",
2012			    filename, linenum, arg);
2013		if (*activep) {
2014			options->ip_qos_interactive = value;
2015			options->ip_qos_bulk = value2;
2016		}
2017		break;
2018
2019	case sVersionAddendum:
2020		if (cp == NULL || *cp == '\0')
2021			fatal("%.200s line %d: Missing argument.", filename,
2022			    linenum);
2023		len = strspn(cp, WHITESPACE);
2024		if (*activep && options->version_addendum == NULL) {
2025			if (strcasecmp(cp + len, "none") == 0)
2026				options->version_addendum = xstrdup("");
2027			else if (strchr(cp + len, '\r') != NULL)
2028				fatal("%.200s line %d: Invalid argument",
2029				    filename, linenum);
2030			else
2031				options->version_addendum = xstrdup(cp + len);
2032		}
2033		return 0;
2034
2035	case sAuthorizedKeysCommand:
2036		if (cp == NULL)
2037			fatal("%.200s line %d: Missing argument.", filename,
2038			    linenum);
2039		len = strspn(cp, WHITESPACE);
2040		if (*activep && options->authorized_keys_command == NULL) {
2041			if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
2042				fatal("%.200s line %d: AuthorizedKeysCommand "
2043				    "must be an absolute path",
2044				    filename, linenum);
2045			options->authorized_keys_command = xstrdup(cp + len);
2046		}
2047		return 0;
2048
2049	case sAuthorizedKeysCommandUser:
2050		charptr = &options->authorized_keys_command_user;
2051
2052		arg = strdelim(&cp);
2053		if (!arg || *arg == '\0')
2054			fatal("%s line %d: missing AuthorizedKeysCommandUser "
2055			    "argument.", filename, linenum);
2056		if (*activep && *charptr == NULL)
2057			*charptr = xstrdup(arg);
2058		break;
2059
2060	case sAuthorizedPrincipalsCommand:
2061		if (cp == NULL)
2062			fatal("%.200s line %d: Missing argument.", filename,
2063			    linenum);
2064		len = strspn(cp, WHITESPACE);
2065		if (*activep &&
2066		    options->authorized_principals_command == NULL) {
2067			if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
2068				fatal("%.200s line %d: "
2069				    "AuthorizedPrincipalsCommand must be "
2070				    "an absolute path", filename, linenum);
2071			options->authorized_principals_command =
2072			    xstrdup(cp + len);
2073		}
2074		return 0;
2075
2076	case sAuthorizedPrincipalsCommandUser:
2077		charptr = &options->authorized_principals_command_user;
2078
2079		arg = strdelim(&cp);
2080		if (!arg || *arg == '\0')
2081			fatal("%s line %d: missing "
2082			    "AuthorizedPrincipalsCommandUser argument.",
2083			    filename, linenum);
2084		if (*activep && *charptr == NULL)
2085			*charptr = xstrdup(arg);
2086		break;
2087
2088	case sAuthenticationMethods:
2089		if (options->num_auth_methods == 0) {
2090			value = 0; /* seen "any" pseudo-method */
2091			value2 = 0; /* successfully parsed any method */
2092			while ((arg = strdelim(&cp)) && *arg != '\0') {
2093				if (strcmp(arg, "any") == 0) {
2094					if (options->num_auth_methods > 0) {
2095						fatal("%s line %d: \"any\" "
2096						    "must appear alone in "
2097						    "AuthenticationMethods",
2098						    filename, linenum);
2099					}
2100					value = 1;
2101				} else if (value) {
2102					fatal("%s line %d: \"any\" must appear "
2103					    "alone in AuthenticationMethods",
2104					    filename, linenum);
2105				} else if (auth2_methods_valid(arg, 0) != 0) {
2106					fatal("%s line %d: invalid "
2107					    "authentication method list.",
2108					    filename, linenum);
2109				}
2110				value2 = 1;
2111				if (!*activep)
2112					continue;
2113				array_append(filename, linenum,
2114				    "AuthenticationMethods",
2115				    &options->auth_methods,
2116				    &options->num_auth_methods, arg);
2117			}
2118			if (value2 == 0) {
2119				fatal("%s line %d: no AuthenticationMethods "
2120				    "specified", filename, linenum);
2121			}
2122		}
2123		return 0;
2124
2125	case sStreamLocalBindMask:
2126		arg = strdelim(&cp);
2127		if (!arg || *arg == '\0')
2128			fatal("%s line %d: missing StreamLocalBindMask "
2129			    "argument.", filename, linenum);
2130		/* Parse mode in octal format */
2131		value = strtol(arg, &p, 8);
2132		if (arg == p || value < 0 || value > 0777)
2133			fatal("%s line %d: Bad mask.", filename, linenum);
2134		if (*activep)
2135			options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
2136		break;
2137
2138	case sStreamLocalBindUnlink:
2139		intptr = &options->fwd_opts.streamlocal_bind_unlink;
2140		goto parse_flag;
2141
2142	case sFingerprintHash:
2143		arg = strdelim(&cp);
2144		if (!arg || *arg == '\0')
2145			fatal("%.200s line %d: Missing argument.",
2146			    filename, linenum);
2147		if ((value = ssh_digest_alg_by_name(arg)) == -1)
2148			fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
2149			    filename, linenum, arg);
2150		if (*activep)
2151			options->fingerprint_hash = value;
2152		break;
2153
2154	case sExposeAuthInfo:
2155		intptr = &options->expose_userauth_info;
2156		goto parse_flag;
2157
2158	case sRDomain:
2159		charptr = &options->routing_domain;
2160		arg = strdelim(&cp);
2161		if (!arg || *arg == '\0')
2162			fatal("%.200s line %d: Missing argument.",
2163			    filename, linenum);
2164		if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
2165		    !valid_rdomain(arg))
2166			fatal("%s line %d: bad routing domain",
2167			    filename, linenum);
2168		if (*activep && *charptr == NULL)
2169			*charptr = xstrdup(arg);
2170		break;
2171
2172	case sUseBlacklist:
2173		intptr = &options->use_blacklist;
2174		goto parse_flag;
2175
2176	case sDeprecated:
2177	case sIgnore:
2178	case sUnsupported:
2179		do_log2(opcode == sIgnore ?
2180		    SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
2181		    "%s line %d: %s option %s", filename, linenum,
2182		    opcode == sUnsupported ? "Unsupported" : "Deprecated", arg);
2183		while (arg)
2184		    arg = strdelim(&cp);
2185		break;
2186
2187	default:
2188		fatal("%s line %d: Missing handler for opcode %s (%d)",
2189		    filename, linenum, arg, opcode);
2190	}
2191	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
2192		fatal("%s line %d: garbage at end of line; \"%.200s\".",
2193		    filename, linenum, arg);
2194	return 0;
2195}
2196
2197/* Reads the server configuration file. */
2198
2199void
2200load_server_config(const char *filename, struct sshbuf *conf)
2201{
2202	char *line = NULL, *cp;
2203	size_t linesize = 0;
2204	FILE *f;
2205	int r, lineno = 0;
2206
2207	debug2("%s: filename %s", __func__, filename);
2208	if ((f = fopen(filename, "r")) == NULL) {
2209		perror(filename);
2210		exit(1);
2211	}
2212	sshbuf_reset(conf);
2213	while (getline(&line, &linesize, f) != -1) {
2214		lineno++;
2215		/*
2216		 * Trim out comments and strip whitespace
2217		 * NB - preserve newlines, they are needed to reproduce
2218		 * line numbers later for error messages
2219		 */
2220		if ((cp = strchr(line, '#')) != NULL)
2221			memcpy(cp, "\n", 2);
2222		cp = line + strspn(line, " \t\r");
2223		if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
2224			fatal("%s: buffer error: %s", __func__, ssh_err(r));
2225	}
2226	free(line);
2227	if ((r = sshbuf_put_u8(conf, 0)) != 0)
2228		fatal("%s: buffer error: %s", __func__, ssh_err(r));
2229	fclose(f);
2230	debug2("%s: done config len = %zu", __func__, sshbuf_len(conf));
2231}
2232
2233void
2234parse_server_match_config(ServerOptions *options,
2235   struct connection_info *connectinfo)
2236{
2237	ServerOptions mo;
2238
2239	initialize_server_options(&mo);
2240	parse_server_config(&mo, "reprocess config", cfg, connectinfo);
2241	copy_set_server_options(options, &mo, 0);
2242}
2243
2244int parse_server_match_testspec(struct connection_info *ci, char *spec)
2245{
2246	char *p;
2247
2248	while ((p = strsep(&spec, ",")) && *p != '\0') {
2249		if (strncmp(p, "addr=", 5) == 0) {
2250			ci->address = xstrdup(p + 5);
2251		} else if (strncmp(p, "host=", 5) == 0) {
2252			ci->host = xstrdup(p + 5);
2253		} else if (strncmp(p, "user=", 5) == 0) {
2254			ci->user = xstrdup(p + 5);
2255		} else if (strncmp(p, "laddr=", 6) == 0) {
2256			ci->laddress = xstrdup(p + 6);
2257		} else if (strncmp(p, "rdomain=", 8) == 0) {
2258			ci->rdomain = xstrdup(p + 8);
2259		} else if (strncmp(p, "lport=", 6) == 0) {
2260			ci->lport = a2port(p + 6);
2261			if (ci->lport == -1) {
2262				fprintf(stderr, "Invalid port '%s' in test mode"
2263				   " specification %s\n", p+6, p);
2264				return -1;
2265			}
2266		} else {
2267			fprintf(stderr, "Invalid test mode specification %s\n",
2268			   p);
2269			return -1;
2270		}
2271	}
2272	return 0;
2273}
2274
2275/*
2276 * Copy any supported values that are set.
2277 *
2278 * If the preauth flag is set, we do not bother copying the string or
2279 * array values that are not used pre-authentication, because any that we
2280 * do use must be explicitly sent in mm_getpwnamallow().
2281 */
2282void
2283copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2284{
2285#define M_CP_INTOPT(n) do {\
2286	if (src->n != -1) \
2287		dst->n = src->n; \
2288} while (0)
2289
2290	M_CP_INTOPT(password_authentication);
2291	M_CP_INTOPT(gss_authentication);
2292	M_CP_INTOPT(pubkey_authentication);
2293	M_CP_INTOPT(kerberos_authentication);
2294	M_CP_INTOPT(hostbased_authentication);
2295	M_CP_INTOPT(hostbased_uses_name_from_packet_only);
2296	M_CP_INTOPT(kbd_interactive_authentication);
2297	M_CP_INTOPT(permit_root_login);
2298	M_CP_INTOPT(permit_empty_passwd);
2299
2300	M_CP_INTOPT(allow_tcp_forwarding);
2301	M_CP_INTOPT(allow_streamlocal_forwarding);
2302	M_CP_INTOPT(allow_agent_forwarding);
2303	M_CP_INTOPT(disable_forwarding);
2304	M_CP_INTOPT(expose_userauth_info);
2305	M_CP_INTOPT(permit_tun);
2306	M_CP_INTOPT(fwd_opts.gateway_ports);
2307	M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
2308	M_CP_INTOPT(x11_display_offset);
2309	M_CP_INTOPT(x11_forwarding);
2310	M_CP_INTOPT(x11_use_localhost);
2311	M_CP_INTOPT(permit_tty);
2312	M_CP_INTOPT(permit_user_rc);
2313	M_CP_INTOPT(max_sessions);
2314	M_CP_INTOPT(max_authtries);
2315	M_CP_INTOPT(client_alive_count_max);
2316	M_CP_INTOPT(client_alive_interval);
2317	M_CP_INTOPT(ip_qos_interactive);
2318	M_CP_INTOPT(ip_qos_bulk);
2319	M_CP_INTOPT(rekey_limit);
2320	M_CP_INTOPT(rekey_interval);
2321	M_CP_INTOPT(log_level);
2322
2323	/*
2324	 * The bind_mask is a mode_t that may be unsigned, so we can't use
2325	 * M_CP_INTOPT - it does a signed comparison that causes compiler
2326	 * warnings.
2327	 */
2328	if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) {
2329		dst->fwd_opts.streamlocal_bind_mask =
2330		    src->fwd_opts.streamlocal_bind_mask;
2331	}
2332
2333	/* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */
2334#define M_CP_STROPT(n) do {\
2335	if (src->n != NULL && dst->n != src->n) { \
2336		free(dst->n); \
2337		dst->n = src->n; \
2338	} \
2339} while(0)
2340#define M_CP_STRARRAYOPT(s, num_s) do {\
2341	u_int i; \
2342	if (src->num_s != 0) { \
2343		for (i = 0; i < dst->num_s; i++) \
2344			free(dst->s[i]); \
2345		free(dst->s); \
2346		dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
2347		for (i = 0; i < src->num_s; i++) \
2348			dst->s[i] = xstrdup(src->s[i]); \
2349		dst->num_s = src->num_s; \
2350	} \
2351} while(0)
2352
2353	/* See comment in servconf.h */
2354	COPY_MATCH_STRING_OPTS();
2355
2356	/* Arguments that accept '+...' need to be expanded */
2357	assemble_algorithms(dst);
2358
2359	/*
2360	 * The only things that should be below this point are string options
2361	 * which are only used after authentication.
2362	 */
2363	if (preauth)
2364		return;
2365
2366	/* These options may be "none" to clear a global setting */
2367	M_CP_STROPT(adm_forced_command);
2368	if (option_clear_or_none(dst->adm_forced_command)) {
2369		free(dst->adm_forced_command);
2370		dst->adm_forced_command = NULL;
2371	}
2372	M_CP_STROPT(chroot_directory);
2373	if (option_clear_or_none(dst->chroot_directory)) {
2374		free(dst->chroot_directory);
2375		dst->chroot_directory = NULL;
2376	}
2377}
2378
2379#undef M_CP_INTOPT
2380#undef M_CP_STROPT
2381#undef M_CP_STRARRAYOPT
2382
2383void
2384parse_server_config(ServerOptions *options, const char *filename,
2385    struct sshbuf *conf, struct connection_info *connectinfo)
2386{
2387	int active, linenum, bad_options = 0;
2388	char *cp, *obuf, *cbuf;
2389
2390	debug2("%s: config %s len %zu", __func__, filename, sshbuf_len(conf));
2391
2392	if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
2393		fatal("%s: sshbuf_dup_string failed", __func__);
2394	active = connectinfo ? 0 : 1;
2395	linenum = 1;
2396	while ((cp = strsep(&cbuf, "\n")) != NULL) {
2397		if (process_server_config_line(options, cp, filename,
2398		    linenum++, &active, connectinfo) != 0)
2399			bad_options++;
2400	}
2401	free(obuf);
2402	if (bad_options > 0)
2403		fatal("%s: terminating, %d bad configuration options",
2404		    filename, bad_options);
2405	process_queued_listen_addrs(options);
2406}
2407
2408static const char *
2409fmt_multistate_int(int val, const struct multistate *m)
2410{
2411	u_int i;
2412
2413	for (i = 0; m[i].key != NULL; i++) {
2414		if (m[i].value == val)
2415			return m[i].key;
2416	}
2417	return "UNKNOWN";
2418}
2419
2420static const char *
2421fmt_intarg(ServerOpCodes code, int val)
2422{
2423	if (val == -1)
2424		return "unset";
2425	switch (code) {
2426	case sAddressFamily:
2427		return fmt_multistate_int(val, multistate_addressfamily);
2428	case sPermitRootLogin:
2429		return fmt_multistate_int(val, multistate_permitrootlogin);
2430	case sGatewayPorts:
2431		return fmt_multistate_int(val, multistate_gatewayports);
2432	case sCompression:
2433		return fmt_multistate_int(val, multistate_compression);
2434	case sAllowTcpForwarding:
2435		return fmt_multistate_int(val, multistate_tcpfwd);
2436	case sAllowStreamLocalForwarding:
2437		return fmt_multistate_int(val, multistate_tcpfwd);
2438	case sFingerprintHash:
2439		return ssh_digest_alg_name(val);
2440	default:
2441		switch (val) {
2442		case 0:
2443			return "no";
2444		case 1:
2445			return "yes";
2446		default:
2447			return "UNKNOWN";
2448		}
2449	}
2450}
2451
2452static void
2453dump_cfg_int(ServerOpCodes code, int val)
2454{
2455	printf("%s %d\n", lookup_opcode_name(code), val);
2456}
2457
2458static void
2459dump_cfg_oct(ServerOpCodes code, int val)
2460{
2461	printf("%s 0%o\n", lookup_opcode_name(code), val);
2462}
2463
2464static void
2465dump_cfg_fmtint(ServerOpCodes code, int val)
2466{
2467	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2468}
2469
2470static void
2471dump_cfg_string(ServerOpCodes code, const char *val)
2472{
2473	printf("%s %s\n", lookup_opcode_name(code),
2474	    val == NULL ? "none" : val);
2475}
2476
2477static void
2478dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
2479{
2480	u_int i;
2481
2482	for (i = 0; i < count; i++)
2483		printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2484}
2485
2486static void
2487dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
2488{
2489	u_int i;
2490
2491	if (count <= 0 && code != sAuthenticationMethods)
2492		return;
2493	printf("%s", lookup_opcode_name(code));
2494	for (i = 0; i < count; i++)
2495		printf(" %s",  vals[i]);
2496	if (code == sAuthenticationMethods && count == 0)
2497		printf(" any");
2498	printf("\n");
2499}
2500
2501static char *
2502format_listen_addrs(struct listenaddr *la)
2503{
2504	int r;
2505	struct addrinfo *ai;
2506	char addr[NI_MAXHOST], port[NI_MAXSERV];
2507	char *laddr1 = xstrdup(""), *laddr2 = NULL;
2508
2509	/*
2510	 * ListenAddress must be after Port.  add_one_listen_addr pushes
2511	 * addresses onto a stack, so to maintain ordering we need to
2512	 * print these in reverse order.
2513	 */
2514	for (ai = la->addrs; ai; ai = ai->ai_next) {
2515		if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
2516		    sizeof(addr), port, sizeof(port),
2517		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
2518			error("getnameinfo: %.100s", ssh_gai_strerror(r));
2519			continue;
2520		}
2521		laddr2 = laddr1;
2522		if (ai->ai_family == AF_INET6) {
2523			xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
2524			    addr, port,
2525			    la->rdomain == NULL ? "" : " rdomain ",
2526			    la->rdomain == NULL ? "" : la->rdomain,
2527			    laddr2);
2528		} else {
2529			xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
2530			    addr, port,
2531			    la->rdomain == NULL ? "" : " rdomain ",
2532			    la->rdomain == NULL ? "" : la->rdomain,
2533			    laddr2);
2534		}
2535		free(laddr2);
2536	}
2537	return laddr1;
2538}
2539
2540void
2541dump_config(ServerOptions *o)
2542{
2543	char *s;
2544	u_int i;
2545
2546	/* these are usually at the top of the config */
2547	for (i = 0; i < o->num_ports; i++)
2548		printf("port %d\n", o->ports[i]);
2549	dump_cfg_fmtint(sAddressFamily, o->address_family);
2550
2551	for (i = 0; i < o->num_listen_addrs; i++) {
2552		s = format_listen_addrs(&o->listen_addrs[i]);
2553		printf("%s", s);
2554		free(s);
2555	}
2556
2557	/* integer arguments */
2558#ifdef USE_PAM
2559	dump_cfg_fmtint(sUsePAM, o->use_pam);
2560#endif
2561	dump_cfg_int(sLoginGraceTime, o->login_grace_time);
2562	dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
2563	dump_cfg_int(sMaxAuthTries, o->max_authtries);
2564	dump_cfg_int(sMaxSessions, o->max_sessions);
2565	dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
2566	dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
2567	dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
2568
2569	/* formatted integer arguments */
2570	dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
2571	dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
2572	dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
2573	dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
2574	dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
2575	    o->hostbased_uses_name_from_packet_only);
2576	dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
2577#ifdef KRB5
2578	dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
2579	dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
2580	dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
2581# ifdef USE_AFS
2582	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
2583# endif
2584#endif
2585#ifdef GSSAPI
2586	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
2587	dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
2588#endif
2589	dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
2590	dump_cfg_fmtint(sKbdInteractiveAuthentication,
2591	    o->kbd_interactive_authentication);
2592	dump_cfg_fmtint(sChallengeResponseAuthentication,
2593	    o->challenge_response_authentication);
2594	dump_cfg_fmtint(sPrintMotd, o->print_motd);
2595#ifndef DISABLE_LASTLOG
2596	dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
2597#endif
2598	dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
2599	dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
2600	dump_cfg_fmtint(sPermitTTY, o->permit_tty);
2601	dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc);
2602	dump_cfg_fmtint(sStrictModes, o->strict_modes);
2603	dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
2604	dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
2605	dump_cfg_fmtint(sCompression, o->compression);
2606	dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
2607	dump_cfg_fmtint(sUseDNS, o->use_dns);
2608	dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
2609	dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
2610	dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
2611	dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2612	dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2613	dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
2614	dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
2615	dump_cfg_fmtint(sUseBlacklist, o->use_blacklist);
2616
2617	/* string arguments */
2618	dump_cfg_string(sPidFile, o->pid_file);
2619	dump_cfg_string(sXAuthLocation, o->xauth_location);
2620	dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT);
2621	dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC);
2622	dump_cfg_string(sBanner, o->banner);
2623	dump_cfg_string(sForceCommand, o->adm_forced_command);
2624	dump_cfg_string(sChrootDirectory, o->chroot_directory);
2625	dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
2626	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
2627	dump_cfg_string(sAuthorizedPrincipalsFile,
2628	    o->authorized_principals_file);
2629	dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
2630	    ? "none" : o->version_addendum);
2631	dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
2632	dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
2633	dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
2634	dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
2635	dump_cfg_string(sHostKeyAgent, o->host_key_agent);
2636	dump_cfg_string(sKexAlgorithms,
2637	    o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX);
2638	dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms ?
2639	    o->ca_sign_algorithms : SSH_ALLOWED_CA_SIGALGS);
2640	dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ?
2641	    o->hostbased_key_types : KEX_DEFAULT_PK_ALG);
2642	dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms ?
2643	    o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
2644	dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
2645	    o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
2646	dump_cfg_string(sRDomain, o->routing_domain);
2647
2648	/* string arguments requiring a lookup */
2649	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
2650	dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
2651
2652	/* string array arguments */
2653	dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
2654	    o->authorized_keys_files);
2655	dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
2656	     o->host_key_files);
2657	dump_cfg_strarray(sHostCertificate, o->num_host_cert_files,
2658	     o->host_cert_files);
2659	dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
2660	dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
2661	dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
2662	dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
2663	dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
2664	dump_cfg_strarray(sSetEnv, o->num_setenv, o->setenv);
2665	dump_cfg_strarray_oneline(sAuthenticationMethods,
2666	    o->num_auth_methods, o->auth_methods);
2667
2668	/* other arguments */
2669	for (i = 0; i < o->num_subsystems; i++)
2670		printf("subsystem %s %s\n", o->subsystem_name[i],
2671		    o->subsystem_args[i]);
2672
2673	printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
2674	    o->max_startups_rate, o->max_startups);
2675
2676	s = NULL;
2677	for (i = 0; tunmode_desc[i].val != -1; i++) {
2678		if (tunmode_desc[i].val == o->permit_tun) {
2679			s = tunmode_desc[i].text;
2680			break;
2681		}
2682	}
2683	dump_cfg_string(sPermitTunnel, s);
2684
2685	printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2686	printf("%s\n", iptos2str(o->ip_qos_bulk));
2687
2688	printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
2689	    o->rekey_interval);
2690
2691	printf("permitopen");
2692	if (o->num_permitted_opens == 0)
2693		printf(" any");
2694	else {
2695		for (i = 0; i < o->num_permitted_opens; i++)
2696			printf(" %s", o->permitted_opens[i]);
2697	}
2698	printf("\n");
2699	printf("permitlisten");
2700	if (o->num_permitted_listens == 0)
2701		printf(" any");
2702	else {
2703		for (i = 0; i < o->num_permitted_listens; i++)
2704			printf(" %s", o->permitted_listens[i]);
2705	}
2706	printf("\n");
2707
2708	if (o->permit_user_env_whitelist == NULL) {
2709		dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
2710	} else {
2711		printf("permituserenvironment %s\n",
2712		    o->permit_user_env_whitelist);
2713	}
2714
2715}
2716