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