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