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