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