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