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