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