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