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