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