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