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