]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - crypto/openssh/servconf.c
Remove (harmless) duplicate entry for VersionAddendum.
[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         { "hpndisabled", sHPNDisabled, SSHCFG_ALL },
503         { "hpnbuffersize", sHPNBufferSize, SSHCFG_ALL },
504         { "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL },
505 #ifdef NONE_CIPHER_ENABLED
506         { "noneenabled", sNoneEnabled, SSHCFG_ALL },
507 #endif
508         { NULL, sBadOption, 0 }
509 };
510
511 static struct {
512         int val;
513         char *text;
514 } tunmode_desc[] = {
515         { SSH_TUNMODE_NO, "no" },
516         { SSH_TUNMODE_POINTOPOINT, "point-to-point" },
517         { SSH_TUNMODE_ETHERNET, "ethernet" },
518         { SSH_TUNMODE_YES, "yes" },
519         { -1, NULL }
520 };
521
522 /*
523  * Returns the number of the token pointed to by cp or sBadOption.
524  */
525
526 static ServerOpCodes
527 parse_token(const char *cp, const char *filename,
528             int linenum, u_int *flags)
529 {
530         u_int i;
531
532         for (i = 0; keywords[i].name; i++)
533                 if (strcasecmp(cp, keywords[i].name) == 0) {
534                         *flags = keywords[i].flags;
535                         return keywords[i].opcode;
536                 }
537
538         error("%s: line %d: Bad configuration option: %s",
539             filename, linenum, cp);
540         return sBadOption;
541 }
542
543 char *
544 derelativise_path(const char *path)
545 {
546         char *expanded, *ret, cwd[MAXPATHLEN];
547
548         expanded = tilde_expand_filename(path, getuid());
549         if (*expanded == '/')
550                 return expanded;
551         if (getcwd(cwd, sizeof(cwd)) == NULL)
552                 fatal("%s: getcwd: %s", __func__, strerror(errno));
553         xasprintf(&ret, "%s/%s", cwd, expanded);
554         xfree(expanded);
555         return ret;
556 }
557
558 static void
559 add_listen_addr(ServerOptions *options, char *addr, int port)
560 {
561         u_int i;
562
563         if (options->num_ports == 0)
564                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
565         if (options->address_family == -1)
566                 options->address_family = AF_UNSPEC;
567         if (port == 0)
568                 for (i = 0; i < options->num_ports; i++)
569                         add_one_listen_addr(options, addr, options->ports[i]);
570         else
571                 add_one_listen_addr(options, addr, port);
572 }
573
574 static void
575 add_one_listen_addr(ServerOptions *options, char *addr, int port)
576 {
577         struct addrinfo hints, *ai, *aitop;
578         char strport[NI_MAXSERV];
579         int gaierr;
580
581         memset(&hints, 0, sizeof(hints));
582         hints.ai_family = options->address_family;
583         hints.ai_socktype = SOCK_STREAM;
584         hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
585         snprintf(strport, sizeof strport, "%d", port);
586         if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
587                 fatal("bad addr or host: %s (%s)",
588                     addr ? addr : "<NULL>",
589                     ssh_gai_strerror(gaierr));
590         for (ai = aitop; ai->ai_next; ai = ai->ai_next)
591                 ;
592         ai->ai_next = options->listen_addrs;
593         options->listen_addrs = aitop;
594 }
595
596 struct connection_info *
597 get_connection_info(int populate, int use_dns)
598 {
599         static struct connection_info ci;
600
601         if (!populate)
602                 return &ci;
603         ci.host = get_canonical_hostname(use_dns);
604         ci.address = get_remote_ipaddr();
605         ci.laddress = get_local_ipaddr(packet_get_connection_in());
606         ci.lport = get_local_port();
607         return &ci;
608 }
609
610 /*
611  * The strategy for the Match blocks is that the config file is parsed twice.
612  *
613  * The first time is at startup.  activep is initialized to 1 and the
614  * directives in the global context are processed and acted on.  Hitting a
615  * Match directive unsets activep and the directives inside the block are
616  * checked for syntax only.
617  *
618  * The second time is after a connection has been established but before
619  * authentication.  activep is initialized to 2 and global config directives
620  * are ignored since they have already been processed.  If the criteria in a
621  * Match block is met, activep is set and the subsequent directives
622  * processed and actioned until EOF or another Match block unsets it.  Any
623  * options set are copied into the main server config.
624  *
625  * Potential additions/improvements:
626  *  - Add Match support for pre-kex directives, eg Protocol, Ciphers.
627  *
628  *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
629  *      Match Address 192.168.0.*
630  *              Tag trusted
631  *      Match Group wheel
632  *              Tag trusted
633  *      Match Tag trusted
634  *              AllowTcpForwarding yes
635  *              GatewayPorts clientspecified
636  *              [...]
637  *
638  *  - Add a PermittedChannelRequests directive
639  *      Match Group shell
640  *              PermittedChannelRequests session,forwarded-tcpip
641  */
642
643 static int
644 match_cfg_line_group(const char *grps, int line, const char *user)
645 {
646         int result = 0;
647         struct passwd *pw;
648
649         if (user == NULL)
650                 goto out;
651
652         if ((pw = getpwnam(user)) == NULL) {
653                 debug("Can't match group at line %d because user %.100s does "
654                     "not exist", line, user);
655         } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
656                 debug("Can't Match group because user %.100s not in any group "
657                     "at line %d", user, line);
658         } else if (ga_match_pattern_list(grps) != 1) {
659                 debug("user %.100s does not match group list %.100s at line %d",
660                     user, grps, line);
661         } else {
662                 debug("user %.100s matched group list %.100s at line %d", user,
663                     grps, line);
664                 result = 1;
665         }
666 out:
667         ga_free();
668         return result;
669 }
670
671 /*
672  * All of the attributes on a single Match line are ANDed together, so we need to check every
673  * attribute and set the result to zero if any attribute does not match.
674  */
675 static int
676 match_cfg_line(char **condition, int line, struct connection_info *ci)
677 {
678         int result = 1, port;
679         char *arg, *attrib, *cp = *condition;
680         size_t len;
681
682         if (ci == NULL)
683                 debug3("checking syntax for 'Match %s'", cp);
684         else
685                 debug3("checking match for '%s' user %s host %s addr %s "
686                     "laddr %s lport %d", cp, ci->user ? ci->user : "(null)",
687                     ci->host ? ci->host : "(null)",
688                     ci->address ? ci->address : "(null)",
689                     ci->laddress ? ci->laddress : "(null)", ci->lport);
690
691         while ((attrib = strdelim(&cp)) && *attrib != '\0') {
692                 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
693                         error("Missing Match criteria for %s", attrib);
694                         return -1;
695                 }
696                 len = strlen(arg);
697                 if (strcasecmp(attrib, "user") == 0) {
698                         if (ci == NULL || ci->user == NULL) {
699                                 result = 0;
700                                 continue;
701                         }
702                         if (match_pattern_list(ci->user, arg, len, 0) != 1)
703                                 result = 0;
704                         else
705                                 debug("user %.100s matched 'User %.100s' at "
706                                     "line %d", ci->user, arg, line);
707                 } else if (strcasecmp(attrib, "group") == 0) {
708                         if (ci == NULL || ci->user == NULL) {
709                                 result = 0;
710                                 continue;
711                         }
712                         switch (match_cfg_line_group(arg, line, ci->user)) {
713                         case -1:
714                                 return -1;
715                         case 0:
716                                 result = 0;
717                         }
718                 } else if (strcasecmp(attrib, "host") == 0) {
719                         if (ci == NULL || ci->host == NULL) {
720                                 result = 0;
721                                 continue;
722                         }
723                         if (match_hostname(ci->host, arg, len) != 1)
724                                 result = 0;
725                         else
726                                 debug("connection from %.100s matched 'Host "
727                                     "%.100s' at line %d", ci->host, arg, line);
728                 } else if (strcasecmp(attrib, "address") == 0) {
729                         if (ci == NULL || ci->address == NULL) {
730                                 result = 0;
731                                 continue;
732                         }
733                         switch (addr_match_list(ci->address, arg)) {
734                         case 1:
735                                 debug("connection from %.100s matched 'Address "
736                                     "%.100s' at line %d", ci->address, arg, line);
737                                 break;
738                         case 0:
739                         case -1:
740                                 result = 0;
741                                 break;
742                         case -2:
743                                 return -1;
744                         }
745                 } else if (strcasecmp(attrib, "localaddress") == 0){
746                         if (ci == NULL || ci->laddress == NULL) {
747                                 result = 0;
748                                 continue;
749                         }
750                         switch (addr_match_list(ci->laddress, arg)) {
751                         case 1:
752                                 debug("connection from %.100s matched "
753                                     "'LocalAddress %.100s' at line %d",
754                                     ci->laddress, arg, line);
755                                 break;
756                         case 0:
757                         case -1:
758                                 result = 0;
759                                 break;
760                         case -2:
761                                 return -1;
762                         }
763                 } else if (strcasecmp(attrib, "localport") == 0) {
764                         if ((port = a2port(arg)) == -1) {
765                                 error("Invalid LocalPort '%s' on Match line",
766                                     arg);
767                                 return -1;
768                         }
769                         if (ci == NULL || ci->lport == 0) {
770                                 result = 0;
771                                 continue;
772                         }
773                         /* TODO support port lists */
774                         if (port == ci->lport)
775                                 debug("connection from %.100s matched "
776                                     "'LocalPort %d' at line %d",
777                                     ci->laddress, port, line);
778                         else
779                                 result = 0;
780                 } else {
781                         error("Unsupported Match attribute %s", attrib);
782                         return -1;
783                 }
784         }
785         if (ci != NULL)
786                 debug3("match %sfound", result ? "" : "not ");
787         *condition = cp;
788         return result;
789 }
790
791 #define WHITESPACE " \t\r\n"
792
793 /* Multistate option parsing */
794 struct multistate {
795         char *key;
796         int value;
797 };
798 static const struct multistate multistate_addressfamily[] = {
799         { "inet",                       AF_INET },
800         { "inet6",                      AF_INET6 },
801         { "any",                        AF_UNSPEC },
802         { NULL, -1 }
803 };
804 static const struct multistate multistate_permitrootlogin[] = {
805         { "without-password",           PERMIT_NO_PASSWD },
806         { "forced-commands-only",       PERMIT_FORCED_ONLY },
807         { "yes",                        PERMIT_YES },
808         { "no",                         PERMIT_NO },
809         { NULL, -1 }
810 };
811 static const struct multistate multistate_compression[] = {
812         { "delayed",                    COMP_DELAYED },
813         { "yes",                        COMP_ZLIB },
814         { "no",                         COMP_NONE },
815         { NULL, -1 }
816 };
817 static const struct multistate multistate_gatewayports[] = {
818         { "clientspecified",            2 },
819         { "yes",                        1 },
820         { "no",                         0 },
821         { NULL, -1 }
822 };
823 static const struct multistate multistate_privsep[] = {
824         { "yes",                        PRIVSEP_NOSANDBOX },
825         { "sandbox",                    PRIVSEP_ON },
826         { "nosandbox",                  PRIVSEP_NOSANDBOX },
827         { "no",                         PRIVSEP_OFF },
828         { NULL, -1 }
829 };
830
831 int
832 process_server_config_line(ServerOptions *options, char *line,
833     const char *filename, int linenum, int *activep,
834     struct connection_info *connectinfo)
835 {
836         char *cp, **charptr, *arg, *p;
837         int cmdline = 0, *intptr, value, value2, n;
838         SyslogFacility *log_facility_ptr;
839         LogLevel *log_level_ptr;
840         ServerOpCodes opcode;
841         int port;
842         u_int i, flags = 0;
843         size_t len;
844         const struct multistate *multistate_ptr;
845
846         cp = line;
847         if ((arg = strdelim(&cp)) == NULL)
848                 return 0;
849         /* Ignore leading whitespace */
850         if (*arg == '\0')
851                 arg = strdelim(&cp);
852         if (!arg || !*arg || *arg == '#')
853                 return 0;
854         intptr = NULL;
855         charptr = NULL;
856         opcode = parse_token(arg, filename, linenum, &flags);
857
858         if (activep == NULL) { /* We are processing a command line directive */
859                 cmdline = 1;
860                 activep = &cmdline;
861         }
862         if (*activep && opcode != sMatch)
863                 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
864         if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
865                 if (connectinfo == NULL) {
866                         fatal("%s line %d: Directive '%s' is not allowed "
867                             "within a Match block", filename, linenum, arg);
868                 } else { /* this is a directive we have already processed */
869                         while (arg)
870                                 arg = strdelim(&cp);
871                         return 0;
872                 }
873         }
874
875         switch (opcode) {
876         /* Portable-specific options */
877         case sUsePAM:
878                 intptr = &options->use_pam;
879                 goto parse_flag;
880
881         /* Standard Options */
882         case sBadOption:
883                 return -1;
884         case sPort:
885                 /* ignore ports from configfile if cmdline specifies ports */
886                 if (options->ports_from_cmdline)
887                         return 0;
888                 if (options->listen_addrs != NULL)
889                         fatal("%s line %d: ports must be specified before "
890                             "ListenAddress.", filename, linenum);
891                 if (options->num_ports >= MAX_PORTS)
892                         fatal("%s line %d: too many ports.",
893                             filename, linenum);
894                 arg = strdelim(&cp);
895                 if (!arg || *arg == '\0')
896                         fatal("%s line %d: missing port number.",
897                             filename, linenum);
898                 options->ports[options->num_ports++] = a2port(arg);
899                 if (options->ports[options->num_ports-1] <= 0)
900                         fatal("%s line %d: Badly formatted port number.",
901                             filename, linenum);
902                 break;
903
904         case sServerKeyBits:
905                 intptr = &options->server_key_bits;
906  parse_int:
907                 arg = strdelim(&cp);
908                 if (!arg || *arg == '\0')
909                         fatal("%s line %d: missing integer value.",
910                             filename, linenum);
911                 value = atoi(arg);
912                 if (*activep && *intptr == -1)
913                         *intptr = value;
914                 break;
915
916         case sLoginGraceTime:
917                 intptr = &options->login_grace_time;
918  parse_time:
919                 arg = strdelim(&cp);
920                 if (!arg || *arg == '\0')
921                         fatal("%s line %d: missing time value.",
922                             filename, linenum);
923                 if ((value = convtime(arg)) == -1)
924                         fatal("%s line %d: invalid time value.",
925                             filename, linenum);
926                 if (*intptr == -1)
927                         *intptr = value;
928                 break;
929
930         case sKeyRegenerationTime:
931                 intptr = &options->key_regeneration_time;
932                 goto parse_time;
933
934         case sListenAddress:
935                 arg = strdelim(&cp);
936                 if (arg == NULL || *arg == '\0')
937                         fatal("%s line %d: missing address",
938                             filename, linenum);
939                 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
940                 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
941                     && strchr(p+1, ':') != NULL) {
942                         add_listen_addr(options, arg, 0);
943                         break;
944                 }
945                 p = hpdelim(&arg);
946                 if (p == NULL)
947                         fatal("%s line %d: bad address:port usage",
948                             filename, linenum);
949                 p = cleanhostname(p);
950                 if (arg == NULL)
951                         port = 0;
952                 else if ((port = a2port(arg)) <= 0)
953                         fatal("%s line %d: bad port number", filename, linenum);
954
955                 add_listen_addr(options, p, port);
956
957                 break;
958
959         case sAddressFamily:
960                 intptr = &options->address_family;
961                 multistate_ptr = multistate_addressfamily;
962                 if (options->listen_addrs != NULL)
963                         fatal("%s line %d: address family must be specified "
964                             "before ListenAddress.", filename, linenum);
965  parse_multistate:
966                 arg = strdelim(&cp);
967                 if (!arg || *arg == '\0')
968                         fatal("%s line %d: missing argument.",
969                             filename, linenum);
970                 value = -1;
971                 for (i = 0; multistate_ptr[i].key != NULL; i++) {
972                         if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
973                                 value = multistate_ptr[i].value;
974                                 break;
975                         }
976                 }
977                 if (value == -1)
978                         fatal("%s line %d: unsupported option \"%s\".",
979                             filename, linenum, arg);
980                 if (*activep && *intptr == -1)
981                         *intptr = value;
982                 break;
983
984         case sHostKeyFile:
985                 intptr = &options->num_host_key_files;
986                 if (*intptr >= MAX_HOSTKEYS)
987                         fatal("%s line %d: too many host keys specified (max %d).",
988                             filename, linenum, MAX_HOSTKEYS);
989                 charptr = &options->host_key_files[*intptr];
990  parse_filename:
991                 arg = strdelim(&cp);
992                 if (!arg || *arg == '\0')
993                         fatal("%s line %d: missing file name.",
994                             filename, linenum);
995                 if (*activep && *charptr == NULL) {
996                         *charptr = derelativise_path(arg);
997                         /* increase optional counter */
998                         if (intptr != NULL)
999                                 *intptr = *intptr + 1;
1000                 }
1001                 break;
1002
1003         case sHostCertificate:
1004                 intptr = &options->num_host_cert_files;
1005                 if (*intptr >= MAX_HOSTKEYS)
1006                         fatal("%s line %d: too many host certificates "
1007                             "specified (max %d).", filename, linenum,
1008                             MAX_HOSTCERTS);
1009                 charptr = &options->host_cert_files[*intptr];
1010                 goto parse_filename;
1011                 break;
1012
1013         case sPidFile:
1014                 charptr = &options->pid_file;
1015                 goto parse_filename;
1016
1017         case sPermitRootLogin:
1018                 intptr = &options->permit_root_login;
1019                 multistate_ptr = multistate_permitrootlogin;
1020                 goto parse_multistate;
1021
1022         case sIgnoreRhosts:
1023                 intptr = &options->ignore_rhosts;
1024  parse_flag:
1025                 arg = strdelim(&cp);
1026                 if (!arg || *arg == '\0')
1027                         fatal("%s line %d: missing yes/no argument.",
1028                             filename, linenum);
1029                 value = 0;      /* silence compiler */
1030                 if (strcmp(arg, "yes") == 0)
1031                         value = 1;
1032                 else if (strcmp(arg, "no") == 0)
1033                         value = 0;
1034                 else
1035                         fatal("%s line %d: Bad yes/no argument: %s",
1036                                 filename, linenum, arg);
1037                 if (*activep && *intptr == -1)
1038                         *intptr = value;
1039                 break;
1040
1041         case sIgnoreUserKnownHosts:
1042                 intptr = &options->ignore_user_known_hosts;
1043                 goto parse_flag;
1044
1045         case sRhostsRSAAuthentication:
1046                 intptr = &options->rhosts_rsa_authentication;
1047                 goto parse_flag;
1048
1049         case sHostbasedAuthentication:
1050                 intptr = &options->hostbased_authentication;
1051                 goto parse_flag;
1052
1053         case sHostbasedUsesNameFromPacketOnly:
1054                 intptr = &options->hostbased_uses_name_from_packet_only;
1055                 goto parse_flag;
1056
1057         case sRSAAuthentication:
1058                 intptr = &options->rsa_authentication;
1059                 goto parse_flag;
1060
1061         case sPubkeyAuthentication:
1062                 intptr = &options->pubkey_authentication;
1063                 goto parse_flag;
1064
1065         case sKerberosAuthentication:
1066                 intptr = &options->kerberos_authentication;
1067                 goto parse_flag;
1068
1069         case sKerberosOrLocalPasswd:
1070                 intptr = &options->kerberos_or_local_passwd;
1071                 goto parse_flag;
1072
1073         case sKerberosTicketCleanup:
1074                 intptr = &options->kerberos_ticket_cleanup;
1075                 goto parse_flag;
1076
1077         case sKerberosGetAFSToken:
1078                 intptr = &options->kerberos_get_afs_token;
1079                 goto parse_flag;
1080
1081         case sGssAuthentication:
1082                 intptr = &options->gss_authentication;
1083                 goto parse_flag;
1084
1085         case sGssCleanupCreds:
1086                 intptr = &options->gss_cleanup_creds;
1087                 goto parse_flag;
1088
1089         case sPasswordAuthentication:
1090                 intptr = &options->password_authentication;
1091                 goto parse_flag;
1092
1093         case sZeroKnowledgePasswordAuthentication:
1094                 intptr = &options->zero_knowledge_password_authentication;
1095                 goto parse_flag;
1096
1097         case sKbdInteractiveAuthentication:
1098                 intptr = &options->kbd_interactive_authentication;
1099                 goto parse_flag;
1100
1101         case sChallengeResponseAuthentication:
1102                 intptr = &options->challenge_response_authentication;
1103                 goto parse_flag;
1104
1105         case sPrintMotd:
1106                 intptr = &options->print_motd;
1107                 goto parse_flag;
1108
1109         case sPrintLastLog:
1110                 intptr = &options->print_lastlog;
1111                 goto parse_flag;
1112
1113         case sX11Forwarding:
1114                 intptr = &options->x11_forwarding;
1115                 goto parse_flag;
1116
1117         case sX11DisplayOffset:
1118                 intptr = &options->x11_display_offset;
1119                 goto parse_int;
1120
1121         case sX11UseLocalhost:
1122                 intptr = &options->x11_use_localhost;
1123                 goto parse_flag;
1124
1125         case sXAuthLocation:
1126                 charptr = &options->xauth_location;
1127                 goto parse_filename;
1128
1129         case sStrictModes:
1130                 intptr = &options->strict_modes;
1131                 goto parse_flag;
1132
1133         case sTCPKeepAlive:
1134                 intptr = &options->tcp_keep_alive;
1135                 goto parse_flag;
1136
1137         case sEmptyPasswd:
1138                 intptr = &options->permit_empty_passwd;
1139                 goto parse_flag;
1140
1141         case sPermitUserEnvironment:
1142                 intptr = &options->permit_user_env;
1143                 goto parse_flag;
1144
1145         case sUseLogin:
1146                 intptr = &options->use_login;
1147                 goto parse_flag;
1148
1149         case sCompression:
1150                 intptr = &options->compression;
1151                 multistate_ptr = multistate_compression;
1152                 goto parse_multistate;
1153
1154         case sGatewayPorts:
1155                 intptr = &options->gateway_ports;
1156                 multistate_ptr = multistate_gatewayports;
1157                 goto parse_multistate;
1158
1159         case sUseDNS:
1160                 intptr = &options->use_dns;
1161                 goto parse_flag;
1162
1163         case sLogFacility:
1164                 log_facility_ptr = &options->log_facility;
1165                 arg = strdelim(&cp);
1166                 value = log_facility_number(arg);
1167                 if (value == SYSLOG_FACILITY_NOT_SET)
1168                         fatal("%.200s line %d: unsupported log facility '%s'",
1169                             filename, linenum, arg ? arg : "<NONE>");
1170                 if (*log_facility_ptr == -1)
1171                         *log_facility_ptr = (SyslogFacility) value;
1172                 break;
1173
1174         case sLogLevel:
1175                 log_level_ptr = &options->log_level;
1176                 arg = strdelim(&cp);
1177                 value = log_level_number(arg);
1178                 if (value == SYSLOG_LEVEL_NOT_SET)
1179                         fatal("%.200s line %d: unsupported log level '%s'",
1180                             filename, linenum, arg ? arg : "<NONE>");
1181                 if (*log_level_ptr == -1)
1182                         *log_level_ptr = (LogLevel) value;
1183                 break;
1184
1185         case sAllowTcpForwarding:
1186                 intptr = &options->allow_tcp_forwarding;
1187                 goto parse_flag;
1188
1189         case sAllowAgentForwarding:
1190                 intptr = &options->allow_agent_forwarding;
1191                 goto parse_flag;
1192
1193         case sUsePrivilegeSeparation:
1194                 intptr = &use_privsep;
1195                 multistate_ptr = multistate_privsep;
1196                 goto parse_multistate;
1197
1198         case sAllowUsers:
1199                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1200                         if (options->num_allow_users >= MAX_ALLOW_USERS)
1201                                 fatal("%s line %d: too many allow users.",
1202                                     filename, linenum);
1203                         if (!*activep)
1204                                 continue;
1205                         options->allow_users[options->num_allow_users++] =
1206                             xstrdup(arg);
1207                 }
1208                 break;
1209
1210         case sDenyUsers:
1211                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1212                         if (options->num_deny_users >= MAX_DENY_USERS)
1213                                 fatal("%s line %d: too many deny users.",
1214                                     filename, linenum);
1215                         if (!*activep)
1216                                 continue;
1217                         options->deny_users[options->num_deny_users++] =
1218                             xstrdup(arg);
1219                 }
1220                 break;
1221
1222         case sAllowGroups:
1223                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1224                         if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1225                                 fatal("%s line %d: too many allow groups.",
1226                                     filename, linenum);
1227                         if (!*activep)
1228                                 continue;
1229                         options->allow_groups[options->num_allow_groups++] =
1230                             xstrdup(arg);
1231                 }
1232                 break;
1233
1234         case sDenyGroups:
1235                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1236                         if (options->num_deny_groups >= MAX_DENY_GROUPS)
1237                                 fatal("%s line %d: too many deny groups.",
1238                                     filename, linenum);
1239                         if (!*activep)
1240                                 continue;
1241                         options->deny_groups[options->num_deny_groups++] =
1242                             xstrdup(arg);
1243                 }
1244                 break;
1245
1246         case sCiphers:
1247                 arg = strdelim(&cp);
1248                 if (!arg || *arg == '\0')
1249                         fatal("%s line %d: Missing argument.", filename, linenum);
1250                 if (!ciphers_valid(arg))
1251                         fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1252                             filename, linenum, arg ? arg : "<NONE>");
1253                 if (options->ciphers == NULL)
1254                         options->ciphers = xstrdup(arg);
1255                 break;
1256
1257         case sMacs:
1258                 arg = strdelim(&cp);
1259                 if (!arg || *arg == '\0')
1260                         fatal("%s line %d: Missing argument.", filename, linenum);
1261                 if (!mac_valid(arg))
1262                         fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1263                             filename, linenum, arg ? arg : "<NONE>");
1264                 if (options->macs == NULL)
1265                         options->macs = xstrdup(arg);
1266                 break;
1267
1268         case sKexAlgorithms:
1269                 arg = strdelim(&cp);
1270                 if (!arg || *arg == '\0')
1271                         fatal("%s line %d: Missing argument.",
1272                             filename, linenum);
1273                 if (!kex_names_valid(arg))
1274                         fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
1275                             filename, linenum, arg ? arg : "<NONE>");
1276                 if (options->kex_algorithms == NULL)
1277                         options->kex_algorithms = xstrdup(arg);
1278                 break;
1279
1280         case sProtocol:
1281                 intptr = &options->protocol;
1282                 arg = strdelim(&cp);
1283                 if (!arg || *arg == '\0')
1284                         fatal("%s line %d: Missing argument.", filename, linenum);
1285                 value = proto_spec(arg);
1286                 if (value == SSH_PROTO_UNKNOWN)
1287                         fatal("%s line %d: Bad protocol spec '%s'.",
1288                             filename, linenum, arg ? arg : "<NONE>");
1289                 if (*intptr == SSH_PROTO_UNKNOWN)
1290                         *intptr = value;
1291                 break;
1292
1293         case sSubsystem:
1294                 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1295                         fatal("%s line %d: too many subsystems defined.",
1296                             filename, linenum);
1297                 }
1298                 arg = strdelim(&cp);
1299                 if (!arg || *arg == '\0')
1300                         fatal("%s line %d: Missing subsystem name.",
1301                             filename, linenum);
1302                 if (!*activep) {
1303                         arg = strdelim(&cp);
1304                         break;
1305                 }
1306                 for (i = 0; i < options->num_subsystems; i++)
1307                         if (strcmp(arg, options->subsystem_name[i]) == 0)
1308                                 fatal("%s line %d: Subsystem '%s' already defined.",
1309                                     filename, linenum, arg);
1310                 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1311                 arg = strdelim(&cp);
1312                 if (!arg || *arg == '\0')
1313                         fatal("%s line %d: Missing subsystem command.",
1314                             filename, linenum);
1315                 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1316
1317                 /* Collect arguments (separate to executable) */
1318                 p = xstrdup(arg);
1319                 len = strlen(p) + 1;
1320                 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1321                         len += 1 + strlen(arg);
1322                         p = xrealloc(p, 1, len);
1323                         strlcat(p, " ", len);
1324                         strlcat(p, arg, len);
1325                 }
1326                 options->subsystem_args[options->num_subsystems] = p;
1327                 options->num_subsystems++;
1328                 break;
1329
1330         case sMaxStartups:
1331                 arg = strdelim(&cp);
1332                 if (!arg || *arg == '\0')
1333                         fatal("%s line %d: Missing MaxStartups spec.",
1334                             filename, linenum);
1335                 if ((n = sscanf(arg, "%d:%d:%d",
1336                     &options->max_startups_begin,
1337                     &options->max_startups_rate,
1338                     &options->max_startups)) == 3) {
1339                         if (options->max_startups_begin >
1340                             options->max_startups ||
1341                             options->max_startups_rate > 100 ||
1342                             options->max_startups_rate < 1)
1343                                 fatal("%s line %d: Illegal MaxStartups spec.",
1344                                     filename, linenum);
1345                 } else if (n != 1)
1346                         fatal("%s line %d: Illegal MaxStartups spec.",
1347                             filename, linenum);
1348                 else
1349                         options->max_startups = options->max_startups_begin;
1350                 break;
1351
1352         case sMaxAuthTries:
1353                 intptr = &options->max_authtries;
1354                 goto parse_int;
1355
1356         case sMaxSessions:
1357                 intptr = &options->max_sessions;
1358                 goto parse_int;
1359
1360         case sBanner:
1361                 charptr = &options->banner;
1362                 goto parse_filename;
1363
1364         /*
1365          * These options can contain %X options expanded at
1366          * connect time, so that you can specify paths like:
1367          *
1368          * AuthorizedKeysFile   /etc/ssh_keys/%u
1369          */
1370         case sAuthorizedKeysFile:
1371                 if (*activep && options->num_authkeys_files == 0) {
1372                         while ((arg = strdelim(&cp)) && *arg != '\0') {
1373                                 if (options->num_authkeys_files >=
1374                                     MAX_AUTHKEYS_FILES)
1375                                         fatal("%s line %d: "
1376                                             "too many authorized keys files.",
1377                                             filename, linenum);
1378                                 options->authorized_keys_files[
1379                                     options->num_authkeys_files++] =
1380                                     tilde_expand_filename(arg, getuid());
1381                         }
1382                 }
1383                 return 0;
1384
1385         case sAuthorizedPrincipalsFile:
1386                 charptr = &options->authorized_principals_file;
1387                 arg = strdelim(&cp);
1388                 if (!arg || *arg == '\0')
1389                         fatal("%s line %d: missing file name.",
1390                             filename, linenum);
1391                 if (*activep && *charptr == NULL) {
1392                         *charptr = tilde_expand_filename(arg, getuid());
1393                         /* increase optional counter */
1394                         if (intptr != NULL)
1395                                 *intptr = *intptr + 1;
1396                 }
1397                 break;
1398
1399         case sClientAliveInterval:
1400                 intptr = &options->client_alive_interval;
1401                 goto parse_time;
1402
1403         case sClientAliveCountMax:
1404                 intptr = &options->client_alive_count_max;
1405                 goto parse_int;
1406
1407         case sAcceptEnv:
1408                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1409                         if (strchr(arg, '=') != NULL)
1410                                 fatal("%s line %d: Invalid environment name.",
1411                                     filename, linenum);
1412                         if (options->num_accept_env >= MAX_ACCEPT_ENV)
1413                                 fatal("%s line %d: too many allow env.",
1414                                     filename, linenum);
1415                         if (!*activep)
1416                                 continue;
1417                         options->accept_env[options->num_accept_env++] =
1418                             xstrdup(arg);
1419                 }
1420                 break;
1421
1422         case sPermitTunnel:
1423                 intptr = &options->permit_tun;
1424                 arg = strdelim(&cp);
1425                 if (!arg || *arg == '\0')
1426                         fatal("%s line %d: Missing yes/point-to-point/"
1427                             "ethernet/no argument.", filename, linenum);
1428                 value = -1;
1429                 for (i = 0; tunmode_desc[i].val != -1; i++)
1430                         if (strcmp(tunmode_desc[i].text, arg) == 0) {
1431                                 value = tunmode_desc[i].val;
1432                                 break;
1433                         }
1434                 if (value == -1)
1435                         fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1436                             "no argument: %s", filename, linenum, arg);
1437                 if (*intptr == -1)
1438                         *intptr = value;
1439                 break;
1440
1441         case sMatch:
1442                 if (cmdline)
1443                         fatal("Match directive not supported as a command-line "
1444                            "option");
1445                 value = match_cfg_line(&cp, linenum, connectinfo);
1446                 if (value < 0)
1447                         fatal("%s line %d: Bad Match condition", filename,
1448                             linenum);
1449                 *activep = value;
1450                 break;
1451
1452         case sPermitOpen:
1453                 arg = strdelim(&cp);
1454                 if (!arg || *arg == '\0')
1455                         fatal("%s line %d: missing PermitOpen specification",
1456                             filename, linenum);
1457                 n = options->num_permitted_opens;       /* modified later */
1458                 if (strcmp(arg, "any") == 0) {
1459                         if (*activep && n == -1) {
1460                                 channel_clear_adm_permitted_opens();
1461                                 options->num_permitted_opens = 0;
1462                         }
1463                         break;
1464                 }
1465                 if (strcmp(arg, "none") == 0) {
1466                         if (*activep && n == -1) {
1467                                 channel_clear_adm_permitted_opens();
1468                                 options->num_permitted_opens = 1;
1469                                 channel_disable_adm_local_opens();
1470                         }
1471                         break;
1472                 }
1473                 if (*activep && n == -1)
1474                         channel_clear_adm_permitted_opens();
1475                 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1476                         p = hpdelim(&arg);
1477                         if (p == NULL)
1478                                 fatal("%s line %d: missing host in PermitOpen",
1479                                     filename, linenum);
1480                         p = cleanhostname(p);
1481                         if (arg == NULL || ((port = permitopen_port(arg)) < 0))
1482                                 fatal("%s line %d: bad port number in "
1483                                     "PermitOpen", filename, linenum);
1484                         if (*activep && n == -1)
1485                                 options->num_permitted_opens =
1486                                     channel_add_adm_permitted_opens(p, port);
1487                 }
1488                 break;
1489
1490         case sForceCommand:
1491                 if (cp == NULL)
1492                         fatal("%.200s line %d: Missing argument.", filename,
1493                             linenum);
1494                 len = strspn(cp, WHITESPACE);
1495                 if (*activep && options->adm_forced_command == NULL)
1496                         options->adm_forced_command = xstrdup(cp + len);
1497                 return 0;
1498
1499         case sChrootDirectory:
1500                 charptr = &options->chroot_directory;
1501
1502                 arg = strdelim(&cp);
1503                 if (!arg || *arg == '\0')
1504                         fatal("%s line %d: missing file name.",
1505                             filename, linenum);
1506                 if (*activep && *charptr == NULL)
1507                         *charptr = xstrdup(arg);
1508                 break;
1509
1510         case sTrustedUserCAKeys:
1511                 charptr = &options->trusted_user_ca_keys;
1512                 goto parse_filename;
1513
1514         case sRevokedKeys:
1515                 charptr = &options->revoked_keys_file;
1516                 goto parse_filename;
1517
1518         case sIPQoS:
1519                 arg = strdelim(&cp);
1520                 if ((value = parse_ipqos(arg)) == -1)
1521                         fatal("%s line %d: Bad IPQoS value: %s",
1522                             filename, linenum, arg);
1523                 arg = strdelim(&cp);
1524                 if (arg == NULL)
1525                         value2 = value;
1526                 else if ((value2 = parse_ipqos(arg)) == -1)
1527                         fatal("%s line %d: Bad IPQoS value: %s",
1528                             filename, linenum, arg);
1529                 if (*activep) {
1530                         options->ip_qos_interactive = value;
1531                         options->ip_qos_bulk = value2;
1532                 }
1533                 break;
1534
1535         case sVersionAddendum:
1536                 if (cp == NULL)
1537                         fatal("%.200s line %d: Missing argument.", filename,
1538                             linenum);
1539                 len = strspn(cp, WHITESPACE);
1540                 if (*activep && options->version_addendum == NULL) {
1541                         if (strcasecmp(cp + len, "none") == 0)
1542                                 options->version_addendum = xstrdup("");
1543                         else if (strchr(cp + len, '\r') != NULL)
1544                                 fatal("%.200s line %d: Invalid argument",
1545                                     filename, linenum);
1546                         else
1547                                 options->version_addendum = xstrdup(cp + len);
1548                 }
1549                 return 0;
1550
1551         case sHPNDisabled:
1552                 intptr = &options->hpn_disabled;
1553                 goto parse_flag;
1554
1555         case sHPNBufferSize:
1556                 intptr = &options->hpn_buffer_size;
1557                 goto parse_int;
1558
1559         case sTcpRcvBufPoll:
1560                 intptr = &options->tcp_rcv_buf_poll;
1561                 goto parse_flag;
1562
1563 #ifdef  NONE_CIPHER_ENABLED
1564         case sNoneEnabled:
1565                 intptr = &options->none_enabled;
1566                 goto parse_flag;
1567 #endif
1568
1569         case sDeprecated:
1570                 logit("%s line %d: Deprecated option %s",
1571                     filename, linenum, arg);
1572                 while (arg)
1573                     arg = strdelim(&cp);
1574                 break;
1575
1576         case sUnsupported:
1577                 logit("%s line %d: Unsupported option %s",
1578                     filename, linenum, arg);
1579                 while (arg)
1580                     arg = strdelim(&cp);
1581                 break;
1582
1583         default:
1584                 fatal("%s line %d: Missing handler for opcode %s (%d)",
1585                     filename, linenum, arg, opcode);
1586         }
1587         if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1588                 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1589                     filename, linenum, arg);
1590         return 0;
1591 }
1592
1593 /* Reads the server configuration file. */
1594
1595 void
1596 load_server_config(const char *filename, Buffer *conf)
1597 {
1598         char line[4096], *cp;
1599         FILE *f;
1600         int lineno = 0;
1601
1602         debug2("%s: filename %s", __func__, filename);
1603         if ((f = fopen(filename, "r")) == NULL) {
1604                 perror(filename);
1605                 exit(1);
1606         }
1607         buffer_clear(conf);
1608         while (fgets(line, sizeof(line), f)) {
1609                 lineno++;
1610                 if (strlen(line) == sizeof(line) - 1)
1611                         fatal("%s line %d too long", filename, lineno);
1612                 /*
1613                  * Trim out comments and strip whitespace
1614                  * NB - preserve newlines, they are needed to reproduce
1615                  * line numbers later for error messages
1616                  */
1617                 if ((cp = strchr(line, '#')) != NULL)
1618                         memcpy(cp, "\n", 2);
1619                 cp = line + strspn(line, " \t\r");
1620
1621                 buffer_append(conf, cp, strlen(cp));
1622         }
1623         buffer_append(conf, "\0", 1);
1624         fclose(f);
1625         debug2("%s: done config len = %d", __func__, buffer_len(conf));
1626 }
1627
1628 void
1629 parse_server_match_config(ServerOptions *options,
1630    struct connection_info *connectinfo)
1631 {
1632         ServerOptions mo;
1633
1634         initialize_server_options(&mo);
1635         parse_server_config(&mo, "reprocess config", &cfg, connectinfo);
1636         copy_set_server_options(options, &mo, 0);
1637 }
1638
1639 int parse_server_match_testspec(struct connection_info *ci, char *spec)
1640 {
1641         char *p;
1642
1643         while ((p = strsep(&spec, ",")) && *p != '\0') {
1644                 if (strncmp(p, "addr=", 5) == 0) {
1645                         ci->address = xstrdup(p + 5);
1646                 } else if (strncmp(p, "host=", 5) == 0) {
1647                         ci->host = xstrdup(p + 5);
1648                 } else if (strncmp(p, "user=", 5) == 0) {
1649                         ci->user = xstrdup(p + 5);
1650                 } else if (strncmp(p, "laddr=", 6) == 0) {
1651                         ci->laddress = xstrdup(p + 6);
1652                 } else if (strncmp(p, "lport=", 6) == 0) {
1653                         ci->lport = a2port(p + 6);
1654                         if (ci->lport == -1) {
1655                                 fprintf(stderr, "Invalid port '%s' in test mode"
1656                                    " specification %s\n", p+6, p);
1657                                 return -1;
1658                         }
1659                 } else {
1660                         fprintf(stderr, "Invalid test mode specification %s\n",
1661                            p);
1662                         return -1;
1663                 }
1664         }
1665         return 0;
1666 }
1667
1668 /*
1669  * returns 1 for a complete spec, 0 for partial spec and -1 for an
1670  * empty spec.
1671  */
1672 int server_match_spec_complete(struct connection_info *ci)
1673 {
1674         if (ci->user && ci->host && ci->address)
1675                 return 1;       /* complete */
1676         if (!ci->user && !ci->host && !ci->address)
1677                 return -1;      /* empty */
1678         return 0;       /* partial */
1679 }
1680
1681 /* Helper macros */
1682 #define M_CP_INTOPT(n) do {\
1683         if (src->n != -1) \
1684                 dst->n = src->n; \
1685 } while (0)
1686 #define M_CP_STROPT(n) do {\
1687         if (src->n != NULL) { \
1688                 if (dst->n != NULL) \
1689                         xfree(dst->n); \
1690                 dst->n = src->n; \
1691         } \
1692 } while(0)
1693 #define M_CP_STRARRAYOPT(n, num_n) do {\
1694         if (src->num_n != 0) { \
1695                 for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \
1696                         dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \
1697         } \
1698 } while(0)
1699
1700 /*
1701  * Copy any supported values that are set.
1702  *
1703  * If the preauth flag is set, we do not bother copying the string or
1704  * array values that are not used pre-authentication, because any that we
1705  * do use must be explictly sent in mm_getpwnamallow().
1706  */
1707 void
1708 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1709 {
1710         M_CP_INTOPT(password_authentication);
1711         M_CP_INTOPT(gss_authentication);
1712         M_CP_INTOPT(rsa_authentication);
1713         M_CP_INTOPT(pubkey_authentication);
1714         M_CP_INTOPT(kerberos_authentication);
1715         M_CP_INTOPT(hostbased_authentication);
1716         M_CP_INTOPT(hostbased_uses_name_from_packet_only);
1717         M_CP_INTOPT(kbd_interactive_authentication);
1718         M_CP_INTOPT(zero_knowledge_password_authentication);
1719         M_CP_INTOPT(permit_root_login);
1720         M_CP_INTOPT(permit_empty_passwd);
1721
1722         M_CP_INTOPT(allow_tcp_forwarding);
1723         M_CP_INTOPT(allow_agent_forwarding);
1724         M_CP_INTOPT(permit_tun);
1725         M_CP_INTOPT(gateway_ports);
1726         M_CP_INTOPT(x11_display_offset);
1727         M_CP_INTOPT(x11_forwarding);
1728         M_CP_INTOPT(x11_use_localhost);
1729         M_CP_INTOPT(max_sessions);
1730         M_CP_INTOPT(max_authtries);
1731         M_CP_INTOPT(ip_qos_interactive);
1732         M_CP_INTOPT(ip_qos_bulk);
1733
1734         /* See comment in servconf.h */
1735         COPY_MATCH_STRING_OPTS();
1736
1737         /*
1738          * The only things that should be below this point are string options
1739          * which are only used after authentication.
1740          */
1741         if (preauth)
1742                 return;
1743
1744         M_CP_STROPT(adm_forced_command);
1745         M_CP_STROPT(chroot_directory);
1746 }
1747
1748 #undef M_CP_INTOPT
1749 #undef M_CP_STROPT
1750 #undef M_CP_STRARRAYOPT
1751
1752 void
1753 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1754     struct connection_info *connectinfo)
1755 {
1756         int active, linenum, bad_options = 0;
1757         char *cp, *obuf, *cbuf;
1758
1759         debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1760
1761         obuf = cbuf = xstrdup(buffer_ptr(conf));
1762         active = connectinfo ? 0 : 1;
1763         linenum = 1;
1764         while ((cp = strsep(&cbuf, "\n")) != NULL) {
1765                 if (process_server_config_line(options, cp, filename,
1766                     linenum++, &active, connectinfo) != 0)
1767                         bad_options++;
1768         }
1769         xfree(obuf);
1770         if (bad_options > 0)
1771                 fatal("%s: terminating, %d bad configuration options",
1772                     filename, bad_options);
1773 }
1774
1775 static const char *
1776 fmt_multistate_int(int val, const struct multistate *m)
1777 {
1778         u_int i;
1779
1780         for (i = 0; m[i].key != NULL; i++) {
1781                 if (m[i].value == val)
1782                         return m[i].key;
1783         }
1784         return "UNKNOWN";
1785 }
1786
1787 static const char *
1788 fmt_intarg(ServerOpCodes code, int val)
1789 {
1790         if (val == -1)
1791                 return "unset";
1792         switch (code) {
1793         case sAddressFamily:
1794                 return fmt_multistate_int(val, multistate_addressfamily);
1795         case sPermitRootLogin:
1796                 return fmt_multistate_int(val, multistate_permitrootlogin);
1797         case sGatewayPorts:
1798                 return fmt_multistate_int(val, multistate_gatewayports);
1799         case sCompression:
1800                 return fmt_multistate_int(val, multistate_compression);
1801         case sUsePrivilegeSeparation:
1802                 return fmt_multistate_int(val, multistate_privsep);
1803         case sProtocol:
1804                 switch (val) {
1805                 case SSH_PROTO_1:
1806                         return "1";
1807                 case SSH_PROTO_2:
1808                         return "2";
1809                 case (SSH_PROTO_1|SSH_PROTO_2):
1810                         return "2,1";
1811                 default:
1812                         return "UNKNOWN";
1813                 }
1814         default:
1815                 switch (val) {
1816                 case 0:
1817                         return "no";
1818                 case 1:
1819                         return "yes";
1820                 default:
1821                         return "UNKNOWN";
1822                 }
1823         }
1824 }
1825
1826 static const char *
1827 lookup_opcode_name(ServerOpCodes code)
1828 {
1829         u_int i;
1830
1831         for (i = 0; keywords[i].name != NULL; i++)
1832                 if (keywords[i].opcode == code)
1833                         return(keywords[i].name);
1834         return "UNKNOWN";
1835 }
1836
1837 static void
1838 dump_cfg_int(ServerOpCodes code, int val)
1839 {
1840         printf("%s %d\n", lookup_opcode_name(code), val);
1841 }
1842
1843 static void
1844 dump_cfg_fmtint(ServerOpCodes code, int val)
1845 {
1846         printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
1847 }
1848
1849 static void
1850 dump_cfg_string(ServerOpCodes code, const char *val)
1851 {
1852         if (val == NULL)
1853                 return;
1854         printf("%s %s\n", lookup_opcode_name(code), val);
1855 }
1856
1857 static void
1858 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
1859 {
1860         u_int i;
1861
1862         for (i = 0; i < count; i++)
1863                 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
1864 }
1865
1866 static void
1867 dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
1868 {
1869         u_int i;
1870
1871         printf("%s", lookup_opcode_name(code));
1872         for (i = 0; i < count; i++)
1873                 printf(" %s",  vals[i]);
1874         printf("\n");
1875 }
1876
1877 void
1878 dump_config(ServerOptions *o)
1879 {
1880         u_int i;
1881         int ret;
1882         struct addrinfo *ai;
1883         char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
1884
1885         /* these are usually at the top of the config */
1886         for (i = 0; i < o->num_ports; i++)
1887                 printf("port %d\n", o->ports[i]);
1888         dump_cfg_fmtint(sProtocol, o->protocol);
1889         dump_cfg_fmtint(sAddressFamily, o->address_family);
1890
1891         /* ListenAddress must be after Port */
1892         for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
1893                 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
1894                     sizeof(addr), port, sizeof(port),
1895                     NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
1896                         error("getnameinfo failed: %.100s",
1897                             (ret != EAI_SYSTEM) ? gai_strerror(ret) :
1898                             strerror(errno));
1899                 } else {
1900                         if (ai->ai_family == AF_INET6)
1901                                 printf("listenaddress [%s]:%s\n", addr, port);
1902                         else
1903                                 printf("listenaddress %s:%s\n", addr, port);
1904                 }
1905         }
1906
1907         /* integer arguments */
1908 #ifdef USE_PAM
1909         dump_cfg_int(sUsePAM, o->use_pam);
1910 #endif
1911         dump_cfg_int(sServerKeyBits, o->server_key_bits);
1912         dump_cfg_int(sLoginGraceTime, o->login_grace_time);
1913         dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
1914         dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
1915         dump_cfg_int(sMaxAuthTries, o->max_authtries);
1916         dump_cfg_int(sMaxSessions, o->max_sessions);
1917         dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
1918         dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
1919
1920         /* formatted integer arguments */
1921         dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
1922         dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
1923         dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
1924         dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication);
1925         dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
1926         dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
1927             o->hostbased_uses_name_from_packet_only);
1928         dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
1929         dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
1930 #ifdef KRB5
1931         dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
1932         dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
1933         dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
1934 # ifdef USE_AFS
1935         dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
1936 # endif
1937 #endif
1938 #ifdef GSSAPI
1939         dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
1940         dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
1941 #endif
1942 #ifdef JPAKE
1943         dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
1944             o->zero_knowledge_password_authentication);
1945 #endif
1946         dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
1947         dump_cfg_fmtint(sKbdInteractiveAuthentication,
1948             o->kbd_interactive_authentication);
1949         dump_cfg_fmtint(sChallengeResponseAuthentication,
1950             o->challenge_response_authentication);
1951         dump_cfg_fmtint(sPrintMotd, o->print_motd);
1952         dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
1953         dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
1954         dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
1955         dump_cfg_fmtint(sStrictModes, o->strict_modes);
1956         dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
1957         dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
1958         dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
1959         dump_cfg_fmtint(sUseLogin, o->use_login);
1960         dump_cfg_fmtint(sCompression, o->compression);
1961         dump_cfg_fmtint(sGatewayPorts, o->gateway_ports);
1962         dump_cfg_fmtint(sUseDNS, o->use_dns);
1963         dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
1964         dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
1965
1966         /* string arguments */
1967         dump_cfg_string(sPidFile, o->pid_file);
1968         dump_cfg_string(sXAuthLocation, o->xauth_location);
1969         dump_cfg_string(sCiphers, o->ciphers);
1970         dump_cfg_string(sMacs, o->macs);
1971         dump_cfg_string(sBanner, o->banner);
1972         dump_cfg_string(sForceCommand, o->adm_forced_command);
1973         dump_cfg_string(sChrootDirectory, o->chroot_directory);
1974         dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
1975         dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
1976         dump_cfg_string(sAuthorizedPrincipalsFile,
1977             o->authorized_principals_file);
1978         dump_cfg_string(sVersionAddendum, o->version_addendum);
1979
1980         /* string arguments requiring a lookup */
1981         dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1982         dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
1983
1984         /* string array arguments */
1985         dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files,
1986             o->authorized_keys_files);
1987         dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
1988              o->host_key_files);
1989         dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files,
1990              o->host_cert_files);
1991         dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
1992         dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
1993         dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
1994         dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
1995         dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
1996
1997         /* other arguments */
1998         for (i = 0; i < o->num_subsystems; i++)
1999                 printf("subsystem %s %s\n", o->subsystem_name[i],
2000                     o->subsystem_args[i]);
2001
2002         printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
2003             o->max_startups_rate, o->max_startups);
2004
2005         for (i = 0; tunmode_desc[i].val != -1; i++)
2006                 if (tunmode_desc[i].val == o->permit_tun) {
2007                         s = tunmode_desc[i].text;
2008                         break;
2009                 }
2010         dump_cfg_string(sPermitTunnel, s);
2011
2012         printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2013         printf("%s\n", iptos2str(o->ip_qos_bulk));
2014
2015         channel_print_adm_permitted_opens();
2016 }