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