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