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