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