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