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