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