servconf.c revision 224638
1/* $OpenBSD: servconf.c,v 1.213 2010/11/13 23:27:50 djm Exp $ */
2/* $FreeBSD: head/crypto/openssh/servconf.c 224638 2011-08-03 19:14:22Z brooks $ */
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: head/crypto/openssh/servconf.c 224638 2011-08-03 19:14:22Z brooks $");
16
17#include <sys/types.h>
18#include <sys/socket.h>
19
20#include <netinet/in.h>
21#include <netinet/in_systm.h>
22#include <netinet/ip.h>
23
24#include <netdb.h>
25#include <pwd.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <signal.h>
30#include <unistd.h>
31#include <stdarg.h>
32#include <errno.h>
33
34#include "openbsd-compat/sys-queue.h"
35#include "xmalloc.h"
36#include "ssh.h"
37#include "log.h"
38#include "buffer.h"
39#include "servconf.h"
40#include "compat.h"
41#include "pathnames.h"
42#include "misc.h"
43#include "cipher.h"
44#include "key.h"
45#include "kex.h"
46#include "mac.h"
47#include "match.h"
48#include "channels.h"
49#include "groupaccess.h"
50#include "version.h"
51
52static void add_listen_addr(ServerOptions *, char *, int);
53static void add_one_listen_addr(ServerOptions *, char *, int);
54
55/* Use of privilege separation or not */
56extern int use_privsep;
57extern Buffer cfg;
58
59/* Initializes the server options to their default values. */
60
61void
62initialize_server_options(ServerOptions *options)
63{
64	memset(options, 0, sizeof(*options));
65
66	/* Portable-specific options */
67	options->use_pam = -1;
68
69	/* Standard Options */
70	options->num_ports = 0;
71	options->ports_from_cmdline = 0;
72	options->listen_addrs = NULL;
73	options->address_family = -1;
74	options->num_host_key_files = 0;
75	options->num_host_cert_files = 0;
76	options->pid_file = NULL;
77	options->server_key_bits = -1;
78	options->login_grace_time = -1;
79	options->key_regeneration_time = -1;
80	options->permit_root_login = PERMIT_NOT_SET;
81	options->ignore_rhosts = -1;
82	options->ignore_user_known_hosts = -1;
83	options->print_motd = -1;
84	options->print_lastlog = -1;
85	options->x11_forwarding = -1;
86	options->x11_display_offset = -1;
87	options->x11_use_localhost = -1;
88	options->xauth_location = NULL;
89	options->strict_modes = -1;
90	options->tcp_keep_alive = -1;
91	options->log_facility = SYSLOG_FACILITY_NOT_SET;
92	options->log_level = SYSLOG_LEVEL_NOT_SET;
93	options->rhosts_rsa_authentication = -1;
94	options->hostbased_authentication = -1;
95	options->hostbased_uses_name_from_packet_only = -1;
96	options->rsa_authentication = -1;
97	options->pubkey_authentication = -1;
98	options->kerberos_authentication = -1;
99	options->kerberos_or_local_passwd = -1;
100	options->kerberos_ticket_cleanup = -1;
101	options->kerberos_get_afs_token = -1;
102	options->gss_authentication=-1;
103	options->gss_cleanup_creds = -1;
104	options->password_authentication = -1;
105	options->kbd_interactive_authentication = -1;
106	options->challenge_response_authentication = -1;
107	options->permit_empty_passwd = -1;
108	options->permit_user_env = -1;
109	options->use_login = -1;
110	options->compression = -1;
111	options->allow_tcp_forwarding = -1;
112	options->allow_agent_forwarding = -1;
113	options->num_allow_users = 0;
114	options->num_deny_users = 0;
115	options->num_allow_groups = 0;
116	options->num_deny_groups = 0;
117	options->ciphers = NULL;
118	options->macs = NULL;
119	options->kex_algorithms = NULL;
120	options->protocol = SSH_PROTO_UNKNOWN;
121	options->gateway_ports = -1;
122	options->num_subsystems = 0;
123	options->max_startups_begin = -1;
124	options->max_startups_rate = -1;
125	options->max_startups = -1;
126	options->max_authtries = -1;
127	options->max_sessions = -1;
128	options->banner = NULL;
129	options->use_dns = -1;
130	options->client_alive_interval = -1;
131	options->client_alive_count_max = -1;
132	options->authorized_keys_file = NULL;
133	options->authorized_keys_file2 = NULL;
134	options->num_accept_env = 0;
135	options->permit_tun = -1;
136	options->num_permitted_opens = -1;
137	options->adm_forced_command = NULL;
138	options->chroot_directory = NULL;
139	options->zero_knowledge_password_authentication = -1;
140	options->revoked_keys_file = NULL;
141	options->trusted_user_ca_keys = NULL;
142	options->authorized_principals_file = NULL;
143	options->ip_qos_interactive = -1;
144	options->ip_qos_bulk = -1;
145	options->hpn_disabled = -1;
146	options->hpn_buffer_size = -1;
147	options->tcp_rcv_buf_poll = -1;
148#ifdef	NONE_CIPHER_ENABLED
149	options->none_enabled = -1;
150#endif
151}
152
153void
154fill_default_server_options(ServerOptions *options)
155{
156	/* Portable-specific options */
157	if (options->use_pam == -1)
158		options->use_pam = 1;
159
160	/* Standard Options */
161	if (options->protocol == SSH_PROTO_UNKNOWN)
162		options->protocol = SSH_PROTO_2;
163	if (options->num_host_key_files == 0) {
164		/* fill default hostkeys for protocols */
165		if (options->protocol & SSH_PROTO_1)
166			options->host_key_files[options->num_host_key_files++] =
167			    _PATH_HOST_KEY_FILE;
168		if (options->protocol & SSH_PROTO_2) {
169			options->host_key_files[options->num_host_key_files++] =
170                            _PATH_HOST_RSA_KEY_FILE;
171			options->host_key_files[options->num_host_key_files++] =
172			    _PATH_HOST_DSA_KEY_FILE;
173#ifdef OPENSSL_HAS_ECC
174			options->host_key_files[options->num_host_key_files++] =
175			    _PATH_HOST_ECDSA_KEY_FILE;
176#endif
177		}
178	}
179	/* No certificates by default */
180	if (options->num_ports == 0)
181		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
182	if (options->listen_addrs == NULL)
183		add_listen_addr(options, NULL, 0);
184	if (options->pid_file == NULL)
185		options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
186	if (options->server_key_bits == -1)
187		options->server_key_bits = 1024;
188	if (options->login_grace_time == -1)
189		options->login_grace_time = 120;
190	if (options->key_regeneration_time == -1)
191		options->key_regeneration_time = 3600;
192	if (options->permit_root_login == PERMIT_NOT_SET)
193		options->permit_root_login = PERMIT_NO;
194	if (options->ignore_rhosts == -1)
195		options->ignore_rhosts = 1;
196	if (options->ignore_user_known_hosts == -1)
197		options->ignore_user_known_hosts = 0;
198	if (options->print_motd == -1)
199		options->print_motd = 1;
200	if (options->print_lastlog == -1)
201		options->print_lastlog = 1;
202	if (options->x11_forwarding == -1)
203		options->x11_forwarding = 1;
204	if (options->x11_display_offset == -1)
205		options->x11_display_offset = 10;
206	if (options->x11_use_localhost == -1)
207		options->x11_use_localhost = 1;
208	if (options->xauth_location == NULL)
209		options->xauth_location = _PATH_XAUTH;
210	if (options->strict_modes == -1)
211		options->strict_modes = 1;
212	if (options->tcp_keep_alive == -1)
213		options->tcp_keep_alive = 1;
214	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
215		options->log_facility = SYSLOG_FACILITY_AUTH;
216	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
217		options->log_level = SYSLOG_LEVEL_INFO;
218	if (options->rhosts_rsa_authentication == -1)
219		options->rhosts_rsa_authentication = 0;
220	if (options->hostbased_authentication == -1)
221		options->hostbased_authentication = 0;
222	if (options->hostbased_uses_name_from_packet_only == -1)
223		options->hostbased_uses_name_from_packet_only = 0;
224	if (options->rsa_authentication == -1)
225		options->rsa_authentication = 1;
226	if (options->pubkey_authentication == -1)
227		options->pubkey_authentication = 1;
228	if (options->kerberos_authentication == -1)
229		options->kerberos_authentication = 0;
230	if (options->kerberos_or_local_passwd == -1)
231		options->kerberos_or_local_passwd = 1;
232	if (options->kerberos_ticket_cleanup == -1)
233		options->kerberos_ticket_cleanup = 1;
234	if (options->kerberos_get_afs_token == -1)
235		options->kerberos_get_afs_token = 0;
236	if (options->gss_authentication == -1)
237		options->gss_authentication = 0;
238	if (options->gss_cleanup_creds == -1)
239		options->gss_cleanup_creds = 1;
240	if (options->password_authentication == -1)
241		options->password_authentication = 0;
242	if (options->kbd_interactive_authentication == -1)
243		options->kbd_interactive_authentication = 0;
244	if (options->challenge_response_authentication == -1)
245		options->challenge_response_authentication = 1;
246	if (options->permit_empty_passwd == -1)
247		options->permit_empty_passwd = 0;
248	if (options->permit_user_env == -1)
249		options->permit_user_env = 0;
250	if (options->use_login == -1)
251		options->use_login = 0;
252	if (options->compression == -1)
253		options->compression = COMP_DELAYED;
254	if (options->allow_tcp_forwarding == -1)
255		options->allow_tcp_forwarding = 1;
256	if (options->allow_agent_forwarding == -1)
257		options->allow_agent_forwarding = 1;
258	if (options->gateway_ports == -1)
259		options->gateway_ports = 0;
260	if (options->max_startups == -1)
261		options->max_startups = 10;
262	if (options->max_startups_rate == -1)
263		options->max_startups_rate = 100;		/* 100% */
264	if (options->max_startups_begin == -1)
265		options->max_startups_begin = options->max_startups;
266	if (options->max_authtries == -1)
267		options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
268	if (options->max_sessions == -1)
269		options->max_sessions = DEFAULT_SESSIONS_MAX;
270	if (options->use_dns == -1)
271		options->use_dns = 1;
272	if (options->client_alive_interval == -1)
273		options->client_alive_interval = 0;
274	if (options->client_alive_count_max == -1)
275		options->client_alive_count_max = 3;
276	if (options->authorized_keys_file2 == NULL) {
277		/* authorized_keys_file2 falls back to authorized_keys_file */
278		if (options->authorized_keys_file != NULL)
279			options->authorized_keys_file2 = xstrdup(options->authorized_keys_file);
280		else
281			options->authorized_keys_file2 = xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2);
282	}
283	if (options->authorized_keys_file == NULL)
284		options->authorized_keys_file = xstrdup(_PATH_SSH_USER_PERMITTED_KEYS);
285	if (options->permit_tun == -1)
286		options->permit_tun = SSH_TUNMODE_NO;
287	if (options->zero_knowledge_password_authentication == -1)
288		options->zero_knowledge_password_authentication = 0;
289	if (options->ip_qos_interactive == -1)
290		options->ip_qos_interactive = IPTOS_LOWDELAY;
291	if (options->ip_qos_bulk == -1)
292		options->ip_qos_bulk = IPTOS_THROUGHPUT;
293	if (options->hpn_disabled == -1)
294		options->hpn_disabled = 0;
295	if (options->hpn_buffer_size == -1) {
296		/*
297		 * HPN buffer size option not explicitly set.  Try to figure
298		 * out what value to use or resort to default.
299		 */
300		options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
301		if (!options->hpn_disabled) {
302			sock_get_rcvbuf(&options->hpn_buffer_size, 0);
303			debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
304		}
305	} else {
306		/*
307		 * In the case that the user sets both values in a
308		 * contradictory manner hpn_disabled overrrides hpn_buffer_size.
309		 */
310		if (options->hpn_disabled <= 0) {
311			u_int maxlen;
312
313			maxlen = buffer_get_max_len();
314			if (options->hpn_buffer_size == 0)
315				options->hpn_buffer_size = 1;
316			/* Limit the maximum buffer to BUFFER_MAX_LEN. */
317			if (options->hpn_buffer_size > maxlen / 1024)
318				options->hpn_buffer_size = maxlen;
319			else
320				options->hpn_buffer_size *= 1024;
321		} else
322			options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
323	}
324
325	/* Turn privilege separation on by default */
326	if (use_privsep == -1)
327		use_privsep = 1;
328
329#ifndef HAVE_MMAP
330	if (use_privsep && options->compression == 1) {
331		error("This platform does not support both privilege "
332		    "separation and compression");
333		error("Compression disabled");
334		options->compression = 0;
335	}
336#endif
337
338}
339
340/* Keyword tokens. */
341typedef enum {
342	sBadOption,		/* == unknown option */
343	/* Portable-specific options */
344	sUsePAM,
345	/* Standard Options */
346	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
347	sPermitRootLogin, sLogFacility, sLogLevel,
348	sRhostsRSAAuthentication, sRSAAuthentication,
349	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
350	sKerberosGetAFSToken,
351	sKerberosTgtPassing, sChallengeResponseAuthentication,
352	sPasswordAuthentication, sKbdInteractiveAuthentication,
353	sListenAddress, sAddressFamily,
354	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
355	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
356	sStrictModes, sEmptyPasswd, sTCPKeepAlive,
357	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
358	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
359	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
360	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
361	sMaxStartups, sMaxAuthTries, sMaxSessions,
362	sBanner, sUseDNS, sHostbasedAuthentication,
363	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
364	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
365	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
366	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
367	sUsePrivilegeSeparation, sAllowAgentForwarding,
368	sZeroKnowledgePasswordAuthentication, sHostCertificate,
369	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
370	sKexAlgorithms, sIPQoS,
371	sHPNDisabled, sHPNBufferSize, sTcpRcvBufPoll,
372#ifdef NONE_CIPHER_ENABLED
373	sNoneEnabled,
374#endif
375	sVersionAddendum,
376	sDeprecated, sUnsupported
377} ServerOpCodes;
378
379#define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
380#define SSHCFG_MATCH	0x02	/* allowed inside a Match section */
381#define SSHCFG_ALL	(SSHCFG_GLOBAL|SSHCFG_MATCH)
382
383/* Textual representation of the tokens. */
384static struct {
385	const char *name;
386	ServerOpCodes opcode;
387	u_int flags;
388} keywords[] = {
389	/* Portable-specific options */
390#ifdef USE_PAM
391	{ "usepam", sUsePAM, SSHCFG_GLOBAL },
392#else
393	{ "usepam", sUnsupported, SSHCFG_GLOBAL },
394#endif
395	{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
396	/* Standard Options */
397	{ "port", sPort, SSHCFG_GLOBAL },
398	{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
399	{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },		/* alias */
400	{ "pidfile", sPidFile, SSHCFG_GLOBAL },
401	{ "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
402	{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
403	{ "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
404	{ "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
405	{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
406	{ "loglevel", sLogLevel, SSHCFG_GLOBAL },
407	{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
408	{ "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
409	{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
410	{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
411	{ "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
412	{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
413	{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
414#ifdef KRB5
415	{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
416	{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
417	{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
418#ifdef USE_AFS
419	{ "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
420#else
421	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
422#endif
423#else
424	{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
425	{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
426	{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
427	{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
428#endif
429	{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
430	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
431#ifdef GSSAPI
432	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
433	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
434#else
435	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
436	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
437#endif
438	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
439	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
440	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
441	{ "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
442#ifdef JPAKE
443	{ "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL },
444#else
445	{ "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL },
446#endif
447	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
448	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
449	{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
450	{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
451	{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
452	{ "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
453	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
454	{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
455	{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
456	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
457	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
458	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
459	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
460	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
461	{ "uselogin", sUseLogin, SSHCFG_GLOBAL },
462	{ "compression", sCompression, SSHCFG_GLOBAL },
463	{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
464	{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },	/* obsolete alias */
465	{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
466	{ "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
467	{ "allowusers", sAllowUsers, SSHCFG_GLOBAL },
468	{ "denyusers", sDenyUsers, SSHCFG_GLOBAL },
469	{ "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
470	{ "denygroups", sDenyGroups, SSHCFG_GLOBAL },
471	{ "ciphers", sCiphers, SSHCFG_GLOBAL },
472	{ "macs", sMacs, SSHCFG_GLOBAL },
473	{ "protocol", sProtocol, SSHCFG_GLOBAL },
474	{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
475	{ "subsystem", sSubsystem, SSHCFG_GLOBAL },
476	{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
477	{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
478	{ "maxsessions", sMaxSessions, SSHCFG_ALL },
479	{ "banner", sBanner, SSHCFG_ALL },
480	{ "usedns", sUseDNS, SSHCFG_GLOBAL },
481	{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
482	{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
483	{ "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
484	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
485	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
486	{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_ALL },
487	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
488	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
489	{ "permittunnel", sPermitTunnel, SSHCFG_ALL },
490	{ "match", sMatch, SSHCFG_ALL },
491	{ "permitopen", sPermitOpen, SSHCFG_ALL },
492	{ "forcecommand", sForceCommand, SSHCFG_ALL },
493	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
494	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
495	{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
496	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
497	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
498	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
499	{ "ipqos", sIPQoS, SSHCFG_ALL },
500	{ "hpndisabled", sHPNDisabled, SSHCFG_ALL },
501	{ "hpnbuffersize", sHPNBufferSize, SSHCFG_ALL },
502	{ "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL },
503#ifdef NONE_CIPHER_ENABLED
504	{ "noneenabled", sNoneEnabled, SSHCFG_ALL },
505#endif
506	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
507	{ NULL, sBadOption, 0 }
508};
509
510static struct {
511	int val;
512	char *text;
513} tunmode_desc[] = {
514	{ SSH_TUNMODE_NO, "no" },
515	{ SSH_TUNMODE_POINTOPOINT, "point-to-point" },
516	{ SSH_TUNMODE_ETHERNET, "ethernet" },
517	{ SSH_TUNMODE_YES, "yes" },
518	{ -1, NULL }
519};
520
521/*
522 * Returns the number of the token pointed to by cp or sBadOption.
523 */
524
525static ServerOpCodes
526parse_token(const char *cp, const char *filename,
527	    int linenum, u_int *flags)
528{
529	u_int i;
530
531	for (i = 0; keywords[i].name; i++)
532		if (strcasecmp(cp, keywords[i].name) == 0) {
533			*flags = keywords[i].flags;
534			return keywords[i].opcode;
535		}
536
537	error("%s: line %d: Bad configuration option: %s",
538	    filename, linenum, cp);
539	return sBadOption;
540}
541
542char *
543derelativise_path(const char *path)
544{
545	char *expanded, *ret, cwd[MAXPATHLEN];
546
547	expanded = tilde_expand_filename(path, getuid());
548	if (*expanded == '/')
549		return expanded;
550	if (getcwd(cwd, sizeof(cwd)) == NULL)
551		fatal("%s: getcwd: %s", __func__, strerror(errno));
552	xasprintf(&ret, "%s/%s", cwd, expanded);
553	xfree(expanded);
554	return ret;
555}
556
557static void
558add_listen_addr(ServerOptions *options, char *addr, int port)
559{
560	u_int i;
561
562	if (options->num_ports == 0)
563		options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
564	if (options->address_family == -1)
565		options->address_family = AF_UNSPEC;
566	if (port == 0)
567		for (i = 0; i < options->num_ports; i++)
568			add_one_listen_addr(options, addr, options->ports[i]);
569	else
570		add_one_listen_addr(options, addr, port);
571}
572
573static void
574add_one_listen_addr(ServerOptions *options, char *addr, int port)
575{
576	struct addrinfo hints, *ai, *aitop;
577	char strport[NI_MAXSERV];
578	int gaierr;
579
580	memset(&hints, 0, sizeof(hints));
581	hints.ai_family = options->address_family;
582	hints.ai_socktype = SOCK_STREAM;
583	hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
584	snprintf(strport, sizeof strport, "%d", port);
585	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
586		fatal("bad addr or host: %s (%s)",
587		    addr ? addr : "<NULL>",
588		    ssh_gai_strerror(gaierr));
589	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
590		;
591	ai->ai_next = options->listen_addrs;
592	options->listen_addrs = aitop;
593}
594
595/*
596 * The strategy for the Match blocks is that the config file is parsed twice.
597 *
598 * The first time is at startup.  activep is initialized to 1 and the
599 * directives in the global context are processed and acted on.  Hitting a
600 * Match directive unsets activep and the directives inside the block are
601 * checked for syntax only.
602 *
603 * The second time is after a connection has been established but before
604 * authentication.  activep is initialized to 2 and global config directives
605 * are ignored since they have already been processed.  If the criteria in a
606 * Match block is met, activep is set and the subsequent directives
607 * processed and actioned until EOF or another Match block unsets it.  Any
608 * options set are copied into the main server config.
609 *
610 * Potential additions/improvements:
611 *  - Add Match support for pre-kex directives, eg Protocol, Ciphers.
612 *
613 *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
614 *	Match Address 192.168.0.*
615 *		Tag trusted
616 *	Match Group wheel
617 *		Tag trusted
618 *	Match Tag trusted
619 *		AllowTcpForwarding yes
620 *		GatewayPorts clientspecified
621 *		[...]
622 *
623 *  - Add a PermittedChannelRequests directive
624 *	Match Group shell
625 *		PermittedChannelRequests session,forwarded-tcpip
626 */
627
628static int
629match_cfg_line_group(const char *grps, int line, const char *user)
630{
631	int result = 0;
632	struct passwd *pw;
633
634	if (user == NULL)
635		goto out;
636
637	if ((pw = getpwnam(user)) == NULL) {
638		debug("Can't match group at line %d because user %.100s does "
639		    "not exist", line, user);
640	} else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
641		debug("Can't Match group because user %.100s not in any group "
642		    "at line %d", user, line);
643	} else if (ga_match_pattern_list(grps) != 1) {
644		debug("user %.100s does not match group list %.100s at line %d",
645		    user, grps, line);
646	} else {
647		debug("user %.100s matched group list %.100s at line %d", user,
648		    grps, line);
649		result = 1;
650	}
651out:
652	ga_free();
653	return result;
654}
655
656static int
657match_cfg_line(char **condition, int line, const char *user, const char *host,
658    const char *address)
659{
660	int result = 1;
661	char *arg, *attrib, *cp = *condition;
662	size_t len;
663
664	if (user == NULL)
665		debug3("checking syntax for 'Match %s'", cp);
666	else
667		debug3("checking match for '%s' user %s host %s addr %s", cp,
668		    user ? user : "(null)", host ? host : "(null)",
669		    address ? address : "(null)");
670
671	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
672		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
673			error("Missing Match criteria for %s", attrib);
674			return -1;
675		}
676		len = strlen(arg);
677		if (strcasecmp(attrib, "user") == 0) {
678			if (!user) {
679				result = 0;
680				continue;
681			}
682			if (match_pattern_list(user, arg, len, 0) != 1)
683				result = 0;
684			else
685				debug("user %.100s matched 'User %.100s' at "
686				    "line %d", user, arg, line);
687		} else if (strcasecmp(attrib, "group") == 0) {
688			switch (match_cfg_line_group(arg, line, user)) {
689			case -1:
690				return -1;
691			case 0:
692				result = 0;
693			}
694		} else if (strcasecmp(attrib, "host") == 0) {
695			if (!host) {
696				result = 0;
697				continue;
698			}
699			if (match_hostname(host, arg, len) != 1)
700				result = 0;
701			else
702				debug("connection from %.100s matched 'Host "
703				    "%.100s' at line %d", host, arg, line);
704		} else if (strcasecmp(attrib, "address") == 0) {
705			switch (addr_match_list(address, arg)) {
706			case 1:
707				debug("connection from %.100s matched 'Address "
708				    "%.100s' at line %d", address, arg, line);
709				break;
710			case 0:
711			case -1:
712				result = 0;
713				break;
714			case -2:
715				return -1;
716			}
717		} else {
718			error("Unsupported Match attribute %s", attrib);
719			return -1;
720		}
721	}
722	if (user != NULL)
723		debug3("match %sfound", result ? "" : "not ");
724	*condition = cp;
725	return result;
726}
727
728#define WHITESPACE " \t\r\n"
729
730int
731process_server_config_line(ServerOptions *options, char *line,
732    const char *filename, int linenum, int *activep, const char *user,
733    const char *host, const char *address)
734{
735	char *cp, **charptr, *arg, *p;
736	int cmdline = 0, *intptr, value, value2, n;
737	SyslogFacility *log_facility_ptr;
738	LogLevel *log_level_ptr;
739	ServerOpCodes opcode;
740	int port;
741	u_int i, flags = 0;
742	size_t len;
743
744	cp = line;
745	if ((arg = strdelim(&cp)) == NULL)
746		return 0;
747	/* Ignore leading whitespace */
748	if (*arg == '\0')
749		arg = strdelim(&cp);
750	if (!arg || !*arg || *arg == '#')
751		return 0;
752	intptr = NULL;
753	charptr = NULL;
754	opcode = parse_token(arg, filename, linenum, &flags);
755
756	if (activep == NULL) { /* We are processing a command line directive */
757		cmdline = 1;
758		activep = &cmdline;
759	}
760	if (*activep && opcode != sMatch)
761		debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
762	if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
763		if (user == NULL) {
764			fatal("%s line %d: Directive '%s' is not allowed "
765			    "within a Match block", filename, linenum, arg);
766		} else { /* this is a directive we have already processed */
767			while (arg)
768				arg = strdelim(&cp);
769			return 0;
770		}
771	}
772
773	switch (opcode) {
774	/* Portable-specific options */
775	case sUsePAM:
776		intptr = &options->use_pam;
777		goto parse_flag;
778
779	/* Standard Options */
780	case sBadOption:
781		return -1;
782	case sPort:
783		/* ignore ports from configfile if cmdline specifies ports */
784		if (options->ports_from_cmdline)
785			return 0;
786		if (options->listen_addrs != NULL)
787			fatal("%s line %d: ports must be specified before "
788			    "ListenAddress.", filename, linenum);
789		if (options->num_ports >= MAX_PORTS)
790			fatal("%s line %d: too many ports.",
791			    filename, linenum);
792		arg = strdelim(&cp);
793		if (!arg || *arg == '\0')
794			fatal("%s line %d: missing port number.",
795			    filename, linenum);
796		options->ports[options->num_ports++] = a2port(arg);
797		if (options->ports[options->num_ports-1] <= 0)
798			fatal("%s line %d: Badly formatted port number.",
799			    filename, linenum);
800		break;
801
802	case sServerKeyBits:
803		intptr = &options->server_key_bits;
804 parse_int:
805		arg = strdelim(&cp);
806		if (!arg || *arg == '\0')
807			fatal("%s line %d: missing integer value.",
808			    filename, linenum);
809		value = atoi(arg);
810		if (*activep && *intptr == -1)
811			*intptr = value;
812		break;
813
814	case sLoginGraceTime:
815		intptr = &options->login_grace_time;
816 parse_time:
817		arg = strdelim(&cp);
818		if (!arg || *arg == '\0')
819			fatal("%s line %d: missing time value.",
820			    filename, linenum);
821		if ((value = convtime(arg)) == -1)
822			fatal("%s line %d: invalid time value.",
823			    filename, linenum);
824		if (*intptr == -1)
825			*intptr = value;
826		break;
827
828	case sKeyRegenerationTime:
829		intptr = &options->key_regeneration_time;
830		goto parse_time;
831
832	case sListenAddress:
833		arg = strdelim(&cp);
834		if (arg == NULL || *arg == '\0')
835			fatal("%s line %d: missing address",
836			    filename, linenum);
837		/* check for bare IPv6 address: no "[]" and 2 or more ":" */
838		if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
839		    && strchr(p+1, ':') != NULL) {
840			add_listen_addr(options, arg, 0);
841			break;
842		}
843		p = hpdelim(&arg);
844		if (p == NULL)
845			fatal("%s line %d: bad address:port usage",
846			    filename, linenum);
847		p = cleanhostname(p);
848		if (arg == NULL)
849			port = 0;
850		else if ((port = a2port(arg)) <= 0)
851			fatal("%s line %d: bad port number", filename, linenum);
852
853		add_listen_addr(options, p, port);
854
855		break;
856
857	case sAddressFamily:
858		arg = strdelim(&cp);
859		if (!arg || *arg == '\0')
860			fatal("%s line %d: missing address family.",
861			    filename, linenum);
862		intptr = &options->address_family;
863		if (options->listen_addrs != NULL)
864			fatal("%s line %d: address family must be specified before "
865			    "ListenAddress.", filename, linenum);
866		if (strcasecmp(arg, "inet") == 0)
867			value = AF_INET;
868		else if (strcasecmp(arg, "inet6") == 0)
869			value = AF_INET6;
870		else if (strcasecmp(arg, "any") == 0)
871			value = AF_UNSPEC;
872		else
873			fatal("%s line %d: unsupported address family \"%s\".",
874			    filename, linenum, arg);
875		if (*intptr == -1)
876			*intptr = value;
877		break;
878
879	case sHostKeyFile:
880		intptr = &options->num_host_key_files;
881		if (*intptr >= MAX_HOSTKEYS)
882			fatal("%s line %d: too many host keys specified (max %d).",
883			    filename, linenum, MAX_HOSTKEYS);
884		charptr = &options->host_key_files[*intptr];
885 parse_filename:
886		arg = strdelim(&cp);
887		if (!arg || *arg == '\0')
888			fatal("%s line %d: missing file name.",
889			    filename, linenum);
890		if (*activep && *charptr == NULL) {
891			*charptr = derelativise_path(arg);
892			/* increase optional counter */
893			if (intptr != NULL)
894				*intptr = *intptr + 1;
895		}
896		break;
897
898	case sHostCertificate:
899		intptr = &options->num_host_cert_files;
900		if (*intptr >= MAX_HOSTKEYS)
901			fatal("%s line %d: too many host certificates "
902			    "specified (max %d).", filename, linenum,
903			    MAX_HOSTCERTS);
904		charptr = &options->host_cert_files[*intptr];
905		goto parse_filename;
906		break;
907
908	case sPidFile:
909		charptr = &options->pid_file;
910		goto parse_filename;
911
912	case sPermitRootLogin:
913		intptr = &options->permit_root_login;
914		arg = strdelim(&cp);
915		if (!arg || *arg == '\0')
916			fatal("%s line %d: missing yes/"
917			    "without-password/forced-commands-only/no "
918			    "argument.", filename, linenum);
919		value = 0;	/* silence compiler */
920		if (strcmp(arg, "without-password") == 0)
921			value = PERMIT_NO_PASSWD;
922		else if (strcmp(arg, "forced-commands-only") == 0)
923			value = PERMIT_FORCED_ONLY;
924		else if (strcmp(arg, "yes") == 0)
925			value = PERMIT_YES;
926		else if (strcmp(arg, "no") == 0)
927			value = PERMIT_NO;
928		else
929			fatal("%s line %d: Bad yes/"
930			    "without-password/forced-commands-only/no "
931			    "argument: %s", filename, linenum, arg);
932		if (*activep && *intptr == -1)
933			*intptr = value;
934		break;
935
936	case sIgnoreRhosts:
937		intptr = &options->ignore_rhosts;
938 parse_flag:
939		arg = strdelim(&cp);
940		if (!arg || *arg == '\0')
941			fatal("%s line %d: missing yes/no argument.",
942			    filename, linenum);
943		value = 0;	/* silence compiler */
944		if (strcmp(arg, "yes") == 0)
945			value = 1;
946		else if (strcmp(arg, "no") == 0)
947			value = 0;
948		else
949			fatal("%s line %d: Bad yes/no argument: %s",
950				filename, linenum, arg);
951		if (*activep && *intptr == -1)
952			*intptr = value;
953		break;
954
955	case sIgnoreUserKnownHosts:
956		intptr = &options->ignore_user_known_hosts;
957		goto parse_flag;
958
959	case sRhostsRSAAuthentication:
960		intptr = &options->rhosts_rsa_authentication;
961		goto parse_flag;
962
963	case sHostbasedAuthentication:
964		intptr = &options->hostbased_authentication;
965		goto parse_flag;
966
967	case sHostbasedUsesNameFromPacketOnly:
968		intptr = &options->hostbased_uses_name_from_packet_only;
969		goto parse_flag;
970
971	case sRSAAuthentication:
972		intptr = &options->rsa_authentication;
973		goto parse_flag;
974
975	case sPubkeyAuthentication:
976		intptr = &options->pubkey_authentication;
977		goto parse_flag;
978
979	case sKerberosAuthentication:
980		intptr = &options->kerberos_authentication;
981		goto parse_flag;
982
983	case sKerberosOrLocalPasswd:
984		intptr = &options->kerberos_or_local_passwd;
985		goto parse_flag;
986
987	case sKerberosTicketCleanup:
988		intptr = &options->kerberos_ticket_cleanup;
989		goto parse_flag;
990
991	case sKerberosGetAFSToken:
992		intptr = &options->kerberos_get_afs_token;
993		goto parse_flag;
994
995	case sGssAuthentication:
996		intptr = &options->gss_authentication;
997		goto parse_flag;
998
999	case sGssCleanupCreds:
1000		intptr = &options->gss_cleanup_creds;
1001		goto parse_flag;
1002
1003	case sPasswordAuthentication:
1004		intptr = &options->password_authentication;
1005		goto parse_flag;
1006
1007	case sZeroKnowledgePasswordAuthentication:
1008		intptr = &options->zero_knowledge_password_authentication;
1009		goto parse_flag;
1010
1011	case sKbdInteractiveAuthentication:
1012		intptr = &options->kbd_interactive_authentication;
1013		goto parse_flag;
1014
1015	case sChallengeResponseAuthentication:
1016		intptr = &options->challenge_response_authentication;
1017		goto parse_flag;
1018
1019	case sPrintMotd:
1020		intptr = &options->print_motd;
1021		goto parse_flag;
1022
1023	case sPrintLastLog:
1024		intptr = &options->print_lastlog;
1025		goto parse_flag;
1026
1027	case sX11Forwarding:
1028		intptr = &options->x11_forwarding;
1029		goto parse_flag;
1030
1031	case sX11DisplayOffset:
1032		intptr = &options->x11_display_offset;
1033		goto parse_int;
1034
1035	case sX11UseLocalhost:
1036		intptr = &options->x11_use_localhost;
1037		goto parse_flag;
1038
1039	case sXAuthLocation:
1040		charptr = &options->xauth_location;
1041		goto parse_filename;
1042
1043	case sStrictModes:
1044		intptr = &options->strict_modes;
1045		goto parse_flag;
1046
1047	case sTCPKeepAlive:
1048		intptr = &options->tcp_keep_alive;
1049		goto parse_flag;
1050
1051	case sEmptyPasswd:
1052		intptr = &options->permit_empty_passwd;
1053		goto parse_flag;
1054
1055	case sPermitUserEnvironment:
1056		intptr = &options->permit_user_env;
1057		goto parse_flag;
1058
1059	case sUseLogin:
1060		intptr = &options->use_login;
1061		goto parse_flag;
1062
1063	case sCompression:
1064		intptr = &options->compression;
1065		arg = strdelim(&cp);
1066		if (!arg || *arg == '\0')
1067			fatal("%s line %d: missing yes/no/delayed "
1068			    "argument.", filename, linenum);
1069		value = 0;	/* silence compiler */
1070		if (strcmp(arg, "delayed") == 0)
1071			value = COMP_DELAYED;
1072		else if (strcmp(arg, "yes") == 0)
1073			value = COMP_ZLIB;
1074		else if (strcmp(arg, "no") == 0)
1075			value = COMP_NONE;
1076		else
1077			fatal("%s line %d: Bad yes/no/delayed "
1078			    "argument: %s", filename, linenum, arg);
1079		if (*intptr == -1)
1080			*intptr = value;
1081		break;
1082
1083	case sGatewayPorts:
1084		intptr = &options->gateway_ports;
1085		arg = strdelim(&cp);
1086		if (!arg || *arg == '\0')
1087			fatal("%s line %d: missing yes/no/clientspecified "
1088			    "argument.", filename, linenum);
1089		value = 0;	/* silence compiler */
1090		if (strcmp(arg, "clientspecified") == 0)
1091			value = 2;
1092		else if (strcmp(arg, "yes") == 0)
1093			value = 1;
1094		else if (strcmp(arg, "no") == 0)
1095			value = 0;
1096		else
1097			fatal("%s line %d: Bad yes/no/clientspecified "
1098			    "argument: %s", filename, linenum, arg);
1099		if (*activep && *intptr == -1)
1100			*intptr = value;
1101		break;
1102
1103	case sUseDNS:
1104		intptr = &options->use_dns;
1105		goto parse_flag;
1106
1107	case sLogFacility:
1108		log_facility_ptr = &options->log_facility;
1109		arg = strdelim(&cp);
1110		value = log_facility_number(arg);
1111		if (value == SYSLOG_FACILITY_NOT_SET)
1112			fatal("%.200s line %d: unsupported log facility '%s'",
1113			    filename, linenum, arg ? arg : "<NONE>");
1114		if (*log_facility_ptr == -1)
1115			*log_facility_ptr = (SyslogFacility) value;
1116		break;
1117
1118	case sLogLevel:
1119		log_level_ptr = &options->log_level;
1120		arg = strdelim(&cp);
1121		value = log_level_number(arg);
1122		if (value == SYSLOG_LEVEL_NOT_SET)
1123			fatal("%.200s line %d: unsupported log level '%s'",
1124			    filename, linenum, arg ? arg : "<NONE>");
1125		if (*log_level_ptr == -1)
1126			*log_level_ptr = (LogLevel) value;
1127		break;
1128
1129	case sAllowTcpForwarding:
1130		intptr = &options->allow_tcp_forwarding;
1131		goto parse_flag;
1132
1133	case sAllowAgentForwarding:
1134		intptr = &options->allow_agent_forwarding;
1135		goto parse_flag;
1136
1137	case sUsePrivilegeSeparation:
1138		intptr = &use_privsep;
1139		goto parse_flag;
1140
1141	case sAllowUsers:
1142		while ((arg = strdelim(&cp)) && *arg != '\0') {
1143			if (options->num_allow_users >= MAX_ALLOW_USERS)
1144				fatal("%s line %d: too many allow users.",
1145				    filename, linenum);
1146			options->allow_users[options->num_allow_users++] =
1147			    xstrdup(arg);
1148		}
1149		break;
1150
1151	case sDenyUsers:
1152		while ((arg = strdelim(&cp)) && *arg != '\0') {
1153			if (options->num_deny_users >= MAX_DENY_USERS)
1154				fatal("%s line %d: too many deny users.",
1155				    filename, linenum);
1156			options->deny_users[options->num_deny_users++] =
1157			    xstrdup(arg);
1158		}
1159		break;
1160
1161	case sAllowGroups:
1162		while ((arg = strdelim(&cp)) && *arg != '\0') {
1163			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1164				fatal("%s line %d: too many allow groups.",
1165				    filename, linenum);
1166			options->allow_groups[options->num_allow_groups++] =
1167			    xstrdup(arg);
1168		}
1169		break;
1170
1171	case sDenyGroups:
1172		while ((arg = strdelim(&cp)) && *arg != '\0') {
1173			if (options->num_deny_groups >= MAX_DENY_GROUPS)
1174				fatal("%s line %d: too many deny groups.",
1175				    filename, linenum);
1176			options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1177		}
1178		break;
1179
1180	case sCiphers:
1181		arg = strdelim(&cp);
1182		if (!arg || *arg == '\0')
1183			fatal("%s line %d: Missing argument.", filename, linenum);
1184		if (!ciphers_valid(arg))
1185			fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1186			    filename, linenum, arg ? arg : "<NONE>");
1187		if (options->ciphers == NULL)
1188			options->ciphers = xstrdup(arg);
1189		break;
1190
1191	case sMacs:
1192		arg = strdelim(&cp);
1193		if (!arg || *arg == '\0')
1194			fatal("%s line %d: Missing argument.", filename, linenum);
1195		if (!mac_valid(arg))
1196			fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1197			    filename, linenum, arg ? arg : "<NONE>");
1198		if (options->macs == NULL)
1199			options->macs = xstrdup(arg);
1200		break;
1201
1202	case sKexAlgorithms:
1203		arg = strdelim(&cp);
1204		if (!arg || *arg == '\0')
1205			fatal("%s line %d: Missing argument.",
1206			    filename, linenum);
1207		if (!kex_names_valid(arg))
1208			fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
1209			    filename, linenum, arg ? arg : "<NONE>");
1210		if (options->kex_algorithms == NULL)
1211			options->kex_algorithms = xstrdup(arg);
1212		break;
1213
1214	case sProtocol:
1215		intptr = &options->protocol;
1216		arg = strdelim(&cp);
1217		if (!arg || *arg == '\0')
1218			fatal("%s line %d: Missing argument.", filename, linenum);
1219		value = proto_spec(arg);
1220		if (value == SSH_PROTO_UNKNOWN)
1221			fatal("%s line %d: Bad protocol spec '%s'.",
1222			    filename, linenum, arg ? arg : "<NONE>");
1223		if (*intptr == SSH_PROTO_UNKNOWN)
1224			*intptr = value;
1225		break;
1226
1227	case sSubsystem:
1228		if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1229			fatal("%s line %d: too many subsystems defined.",
1230			    filename, linenum);
1231		}
1232		arg = strdelim(&cp);
1233		if (!arg || *arg == '\0')
1234			fatal("%s line %d: Missing subsystem name.",
1235			    filename, linenum);
1236		if (!*activep) {
1237			arg = strdelim(&cp);
1238			break;
1239		}
1240		for (i = 0; i < options->num_subsystems; i++)
1241			if (strcmp(arg, options->subsystem_name[i]) == 0)
1242				fatal("%s line %d: Subsystem '%s' already defined.",
1243				    filename, linenum, arg);
1244		options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1245		arg = strdelim(&cp);
1246		if (!arg || *arg == '\0')
1247			fatal("%s line %d: Missing subsystem command.",
1248			    filename, linenum);
1249		options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1250
1251		/* Collect arguments (separate to executable) */
1252		p = xstrdup(arg);
1253		len = strlen(p) + 1;
1254		while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1255			len += 1 + strlen(arg);
1256			p = xrealloc(p, 1, len);
1257			strlcat(p, " ", len);
1258			strlcat(p, arg, len);
1259		}
1260		options->subsystem_args[options->num_subsystems] = p;
1261		options->num_subsystems++;
1262		break;
1263
1264	case sMaxStartups:
1265		arg = strdelim(&cp);
1266		if (!arg || *arg == '\0')
1267			fatal("%s line %d: Missing MaxStartups spec.",
1268			    filename, linenum);
1269		if ((n = sscanf(arg, "%d:%d:%d",
1270		    &options->max_startups_begin,
1271		    &options->max_startups_rate,
1272		    &options->max_startups)) == 3) {
1273			if (options->max_startups_begin >
1274			    options->max_startups ||
1275			    options->max_startups_rate > 100 ||
1276			    options->max_startups_rate < 1)
1277				fatal("%s line %d: Illegal MaxStartups spec.",
1278				    filename, linenum);
1279		} else if (n != 1)
1280			fatal("%s line %d: Illegal MaxStartups spec.",
1281			    filename, linenum);
1282		else
1283			options->max_startups = options->max_startups_begin;
1284		break;
1285
1286	case sMaxAuthTries:
1287		intptr = &options->max_authtries;
1288		goto parse_int;
1289
1290	case sMaxSessions:
1291		intptr = &options->max_sessions;
1292		goto parse_int;
1293
1294	case sBanner:
1295		charptr = &options->banner;
1296		goto parse_filename;
1297
1298	/*
1299	 * These options can contain %X options expanded at
1300	 * connect time, so that you can specify paths like:
1301	 *
1302	 * AuthorizedKeysFile	/etc/ssh_keys/%u
1303	 */
1304	case sAuthorizedKeysFile:
1305		charptr = &options->authorized_keys_file;
1306		goto parse_tilde_filename;
1307	case sAuthorizedKeysFile2:
1308		charptr = &options->authorized_keys_file2;
1309		goto parse_tilde_filename;
1310	case sAuthorizedPrincipalsFile:
1311		charptr = &options->authorized_principals_file;
1312 parse_tilde_filename:
1313		arg = strdelim(&cp);
1314		if (!arg || *arg == '\0')
1315			fatal("%s line %d: missing file name.",
1316			    filename, linenum);
1317		if (*activep && *charptr == NULL) {
1318			*charptr = tilde_expand_filename(arg, getuid());
1319			/* increase optional counter */
1320			if (intptr != NULL)
1321				*intptr = *intptr + 1;
1322		}
1323		break;
1324
1325	case sClientAliveInterval:
1326		intptr = &options->client_alive_interval;
1327		goto parse_time;
1328
1329	case sClientAliveCountMax:
1330		intptr = &options->client_alive_count_max;
1331		goto parse_int;
1332
1333	case sAcceptEnv:
1334		while ((arg = strdelim(&cp)) && *arg != '\0') {
1335			if (strchr(arg, '=') != NULL)
1336				fatal("%s line %d: Invalid environment name.",
1337				    filename, linenum);
1338			if (options->num_accept_env >= MAX_ACCEPT_ENV)
1339				fatal("%s line %d: too many allow env.",
1340				    filename, linenum);
1341			if (!*activep)
1342				break;
1343			options->accept_env[options->num_accept_env++] =
1344			    xstrdup(arg);
1345		}
1346		break;
1347
1348	case sPermitTunnel:
1349		intptr = &options->permit_tun;
1350		arg = strdelim(&cp);
1351		if (!arg || *arg == '\0')
1352			fatal("%s line %d: Missing yes/point-to-point/"
1353			    "ethernet/no argument.", filename, linenum);
1354		value = -1;
1355		for (i = 0; tunmode_desc[i].val != -1; i++)
1356			if (strcmp(tunmode_desc[i].text, arg) == 0) {
1357				value = tunmode_desc[i].val;
1358				break;
1359			}
1360		if (value == -1)
1361			fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1362			    "no argument: %s", filename, linenum, arg);
1363		if (*intptr == -1)
1364			*intptr = value;
1365		break;
1366
1367	case sMatch:
1368		if (cmdline)
1369			fatal("Match directive not supported as a command-line "
1370			   "option");
1371		value = match_cfg_line(&cp, linenum, user, host, address);
1372		if (value < 0)
1373			fatal("%s line %d: Bad Match condition", filename,
1374			    linenum);
1375		*activep = value;
1376		break;
1377
1378	case sPermitOpen:
1379		arg = strdelim(&cp);
1380		if (!arg || *arg == '\0')
1381			fatal("%s line %d: missing PermitOpen specification",
1382			    filename, linenum);
1383		n = options->num_permitted_opens;	/* modified later */
1384		if (strcmp(arg, "any") == 0) {
1385			if (*activep && n == -1) {
1386				channel_clear_adm_permitted_opens();
1387				options->num_permitted_opens = 0;
1388			}
1389			break;
1390		}
1391		if (*activep && n == -1)
1392			channel_clear_adm_permitted_opens();
1393		for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1394			p = hpdelim(&arg);
1395			if (p == NULL)
1396				fatal("%s line %d: missing host in PermitOpen",
1397				    filename, linenum);
1398			p = cleanhostname(p);
1399			if (arg == NULL || (port = a2port(arg)) <= 0)
1400				fatal("%s line %d: bad port number in "
1401				    "PermitOpen", filename, linenum);
1402			if (*activep && n == -1)
1403				options->num_permitted_opens =
1404				    channel_add_adm_permitted_opens(p, port);
1405		}
1406		break;
1407
1408	case sForceCommand:
1409		if (cp == NULL)
1410			fatal("%.200s line %d: Missing argument.", filename,
1411			    linenum);
1412		len = strspn(cp, WHITESPACE);
1413		if (*activep && options->adm_forced_command == NULL)
1414			options->adm_forced_command = xstrdup(cp + len);
1415		return 0;
1416
1417	case sChrootDirectory:
1418		charptr = &options->chroot_directory;
1419
1420		arg = strdelim(&cp);
1421		if (!arg || *arg == '\0')
1422			fatal("%s line %d: missing file name.",
1423			    filename, linenum);
1424		if (*activep && *charptr == NULL)
1425			*charptr = xstrdup(arg);
1426		break;
1427
1428	case sTrustedUserCAKeys:
1429		charptr = &options->trusted_user_ca_keys;
1430		goto parse_filename;
1431
1432	case sRevokedKeys:
1433		charptr = &options->revoked_keys_file;
1434		goto parse_filename;
1435
1436	case sIPQoS:
1437		arg = strdelim(&cp);
1438		if ((value = parse_ipqos(arg)) == -1)
1439			fatal("%s line %d: Bad IPQoS value: %s",
1440			    filename, linenum, arg);
1441		arg = strdelim(&cp);
1442		if (arg == NULL)
1443			value2 = value;
1444		else if ((value2 = parse_ipqos(arg)) == -1)
1445			fatal("%s line %d: Bad IPQoS value: %s",
1446			    filename, linenum, arg);
1447		if (*activep) {
1448			options->ip_qos_interactive = value;
1449			options->ip_qos_bulk = value2;
1450		}
1451		break;
1452
1453	case sVersionAddendum:
1454		ssh_version_set_addendum(strtok(cp, "\n"));
1455		do {
1456			arg = strdelim(&cp);
1457		} while (arg != NULL && *arg != '\0');
1458		break;
1459
1460	case sHPNDisabled:
1461		intptr = &options->hpn_disabled;
1462		goto parse_flag;
1463
1464	case sHPNBufferSize:
1465		intptr = &options->hpn_buffer_size;
1466		goto parse_int;
1467
1468	case sTcpRcvBufPoll:
1469		intptr = &options->tcp_rcv_buf_poll;
1470		goto parse_flag;
1471
1472#ifdef	NONE_CIPHER_ENABLED
1473	case sNoneEnabled:
1474		intptr = &options->none_enabled;
1475		goto parse_flag;
1476#endif
1477
1478	case sDeprecated:
1479		logit("%s line %d: Deprecated option %s",
1480		    filename, linenum, arg);
1481		while (arg)
1482		    arg = strdelim(&cp);
1483		break;
1484
1485	case sUnsupported:
1486		logit("%s line %d: Unsupported option %s",
1487		    filename, linenum, arg);
1488		while (arg)
1489		    arg = strdelim(&cp);
1490		break;
1491
1492	default:
1493		fatal("%s line %d: Missing handler for opcode %s (%d)",
1494		    filename, linenum, arg, opcode);
1495	}
1496	if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1497		fatal("%s line %d: garbage at end of line; \"%.200s\".",
1498		    filename, linenum, arg);
1499	return 0;
1500}
1501
1502/* Reads the server configuration file. */
1503
1504void
1505load_server_config(const char *filename, Buffer *conf)
1506{
1507	char line[1024], *cp;
1508	FILE *f;
1509
1510	debug2("%s: filename %s", __func__, filename);
1511	if ((f = fopen(filename, "r")) == NULL) {
1512		perror(filename);
1513		exit(1);
1514	}
1515	buffer_clear(conf);
1516	while (fgets(line, sizeof(line), f)) {
1517		/*
1518		 * Trim out comments and strip whitespace
1519		 * NB - preserve newlines, they are needed to reproduce
1520		 * line numbers later for error messages
1521		 */
1522		if ((cp = strchr(line, '#')) != NULL)
1523			memcpy(cp, "\n", 2);
1524		cp = line + strspn(line, " \t\r");
1525
1526		buffer_append(conf, cp, strlen(cp));
1527	}
1528	buffer_append(conf, "\0", 1);
1529	fclose(f);
1530	debug2("%s: done config len = %d", __func__, buffer_len(conf));
1531}
1532
1533void
1534parse_server_match_config(ServerOptions *options, const char *user,
1535    const char *host, const char *address)
1536{
1537	ServerOptions mo;
1538
1539	initialize_server_options(&mo);
1540	parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1541	copy_set_server_options(options, &mo, 0);
1542}
1543
1544/* Helper macros */
1545#define M_CP_INTOPT(n) do {\
1546	if (src->n != -1) \
1547		dst->n = src->n; \
1548} while (0)
1549#define M_CP_STROPT(n) do {\
1550	if (src->n != NULL) { \
1551		if (dst->n != NULL) \
1552			xfree(dst->n); \
1553		dst->n = src->n; \
1554	} \
1555} while(0)
1556
1557/*
1558 * Copy any supported values that are set.
1559 *
1560 * If the preauth flag is set, we do not bother copying the string or
1561 * array values that are not used pre-authentication, because any that we
1562 * do use must be explictly sent in mm_getpwnamallow().
1563 */
1564void
1565copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1566{
1567	M_CP_INTOPT(password_authentication);
1568	M_CP_INTOPT(gss_authentication);
1569	M_CP_INTOPT(rsa_authentication);
1570	M_CP_INTOPT(pubkey_authentication);
1571	M_CP_INTOPT(kerberos_authentication);
1572	M_CP_INTOPT(hostbased_authentication);
1573	M_CP_INTOPT(hostbased_uses_name_from_packet_only);
1574	M_CP_INTOPT(kbd_interactive_authentication);
1575	M_CP_INTOPT(zero_knowledge_password_authentication);
1576	M_CP_INTOPT(permit_root_login);
1577	M_CP_INTOPT(permit_empty_passwd);
1578
1579	M_CP_INTOPT(allow_tcp_forwarding);
1580	M_CP_INTOPT(allow_agent_forwarding);
1581	M_CP_INTOPT(permit_tun);
1582	M_CP_INTOPT(gateway_ports);
1583	M_CP_INTOPT(x11_display_offset);
1584	M_CP_INTOPT(x11_forwarding);
1585	M_CP_INTOPT(x11_use_localhost);
1586	M_CP_INTOPT(max_sessions);
1587	M_CP_INTOPT(max_authtries);
1588	M_CP_INTOPT(ip_qos_interactive);
1589	M_CP_INTOPT(ip_qos_bulk);
1590
1591	M_CP_STROPT(banner);
1592	if (preauth)
1593		return;
1594	M_CP_STROPT(adm_forced_command);
1595	M_CP_STROPT(chroot_directory);
1596	M_CP_STROPT(trusted_user_ca_keys);
1597	M_CP_STROPT(revoked_keys_file);
1598	M_CP_STROPT(authorized_keys_file);
1599	M_CP_STROPT(authorized_keys_file2);
1600	M_CP_STROPT(authorized_principals_file);
1601}
1602
1603#undef M_CP_INTOPT
1604#undef M_CP_STROPT
1605
1606void
1607parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1608    const char *user, const char *host, const char *address)
1609{
1610	int active, linenum, bad_options = 0;
1611	char *cp, *obuf, *cbuf;
1612
1613	debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1614
1615	obuf = cbuf = xstrdup(buffer_ptr(conf));
1616	active = user ? 0 : 1;
1617	linenum = 1;
1618	while ((cp = strsep(&cbuf, "\n")) != NULL) {
1619		if (process_server_config_line(options, cp, filename,
1620		    linenum++, &active, user, host, address) != 0)
1621			bad_options++;
1622	}
1623	xfree(obuf);
1624	if (bad_options > 0)
1625		fatal("%s: terminating, %d bad configuration options",
1626		    filename, bad_options);
1627}
1628
1629static const char *
1630fmt_intarg(ServerOpCodes code, int val)
1631{
1632	if (code == sAddressFamily) {
1633		switch (val) {
1634		case AF_INET:
1635			return "inet";
1636		case AF_INET6:
1637			return "inet6";
1638		case AF_UNSPEC:
1639			return "any";
1640		default:
1641			return "UNKNOWN";
1642		}
1643	}
1644	if (code == sPermitRootLogin) {
1645		switch (val) {
1646		case PERMIT_NO_PASSWD:
1647			return "without-password";
1648		case PERMIT_FORCED_ONLY:
1649			return "forced-commands-only";
1650		case PERMIT_YES:
1651			return "yes";
1652		}
1653	}
1654	if (code == sProtocol) {
1655		switch (val) {
1656		case SSH_PROTO_1:
1657			return "1";
1658		case SSH_PROTO_2:
1659			return "2";
1660		case (SSH_PROTO_1|SSH_PROTO_2):
1661			return "2,1";
1662		default:
1663			return "UNKNOWN";
1664		}
1665	}
1666	if (code == sGatewayPorts && val == 2)
1667		return "clientspecified";
1668	if (code == sCompression && val == COMP_DELAYED)
1669		return "delayed";
1670	switch (val) {
1671	case -1:
1672		return "unset";
1673	case 0:
1674		return "no";
1675	case 1:
1676		return "yes";
1677	}
1678	return "UNKNOWN";
1679}
1680
1681static const char *
1682lookup_opcode_name(ServerOpCodes code)
1683{
1684	u_int i;
1685
1686	for (i = 0; keywords[i].name != NULL; i++)
1687		if (keywords[i].opcode == code)
1688			return(keywords[i].name);
1689	return "UNKNOWN";
1690}
1691
1692static void
1693dump_cfg_int(ServerOpCodes code, int val)
1694{
1695	printf("%s %d\n", lookup_opcode_name(code), val);
1696}
1697
1698static void
1699dump_cfg_fmtint(ServerOpCodes code, int val)
1700{
1701	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
1702}
1703
1704static void
1705dump_cfg_string(ServerOpCodes code, const char *val)
1706{
1707	if (val == NULL)
1708		return;
1709	printf("%s %s\n", lookup_opcode_name(code), val);
1710}
1711
1712static void
1713dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
1714{
1715	u_int i;
1716
1717	for (i = 0; i < count; i++)
1718		printf("%s %s\n", lookup_opcode_name(code),  vals[i]);
1719}
1720
1721void
1722dump_config(ServerOptions *o)
1723{
1724	u_int i;
1725	int ret;
1726	struct addrinfo *ai;
1727	char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
1728
1729	/* these are usually at the top of the config */
1730	for (i = 0; i < o->num_ports; i++)
1731		printf("port %d\n", o->ports[i]);
1732	dump_cfg_fmtint(sProtocol, o->protocol);
1733	dump_cfg_fmtint(sAddressFamily, o->address_family);
1734
1735	/* ListenAddress must be after Port */
1736	for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
1737		if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
1738		    sizeof(addr), port, sizeof(port),
1739		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
1740			error("getnameinfo failed: %.100s",
1741			    (ret != EAI_SYSTEM) ? gai_strerror(ret) :
1742			    strerror(errno));
1743		} else {
1744			if (ai->ai_family == AF_INET6)
1745				printf("listenaddress [%s]:%s\n", addr, port);
1746			else
1747				printf("listenaddress %s:%s\n", addr, port);
1748		}
1749	}
1750
1751	/* integer arguments */
1752#ifdef USE_PAM
1753	dump_cfg_int(sUsePAM, o->use_pam);
1754#endif
1755	dump_cfg_int(sServerKeyBits, o->server_key_bits);
1756	dump_cfg_int(sLoginGraceTime, o->login_grace_time);
1757	dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
1758	dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
1759	dump_cfg_int(sMaxAuthTries, o->max_authtries);
1760	dump_cfg_int(sMaxSessions, o->max_sessions);
1761	dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
1762	dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
1763
1764	/* formatted integer arguments */
1765	dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
1766	dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
1767	dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
1768	dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication);
1769	dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
1770	dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
1771	    o->hostbased_uses_name_from_packet_only);
1772	dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
1773	dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
1774#ifdef KRB5
1775	dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
1776	dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
1777	dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
1778# ifdef USE_AFS
1779	dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
1780# endif
1781#endif
1782#ifdef GSSAPI
1783	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
1784	dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
1785#endif
1786#ifdef JPAKE
1787	dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
1788	    o->zero_knowledge_password_authentication);
1789#endif
1790	dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
1791	dump_cfg_fmtint(sKbdInteractiveAuthentication,
1792	    o->kbd_interactive_authentication);
1793	dump_cfg_fmtint(sChallengeResponseAuthentication,
1794	    o->challenge_response_authentication);
1795	dump_cfg_fmtint(sPrintMotd, o->print_motd);
1796	dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
1797	dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
1798	dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
1799	dump_cfg_fmtint(sStrictModes, o->strict_modes);
1800	dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
1801	dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
1802	dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
1803	dump_cfg_fmtint(sUseLogin, o->use_login);
1804	dump_cfg_fmtint(sCompression, o->compression);
1805	dump_cfg_fmtint(sGatewayPorts, o->gateway_ports);
1806	dump_cfg_fmtint(sUseDNS, o->use_dns);
1807	dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
1808	dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
1809
1810	/* string arguments */
1811	dump_cfg_string(sPidFile, o->pid_file);
1812	dump_cfg_string(sXAuthLocation, o->xauth_location);
1813	dump_cfg_string(sCiphers, o->ciphers);
1814	dump_cfg_string(sMacs, o->macs);
1815	dump_cfg_string(sBanner, o->banner);
1816	dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
1817	dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
1818	dump_cfg_string(sForceCommand, o->adm_forced_command);
1819	dump_cfg_string(sChrootDirectory, o->chroot_directory);
1820	dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
1821	dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
1822	dump_cfg_string(sAuthorizedPrincipalsFile,
1823	    o->authorized_principals_file);
1824
1825	/* string arguments requiring a lookup */
1826	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1827	dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
1828
1829	/* string array arguments */
1830	dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
1831	     o->host_key_files);
1832	dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files,
1833	     o->host_cert_files);
1834	dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
1835	dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
1836	dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
1837	dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
1838	dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
1839
1840	/* other arguments */
1841	for (i = 0; i < o->num_subsystems; i++)
1842		printf("subsystem %s %s\n", o->subsystem_name[i],
1843		    o->subsystem_args[i]);
1844
1845	printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
1846	    o->max_startups_rate, o->max_startups);
1847
1848	for (i = 0; tunmode_desc[i].val != -1; i++)
1849		if (tunmode_desc[i].val == o->permit_tun) {
1850			s = tunmode_desc[i].text;
1851			break;
1852		}
1853	dump_cfg_string(sPermitTunnel, s);
1854
1855	printf("ipqos 0x%02x 0x%02x\n", o->ip_qos_interactive, o->ip_qos_bulk);
1856
1857	channel_print_adm_permitted_opens();
1858}
1859