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