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