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