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