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