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