xref: /openbsd-src/usr.bin/ssh/readconf.c (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1 /* $OpenBSD: readconf.c,v 1.218 2014/02/23 20:11:36 djm Exp $ */
2 /*
3  * Author: Tatu Ylonen <ylo@cs.hut.fi>
4  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5  *                    All rights reserved
6  * Functions for reading the configuration files.
7  *
8  * As far as I am concerned, the code I have written for this software
9  * can be used freely for any purpose.  Any derived versions of this
10  * software must be clearly marked as such, and if the derived work is
11  * incompatible with the protocol description in the RFC file, it must be
12  * called by a name other than "ssh" or "Secure Shell".
13  */
14 
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <sys/socket.h>
18 #include <sys/wait.h>
19 
20 #include <netinet/in.h>
21 #include <netinet/in_systm.h>
22 #include <netinet/ip.h>
23 
24 #include <ctype.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <netdb.h>
28 #include <paths.h>
29 #include <pwd.h>
30 #include <signal.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <util.h>
35 
36 #include "xmalloc.h"
37 #include "ssh.h"
38 #include "compat.h"
39 #include "cipher.h"
40 #include "pathnames.h"
41 #include "log.h"
42 #include "key.h"
43 #include "readconf.h"
44 #include "match.h"
45 #include "misc.h"
46 #include "buffer.h"
47 #include "kex.h"
48 #include "mac.h"
49 #include "uidswap.h"
50 
51 /* Format of the configuration file:
52 
53    # Configuration data is parsed as follows:
54    #  1. command line options
55    #  2. user-specific file
56    #  3. system-wide file
57    # Any configuration value is only changed the first time it is set.
58    # Thus, host-specific definitions should be at the beginning of the
59    # configuration file, and defaults at the end.
60 
61    # Host-specific declarations.  These may override anything above.  A single
62    # host may match multiple declarations; these are processed in the order
63    # that they are given in.
64 
65    Host *.ngs.fi ngs.fi
66      User foo
67 
68    Host fake.com
69      HostName another.host.name.real.org
70      User blaah
71      Port 34289
72      ForwardX11 no
73      ForwardAgent no
74 
75    Host books.com
76      RemoteForward 9999 shadows.cs.hut.fi:9999
77      Cipher 3des
78 
79    Host fascist.blob.com
80      Port 23123
81      User tylonen
82      PasswordAuthentication no
83 
84    Host puukko.hut.fi
85      User t35124p
86      ProxyCommand ssh-proxy %h %p
87 
88    Host *.fr
89      PublicKeyAuthentication no
90 
91    Host *.su
92      Cipher none
93      PasswordAuthentication no
94 
95    Host vpn.fake.com
96      Tunnel yes
97      TunnelDevice 3
98 
99    # Defaults for various options
100    Host *
101      ForwardAgent no
102      ForwardX11 no
103      PasswordAuthentication yes
104      RSAAuthentication yes
105      RhostsRSAAuthentication yes
106      StrictHostKeyChecking yes
107      TcpKeepAlive no
108      IdentityFile ~/.ssh/identity
109      Port 22
110      EscapeChar ~
111 
112 */
113 
114 /* Keyword tokens. */
115 
116 typedef enum {
117 	oBadOption,
118 	oHost, oMatch,
119 	oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
120 	oGatewayPorts, oExitOnForwardFailure,
121 	oPasswordAuthentication, oRSAAuthentication,
122 	oChallengeResponseAuthentication, oXAuthLocation,
123 	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
124 	oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
125 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
126 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
127 	oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
128 	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
129 	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
130 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
131 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
132 	oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
133 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
134 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
135 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
136 	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
137 	oSendEnv, oControlPath, oControlMaster, oControlPersist,
138 	oHashKnownHosts,
139 	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
140 	oVisualHostKey, oUseRoaming,
141 	oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
142 	oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
143 	oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
144 	oIgnoredUnknownOption, oDeprecated, oUnsupported
145 } OpCodes;
146 
147 /* Textual representations of the tokens. */
148 
149 static struct {
150 	const char *name;
151 	OpCodes opcode;
152 } keywords[] = {
153 	{ "forwardagent", oForwardAgent },
154 	{ "forwardx11", oForwardX11 },
155 	{ "forwardx11trusted", oForwardX11Trusted },
156 	{ "forwardx11timeout", oForwardX11Timeout },
157 	{ "exitonforwardfailure", oExitOnForwardFailure },
158 	{ "xauthlocation", oXAuthLocation },
159 	{ "gatewayports", oGatewayPorts },
160 	{ "useprivilegedport", oUsePrivilegedPort },
161 	{ "rhostsauthentication", oDeprecated },
162 	{ "passwordauthentication", oPasswordAuthentication },
163 	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
164 	{ "kbdinteractivedevices", oKbdInteractiveDevices },
165 	{ "rsaauthentication", oRSAAuthentication },
166 	{ "pubkeyauthentication", oPubkeyAuthentication },
167 	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
168 	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
169 	{ "hostbasedauthentication", oHostbasedAuthentication },
170 	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
171 	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
172 	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
173 	{ "kerberosauthentication", oUnsupported },
174 	{ "kerberostgtpassing", oUnsupported },
175 	{ "afstokenpassing", oUnsupported },
176 #if defined(GSSAPI)
177 	{ "gssapiauthentication", oGssAuthentication },
178 	{ "gssapidelegatecredentials", oGssDelegateCreds },
179 #else
180 	{ "gssapiauthentication", oUnsupported },
181 	{ "gssapidelegatecredentials", oUnsupported },
182 #endif
183 	{ "fallbacktorsh", oDeprecated },
184 	{ "usersh", oDeprecated },
185 	{ "identityfile", oIdentityFile },
186 	{ "identityfile2", oIdentityFile },			/* obsolete */
187 	{ "identitiesonly", oIdentitiesOnly },
188 	{ "hostname", oHostName },
189 	{ "hostkeyalias", oHostKeyAlias },
190 	{ "proxycommand", oProxyCommand },
191 	{ "port", oPort },
192 	{ "cipher", oCipher },
193 	{ "ciphers", oCiphers },
194 	{ "macs", oMacs },
195 	{ "protocol", oProtocol },
196 	{ "remoteforward", oRemoteForward },
197 	{ "localforward", oLocalForward },
198 	{ "user", oUser },
199 	{ "host", oHost },
200 	{ "match", oMatch },
201 	{ "escapechar", oEscapeChar },
202 	{ "globalknownhostsfile", oGlobalKnownHostsFile },
203 	{ "globalknownhostsfile2", oDeprecated },
204 	{ "userknownhostsfile", oUserKnownHostsFile },
205 	{ "userknownhostsfile2", oDeprecated },
206 	{ "connectionattempts", oConnectionAttempts },
207 	{ "batchmode", oBatchMode },
208 	{ "checkhostip", oCheckHostIP },
209 	{ "stricthostkeychecking", oStrictHostKeyChecking },
210 	{ "compression", oCompression },
211 	{ "compressionlevel", oCompressionLevel },
212 	{ "tcpkeepalive", oTCPKeepAlive },
213 	{ "keepalive", oTCPKeepAlive },				/* obsolete */
214 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
215 	{ "loglevel", oLogLevel },
216 	{ "dynamicforward", oDynamicForward },
217 	{ "preferredauthentications", oPreferredAuthentications },
218 	{ "hostkeyalgorithms", oHostKeyAlgorithms },
219 	{ "bindaddress", oBindAddress },
220 #ifdef ENABLE_PKCS11
221 	{ "smartcarddevice", oPKCS11Provider },
222 	{ "pkcs11provider", oPKCS11Provider },
223 #else
224 	{ "smartcarddevice", oUnsupported },
225 	{ "pkcs11provider", oUnsupported },
226 #endif
227 	{ "clearallforwardings", oClearAllForwardings },
228 	{ "enablesshkeysign", oEnableSSHKeysign },
229 	{ "verifyhostkeydns", oVerifyHostKeyDNS },
230 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
231 	{ "rekeylimit", oRekeyLimit },
232 	{ "connecttimeout", oConnectTimeout },
233 	{ "addressfamily", oAddressFamily },
234 	{ "serveraliveinterval", oServerAliveInterval },
235 	{ "serveralivecountmax", oServerAliveCountMax },
236 	{ "sendenv", oSendEnv },
237 	{ "controlpath", oControlPath },
238 	{ "controlmaster", oControlMaster },
239 	{ "controlpersist", oControlPersist },
240 	{ "hashknownhosts", oHashKnownHosts },
241 	{ "tunnel", oTunnel },
242 	{ "tunneldevice", oTunnelDevice },
243 	{ "localcommand", oLocalCommand },
244 	{ "permitlocalcommand", oPermitLocalCommand },
245 	{ "visualhostkey", oVisualHostKey },
246 	{ "useroaming", oUseRoaming },
247 	{ "kexalgorithms", oKexAlgorithms },
248 	{ "ipqos", oIPQoS },
249 	{ "requesttty", oRequestTTY },
250 	{ "proxyusefdpass", oProxyUseFdpass },
251 	{ "canonicaldomains", oCanonicalDomains },
252 	{ "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
253 	{ "canonicalizehostname", oCanonicalizeHostname },
254 	{ "canonicalizemaxdots", oCanonicalizeMaxDots },
255 	{ "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
256 	{ "ignoreunknown", oIgnoreUnknown },
257 
258 	{ NULL, oBadOption }
259 };
260 
261 /*
262  * Adds a local TCP/IP port forward to options.  Never returns if there is an
263  * error.
264  */
265 
266 void
267 add_local_forward(Options *options, const Forward *newfwd)
268 {
269 	Forward *fwd;
270 	extern uid_t original_real_uid;
271 
272 	if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
273 		fatal("Privileged ports can only be forwarded by root.");
274 	options->local_forwards = xrealloc(options->local_forwards,
275 	    options->num_local_forwards + 1,
276 	    sizeof(*options->local_forwards));
277 	fwd = &options->local_forwards[options->num_local_forwards++];
278 
279 	fwd->listen_host = newfwd->listen_host;
280 	fwd->listen_port = newfwd->listen_port;
281 	fwd->connect_host = newfwd->connect_host;
282 	fwd->connect_port = newfwd->connect_port;
283 }
284 
285 /*
286  * Adds a remote TCP/IP port forward to options.  Never returns if there is
287  * an error.
288  */
289 
290 void
291 add_remote_forward(Options *options, const Forward *newfwd)
292 {
293 	Forward *fwd;
294 
295 	options->remote_forwards = xrealloc(options->remote_forwards,
296 	    options->num_remote_forwards + 1,
297 	    sizeof(*options->remote_forwards));
298 	fwd = &options->remote_forwards[options->num_remote_forwards++];
299 
300 	fwd->listen_host = newfwd->listen_host;
301 	fwd->listen_port = newfwd->listen_port;
302 	fwd->connect_host = newfwd->connect_host;
303 	fwd->connect_port = newfwd->connect_port;
304 	fwd->handle = newfwd->handle;
305 	fwd->allocated_port = 0;
306 }
307 
308 static void
309 clear_forwardings(Options *options)
310 {
311 	int i;
312 
313 	for (i = 0; i < options->num_local_forwards; i++) {
314 		free(options->local_forwards[i].listen_host);
315 		free(options->local_forwards[i].connect_host);
316 	}
317 	if (options->num_local_forwards > 0) {
318 		free(options->local_forwards);
319 		options->local_forwards = NULL;
320 	}
321 	options->num_local_forwards = 0;
322 	for (i = 0; i < options->num_remote_forwards; i++) {
323 		free(options->remote_forwards[i].listen_host);
324 		free(options->remote_forwards[i].connect_host);
325 	}
326 	if (options->num_remote_forwards > 0) {
327 		free(options->remote_forwards);
328 		options->remote_forwards = NULL;
329 	}
330 	options->num_remote_forwards = 0;
331 	options->tun_open = SSH_TUNMODE_NO;
332 }
333 
334 void
335 add_identity_file(Options *options, const char *dir, const char *filename,
336     int userprovided)
337 {
338 	char *path;
339 
340 	if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
341 		fatal("Too many identity files specified (max %d)",
342 		    SSH_MAX_IDENTITY_FILES);
343 
344 	if (dir == NULL) /* no dir, filename is absolute */
345 		path = xstrdup(filename);
346 	else
347 		(void)xasprintf(&path, "%.100s%.100s", dir, filename);
348 
349 	options->identity_file_userprovided[options->num_identity_files] =
350 	    userprovided;
351 	options->identity_files[options->num_identity_files++] = path;
352 }
353 
354 int
355 default_ssh_port(void)
356 {
357 	static int port;
358 	struct servent *sp;
359 
360 	if (port == 0) {
361 		sp = getservbyname(SSH_SERVICE_NAME, "tcp");
362 		port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
363 	}
364 	return port;
365 }
366 
367 /*
368  * Execute a command in a shell.
369  * Return its exit status or -1 on abnormal exit.
370  */
371 static int
372 execute_in_shell(const char *cmd)
373 {
374 	char *shell, *command_string;
375 	pid_t pid;
376 	int devnull, status;
377 	extern uid_t original_real_uid;
378 
379 	if ((shell = getenv("SHELL")) == NULL)
380 		shell = _PATH_BSHELL;
381 
382 	/*
383 	 * Use "exec" to avoid "sh -c" processes on some platforms
384 	 * (e.g. Solaris)
385 	 */
386 	xasprintf(&command_string, "exec %s", cmd);
387 
388 	/* Need this to redirect subprocess stdin/out */
389 	if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
390 		fatal("open(/dev/null): %s", strerror(errno));
391 
392 	debug("Executing command: '%.500s'", cmd);
393 
394 	/* Fork and execute the command. */
395 	if ((pid = fork()) == 0) {
396 		char *argv[4];
397 
398 		/* Child.  Permanently give up superuser privileges. */
399 		permanently_drop_suid(original_real_uid);
400 
401 		/* Redirect child stdin and stdout. Leave stderr */
402 		if (dup2(devnull, STDIN_FILENO) == -1)
403 			fatal("dup2: %s", strerror(errno));
404 		if (dup2(devnull, STDOUT_FILENO) == -1)
405 			fatal("dup2: %s", strerror(errno));
406 		if (devnull > STDERR_FILENO)
407 			close(devnull);
408 		closefrom(STDERR_FILENO + 1);
409 
410 		argv[0] = shell;
411 		argv[1] = "-c";
412 		argv[2] = command_string;
413 		argv[3] = NULL;
414 
415 		execv(argv[0], argv);
416 		error("Unable to execute '%.100s': %s", cmd, strerror(errno));
417 		/* Die with signal to make this error apparent to parent. */
418 		signal(SIGTERM, SIG_DFL);
419 		kill(getpid(), SIGTERM);
420 		_exit(1);
421 	}
422 	/* Parent. */
423 	if (pid < 0)
424 		fatal("%s: fork: %.100s", __func__, strerror(errno));
425 
426 	close(devnull);
427 	free(command_string);
428 
429 	while (waitpid(pid, &status, 0) == -1) {
430 		if (errno != EINTR && errno != EAGAIN)
431 			fatal("%s: waitpid: %s", __func__, strerror(errno));
432 	}
433 	if (!WIFEXITED(status)) {
434 		error("command '%.100s' exited abnormally", cmd);
435 		return -1;
436 	}
437 	debug3("command returned status %d", WEXITSTATUS(status));
438 	return WEXITSTATUS(status);
439 }
440 
441 /*
442  * Parse and execute a Match directive.
443  */
444 static int
445 match_cfg_line(Options *options, char **condition, struct passwd *pw,
446     const char *host_arg, const char *filename, int linenum)
447 {
448 	char *arg, *attrib, *cmd, *cp = *condition, *host;
449 	const char *ruser;
450 	int r, port, result = 1, attributes = 0;
451 	size_t len;
452 	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
453 
454 	/*
455 	 * Configuration is likely to be incomplete at this point so we
456 	 * must be prepared to use default values.
457 	 */
458 	port = options->port <= 0 ? default_ssh_port() : options->port;
459 	ruser = options->user == NULL ? pw->pw_name : options->user;
460 	if (options->hostname != NULL) {
461 		/* NB. Please keep in sync with ssh.c:main() */
462 		host = percent_expand(options->hostname,
463 		    "h", host_arg, (char *)NULL);
464 	} else
465 		host = xstrdup(host_arg);
466 
467 	debug3("checking match for '%s' host %s", cp, host);
468 	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
469 		attributes++;
470 		if (strcasecmp(attrib, "all") == 0) {
471 			if (attributes != 1 ||
472 			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
473 				error("'all' cannot be combined with other "
474 				    "Match attributes");
475 				result = -1;
476 				goto out;
477 			}
478 			*condition = cp;
479 			result = 1;
480 			goto out;
481 		}
482 		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
483 			error("Missing Match criteria for %s", attrib);
484 			result = -1;
485 			goto out;
486 		}
487 		len = strlen(arg);
488 		if (strcasecmp(attrib, "host") == 0) {
489 			if (match_hostname(host, arg, len) != 1)
490 				result = 0;
491 			else
492 				debug("%.200s line %d: matched 'Host %.100s' ",
493 				    filename, linenum, host);
494 		} else if (strcasecmp(attrib, "originalhost") == 0) {
495 			if (match_hostname(host_arg, arg, len) != 1)
496 				result = 0;
497 			else
498 				debug("%.200s line %d: matched "
499 				    "'OriginalHost %.100s' ",
500 				    filename, linenum, host_arg);
501 		} else if (strcasecmp(attrib, "user") == 0) {
502 			if (match_pattern_list(ruser, arg, len, 0) != 1)
503 				result = 0;
504 			else
505 				debug("%.200s line %d: matched 'User %.100s' ",
506 				    filename, linenum, ruser);
507 		} else if (strcasecmp(attrib, "localuser") == 0) {
508 			if (match_pattern_list(pw->pw_name, arg, len, 0) != 1)
509 				result = 0;
510 			else
511 				debug("%.200s line %d: matched "
512 				    "'LocalUser %.100s' ",
513 				    filename, linenum, pw->pw_name);
514 		} else if (strcasecmp(attrib, "exec") == 0) {
515 			if (gethostname(thishost, sizeof(thishost)) == -1)
516 				fatal("gethostname: %s", strerror(errno));
517 			strlcpy(shorthost, thishost, sizeof(shorthost));
518 			shorthost[strcspn(thishost, ".")] = '\0';
519 			snprintf(portstr, sizeof(portstr), "%d", port);
520 
521 			cmd = percent_expand(arg,
522 			    "L", shorthost,
523 			    "d", pw->pw_dir,
524 			    "h", host,
525 			    "l", thishost,
526 			    "n", host_arg,
527 			    "p", portstr,
528 			    "r", ruser,
529 			    "u", pw->pw_name,
530 			    (char *)NULL);
531 			if (result != 1) {
532 				/* skip execution if prior predicate failed */
533 				debug("%.200s line %d: skipped exec \"%.100s\"",
534 				    filename, linenum, cmd);
535 			} else {
536 				r = execute_in_shell(cmd);
537 				if (r == -1) {
538 					fatal("%.200s line %d: match exec "
539 					    "'%.100s' error", filename,
540 					    linenum, cmd);
541 				} else if (r == 0) {
542 					debug("%.200s line %d: matched "
543 					    "'exec \"%.100s\"'", filename,
544 					    linenum, cmd);
545 				} else {
546 					debug("%.200s line %d: no match "
547 					    "'exec \"%.100s\"'", filename,
548 					    linenum, cmd);
549 					result = 0;
550 				}
551 			}
552 			free(cmd);
553 		} else {
554 			error("Unsupported Match attribute %s", attrib);
555 			result = -1;
556 			goto out;
557 		}
558 	}
559 	if (attributes == 0) {
560 		error("One or more attributes required for Match");
561 		result = -1;
562 		goto out;
563 	}
564 	debug3("match %sfound", result ? "" : "not ");
565 	*condition = cp;
566  out:
567 	free(host);
568 	return result;
569 }
570 
571 /* Check and prepare a domain name: removes trailing '.' and lowercases */
572 static void
573 valid_domain(char *name, const char *filename, int linenum)
574 {
575 	size_t i, l = strlen(name);
576 	u_char c, last = '\0';
577 
578 	if (l == 0)
579 		fatal("%s line %d: empty hostname suffix", filename, linenum);
580 	if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
581 		fatal("%s line %d: hostname suffix \"%.100s\" "
582 		    "starts with invalid character", filename, linenum, name);
583 	for (i = 0; i < l; i++) {
584 		c = tolower((u_char)name[i]);
585 		name[i] = (char)c;
586 		if (last == '.' && c == '.')
587 			fatal("%s line %d: hostname suffix \"%.100s\" contains "
588 			    "consecutive separators", filename, linenum, name);
589 		if (c != '.' && c != '-' && !isalnum(c) &&
590 		    c != '_') /* technically invalid, but common */
591 			fatal("%s line %d: hostname suffix \"%.100s\" contains "
592 			    "invalid characters", filename, linenum, name);
593 		last = c;
594 	}
595 	if (name[l - 1] == '.')
596 		name[l - 1] = '\0';
597 }
598 
599 /*
600  * Returns the number of the token pointed to by cp or oBadOption.
601  */
602 static OpCodes
603 parse_token(const char *cp, const char *filename, int linenum,
604     const char *ignored_unknown)
605 {
606 	int i;
607 
608 	for (i = 0; keywords[i].name; i++)
609 		if (strcmp(cp, keywords[i].name) == 0)
610 			return keywords[i].opcode;
611 	if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown,
612 	    strlen(ignored_unknown), 1) == 1)
613 		return oIgnoredUnknownOption;
614 	error("%s: line %d: Bad configuration option: %s",
615 	    filename, linenum, cp);
616 	return oBadOption;
617 }
618 
619 /* Multistate option parsing */
620 struct multistate {
621 	char *key;
622 	int value;
623 };
624 static const struct multistate multistate_flag[] = {
625 	{ "true",			1 },
626 	{ "false",			0 },
627 	{ "yes",			1 },
628 	{ "no",				0 },
629 	{ NULL, -1 }
630 };
631 static const struct multistate multistate_yesnoask[] = {
632 	{ "true",			1 },
633 	{ "false",			0 },
634 	{ "yes",			1 },
635 	{ "no",				0 },
636 	{ "ask",			2 },
637 	{ NULL, -1 }
638 };
639 static const struct multistate multistate_addressfamily[] = {
640 	{ "inet",			AF_INET },
641 	{ "inet6",			AF_INET6 },
642 	{ "any",			AF_UNSPEC },
643 	{ NULL, -1 }
644 };
645 static const struct multistate multistate_controlmaster[] = {
646 	{ "true",			SSHCTL_MASTER_YES },
647 	{ "yes",			SSHCTL_MASTER_YES },
648 	{ "false",			SSHCTL_MASTER_NO },
649 	{ "no",				SSHCTL_MASTER_NO },
650 	{ "auto",			SSHCTL_MASTER_AUTO },
651 	{ "ask",			SSHCTL_MASTER_ASK },
652 	{ "autoask",			SSHCTL_MASTER_AUTO_ASK },
653 	{ NULL, -1 }
654 };
655 static const struct multistate multistate_tunnel[] = {
656 	{ "ethernet",			SSH_TUNMODE_ETHERNET },
657 	{ "point-to-point",		SSH_TUNMODE_POINTOPOINT },
658 	{ "true",			SSH_TUNMODE_DEFAULT },
659 	{ "yes",			SSH_TUNMODE_DEFAULT },
660 	{ "false",			SSH_TUNMODE_NO },
661 	{ "no",				SSH_TUNMODE_NO },
662 	{ NULL, -1 }
663 };
664 static const struct multistate multistate_requesttty[] = {
665 	{ "true",			REQUEST_TTY_YES },
666 	{ "yes",			REQUEST_TTY_YES },
667 	{ "false",			REQUEST_TTY_NO },
668 	{ "no",				REQUEST_TTY_NO },
669 	{ "force",			REQUEST_TTY_FORCE },
670 	{ "auto",			REQUEST_TTY_AUTO },
671 	{ NULL, -1 }
672 };
673 static const struct multistate multistate_canonicalizehostname[] = {
674 	{ "true",			SSH_CANONICALISE_YES },
675 	{ "false",			SSH_CANONICALISE_NO },
676 	{ "yes",			SSH_CANONICALISE_YES },
677 	{ "no",				SSH_CANONICALISE_NO },
678 	{ "always",			SSH_CANONICALISE_ALWAYS },
679 	{ NULL, -1 }
680 };
681 
682 /*
683  * Processes a single option line as used in the configuration files. This
684  * only sets those values that have not already been set.
685  */
686 #define WHITESPACE " \t\r\n"
687 int
688 process_config_line(Options *options, struct passwd *pw, const char *host,
689     char *line, const char *filename, int linenum, int *activep, int userconfig)
690 {
691 	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
692 	char **cpptr, fwdarg[256];
693 	u_int i, *uintptr, max_entries = 0;
694 	int negated, opcode, *intptr, value, value2, cmdline = 0;
695 	LogLevel *log_level_ptr;
696 	long long val64;
697 	size_t len;
698 	Forward fwd;
699 	const struct multistate *multistate_ptr;
700 	struct allowed_cname *cname;
701 
702 	if (activep == NULL) { /* We are processing a command line directive */
703 		cmdline = 1;
704 		activep = &cmdline;
705 	}
706 
707 	/* Strip trailing whitespace */
708 	for (len = strlen(line) - 1; len > 0; len--) {
709 		if (strchr(WHITESPACE, line[len]) == NULL)
710 			break;
711 		line[len] = '\0';
712 	}
713 
714 	s = line;
715 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
716 	if ((keyword = strdelim(&s)) == NULL)
717 		return 0;
718 	/* Ignore leading whitespace. */
719 	if (*keyword == '\0')
720 		keyword = strdelim(&s);
721 	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
722 		return 0;
723 	/* Match lowercase keyword */
724 	lowercase(keyword);
725 
726 	opcode = parse_token(keyword, filename, linenum,
727 	    options->ignored_unknown);
728 
729 	switch (opcode) {
730 	case oBadOption:
731 		/* don't panic, but count bad options */
732 		return -1;
733 		/* NOTREACHED */
734 	case oIgnoredUnknownOption:
735 		debug("%s line %d: Ignored unknown option \"%s\"",
736 		    filename, linenum, keyword);
737 		return 0;
738 	case oConnectTimeout:
739 		intptr = &options->connection_timeout;
740 parse_time:
741 		arg = strdelim(&s);
742 		if (!arg || *arg == '\0')
743 			fatal("%s line %d: missing time value.",
744 			    filename, linenum);
745 		if ((value = convtime(arg)) == -1)
746 			fatal("%s line %d: invalid time value.",
747 			    filename, linenum);
748 		if (*activep && *intptr == -1)
749 			*intptr = value;
750 		break;
751 
752 	case oForwardAgent:
753 		intptr = &options->forward_agent;
754  parse_flag:
755 		multistate_ptr = multistate_flag;
756  parse_multistate:
757 		arg = strdelim(&s);
758 		if (!arg || *arg == '\0')
759 			fatal("%s line %d: missing argument.",
760 			    filename, linenum);
761 		value = -1;
762 		for (i = 0; multistate_ptr[i].key != NULL; i++) {
763 			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
764 				value = multistate_ptr[i].value;
765 				break;
766 			}
767 		}
768 		if (value == -1)
769 			fatal("%s line %d: unsupported option \"%s\".",
770 			    filename, linenum, arg);
771 		if (*activep && *intptr == -1)
772 			*intptr = value;
773 		break;
774 
775 	case oForwardX11:
776 		intptr = &options->forward_x11;
777 		goto parse_flag;
778 
779 	case oForwardX11Trusted:
780 		intptr = &options->forward_x11_trusted;
781 		goto parse_flag;
782 
783 	case oForwardX11Timeout:
784 		intptr = &options->forward_x11_timeout;
785 		goto parse_time;
786 
787 	case oGatewayPorts:
788 		intptr = &options->gateway_ports;
789 		goto parse_flag;
790 
791 	case oExitOnForwardFailure:
792 		intptr = &options->exit_on_forward_failure;
793 		goto parse_flag;
794 
795 	case oUsePrivilegedPort:
796 		intptr = &options->use_privileged_port;
797 		goto parse_flag;
798 
799 	case oPasswordAuthentication:
800 		intptr = &options->password_authentication;
801 		goto parse_flag;
802 
803 	case oKbdInteractiveAuthentication:
804 		intptr = &options->kbd_interactive_authentication;
805 		goto parse_flag;
806 
807 	case oKbdInteractiveDevices:
808 		charptr = &options->kbd_interactive_devices;
809 		goto parse_string;
810 
811 	case oPubkeyAuthentication:
812 		intptr = &options->pubkey_authentication;
813 		goto parse_flag;
814 
815 	case oRSAAuthentication:
816 		intptr = &options->rsa_authentication;
817 		goto parse_flag;
818 
819 	case oRhostsRSAAuthentication:
820 		intptr = &options->rhosts_rsa_authentication;
821 		goto parse_flag;
822 
823 	case oHostbasedAuthentication:
824 		intptr = &options->hostbased_authentication;
825 		goto parse_flag;
826 
827 	case oChallengeResponseAuthentication:
828 		intptr = &options->challenge_response_authentication;
829 		goto parse_flag;
830 
831 	case oGssAuthentication:
832 		intptr = &options->gss_authentication;
833 		goto parse_flag;
834 
835 	case oGssDelegateCreds:
836 		intptr = &options->gss_deleg_creds;
837 		goto parse_flag;
838 
839 	case oBatchMode:
840 		intptr = &options->batch_mode;
841 		goto parse_flag;
842 
843 	case oCheckHostIP:
844 		intptr = &options->check_host_ip;
845 		goto parse_flag;
846 
847 	case oVerifyHostKeyDNS:
848 		intptr = &options->verify_host_key_dns;
849 		multistate_ptr = multistate_yesnoask;
850 		goto parse_multistate;
851 
852 	case oStrictHostKeyChecking:
853 		intptr = &options->strict_host_key_checking;
854 		multistate_ptr = multistate_yesnoask;
855 		goto parse_multistate;
856 
857 	case oCompression:
858 		intptr = &options->compression;
859 		goto parse_flag;
860 
861 	case oTCPKeepAlive:
862 		intptr = &options->tcp_keep_alive;
863 		goto parse_flag;
864 
865 	case oNoHostAuthenticationForLocalhost:
866 		intptr = &options->no_host_authentication_for_localhost;
867 		goto parse_flag;
868 
869 	case oNumberOfPasswordPrompts:
870 		intptr = &options->number_of_password_prompts;
871 		goto parse_int;
872 
873 	case oCompressionLevel:
874 		intptr = &options->compression_level;
875 		goto parse_int;
876 
877 	case oRekeyLimit:
878 		arg = strdelim(&s);
879 		if (!arg || *arg == '\0')
880 			fatal("%.200s line %d: Missing argument.", filename,
881 			    linenum);
882 		if (strcmp(arg, "default") == 0) {
883 			val64 = 0;
884 		} else {
885 			if (scan_scaled(arg, &val64) == -1)
886 				fatal("%.200s line %d: Bad number '%s': %s",
887 				    filename, linenum, arg, strerror(errno));
888 			/* check for too-large or too-small limits */
889 			if (val64 > UINT_MAX)
890 				fatal("%.200s line %d: RekeyLimit too large",
891 				    filename, linenum);
892 			if (val64 != 0 && val64 < 16)
893 				fatal("%.200s line %d: RekeyLimit too small",
894 				    filename, linenum);
895 		}
896 		if (*activep && options->rekey_limit == -1)
897 			options->rekey_limit = (u_int32_t)val64;
898 		if (s != NULL) { /* optional rekey interval present */
899 			if (strcmp(s, "none") == 0) {
900 				(void)strdelim(&s);	/* discard */
901 				break;
902 			}
903 			intptr = &options->rekey_interval;
904 			goto parse_time;
905 		}
906 		break;
907 
908 	case oIdentityFile:
909 		arg = strdelim(&s);
910 		if (!arg || *arg == '\0')
911 			fatal("%.200s line %d: Missing argument.", filename, linenum);
912 		if (*activep) {
913 			intptr = &options->num_identity_files;
914 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
915 				fatal("%.200s line %d: Too many identity files specified (max %d).",
916 				    filename, linenum, SSH_MAX_IDENTITY_FILES);
917 			add_identity_file(options, NULL, arg, userconfig);
918 		}
919 		break;
920 
921 	case oXAuthLocation:
922 		charptr=&options->xauth_location;
923 		goto parse_string;
924 
925 	case oUser:
926 		charptr = &options->user;
927 parse_string:
928 		arg = strdelim(&s);
929 		if (!arg || *arg == '\0')
930 			fatal("%.200s line %d: Missing argument.",
931 			    filename, linenum);
932 		if (*activep && *charptr == NULL)
933 			*charptr = xstrdup(arg);
934 		break;
935 
936 	case oGlobalKnownHostsFile:
937 		cpptr = (char **)&options->system_hostfiles;
938 		uintptr = &options->num_system_hostfiles;
939 		max_entries = SSH_MAX_HOSTS_FILES;
940 parse_char_array:
941 		if (*activep && *uintptr == 0) {
942 			while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
943 				if ((*uintptr) >= max_entries)
944 					fatal("%s line %d: "
945 					    "too many authorized keys files.",
946 					    filename, linenum);
947 				cpptr[(*uintptr)++] = xstrdup(arg);
948 			}
949 		}
950 		return 0;
951 
952 	case oUserKnownHostsFile:
953 		cpptr = (char **)&options->user_hostfiles;
954 		uintptr = &options->num_user_hostfiles;
955 		max_entries = SSH_MAX_HOSTS_FILES;
956 		goto parse_char_array;
957 
958 	case oHostName:
959 		charptr = &options->hostname;
960 		goto parse_string;
961 
962 	case oHostKeyAlias:
963 		charptr = &options->host_key_alias;
964 		goto parse_string;
965 
966 	case oPreferredAuthentications:
967 		charptr = &options->preferred_authentications;
968 		goto parse_string;
969 
970 	case oBindAddress:
971 		charptr = &options->bind_address;
972 		goto parse_string;
973 
974 	case oPKCS11Provider:
975 		charptr = &options->pkcs11_provider;
976 		goto parse_string;
977 
978 	case oProxyCommand:
979 		charptr = &options->proxy_command;
980 parse_command:
981 		if (s == NULL)
982 			fatal("%.200s line %d: Missing argument.", filename, linenum);
983 		len = strspn(s, WHITESPACE "=");
984 		if (*activep && *charptr == NULL)
985 			*charptr = xstrdup(s + len);
986 		return 0;
987 
988 	case oPort:
989 		intptr = &options->port;
990 parse_int:
991 		arg = strdelim(&s);
992 		if (!arg || *arg == '\0')
993 			fatal("%.200s line %d: Missing argument.", filename, linenum);
994 		if (arg[0] < '0' || arg[0] > '9')
995 			fatal("%.200s line %d: Bad number.", filename, linenum);
996 
997 		/* Octal, decimal, or hex format? */
998 		value = strtol(arg, &endofnumber, 0);
999 		if (arg == endofnumber)
1000 			fatal("%.200s line %d: Bad number.", filename, linenum);
1001 		if (*activep && *intptr == -1)
1002 			*intptr = value;
1003 		break;
1004 
1005 	case oConnectionAttempts:
1006 		intptr = &options->connection_attempts;
1007 		goto parse_int;
1008 
1009 	case oCipher:
1010 		intptr = &options->cipher;
1011 		arg = strdelim(&s);
1012 		if (!arg || *arg == '\0')
1013 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1014 		value = cipher_number(arg);
1015 		if (value == -1)
1016 			fatal("%.200s line %d: Bad cipher '%s'.",
1017 			    filename, linenum, arg ? arg : "<NONE>");
1018 		if (*activep && *intptr == -1)
1019 			*intptr = value;
1020 		break;
1021 
1022 	case oCiphers:
1023 		arg = strdelim(&s);
1024 		if (!arg || *arg == '\0')
1025 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1026 		if (!ciphers_valid(arg))
1027 			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1028 			    filename, linenum, arg ? arg : "<NONE>");
1029 		if (*activep && options->ciphers == NULL)
1030 			options->ciphers = xstrdup(arg);
1031 		break;
1032 
1033 	case oMacs:
1034 		arg = strdelim(&s);
1035 		if (!arg || *arg == '\0')
1036 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1037 		if (!mac_valid(arg))
1038 			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1039 			    filename, linenum, arg ? arg : "<NONE>");
1040 		if (*activep && options->macs == NULL)
1041 			options->macs = xstrdup(arg);
1042 		break;
1043 
1044 	case oKexAlgorithms:
1045 		arg = strdelim(&s);
1046 		if (!arg || *arg == '\0')
1047 			fatal("%.200s line %d: Missing argument.",
1048 			    filename, linenum);
1049 		if (!kex_names_valid(arg))
1050 			fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1051 			    filename, linenum, arg ? arg : "<NONE>");
1052 		if (*activep && options->kex_algorithms == NULL)
1053 			options->kex_algorithms = xstrdup(arg);
1054 		break;
1055 
1056 	case oHostKeyAlgorithms:
1057 		arg = strdelim(&s);
1058 		if (!arg || *arg == '\0')
1059 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1060 		if (!key_names_valid2(arg))
1061 			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
1062 			    filename, linenum, arg ? arg : "<NONE>");
1063 		if (*activep && options->hostkeyalgorithms == NULL)
1064 			options->hostkeyalgorithms = xstrdup(arg);
1065 		break;
1066 
1067 	case oProtocol:
1068 		intptr = &options->protocol;
1069 		arg = strdelim(&s);
1070 		if (!arg || *arg == '\0')
1071 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1072 		value = proto_spec(arg);
1073 		if (value == SSH_PROTO_UNKNOWN)
1074 			fatal("%.200s line %d: Bad protocol spec '%s'.",
1075 			    filename, linenum, arg ? arg : "<NONE>");
1076 		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1077 			*intptr = value;
1078 		break;
1079 
1080 	case oLogLevel:
1081 		log_level_ptr = &options->log_level;
1082 		arg = strdelim(&s);
1083 		value = log_level_number(arg);
1084 		if (value == SYSLOG_LEVEL_NOT_SET)
1085 			fatal("%.200s line %d: unsupported log level '%s'",
1086 			    filename, linenum, arg ? arg : "<NONE>");
1087 		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1088 			*log_level_ptr = (LogLevel) value;
1089 		break;
1090 
1091 	case oLocalForward:
1092 	case oRemoteForward:
1093 	case oDynamicForward:
1094 		arg = strdelim(&s);
1095 		if (arg == NULL || *arg == '\0')
1096 			fatal("%.200s line %d: Missing port argument.",
1097 			    filename, linenum);
1098 
1099 		if (opcode == oLocalForward ||
1100 		    opcode == oRemoteForward) {
1101 			arg2 = strdelim(&s);
1102 			if (arg2 == NULL || *arg2 == '\0')
1103 				fatal("%.200s line %d: Missing target argument.",
1104 				    filename, linenum);
1105 
1106 			/* construct a string for parse_forward */
1107 			snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1108 		} else if (opcode == oDynamicForward) {
1109 			strlcpy(fwdarg, arg, sizeof(fwdarg));
1110 		}
1111 
1112 		if (parse_forward(&fwd, fwdarg,
1113 		    opcode == oDynamicForward ? 1 : 0,
1114 		    opcode == oRemoteForward ? 1 : 0) == 0)
1115 			fatal("%.200s line %d: Bad forwarding specification.",
1116 			    filename, linenum);
1117 
1118 		if (*activep) {
1119 			if (opcode == oLocalForward ||
1120 			    opcode == oDynamicForward)
1121 				add_local_forward(options, &fwd);
1122 			else if (opcode == oRemoteForward)
1123 				add_remote_forward(options, &fwd);
1124 		}
1125 		break;
1126 
1127 	case oClearAllForwardings:
1128 		intptr = &options->clear_forwardings;
1129 		goto parse_flag;
1130 
1131 	case oHost:
1132 		if (cmdline)
1133 			fatal("Host directive not supported as a command-line "
1134 			    "option");
1135 		*activep = 0;
1136 		arg2 = NULL;
1137 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1138 			negated = *arg == '!';
1139 			if (negated)
1140 				arg++;
1141 			if (match_pattern(host, arg)) {
1142 				if (negated) {
1143 					debug("%.200s line %d: Skipping Host "
1144 					    "block because of negated match "
1145 					    "for %.100s", filename, linenum,
1146 					    arg);
1147 					*activep = 0;
1148 					break;
1149 				}
1150 				if (!*activep)
1151 					arg2 = arg; /* logged below */
1152 				*activep = 1;
1153 			}
1154 		}
1155 		if (*activep)
1156 			debug("%.200s line %d: Applying options for %.100s",
1157 			    filename, linenum, arg2);
1158 		/* Avoid garbage check below, as strdelim is done. */
1159 		return 0;
1160 
1161 	case oMatch:
1162 		if (cmdline)
1163 			fatal("Host directive not supported as a command-line "
1164 			    "option");
1165 		value = match_cfg_line(options, &s, pw, host,
1166 		    filename, linenum);
1167 		if (value < 0)
1168 			fatal("%.200s line %d: Bad Match condition", filename,
1169 			    linenum);
1170 		*activep = value;
1171 		break;
1172 
1173 	case oEscapeChar:
1174 		intptr = &options->escape_char;
1175 		arg = strdelim(&s);
1176 		if (!arg || *arg == '\0')
1177 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1178 		if (arg[0] == '^' && arg[2] == 0 &&
1179 		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1180 			value = (u_char) arg[1] & 31;
1181 		else if (strlen(arg) == 1)
1182 			value = (u_char) arg[0];
1183 		else if (strcmp(arg, "none") == 0)
1184 			value = SSH_ESCAPECHAR_NONE;
1185 		else {
1186 			fatal("%.200s line %d: Bad escape character.",
1187 			    filename, linenum);
1188 			/* NOTREACHED */
1189 			value = 0;	/* Avoid compiler warning. */
1190 		}
1191 		if (*activep && *intptr == -1)
1192 			*intptr = value;
1193 		break;
1194 
1195 	case oAddressFamily:
1196 		intptr = &options->address_family;
1197 		multistate_ptr = multistate_addressfamily;
1198 		goto parse_multistate;
1199 
1200 	case oEnableSSHKeysign:
1201 		intptr = &options->enable_ssh_keysign;
1202 		goto parse_flag;
1203 
1204 	case oIdentitiesOnly:
1205 		intptr = &options->identities_only;
1206 		goto parse_flag;
1207 
1208 	case oServerAliveInterval:
1209 		intptr = &options->server_alive_interval;
1210 		goto parse_time;
1211 
1212 	case oServerAliveCountMax:
1213 		intptr = &options->server_alive_count_max;
1214 		goto parse_int;
1215 
1216 	case oSendEnv:
1217 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1218 			if (strchr(arg, '=') != NULL)
1219 				fatal("%s line %d: Invalid environment name.",
1220 				    filename, linenum);
1221 			if (!*activep)
1222 				continue;
1223 			if (options->num_send_env >= MAX_SEND_ENV)
1224 				fatal("%s line %d: too many send env.",
1225 				    filename, linenum);
1226 			options->send_env[options->num_send_env++] =
1227 			    xstrdup(arg);
1228 		}
1229 		break;
1230 
1231 	case oControlPath:
1232 		charptr = &options->control_path;
1233 		goto parse_string;
1234 
1235 	case oControlMaster:
1236 		intptr = &options->control_master;
1237 		multistate_ptr = multistate_controlmaster;
1238 		goto parse_multistate;
1239 
1240 	case oControlPersist:
1241 		/* no/false/yes/true, or a time spec */
1242 		intptr = &options->control_persist;
1243 		arg = strdelim(&s);
1244 		if (!arg || *arg == '\0')
1245 			fatal("%.200s line %d: Missing ControlPersist"
1246 			    " argument.", filename, linenum);
1247 		value = 0;
1248 		value2 = 0;	/* timeout */
1249 		if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1250 			value = 0;
1251 		else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1252 			value = 1;
1253 		else if ((value2 = convtime(arg)) >= 0)
1254 			value = 1;
1255 		else
1256 			fatal("%.200s line %d: Bad ControlPersist argument.",
1257 			    filename, linenum);
1258 		if (*activep && *intptr == -1) {
1259 			*intptr = value;
1260 			options->control_persist_timeout = value2;
1261 		}
1262 		break;
1263 
1264 	case oHashKnownHosts:
1265 		intptr = &options->hash_known_hosts;
1266 		goto parse_flag;
1267 
1268 	case oTunnel:
1269 		intptr = &options->tun_open;
1270 		multistate_ptr = multistate_tunnel;
1271 		goto parse_multistate;
1272 
1273 	case oTunnelDevice:
1274 		arg = strdelim(&s);
1275 		if (!arg || *arg == '\0')
1276 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1277 		value = a2tun(arg, &value2);
1278 		if (value == SSH_TUNID_ERR)
1279 			fatal("%.200s line %d: Bad tun device.", filename, linenum);
1280 		if (*activep) {
1281 			options->tun_local = value;
1282 			options->tun_remote = value2;
1283 		}
1284 		break;
1285 
1286 	case oLocalCommand:
1287 		charptr = &options->local_command;
1288 		goto parse_command;
1289 
1290 	case oPermitLocalCommand:
1291 		intptr = &options->permit_local_command;
1292 		goto parse_flag;
1293 
1294 	case oVisualHostKey:
1295 		intptr = &options->visual_host_key;
1296 		goto parse_flag;
1297 
1298 	case oIPQoS:
1299 		arg = strdelim(&s);
1300 		if ((value = parse_ipqos(arg)) == -1)
1301 			fatal("%s line %d: Bad IPQoS value: %s",
1302 			    filename, linenum, arg);
1303 		arg = strdelim(&s);
1304 		if (arg == NULL)
1305 			value2 = value;
1306 		else if ((value2 = parse_ipqos(arg)) == -1)
1307 			fatal("%s line %d: Bad IPQoS value: %s",
1308 			    filename, linenum, arg);
1309 		if (*activep) {
1310 			options->ip_qos_interactive = value;
1311 			options->ip_qos_bulk = value2;
1312 		}
1313 		break;
1314 
1315 	case oUseRoaming:
1316 		intptr = &options->use_roaming;
1317 		goto parse_flag;
1318 
1319 	case oRequestTTY:
1320 		intptr = &options->request_tty;
1321 		multistate_ptr = multistate_requesttty;
1322 		goto parse_multistate;
1323 
1324 	case oIgnoreUnknown:
1325 		charptr = &options->ignored_unknown;
1326 		goto parse_string;
1327 
1328 	case oProxyUseFdpass:
1329 		intptr = &options->proxy_use_fdpass;
1330 		goto parse_flag;
1331 
1332 	case oCanonicalDomains:
1333 		value = options->num_canonical_domains != 0;
1334 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1335 			valid_domain(arg, filename, linenum);
1336 			if (!*activep || value)
1337 				continue;
1338 			if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1339 				fatal("%s line %d: too many hostname suffixes.",
1340 				    filename, linenum);
1341 			options->canonical_domains[
1342 			    options->num_canonical_domains++] = xstrdup(arg);
1343 		}
1344 		break;
1345 
1346 	case oCanonicalizePermittedCNAMEs:
1347 		value = options->num_permitted_cnames != 0;
1348 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1349 			/* Either '*' for everything or 'list:list' */
1350 			if (strcmp(arg, "*") == 0)
1351 				arg2 = arg;
1352 			else {
1353 				lowercase(arg);
1354 				if ((arg2 = strchr(arg, ':')) == NULL ||
1355 				    arg2[1] == '\0') {
1356 					fatal("%s line %d: "
1357 					    "Invalid permitted CNAME \"%s\"",
1358 					    filename, linenum, arg);
1359 				}
1360 				*arg2 = '\0';
1361 				arg2++;
1362 			}
1363 			if (!*activep || value)
1364 				continue;
1365 			if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1366 				fatal("%s line %d: too many permitted CNAMEs.",
1367 				    filename, linenum);
1368 			cname = options->permitted_cnames +
1369 			    options->num_permitted_cnames++;
1370 			cname->source_list = xstrdup(arg);
1371 			cname->target_list = xstrdup(arg2);
1372 		}
1373 		break;
1374 
1375 	case oCanonicalizeHostname:
1376 		intptr = &options->canonicalize_hostname;
1377 		multistate_ptr = multistate_canonicalizehostname;
1378 		goto parse_multistate;
1379 
1380 	case oCanonicalizeMaxDots:
1381 		intptr = &options->canonicalize_max_dots;
1382 		goto parse_int;
1383 
1384 	case oCanonicalizeFallbackLocal:
1385 		intptr = &options->canonicalize_fallback_local;
1386 		goto parse_flag;
1387 
1388 	case oDeprecated:
1389 		debug("%s line %d: Deprecated option \"%s\"",
1390 		    filename, linenum, keyword);
1391 		return 0;
1392 
1393 	case oUnsupported:
1394 		error("%s line %d: Unsupported option \"%s\"",
1395 		    filename, linenum, keyword);
1396 		return 0;
1397 
1398 	default:
1399 		fatal("process_config_line: Unimplemented opcode %d", opcode);
1400 	}
1401 
1402 	/* Check that there is no garbage at end of line. */
1403 	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1404 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1405 		    filename, linenum, arg);
1406 	}
1407 	return 0;
1408 }
1409 
1410 
1411 /*
1412  * Reads the config file and modifies the options accordingly.  Options
1413  * should already be initialized before this call.  This never returns if
1414  * there is an error.  If the file does not exist, this returns 0.
1415  */
1416 
1417 int
1418 read_config_file(const char *filename, struct passwd *pw, const char *host,
1419     Options *options, int flags)
1420 {
1421 	FILE *f;
1422 	char line[1024];
1423 	int active, linenum;
1424 	int bad_options = 0;
1425 
1426 	if ((f = fopen(filename, "r")) == NULL)
1427 		return 0;
1428 
1429 	if (flags & SSHCONF_CHECKPERM) {
1430 		struct stat sb;
1431 
1432 		if (fstat(fileno(f), &sb) == -1)
1433 			fatal("fstat %s: %s", filename, strerror(errno));
1434 		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1435 		    (sb.st_mode & 022) != 0))
1436 			fatal("Bad owner or permissions on %s", filename);
1437 	}
1438 
1439 	debug("Reading configuration data %.200s", filename);
1440 
1441 	/*
1442 	 * Mark that we are now processing the options.  This flag is turned
1443 	 * on/off by Host specifications.
1444 	 */
1445 	active = 1;
1446 	linenum = 0;
1447 	while (fgets(line, sizeof(line), f)) {
1448 		/* Update line number counter. */
1449 		linenum++;
1450 		if (process_config_line(options, pw, host, line, filename,
1451 		    linenum, &active, flags & SSHCONF_USERCONF) != 0)
1452 			bad_options++;
1453 	}
1454 	fclose(f);
1455 	if (bad_options > 0)
1456 		fatal("%s: terminating, %d bad configuration options",
1457 		    filename, bad_options);
1458 	return 1;
1459 }
1460 
1461 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1462 int
1463 option_clear_or_none(const char *o)
1464 {
1465 	return o == NULL || strcasecmp(o, "none") == 0;
1466 }
1467 
1468 /*
1469  * Initializes options to special values that indicate that they have not yet
1470  * been set.  Read_config_file will only set options with this value. Options
1471  * are processed in the following order: command line, user config file,
1472  * system config file.  Last, fill_default_options is called.
1473  */
1474 
1475 void
1476 initialize_options(Options * options)
1477 {
1478 	memset(options, 'X', sizeof(*options));
1479 	options->forward_agent = -1;
1480 	options->forward_x11 = -1;
1481 	options->forward_x11_trusted = -1;
1482 	options->forward_x11_timeout = -1;
1483 	options->exit_on_forward_failure = -1;
1484 	options->xauth_location = NULL;
1485 	options->gateway_ports = -1;
1486 	options->use_privileged_port = -1;
1487 	options->rsa_authentication = -1;
1488 	options->pubkey_authentication = -1;
1489 	options->challenge_response_authentication = -1;
1490 	options->gss_authentication = -1;
1491 	options->gss_deleg_creds = -1;
1492 	options->password_authentication = -1;
1493 	options->kbd_interactive_authentication = -1;
1494 	options->kbd_interactive_devices = NULL;
1495 	options->rhosts_rsa_authentication = -1;
1496 	options->hostbased_authentication = -1;
1497 	options->batch_mode = -1;
1498 	options->check_host_ip = -1;
1499 	options->strict_host_key_checking = -1;
1500 	options->compression = -1;
1501 	options->tcp_keep_alive = -1;
1502 	options->compression_level = -1;
1503 	options->port = -1;
1504 	options->address_family = -1;
1505 	options->connection_attempts = -1;
1506 	options->connection_timeout = -1;
1507 	options->number_of_password_prompts = -1;
1508 	options->cipher = -1;
1509 	options->ciphers = NULL;
1510 	options->macs = NULL;
1511 	options->kex_algorithms = NULL;
1512 	options->hostkeyalgorithms = NULL;
1513 	options->protocol = SSH_PROTO_UNKNOWN;
1514 	options->num_identity_files = 0;
1515 	options->hostname = NULL;
1516 	options->host_key_alias = NULL;
1517 	options->proxy_command = NULL;
1518 	options->user = NULL;
1519 	options->escape_char = -1;
1520 	options->num_system_hostfiles = 0;
1521 	options->num_user_hostfiles = 0;
1522 	options->local_forwards = NULL;
1523 	options->num_local_forwards = 0;
1524 	options->remote_forwards = NULL;
1525 	options->num_remote_forwards = 0;
1526 	options->clear_forwardings = -1;
1527 	options->log_level = SYSLOG_LEVEL_NOT_SET;
1528 	options->preferred_authentications = NULL;
1529 	options->bind_address = NULL;
1530 	options->pkcs11_provider = NULL;
1531 	options->enable_ssh_keysign = - 1;
1532 	options->no_host_authentication_for_localhost = - 1;
1533 	options->identities_only = - 1;
1534 	options->rekey_limit = - 1;
1535 	options->rekey_interval = -1;
1536 	options->verify_host_key_dns = -1;
1537 	options->server_alive_interval = -1;
1538 	options->server_alive_count_max = -1;
1539 	options->num_send_env = 0;
1540 	options->control_path = NULL;
1541 	options->control_master = -1;
1542 	options->control_persist = -1;
1543 	options->control_persist_timeout = 0;
1544 	options->hash_known_hosts = -1;
1545 	options->tun_open = -1;
1546 	options->tun_local = -1;
1547 	options->tun_remote = -1;
1548 	options->local_command = NULL;
1549 	options->permit_local_command = -1;
1550 	options->use_roaming = -1;
1551 	options->visual_host_key = -1;
1552 	options->ip_qos_interactive = -1;
1553 	options->ip_qos_bulk = -1;
1554 	options->request_tty = -1;
1555 	options->proxy_use_fdpass = -1;
1556 	options->ignored_unknown = NULL;
1557 	options->num_canonical_domains = 0;
1558 	options->num_permitted_cnames = 0;
1559 	options->canonicalize_max_dots = -1;
1560 	options->canonicalize_fallback_local = -1;
1561 	options->canonicalize_hostname = -1;
1562 }
1563 
1564 /*
1565  * A petite version of fill_default_options() that just fills the options
1566  * needed for hostname canonicalization to proceed.
1567  */
1568 void
1569 fill_default_options_for_canonicalization(Options *options)
1570 {
1571 	if (options->canonicalize_max_dots == -1)
1572 		options->canonicalize_max_dots = 1;
1573 	if (options->canonicalize_fallback_local == -1)
1574 		options->canonicalize_fallback_local = 1;
1575 	if (options->canonicalize_hostname == -1)
1576 		options->canonicalize_hostname = SSH_CANONICALISE_NO;
1577 }
1578 
1579 /*
1580  * Called after processing other sources of option data, this fills those
1581  * options for which no value has been specified with their default values.
1582  */
1583 void
1584 fill_default_options(Options * options)
1585 {
1586 	if (options->forward_agent == -1)
1587 		options->forward_agent = 0;
1588 	if (options->forward_x11 == -1)
1589 		options->forward_x11 = 0;
1590 	if (options->forward_x11_trusted == -1)
1591 		options->forward_x11_trusted = 0;
1592 	if (options->forward_x11_timeout == -1)
1593 		options->forward_x11_timeout = 1200;
1594 	if (options->exit_on_forward_failure == -1)
1595 		options->exit_on_forward_failure = 0;
1596 	if (options->xauth_location == NULL)
1597 		options->xauth_location = _PATH_XAUTH;
1598 	if (options->gateway_ports == -1)
1599 		options->gateway_ports = 0;
1600 	if (options->use_privileged_port == -1)
1601 		options->use_privileged_port = 0;
1602 	if (options->rsa_authentication == -1)
1603 		options->rsa_authentication = 1;
1604 	if (options->pubkey_authentication == -1)
1605 		options->pubkey_authentication = 1;
1606 	if (options->challenge_response_authentication == -1)
1607 		options->challenge_response_authentication = 1;
1608 	if (options->gss_authentication == -1)
1609 		options->gss_authentication = 0;
1610 	if (options->gss_deleg_creds == -1)
1611 		options->gss_deleg_creds = 0;
1612 	if (options->password_authentication == -1)
1613 		options->password_authentication = 1;
1614 	if (options->kbd_interactive_authentication == -1)
1615 		options->kbd_interactive_authentication = 1;
1616 	if (options->rhosts_rsa_authentication == -1)
1617 		options->rhosts_rsa_authentication = 0;
1618 	if (options->hostbased_authentication == -1)
1619 		options->hostbased_authentication = 0;
1620 	if (options->batch_mode == -1)
1621 		options->batch_mode = 0;
1622 	if (options->check_host_ip == -1)
1623 		options->check_host_ip = 1;
1624 	if (options->strict_host_key_checking == -1)
1625 		options->strict_host_key_checking = 2;	/* 2 is default */
1626 	if (options->compression == -1)
1627 		options->compression = 0;
1628 	if (options->tcp_keep_alive == -1)
1629 		options->tcp_keep_alive = 1;
1630 	if (options->compression_level == -1)
1631 		options->compression_level = 6;
1632 	if (options->port == -1)
1633 		options->port = 0;	/* Filled in ssh_connect. */
1634 	if (options->address_family == -1)
1635 		options->address_family = AF_UNSPEC;
1636 	if (options->connection_attempts == -1)
1637 		options->connection_attempts = 1;
1638 	if (options->number_of_password_prompts == -1)
1639 		options->number_of_password_prompts = 3;
1640 	/* Selected in ssh_login(). */
1641 	if (options->cipher == -1)
1642 		options->cipher = SSH_CIPHER_NOT_SET;
1643 	/* options->ciphers, default set in myproposals.h */
1644 	/* options->macs, default set in myproposals.h */
1645 	/* options->kex_algorithms, default set in myproposals.h */
1646 	/* options->hostkeyalgorithms, default set in myproposals.h */
1647 	if (options->protocol == SSH_PROTO_UNKNOWN)
1648 		options->protocol = SSH_PROTO_2;
1649 	if (options->num_identity_files == 0) {
1650 		if (options->protocol & SSH_PROTO_1) {
1651 			add_identity_file(options, "~/",
1652 			    _PATH_SSH_CLIENT_IDENTITY, 0);
1653 		}
1654 		if (options->protocol & SSH_PROTO_2) {
1655 			add_identity_file(options, "~/",
1656 			    _PATH_SSH_CLIENT_ID_RSA, 0);
1657 			add_identity_file(options, "~/",
1658 			    _PATH_SSH_CLIENT_ID_DSA, 0);
1659 			add_identity_file(options, "~/",
1660 			    _PATH_SSH_CLIENT_ID_ECDSA, 0);
1661 			add_identity_file(options, "~/",
1662 			    _PATH_SSH_CLIENT_ID_ED25519, 0);
1663 		}
1664 	}
1665 	if (options->escape_char == -1)
1666 		options->escape_char = '~';
1667 	if (options->num_system_hostfiles == 0) {
1668 		options->system_hostfiles[options->num_system_hostfiles++] =
1669 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1670 		options->system_hostfiles[options->num_system_hostfiles++] =
1671 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1672 	}
1673 	if (options->num_user_hostfiles == 0) {
1674 		options->user_hostfiles[options->num_user_hostfiles++] =
1675 		    xstrdup(_PATH_SSH_USER_HOSTFILE);
1676 		options->user_hostfiles[options->num_user_hostfiles++] =
1677 		    xstrdup(_PATH_SSH_USER_HOSTFILE2);
1678 	}
1679 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1680 		options->log_level = SYSLOG_LEVEL_INFO;
1681 	if (options->clear_forwardings == 1)
1682 		clear_forwardings(options);
1683 	if (options->no_host_authentication_for_localhost == - 1)
1684 		options->no_host_authentication_for_localhost = 0;
1685 	if (options->identities_only == -1)
1686 		options->identities_only = 0;
1687 	if (options->enable_ssh_keysign == -1)
1688 		options->enable_ssh_keysign = 0;
1689 	if (options->rekey_limit == -1)
1690 		options->rekey_limit = 0;
1691 	if (options->rekey_interval == -1)
1692 		options->rekey_interval = 0;
1693 	if (options->verify_host_key_dns == -1)
1694 		options->verify_host_key_dns = 0;
1695 	if (options->server_alive_interval == -1)
1696 		options->server_alive_interval = 0;
1697 	if (options->server_alive_count_max == -1)
1698 		options->server_alive_count_max = 3;
1699 	if (options->control_master == -1)
1700 		options->control_master = 0;
1701 	if (options->control_persist == -1) {
1702 		options->control_persist = 0;
1703 		options->control_persist_timeout = 0;
1704 	}
1705 	if (options->hash_known_hosts == -1)
1706 		options->hash_known_hosts = 0;
1707 	if (options->tun_open == -1)
1708 		options->tun_open = SSH_TUNMODE_NO;
1709 	if (options->tun_local == -1)
1710 		options->tun_local = SSH_TUNID_ANY;
1711 	if (options->tun_remote == -1)
1712 		options->tun_remote = SSH_TUNID_ANY;
1713 	if (options->permit_local_command == -1)
1714 		options->permit_local_command = 0;
1715 	if (options->use_roaming == -1)
1716 		options->use_roaming = 1;
1717 	if (options->visual_host_key == -1)
1718 		options->visual_host_key = 0;
1719 	if (options->ip_qos_interactive == -1)
1720 		options->ip_qos_interactive = IPTOS_LOWDELAY;
1721 	if (options->ip_qos_bulk == -1)
1722 		options->ip_qos_bulk = IPTOS_THROUGHPUT;
1723 	if (options->request_tty == -1)
1724 		options->request_tty = REQUEST_TTY_AUTO;
1725 	if (options->proxy_use_fdpass == -1)
1726 		options->proxy_use_fdpass = 0;
1727 	if (options->canonicalize_max_dots == -1)
1728 		options->canonicalize_max_dots = 1;
1729 	if (options->canonicalize_fallback_local == -1)
1730 		options->canonicalize_fallback_local = 1;
1731 	if (options->canonicalize_hostname == -1)
1732 		options->canonicalize_hostname = SSH_CANONICALISE_NO;
1733 #define CLEAR_ON_NONE(v) \
1734 	do { \
1735 		if (option_clear_or_none(v)) { \
1736 			free(v); \
1737 			v = NULL; \
1738 		} \
1739 	} while(0)
1740 	CLEAR_ON_NONE(options->local_command);
1741 	CLEAR_ON_NONE(options->proxy_command);
1742 	CLEAR_ON_NONE(options->control_path);
1743 	/* options->user will be set in the main program if appropriate */
1744 	/* options->hostname will be set in the main program if appropriate */
1745 	/* options->host_key_alias should not be set by default */
1746 	/* options->preferred_authentications will be set in ssh */
1747 }
1748 
1749 /*
1750  * parse_forward
1751  * parses a string containing a port forwarding specification of the form:
1752  *   dynamicfwd == 0
1753  *	[listenhost:]listenport:connecthost:connectport
1754  *   dynamicfwd == 1
1755  *	[listenhost:]listenport
1756  * returns number of arguments parsed or zero on error
1757  */
1758 int
1759 parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1760 {
1761 	int i;
1762 	char *p, *cp, *fwdarg[4];
1763 
1764 	memset(fwd, '\0', sizeof(*fwd));
1765 
1766 	cp = p = xstrdup(fwdspec);
1767 
1768 	/* skip leading spaces */
1769 	while (isspace((u_char)*cp))
1770 		cp++;
1771 
1772 	for (i = 0; i < 4; ++i)
1773 		if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1774 			break;
1775 
1776 	/* Check for trailing garbage */
1777 	if (cp != NULL)
1778 		i = 0;	/* failure */
1779 
1780 	switch (i) {
1781 	case 1:
1782 		fwd->listen_host = NULL;
1783 		fwd->listen_port = a2port(fwdarg[0]);
1784 		fwd->connect_host = xstrdup("socks");
1785 		break;
1786 
1787 	case 2:
1788 		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1789 		fwd->listen_port = a2port(fwdarg[1]);
1790 		fwd->connect_host = xstrdup("socks");
1791 		break;
1792 
1793 	case 3:
1794 		fwd->listen_host = NULL;
1795 		fwd->listen_port = a2port(fwdarg[0]);
1796 		fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1797 		fwd->connect_port = a2port(fwdarg[2]);
1798 		break;
1799 
1800 	case 4:
1801 		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1802 		fwd->listen_port = a2port(fwdarg[1]);
1803 		fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1804 		fwd->connect_port = a2port(fwdarg[3]);
1805 		break;
1806 	default:
1807 		i = 0; /* failure */
1808 	}
1809 
1810 	free(p);
1811 
1812 	if (dynamicfwd) {
1813 		if (!(i == 1 || i == 2))
1814 			goto fail_free;
1815 	} else {
1816 		if (!(i == 3 || i == 4))
1817 			goto fail_free;
1818 		if (fwd->connect_port <= 0)
1819 			goto fail_free;
1820 	}
1821 
1822 	if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
1823 		goto fail_free;
1824 
1825 	if (fwd->connect_host != NULL &&
1826 	    strlen(fwd->connect_host) >= NI_MAXHOST)
1827 		goto fail_free;
1828 	if (fwd->listen_host != NULL &&
1829 	    strlen(fwd->listen_host) >= NI_MAXHOST)
1830 		goto fail_free;
1831 
1832 
1833 	return (i);
1834 
1835  fail_free:
1836 	free(fwd->connect_host);
1837 	fwd->connect_host = NULL;
1838 	free(fwd->listen_host);
1839 	fwd->listen_host = NULL;
1840 	return (0);
1841 }
1842