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