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