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