servconf.c revision 181111
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: head/crypto/openssh/servconf.c 181111 2008-08-01 02:48:36Z 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 *, u_short);
47static void add_one_listen_addr(ServerOptions *, char *, u_short);
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}
132
133void
134fill_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. */
279typedef 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. */
315static 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
424static 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
439static ServerOpCodes
440parse_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
456static void
457add_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
472static void
473add_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
527static int
528match_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	}
550out:
551	ga_free();
552	return result;
553}
554
555static int
556match_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
629int
630process_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
1320void
1321load_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
1349void
1350parse_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 */
1380void
1381copy_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
1411void
1412parse_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
1434static const char *
1435fmt_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
1486static const char *
1487lookup_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
1497static void
1498dump_cfg_int(ServerOpCodes code, int val)
1499{
1500	printf("%s %d\n", lookup_opcode_name(code), val);
1501}
1502
1503static void
1504dump_cfg_fmtint(ServerOpCodes code, int val)
1505{
1506	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
1507}
1508
1509static void
1510dump_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
1517static void
1518dump_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
1526void
1527dump_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}
1643