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