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