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