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