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