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