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