xref: /openbsd-src/usr.bin/ssh/readconf.c (revision 1a8dbaac879b9f3335ad7fb25429ce63ac1d6bac)
1 /* $OpenBSD: readconf.c,v 1.339 2020/10/16 13:26:13 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 #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 <glob.h>
28 #include <netdb.h>
29 #include <paths.h>
30 #include <pwd.h>
31 #include <signal.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <stdarg.h>
35 #include <unistd.h>
36 #include <limits.h>
37 #include <util.h>
38 #include <vis.h>
39 
40 #include "xmalloc.h"
41 #include "ssh.h"
42 #include "ssherr.h"
43 #include "compat.h"
44 #include "cipher.h"
45 #include "pathnames.h"
46 #include "log.h"
47 #include "sshkey.h"
48 #include "misc.h"
49 #include "readconf.h"
50 #include "match.h"
51 #include "kex.h"
52 #include "mac.h"
53 #include "uidswap.h"
54 #include "myproposal.h"
55 #include "digest.h"
56 
57 /* Format of the configuration file:
58 
59    # Configuration data is parsed as follows:
60    #  1. command line options
61    #  2. user-specific file
62    #  3. system-wide file
63    # Any configuration value is only changed the first time it is set.
64    # Thus, host-specific definitions should be at the beginning of the
65    # configuration file, and defaults at the end.
66 
67    # Host-specific declarations.  These may override anything above.  A single
68    # host may match multiple declarations; these are processed in the order
69    # that they are given in.
70 
71    Host *.ngs.fi ngs.fi
72      User foo
73 
74    Host fake.com
75      Hostname another.host.name.real.org
76      User blaah
77      Port 34289
78      ForwardX11 no
79      ForwardAgent no
80 
81    Host books.com
82      RemoteForward 9999 shadows.cs.hut.fi:9999
83      Ciphers 3des-cbc
84 
85    Host fascist.blob.com
86      Port 23123
87      User tylonen
88      PasswordAuthentication no
89 
90    Host puukko.hut.fi
91      User t35124p
92      ProxyCommand ssh-proxy %h %p
93 
94    Host *.fr
95      PublicKeyAuthentication no
96 
97    Host *.su
98      Ciphers aes128-ctr
99      PasswordAuthentication no
100 
101    Host vpn.fake.com
102      Tunnel yes
103      TunnelDevice 3
104 
105    # Defaults for various options
106    Host *
107      ForwardAgent no
108      ForwardX11 no
109      PasswordAuthentication yes
110      StrictHostKeyChecking yes
111      TcpKeepAlive no
112      IdentityFile ~/.ssh/identity
113      Port 22
114      EscapeChar ~
115 
116 */
117 
118 static int read_config_file_depth(const char *filename, struct passwd *pw,
119     const char *host, const char *original_host, Options *options,
120     int flags, int *activep, int *want_final_pass, int depth);
121 static int process_config_line_depth(Options *options, struct passwd *pw,
122     const char *host, const char *original_host, char *line,
123     const char *filename, int linenum, int *activep, int flags,
124     int *want_final_pass, int depth);
125 
126 /* Keyword tokens. */
127 
128 typedef enum {
129 	oBadOption,
130 	oHost, oMatch, oInclude,
131 	oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
132 	oGatewayPorts, oExitOnForwardFailure,
133 	oPasswordAuthentication,
134 	oChallengeResponseAuthentication, oXAuthLocation,
135 	oIdentityFile, oHostname, oPort, oRemoteForward, oLocalForward,
136 	oCertificateFile, oAddKeysToAgent, oIdentityAgent,
137 	oUser, oEscapeChar, oProxyCommand,
138 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
139 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
140 	oTCPKeepAlive, oNumberOfPasswordPrompts,
141 	oLogFacility, oLogLevel, oLogVerbose, oCiphers, oMacs,
142 	oPubkeyAuthentication,
143 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
144 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
145 	oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider,
146 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
147 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
148 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
149 	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
150 	oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
151 	oHashKnownHosts,
152 	oTunnel, oTunnelDevice,
153 	oLocalCommand, oPermitLocalCommand, oRemoteCommand,
154 	oVisualHostKey,
155 	oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
156 	oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
157 	oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
158 	oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
159 	oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
160 	oPubkeyAcceptedKeyTypes, oCASignatureAlgorithms, oProxyJump,
161 	oSecurityKeyProvider,
162 	oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
163 } OpCodes;
164 
165 /* Textual representations of the tokens. */
166 
167 static struct {
168 	const char *name;
169 	OpCodes opcode;
170 } keywords[] = {
171 	/* Deprecated options */
172 	{ "protocol", oIgnore }, /* NB. silently ignored */
173 	{ "cipher", oDeprecated },
174 	{ "fallbacktorsh", oDeprecated },
175 	{ "globalknownhostsfile2", oDeprecated },
176 	{ "rhostsauthentication", oDeprecated },
177 	{ "userknownhostsfile2", oDeprecated },
178 	{ "useroaming", oDeprecated },
179 	{ "usersh", oDeprecated },
180 	{ "useprivilegedport", oDeprecated },
181 
182 	/* Unsupported options */
183 	{ "afstokenpassing", oUnsupported },
184 	{ "kerberosauthentication", oUnsupported },
185 	{ "kerberostgtpassing", oUnsupported },
186 	{ "rsaauthentication", oUnsupported },
187 	{ "rhostsrsaauthentication", oUnsupported },
188 	{ "compressionlevel", oUnsupported },
189 
190 	/* Sometimes-unsupported options */
191 #if defined(GSSAPI)
192 	{ "gssapiauthentication", oGssAuthentication },
193 	{ "gssapidelegatecredentials", oGssDelegateCreds },
194 # else
195 	{ "gssapiauthentication", oUnsupported },
196 	{ "gssapidelegatecredentials", oUnsupported },
197 #endif
198 #ifdef ENABLE_PKCS11
199 	{ "pkcs11provider", oPKCS11Provider },
200 	{ "smartcarddevice", oPKCS11Provider },
201 # else
202 	{ "smartcarddevice", oUnsupported },
203 	{ "pkcs11provider", oUnsupported },
204 #endif
205 
206 	{ "forwardagent", oForwardAgent },
207 	{ "forwardx11", oForwardX11 },
208 	{ "forwardx11trusted", oForwardX11Trusted },
209 	{ "forwardx11timeout", oForwardX11Timeout },
210 	{ "exitonforwardfailure", oExitOnForwardFailure },
211 	{ "xauthlocation", oXAuthLocation },
212 	{ "gatewayports", oGatewayPorts },
213 	{ "passwordauthentication", oPasswordAuthentication },
214 	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
215 	{ "kbdinteractivedevices", oKbdInteractiveDevices },
216 	{ "pubkeyauthentication", oPubkeyAuthentication },
217 	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
218 	{ "hostbasedauthentication", oHostbasedAuthentication },
219 	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
220 	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
221 	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
222 	{ "identityfile", oIdentityFile },
223 	{ "identityfile2", oIdentityFile },			/* obsolete */
224 	{ "identitiesonly", oIdentitiesOnly },
225 	{ "certificatefile", oCertificateFile },
226 	{ "addkeystoagent", oAddKeysToAgent },
227 	{ "identityagent", oIdentityAgent },
228 	{ "hostname", oHostname },
229 	{ "hostkeyalias", oHostKeyAlias },
230 	{ "proxycommand", oProxyCommand },
231 	{ "port", oPort },
232 	{ "ciphers", oCiphers },
233 	{ "macs", oMacs },
234 	{ "remoteforward", oRemoteForward },
235 	{ "localforward", oLocalForward },
236 	{ "user", oUser },
237 	{ "host", oHost },
238 	{ "match", oMatch },
239 	{ "escapechar", oEscapeChar },
240 	{ "globalknownhostsfile", oGlobalKnownHostsFile },
241 	{ "userknownhostsfile", oUserKnownHostsFile },
242 	{ "connectionattempts", oConnectionAttempts },
243 	{ "batchmode", oBatchMode },
244 	{ "checkhostip", oCheckHostIP },
245 	{ "stricthostkeychecking", oStrictHostKeyChecking },
246 	{ "compression", oCompression },
247 	{ "tcpkeepalive", oTCPKeepAlive },
248 	{ "keepalive", oTCPKeepAlive },				/* obsolete */
249 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
250 	{ "syslogfacility", oLogFacility },
251 	{ "loglevel", oLogLevel },
252 	{ "logverbose", oLogVerbose },
253 	{ "dynamicforward", oDynamicForward },
254 	{ "preferredauthentications", oPreferredAuthentications },
255 	{ "hostkeyalgorithms", oHostKeyAlgorithms },
256 	{ "casignaturealgorithms", oCASignatureAlgorithms },
257 	{ "bindaddress", oBindAddress },
258 	{ "bindinterface", oBindInterface },
259 	{ "clearallforwardings", oClearAllForwardings },
260 	{ "enablesshkeysign", oEnableSSHKeysign },
261 	{ "verifyhostkeydns", oVerifyHostKeyDNS },
262 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
263 	{ "rekeylimit", oRekeyLimit },
264 	{ "connecttimeout", oConnectTimeout },
265 	{ "addressfamily", oAddressFamily },
266 	{ "serveraliveinterval", oServerAliveInterval },
267 	{ "serveralivecountmax", oServerAliveCountMax },
268 	{ "sendenv", oSendEnv },
269 	{ "setenv", oSetEnv },
270 	{ "controlpath", oControlPath },
271 	{ "controlmaster", oControlMaster },
272 	{ "controlpersist", oControlPersist },
273 	{ "hashknownhosts", oHashKnownHosts },
274 	{ "include", oInclude },
275 	{ "tunnel", oTunnel },
276 	{ "tunneldevice", oTunnelDevice },
277 	{ "localcommand", oLocalCommand },
278 	{ "permitlocalcommand", oPermitLocalCommand },
279 	{ "remotecommand", oRemoteCommand },
280 	{ "visualhostkey", oVisualHostKey },
281 	{ "kexalgorithms", oKexAlgorithms },
282 	{ "ipqos", oIPQoS },
283 	{ "requesttty", oRequestTTY },
284 	{ "proxyusefdpass", oProxyUseFdpass },
285 	{ "canonicaldomains", oCanonicalDomains },
286 	{ "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
287 	{ "canonicalizehostname", oCanonicalizeHostname },
288 	{ "canonicalizemaxdots", oCanonicalizeMaxDots },
289 	{ "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
290 	{ "streamlocalbindmask", oStreamLocalBindMask },
291 	{ "streamlocalbindunlink", oStreamLocalBindUnlink },
292 	{ "revokedhostkeys", oRevokedHostKeys },
293 	{ "fingerprinthash", oFingerprintHash },
294 	{ "updatehostkeys", oUpdateHostkeys },
295 	{ "hostbasedkeytypes", oHostbasedKeyTypes },
296 	{ "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
297 	{ "ignoreunknown", oIgnoreUnknown },
298 	{ "proxyjump", oProxyJump },
299 	{ "securitykeyprovider", oSecurityKeyProvider },
300 
301 	{ NULL, oBadOption }
302 };
303 
304 static char *kex_default_pk_alg_filtered;
305 
306 const char *
307 kex_default_pk_alg(void)
308 {
309 	if (kex_default_pk_alg_filtered == NULL)
310 		fatal("kex_default_pk_alg not initialized.");
311 	return kex_default_pk_alg_filtered;
312 }
313 
314 char *
315 ssh_connection_hash(const char *thishost, const char *host, const char *portstr,
316     const char *user)
317 {
318 	struct ssh_digest_ctx *md;
319 	u_char conn_hash[SSH_DIGEST_MAX_LENGTH];
320 
321 	if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL ||
322 	    ssh_digest_update(md, thishost, strlen(thishost)) < 0 ||
323 	    ssh_digest_update(md, host, strlen(host)) < 0 ||
324 	    ssh_digest_update(md, portstr, strlen(portstr)) < 0 ||
325 	    ssh_digest_update(md, user, strlen(user)) < 0 ||
326 	    ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0)
327 		fatal("%s: mux digest failed", __func__);
328 	ssh_digest_free(md);
329 	return tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
330 }
331 
332 /*
333  * Adds a local TCP/IP port forward to options.  Never returns if there is an
334  * error.
335  */
336 
337 void
338 add_local_forward(Options *options, const struct Forward *newfwd)
339 {
340 	struct Forward *fwd;
341 	int i;
342 
343 	/* Don't add duplicates */
344 	for (i = 0; i < options->num_local_forwards; i++) {
345 		if (forward_equals(newfwd, options->local_forwards + i))
346 			return;
347 	}
348 	options->local_forwards = xreallocarray(options->local_forwards,
349 	    options->num_local_forwards + 1,
350 	    sizeof(*options->local_forwards));
351 	fwd = &options->local_forwards[options->num_local_forwards++];
352 
353 	fwd->listen_host = newfwd->listen_host;
354 	fwd->listen_port = newfwd->listen_port;
355 	fwd->listen_path = newfwd->listen_path;
356 	fwd->connect_host = newfwd->connect_host;
357 	fwd->connect_port = newfwd->connect_port;
358 	fwd->connect_path = newfwd->connect_path;
359 }
360 
361 /*
362  * Adds a remote TCP/IP port forward to options.  Never returns if there is
363  * an error.
364  */
365 
366 void
367 add_remote_forward(Options *options, const struct Forward *newfwd)
368 {
369 	struct Forward *fwd;
370 	int i;
371 
372 	/* Don't add duplicates */
373 	for (i = 0; i < options->num_remote_forwards; i++) {
374 		if (forward_equals(newfwd, options->remote_forwards + i))
375 			return;
376 	}
377 	options->remote_forwards = xreallocarray(options->remote_forwards,
378 	    options->num_remote_forwards + 1,
379 	    sizeof(*options->remote_forwards));
380 	fwd = &options->remote_forwards[options->num_remote_forwards++];
381 
382 	fwd->listen_host = newfwd->listen_host;
383 	fwd->listen_port = newfwd->listen_port;
384 	fwd->listen_path = newfwd->listen_path;
385 	fwd->connect_host = newfwd->connect_host;
386 	fwd->connect_port = newfwd->connect_port;
387 	fwd->connect_path = newfwd->connect_path;
388 	fwd->handle = newfwd->handle;
389 	fwd->allocated_port = 0;
390 }
391 
392 static void
393 clear_forwardings(Options *options)
394 {
395 	int i;
396 
397 	for (i = 0; i < options->num_local_forwards; i++) {
398 		free(options->local_forwards[i].listen_host);
399 		free(options->local_forwards[i].listen_path);
400 		free(options->local_forwards[i].connect_host);
401 		free(options->local_forwards[i].connect_path);
402 	}
403 	if (options->num_local_forwards > 0) {
404 		free(options->local_forwards);
405 		options->local_forwards = NULL;
406 	}
407 	options->num_local_forwards = 0;
408 	for (i = 0; i < options->num_remote_forwards; i++) {
409 		free(options->remote_forwards[i].listen_host);
410 		free(options->remote_forwards[i].listen_path);
411 		free(options->remote_forwards[i].connect_host);
412 		free(options->remote_forwards[i].connect_path);
413 	}
414 	if (options->num_remote_forwards > 0) {
415 		free(options->remote_forwards);
416 		options->remote_forwards = NULL;
417 	}
418 	options->num_remote_forwards = 0;
419 	options->tun_open = SSH_TUNMODE_NO;
420 }
421 
422 void
423 add_certificate_file(Options *options, const char *path, int userprovided)
424 {
425 	int i;
426 
427 	if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
428 		fatal("Too many certificate files specified (max %d)",
429 		    SSH_MAX_CERTIFICATE_FILES);
430 
431 	/* Avoid registering duplicates */
432 	for (i = 0; i < options->num_certificate_files; i++) {
433 		if (options->certificate_file_userprovided[i] == userprovided &&
434 		    strcmp(options->certificate_files[i], path) == 0) {
435 			debug2("%s: ignoring duplicate key %s", __func__, path);
436 			return;
437 		}
438 	}
439 
440 	options->certificate_file_userprovided[options->num_certificate_files] =
441 	    userprovided;
442 	options->certificate_files[options->num_certificate_files++] =
443 	    xstrdup(path);
444 }
445 
446 void
447 add_identity_file(Options *options, const char *dir, const char *filename,
448     int userprovided)
449 {
450 	char *path;
451 	int i;
452 
453 	if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
454 		fatal("Too many identity files specified (max %d)",
455 		    SSH_MAX_IDENTITY_FILES);
456 
457 	if (dir == NULL) /* no dir, filename is absolute */
458 		path = xstrdup(filename);
459 	else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
460 		fatal("Identity file path %s too long", path);
461 
462 	/* Avoid registering duplicates */
463 	for (i = 0; i < options->num_identity_files; i++) {
464 		if (options->identity_file_userprovided[i] == userprovided &&
465 		    strcmp(options->identity_files[i], path) == 0) {
466 			debug2("%s: ignoring duplicate key %s", __func__, path);
467 			free(path);
468 			return;
469 		}
470 	}
471 
472 	options->identity_file_userprovided[options->num_identity_files] =
473 	    userprovided;
474 	options->identity_files[options->num_identity_files++] = path;
475 }
476 
477 int
478 default_ssh_port(void)
479 {
480 	static int port;
481 	struct servent *sp;
482 
483 	if (port == 0) {
484 		sp = getservbyname(SSH_SERVICE_NAME, "tcp");
485 		port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
486 	}
487 	return port;
488 }
489 
490 /*
491  * Execute a command in a shell.
492  * Return its exit status or -1 on abnormal exit.
493  */
494 static int
495 execute_in_shell(const char *cmd)
496 {
497 	char *shell;
498 	pid_t pid;
499 	int status;
500 
501 	if ((shell = getenv("SHELL")) == NULL)
502 		shell = _PATH_BSHELL;
503 
504 	if (access(shell, X_OK) == -1) {
505 		fatal("Shell \"%s\" is not executable: %s",
506 		    shell, strerror(errno));
507 	}
508 
509 	debug("Executing command: '%.500s'", cmd);
510 
511 	/* Fork and execute the command. */
512 	if ((pid = fork()) == 0) {
513 		char *argv[4];
514 
515 		if (stdfd_devnull(1, 1, 0) == -1)
516 			fatal("%s: stdfd_devnull failed", __func__);
517 		closefrom(STDERR_FILENO + 1);
518 
519 		argv[0] = shell;
520 		argv[1] = "-c";
521 		argv[2] = xstrdup(cmd);
522 		argv[3] = NULL;
523 
524 		execv(argv[0], argv);
525 		error("Unable to execute '%.100s': %s", cmd, strerror(errno));
526 		/* Die with signal to make this error apparent to parent. */
527 		ssh_signal(SIGTERM, SIG_DFL);
528 		kill(getpid(), SIGTERM);
529 		_exit(1);
530 	}
531 	/* Parent. */
532 	if (pid == -1)
533 		fatal("%s: fork: %.100s", __func__, strerror(errno));
534 
535 	while (waitpid(pid, &status, 0) == -1) {
536 		if (errno != EINTR && errno != EAGAIN)
537 			fatal("%s: waitpid: %s", __func__, strerror(errno));
538 	}
539 	if (!WIFEXITED(status)) {
540 		error("command '%.100s' exited abnormally", cmd);
541 		return -1;
542 	}
543 	debug3("command returned status %d", WEXITSTATUS(status));
544 	return WEXITSTATUS(status);
545 }
546 
547 /*
548  * Parse and execute a Match directive.
549  */
550 static int
551 match_cfg_line(Options *options, char **condition, struct passwd *pw,
552     const char *host_arg, const char *original_host, int final_pass,
553     int *want_final_pass, const char *filename, int linenum)
554 {
555 	char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
556 	const char *ruser;
557 	int r, port, this_result, result = 1, attributes = 0, negate;
558 	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
559 	char uidstr[32];
560 
561 	/*
562 	 * Configuration is likely to be incomplete at this point so we
563 	 * must be prepared to use default values.
564 	 */
565 	port = options->port <= 0 ? default_ssh_port() : options->port;
566 	ruser = options->user == NULL ? pw->pw_name : options->user;
567 	if (final_pass) {
568 		host = xstrdup(options->hostname);
569 	} else if (options->hostname != NULL) {
570 		/* NB. Please keep in sync with ssh.c:main() */
571 		host = percent_expand(options->hostname,
572 		    "h", host_arg, (char *)NULL);
573 	} else {
574 		host = xstrdup(host_arg);
575 	}
576 
577 	debug2("checking match for '%s' host %s originally %s",
578 	    cp, host, original_host);
579 	while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
580 		criteria = NULL;
581 		this_result = 1;
582 		if ((negate = attrib[0] == '!'))
583 			attrib++;
584 		/* criteria "all" and "canonical" have no argument */
585 		if (strcasecmp(attrib, "all") == 0) {
586 			if (attributes > 1 ||
587 			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
588 				error("%.200s line %d: '%s' cannot be combined "
589 				    "with other Match attributes",
590 				    filename, linenum, oattrib);
591 				result = -1;
592 				goto out;
593 			}
594 			if (result)
595 				result = negate ? 0 : 1;
596 			goto out;
597 		}
598 		attributes++;
599 		if (strcasecmp(attrib, "canonical") == 0 ||
600 		    strcasecmp(attrib, "final") == 0) {
601 			/*
602 			 * If the config requests "Match final" then remember
603 			 * this so we can perform a second pass later.
604 			 */
605 			if (strcasecmp(attrib, "final") == 0 &&
606 			    want_final_pass != NULL)
607 				*want_final_pass = 1;
608 			r = !!final_pass;  /* force bitmask member to boolean */
609 			if (r == (negate ? 1 : 0))
610 				this_result = result = 0;
611 			debug3("%.200s line %d: %smatched '%s'",
612 			    filename, linenum,
613 			    this_result ? "" : "not ", oattrib);
614 			continue;
615 		}
616 		/* All other criteria require an argument */
617 		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
618 			error("Missing Match criteria for %s", attrib);
619 			result = -1;
620 			goto out;
621 		}
622 		if (strcasecmp(attrib, "host") == 0) {
623 			criteria = xstrdup(host);
624 			r = match_hostname(host, arg) == 1;
625 			if (r == (negate ? 1 : 0))
626 				this_result = result = 0;
627 		} else if (strcasecmp(attrib, "originalhost") == 0) {
628 			criteria = xstrdup(original_host);
629 			r = match_hostname(original_host, arg) == 1;
630 			if (r == (negate ? 1 : 0))
631 				this_result = result = 0;
632 		} else if (strcasecmp(attrib, "user") == 0) {
633 			criteria = xstrdup(ruser);
634 			r = match_pattern_list(ruser, arg, 0) == 1;
635 			if (r == (negate ? 1 : 0))
636 				this_result = result = 0;
637 		} else if (strcasecmp(attrib, "localuser") == 0) {
638 			criteria = xstrdup(pw->pw_name);
639 			r = match_pattern_list(pw->pw_name, arg, 0) == 1;
640 			if (r == (negate ? 1 : 0))
641 				this_result = result = 0;
642 		} else if (strcasecmp(attrib, "exec") == 0) {
643 			char *conn_hash_hex, *keyalias;
644 
645 			if (gethostname(thishost, sizeof(thishost)) == -1)
646 				fatal("gethostname: %s", strerror(errno));
647 			strlcpy(shorthost, thishost, sizeof(shorthost));
648 			shorthost[strcspn(thishost, ".")] = '\0';
649 			snprintf(portstr, sizeof(portstr), "%d", port);
650 			snprintf(uidstr, sizeof(uidstr), "%llu",
651 			    (unsigned long long)pw->pw_uid);
652 			conn_hash_hex = ssh_connection_hash(thishost, host,
653 			   portstr, ruser);
654 			keyalias = options->host_key_alias ?
655 			    options->host_key_alias : host;
656 
657 			cmd = percent_expand(arg,
658 			    "C", conn_hash_hex,
659 			    "L", shorthost,
660 			    "d", pw->pw_dir,
661 			    "h", host,
662 			    "k", keyalias,
663 			    "l", thishost,
664 			    "n", original_host,
665 			    "p", portstr,
666 			    "r", ruser,
667 			    "u", pw->pw_name,
668 			    "i", uidstr,
669 			    (char *)NULL);
670 			free(conn_hash_hex);
671 			if (result != 1) {
672 				/* skip execution if prior predicate failed */
673 				debug3("%.200s line %d: skipped exec "
674 				    "\"%.100s\"", filename, linenum, cmd);
675 				free(cmd);
676 				continue;
677 			}
678 			r = execute_in_shell(cmd);
679 			if (r == -1) {
680 				fatal("%.200s line %d: match exec "
681 				    "'%.100s' error", filename,
682 				    linenum, cmd);
683 			}
684 			criteria = xstrdup(cmd);
685 			free(cmd);
686 			/* Force exit status to boolean */
687 			r = r == 0;
688 			if (r == (negate ? 1 : 0))
689 				this_result = result = 0;
690 		} else {
691 			error("Unsupported Match attribute %s", attrib);
692 			result = -1;
693 			goto out;
694 		}
695 		debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
696 		    filename, linenum, this_result ? "": "not ",
697 		    oattrib, criteria);
698 		free(criteria);
699 	}
700 	if (attributes == 0) {
701 		error("One or more attributes required for Match");
702 		result = -1;
703 		goto out;
704 	}
705  out:
706 	if (result != -1)
707 		debug2("match %sfound", result ? "" : "not ");
708 	*condition = cp;
709 	free(host);
710 	return result;
711 }
712 
713 /* Remove environment variable by pattern */
714 static void
715 rm_env(Options *options, const char *arg, const char *filename, int linenum)
716 {
717 	int i, j, onum_send_env = options->num_send_env;
718 	char *cp;
719 
720 	/* Remove an environment variable */
721 	for (i = 0; i < options->num_send_env; ) {
722 		cp = xstrdup(options->send_env[i]);
723 		if (!match_pattern(cp, arg + 1)) {
724 			free(cp);
725 			i++;
726 			continue;
727 		}
728 		debug3("%s line %d: removing environment %s",
729 		    filename, linenum, cp);
730 		free(cp);
731 		free(options->send_env[i]);
732 		options->send_env[i] = NULL;
733 		for (j = i; j < options->num_send_env - 1; j++) {
734 			options->send_env[j] = options->send_env[j + 1];
735 			options->send_env[j + 1] = NULL;
736 		}
737 		options->num_send_env--;
738 		/* NB. don't increment i */
739 	}
740 	if (onum_send_env != options->num_send_env) {
741 		options->send_env = xrecallocarray(options->send_env,
742 		    onum_send_env, options->num_send_env,
743 		    sizeof(*options->send_env));
744 	}
745 }
746 
747 /*
748  * Returns the number of the token pointed to by cp or oBadOption.
749  */
750 static OpCodes
751 parse_token(const char *cp, const char *filename, int linenum,
752     const char *ignored_unknown)
753 {
754 	int i;
755 
756 	for (i = 0; keywords[i].name; i++)
757 		if (strcmp(cp, keywords[i].name) == 0)
758 			return keywords[i].opcode;
759 	if (ignored_unknown != NULL &&
760 	    match_pattern_list(cp, ignored_unknown, 1) == 1)
761 		return oIgnoredUnknownOption;
762 	error("%s: line %d: Bad configuration option: %s",
763 	    filename, linenum, cp);
764 	return oBadOption;
765 }
766 
767 /* Multistate option parsing */
768 struct multistate {
769 	char *key;
770 	int value;
771 };
772 static const struct multistate multistate_flag[] = {
773 	{ "true",			1 },
774 	{ "false",			0 },
775 	{ "yes",			1 },
776 	{ "no",				0 },
777 	{ NULL, -1 }
778 };
779 static const struct multistate multistate_yesnoask[] = {
780 	{ "true",			1 },
781 	{ "false",			0 },
782 	{ "yes",			1 },
783 	{ "no",				0 },
784 	{ "ask",			2 },
785 	{ NULL, -1 }
786 };
787 static const struct multistate multistate_strict_hostkey[] = {
788 	{ "true",			SSH_STRICT_HOSTKEY_YES },
789 	{ "false",			SSH_STRICT_HOSTKEY_OFF },
790 	{ "yes",			SSH_STRICT_HOSTKEY_YES },
791 	{ "no",				SSH_STRICT_HOSTKEY_OFF },
792 	{ "ask",			SSH_STRICT_HOSTKEY_ASK },
793 	{ "off",			SSH_STRICT_HOSTKEY_OFF },
794 	{ "accept-new",			SSH_STRICT_HOSTKEY_NEW },
795 	{ NULL, -1 }
796 };
797 static const struct multistate multistate_yesnoaskconfirm[] = {
798 	{ "true",			1 },
799 	{ "false",			0 },
800 	{ "yes",			1 },
801 	{ "no",				0 },
802 	{ "ask",			2 },
803 	{ "confirm",			3 },
804 	{ NULL, -1 }
805 };
806 static const struct multistate multistate_addressfamily[] = {
807 	{ "inet",			AF_INET },
808 	{ "inet6",			AF_INET6 },
809 	{ "any",			AF_UNSPEC },
810 	{ NULL, -1 }
811 };
812 static const struct multistate multistate_controlmaster[] = {
813 	{ "true",			SSHCTL_MASTER_YES },
814 	{ "yes",			SSHCTL_MASTER_YES },
815 	{ "false",			SSHCTL_MASTER_NO },
816 	{ "no",				SSHCTL_MASTER_NO },
817 	{ "auto",			SSHCTL_MASTER_AUTO },
818 	{ "ask",			SSHCTL_MASTER_ASK },
819 	{ "autoask",			SSHCTL_MASTER_AUTO_ASK },
820 	{ NULL, -1 }
821 };
822 static const struct multistate multistate_tunnel[] = {
823 	{ "ethernet",			SSH_TUNMODE_ETHERNET },
824 	{ "point-to-point",		SSH_TUNMODE_POINTOPOINT },
825 	{ "true",			SSH_TUNMODE_DEFAULT },
826 	{ "yes",			SSH_TUNMODE_DEFAULT },
827 	{ "false",			SSH_TUNMODE_NO },
828 	{ "no",				SSH_TUNMODE_NO },
829 	{ NULL, -1 }
830 };
831 static const struct multistate multistate_requesttty[] = {
832 	{ "true",			REQUEST_TTY_YES },
833 	{ "yes",			REQUEST_TTY_YES },
834 	{ "false",			REQUEST_TTY_NO },
835 	{ "no",				REQUEST_TTY_NO },
836 	{ "force",			REQUEST_TTY_FORCE },
837 	{ "auto",			REQUEST_TTY_AUTO },
838 	{ NULL, -1 }
839 };
840 static const struct multistate multistate_canonicalizehostname[] = {
841 	{ "true",			SSH_CANONICALISE_YES },
842 	{ "false",			SSH_CANONICALISE_NO },
843 	{ "yes",			SSH_CANONICALISE_YES },
844 	{ "no",				SSH_CANONICALISE_NO },
845 	{ "always",			SSH_CANONICALISE_ALWAYS },
846 	{ NULL, -1 }
847 };
848 static const struct multistate multistate_compression[] = {
849 #ifdef WITH_ZLIB
850 	{ "yes",			COMP_ZLIB },
851 #endif
852 	{ "no",				COMP_NONE },
853 	{ NULL, -1 }
854 };
855 
856 static int
857 parse_multistate_value(const char *arg, const char *filename, int linenum,
858     const struct multistate *multistate_ptr)
859 {
860 	int i;
861 
862 	if (!arg || *arg == '\0')
863 		fatal("%s line %d: missing argument.", filename, linenum);
864 	for (i = 0; multistate_ptr[i].key != NULL; i++) {
865 		if (strcasecmp(arg, multistate_ptr[i].key) == 0)
866 			return multistate_ptr[i].value;
867 	}
868 	return -1;
869 }
870 
871 /*
872  * Processes a single option line as used in the configuration files. This
873  * only sets those values that have not already been set.
874  */
875 int
876 process_config_line(Options *options, struct passwd *pw, const char *host,
877     const char *original_host, char *line, const char *filename,
878     int linenum, int *activep, int flags)
879 {
880 	return process_config_line_depth(options, pw, host, original_host,
881 	    line, filename, linenum, activep, flags, NULL, 0);
882 }
883 
884 #define WHITESPACE " \t\r\n"
885 static int
886 process_config_line_depth(Options *options, struct passwd *pw, const char *host,
887     const char *original_host, char *line, const char *filename,
888     int linenum, int *activep, int flags, int *want_final_pass, int depth)
889 {
890 	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
891 	char **cpptr, ***cppptr, fwdarg[256];
892 	u_int i, *uintptr, max_entries = 0;
893 	int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
894 	int remotefwd, dynamicfwd;
895 	LogLevel *log_level_ptr;
896 	SyslogFacility *log_facility_ptr;
897 	long long val64;
898 	size_t len;
899 	struct Forward fwd;
900 	const struct multistate *multistate_ptr;
901 	struct allowed_cname *cname;
902 	glob_t gl;
903 	const char *errstr;
904 
905 	if (activep == NULL) { /* We are processing a command line directive */
906 		cmdline = 1;
907 		activep = &cmdline;
908 	}
909 
910 	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
911 	if ((len = strlen(line)) == 0)
912 		return 0;
913 	for (len--; len > 0; len--) {
914 		if (strchr(WHITESPACE "\f", line[len]) == NULL)
915 			break;
916 		line[len] = '\0';
917 	}
918 
919 	s = line;
920 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
921 	if ((keyword = strdelim(&s)) == NULL)
922 		return 0;
923 	/* Ignore leading whitespace. */
924 	if (*keyword == '\0')
925 		keyword = strdelim(&s);
926 	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
927 		return 0;
928 	/* Match lowercase keyword */
929 	lowercase(keyword);
930 
931 	opcode = parse_token(keyword, filename, linenum,
932 	    options->ignored_unknown);
933 
934 	switch (opcode) {
935 	case oBadOption:
936 		/* don't panic, but count bad options */
937 		return -1;
938 	case oIgnore:
939 		return 0;
940 	case oIgnoredUnknownOption:
941 		debug("%s line %d: Ignored unknown option \"%s\"",
942 		    filename, linenum, keyword);
943 		return 0;
944 	case oConnectTimeout:
945 		intptr = &options->connection_timeout;
946 parse_time:
947 		arg = strdelim(&s);
948 		if (!arg || *arg == '\0')
949 			fatal("%s line %d: missing time value.",
950 			    filename, linenum);
951 		if (strcmp(arg, "none") == 0)
952 			value = -1;
953 		else if ((value = convtime(arg)) == -1)
954 			fatal("%s line %d: invalid time value.",
955 			    filename, linenum);
956 		if (*activep && *intptr == -1)
957 			*intptr = value;
958 		break;
959 
960 	case oForwardAgent:
961 		intptr = &options->forward_agent;
962 
963 		arg = strdelim(&s);
964 		if (!arg || *arg == '\0')
965 			fatal("%s line %d: missing argument.",
966 			    filename, linenum);
967 
968 		value = -1;
969 		multistate_ptr = multistate_flag;
970 		for (i = 0; multistate_ptr[i].key != NULL; i++) {
971 			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
972 				value = multistate_ptr[i].value;
973 				break;
974 			}
975 		}
976 		if (value != -1) {
977 			if (*activep && *intptr == -1)
978 				*intptr = value;
979 			break;
980 		}
981 		/* ForwardAgent wasn't 'yes' or 'no', assume a path */
982 		if (*activep && *intptr == -1)
983 			*intptr = 1;
984 
985 		charptr = &options->forward_agent_sock_path;
986 		goto parse_agent_path;
987 
988 	case oForwardX11:
989 		intptr = &options->forward_x11;
990  parse_flag:
991 		multistate_ptr = multistate_flag;
992  parse_multistate:
993 		arg = strdelim(&s);
994 		if ((value = parse_multistate_value(arg, filename, linenum,
995 		     multistate_ptr)) == -1) {
996 			fatal("%s line %d: unsupported option \"%s\".",
997 			    filename, linenum, arg);
998 		}
999 		if (*activep && *intptr == -1)
1000 			*intptr = value;
1001 		break;
1002 
1003 	case oForwardX11Trusted:
1004 		intptr = &options->forward_x11_trusted;
1005 		goto parse_flag;
1006 
1007 	case oForwardX11Timeout:
1008 		intptr = &options->forward_x11_timeout;
1009 		goto parse_time;
1010 
1011 	case oGatewayPorts:
1012 		intptr = &options->fwd_opts.gateway_ports;
1013 		goto parse_flag;
1014 
1015 	case oExitOnForwardFailure:
1016 		intptr = &options->exit_on_forward_failure;
1017 		goto parse_flag;
1018 
1019 	case oPasswordAuthentication:
1020 		intptr = &options->password_authentication;
1021 		goto parse_flag;
1022 
1023 	case oKbdInteractiveAuthentication:
1024 		intptr = &options->kbd_interactive_authentication;
1025 		goto parse_flag;
1026 
1027 	case oKbdInteractiveDevices:
1028 		charptr = &options->kbd_interactive_devices;
1029 		goto parse_string;
1030 
1031 	case oPubkeyAuthentication:
1032 		intptr = &options->pubkey_authentication;
1033 		goto parse_flag;
1034 
1035 	case oHostbasedAuthentication:
1036 		intptr = &options->hostbased_authentication;
1037 		goto parse_flag;
1038 
1039 	case oChallengeResponseAuthentication:
1040 		intptr = &options->challenge_response_authentication;
1041 		goto parse_flag;
1042 
1043 	case oGssAuthentication:
1044 		intptr = &options->gss_authentication;
1045 		goto parse_flag;
1046 
1047 	case oGssDelegateCreds:
1048 		intptr = &options->gss_deleg_creds;
1049 		goto parse_flag;
1050 
1051 	case oBatchMode:
1052 		intptr = &options->batch_mode;
1053 		goto parse_flag;
1054 
1055 	case oCheckHostIP:
1056 		intptr = &options->check_host_ip;
1057 		goto parse_flag;
1058 
1059 	case oVerifyHostKeyDNS:
1060 		intptr = &options->verify_host_key_dns;
1061 		multistate_ptr = multistate_yesnoask;
1062 		goto parse_multistate;
1063 
1064 	case oStrictHostKeyChecking:
1065 		intptr = &options->strict_host_key_checking;
1066 		multistate_ptr = multistate_strict_hostkey;
1067 		goto parse_multistate;
1068 
1069 	case oCompression:
1070 		intptr = &options->compression;
1071 		multistate_ptr = multistate_compression;
1072 		goto parse_multistate;
1073 
1074 	case oTCPKeepAlive:
1075 		intptr = &options->tcp_keep_alive;
1076 		goto parse_flag;
1077 
1078 	case oNoHostAuthenticationForLocalhost:
1079 		intptr = &options->no_host_authentication_for_localhost;
1080 		goto parse_flag;
1081 
1082 	case oNumberOfPasswordPrompts:
1083 		intptr = &options->number_of_password_prompts;
1084 		goto parse_int;
1085 
1086 	case oRekeyLimit:
1087 		arg = strdelim(&s);
1088 		if (!arg || *arg == '\0')
1089 			fatal("%.200s line %d: Missing argument.", filename,
1090 			    linenum);
1091 		if (strcmp(arg, "default") == 0) {
1092 			val64 = 0;
1093 		} else {
1094 			if (scan_scaled(arg, &val64) == -1)
1095 				fatal("%.200s line %d: Bad number '%s': %s",
1096 				    filename, linenum, arg, strerror(errno));
1097 			if (val64 != 0 && val64 < 16)
1098 				fatal("%.200s line %d: RekeyLimit too small",
1099 				    filename, linenum);
1100 		}
1101 		if (*activep && options->rekey_limit == -1)
1102 			options->rekey_limit = val64;
1103 		if (s != NULL) { /* optional rekey interval present */
1104 			if (strcmp(s, "none") == 0) {
1105 				(void)strdelim(&s);	/* discard */
1106 				break;
1107 			}
1108 			intptr = &options->rekey_interval;
1109 			goto parse_time;
1110 		}
1111 		break;
1112 
1113 	case oIdentityFile:
1114 		arg = strdelim(&s);
1115 		if (!arg || *arg == '\0')
1116 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1117 		if (*activep) {
1118 			intptr = &options->num_identity_files;
1119 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
1120 				fatal("%.200s line %d: Too many identity files specified (max %d).",
1121 				    filename, linenum, SSH_MAX_IDENTITY_FILES);
1122 			add_identity_file(options, NULL,
1123 			    arg, flags & SSHCONF_USERCONF);
1124 		}
1125 		break;
1126 
1127 	case oCertificateFile:
1128 		arg = strdelim(&s);
1129 		if (!arg || *arg == '\0')
1130 			fatal("%.200s line %d: Missing argument.",
1131 			    filename, linenum);
1132 		if (*activep) {
1133 			intptr = &options->num_certificate_files;
1134 			if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1135 				fatal("%.200s line %d: Too many certificate "
1136 				    "files specified (max %d).",
1137 				    filename, linenum,
1138 				    SSH_MAX_CERTIFICATE_FILES);
1139 			}
1140 			add_certificate_file(options, arg,
1141 			    flags & SSHCONF_USERCONF);
1142 		}
1143 		break;
1144 
1145 	case oXAuthLocation:
1146 		charptr=&options->xauth_location;
1147 		goto parse_string;
1148 
1149 	case oUser:
1150 		charptr = &options->user;
1151 parse_string:
1152 		arg = strdelim(&s);
1153 		if (!arg || *arg == '\0')
1154 			fatal("%.200s line %d: Missing argument.",
1155 			    filename, linenum);
1156 		if (*activep && *charptr == NULL)
1157 			*charptr = xstrdup(arg);
1158 		break;
1159 
1160 	case oGlobalKnownHostsFile:
1161 		cpptr = (char **)&options->system_hostfiles;
1162 		uintptr = &options->num_system_hostfiles;
1163 		max_entries = SSH_MAX_HOSTS_FILES;
1164 parse_char_array:
1165 		if (*activep && *uintptr == 0) {
1166 			while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1167 				if ((*uintptr) >= max_entries)
1168 					fatal("%s line %d: "
1169 					    "too many known hosts files.",
1170 					    filename, linenum);
1171 				cpptr[(*uintptr)++] = xstrdup(arg);
1172 			}
1173 		}
1174 		return 0;
1175 
1176 	case oUserKnownHostsFile:
1177 		cpptr = (char **)&options->user_hostfiles;
1178 		uintptr = &options->num_user_hostfiles;
1179 		max_entries = SSH_MAX_HOSTS_FILES;
1180 		goto parse_char_array;
1181 
1182 	case oHostname:
1183 		charptr = &options->hostname;
1184 		goto parse_string;
1185 
1186 	case oHostKeyAlias:
1187 		charptr = &options->host_key_alias;
1188 		goto parse_string;
1189 
1190 	case oPreferredAuthentications:
1191 		charptr = &options->preferred_authentications;
1192 		goto parse_string;
1193 
1194 	case oBindAddress:
1195 		charptr = &options->bind_address;
1196 		goto parse_string;
1197 
1198 	case oBindInterface:
1199 		charptr = &options->bind_interface;
1200 		goto parse_string;
1201 
1202 	case oPKCS11Provider:
1203 		charptr = &options->pkcs11_provider;
1204 		goto parse_string;
1205 
1206 	case oSecurityKeyProvider:
1207 		charptr = &options->sk_provider;
1208 		goto parse_string;
1209 
1210 	case oProxyCommand:
1211 		charptr = &options->proxy_command;
1212 		/* Ignore ProxyCommand if ProxyJump already specified */
1213 		if (options->jump_host != NULL)
1214 			charptr = &options->jump_host; /* Skip below */
1215 parse_command:
1216 		if (s == NULL)
1217 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1218 		len = strspn(s, WHITESPACE "=");
1219 		if (*activep && *charptr == NULL)
1220 			*charptr = xstrdup(s + len);
1221 		return 0;
1222 
1223 	case oProxyJump:
1224 		if (s == NULL) {
1225 			fatal("%.200s line %d: Missing argument.",
1226 			    filename, linenum);
1227 		}
1228 		len = strspn(s, WHITESPACE "=");
1229 		if (parse_jump(s + len, options, *activep) == -1) {
1230 			fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1231 			    filename, linenum, s + len);
1232 		}
1233 		return 0;
1234 
1235 	case oPort:
1236 		arg = strdelim(&s);
1237 		if (!arg || *arg == '\0')
1238 			fatal("%.200s line %d: Missing argument.",
1239 			    filename, linenum);
1240 		value = a2port(arg);
1241 		if (value <= 0)
1242 			fatal("%.200s line %d: Bad port '%s'.",
1243 			    filename, linenum, arg);
1244 		if (*activep && options->port == -1)
1245 			options->port = value;
1246 		break;
1247 
1248 	case oConnectionAttempts:
1249 		intptr = &options->connection_attempts;
1250 parse_int:
1251 		arg = strdelim(&s);
1252 		if ((errstr = atoi_err(arg, &value)) != NULL)
1253 			fatal("%s line %d: integer value %s.",
1254 			    filename, linenum, errstr);
1255 		if (*activep && *intptr == -1)
1256 			*intptr = value;
1257 		break;
1258 
1259 	case oCiphers:
1260 		arg = strdelim(&s);
1261 		if (!arg || *arg == '\0')
1262 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1263 		if (*arg != '-' &&
1264 		    !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1265 			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1266 			    filename, linenum, arg ? arg : "<NONE>");
1267 		if (*activep && options->ciphers == NULL)
1268 			options->ciphers = xstrdup(arg);
1269 		break;
1270 
1271 	case oMacs:
1272 		arg = strdelim(&s);
1273 		if (!arg || *arg == '\0')
1274 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1275 		if (*arg != '-' &&
1276 		    !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
1277 			fatal("%.200s line %d: Bad SSH2 MAC spec '%s'.",
1278 			    filename, linenum, arg ? arg : "<NONE>");
1279 		if (*activep && options->macs == NULL)
1280 			options->macs = xstrdup(arg);
1281 		break;
1282 
1283 	case oKexAlgorithms:
1284 		arg = strdelim(&s);
1285 		if (!arg || *arg == '\0')
1286 			fatal("%.200s line %d: Missing argument.",
1287 			    filename, linenum);
1288 		if (*arg != '-' &&
1289 		    !kex_names_valid(*arg == '+' || *arg == '^' ?
1290 		    arg + 1 : arg))
1291 			fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1292 			    filename, linenum, arg ? arg : "<NONE>");
1293 		if (*activep && options->kex_algorithms == NULL)
1294 			options->kex_algorithms = xstrdup(arg);
1295 		break;
1296 
1297 	case oHostKeyAlgorithms:
1298 		charptr = &options->hostkeyalgorithms;
1299 parse_keytypes:
1300 		arg = strdelim(&s);
1301 		if (!arg || *arg == '\0')
1302 			fatal("%.200s line %d: Missing argument.",
1303 			    filename, linenum);
1304 		if (*arg != '-' &&
1305 		    !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
1306 		    arg + 1 : arg, 1))
1307 			fatal("%s line %d: Bad key types '%s'.",
1308 				filename, linenum, arg ? arg : "<NONE>");
1309 		if (*activep && *charptr == NULL)
1310 			*charptr = xstrdup(arg);
1311 		break;
1312 
1313 	case oCASignatureAlgorithms:
1314 		charptr = &options->ca_sign_algorithms;
1315 		goto parse_keytypes;
1316 
1317 	case oLogLevel:
1318 		log_level_ptr = &options->log_level;
1319 		arg = strdelim(&s);
1320 		value = log_level_number(arg);
1321 		if (value == SYSLOG_LEVEL_NOT_SET)
1322 			fatal("%.200s line %d: unsupported log level '%s'",
1323 			    filename, linenum, arg ? arg : "<NONE>");
1324 		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1325 			*log_level_ptr = (LogLevel) value;
1326 		break;
1327 
1328 	case oLogFacility:
1329 		log_facility_ptr = &options->log_facility;
1330 		arg = strdelim(&s);
1331 		value = log_facility_number(arg);
1332 		if (value == SYSLOG_FACILITY_NOT_SET)
1333 			fatal("%.200s line %d: unsupported log facility '%s'",
1334 			    filename, linenum, arg ? arg : "<NONE>");
1335 		if (*log_facility_ptr == -1)
1336 			*log_facility_ptr = (SyslogFacility) value;
1337 		break;
1338 
1339 	case oLogVerbose:
1340 		cppptr = &options->log_verbose;
1341 		uintptr = &options->num_log_verbose;
1342 		if (*activep && *uintptr == 0) {
1343 			while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1344 				*cppptr = xrecallocarray(*cppptr, *uintptr,
1345 				    *uintptr + 1, sizeof(**cppptr));
1346 				(*cppptr)[(*uintptr)++] = xstrdup(arg);
1347 			}
1348 		}
1349 		return 0;
1350 
1351 	case oLocalForward:
1352 	case oRemoteForward:
1353 	case oDynamicForward:
1354 		arg = strdelim(&s);
1355 		if (arg == NULL || *arg == '\0')
1356 			fatal("%.200s line %d: Missing port argument.",
1357 			    filename, linenum);
1358 
1359 		remotefwd = (opcode == oRemoteForward);
1360 		dynamicfwd = (opcode == oDynamicForward);
1361 
1362 		if (!dynamicfwd) {
1363 			arg2 = strdelim(&s);
1364 			if (arg2 == NULL || *arg2 == '\0') {
1365 				if (remotefwd)
1366 					dynamicfwd = 1;
1367 				else
1368 					fatal("%.200s line %d: Missing target "
1369 					    "argument.", filename, linenum);
1370 			} else {
1371 				/* construct a string for parse_forward */
1372 				snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
1373 				    arg2);
1374 			}
1375 		}
1376 		if (dynamicfwd)
1377 			strlcpy(fwdarg, arg, sizeof(fwdarg));
1378 
1379 		if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
1380 			fatal("%.200s line %d: Bad forwarding specification.",
1381 			    filename, linenum);
1382 
1383 		if (*activep) {
1384 			if (remotefwd) {
1385 				add_remote_forward(options, &fwd);
1386 			} else {
1387 				add_local_forward(options, &fwd);
1388 			}
1389 		}
1390 		break;
1391 
1392 	case oClearAllForwardings:
1393 		intptr = &options->clear_forwardings;
1394 		goto parse_flag;
1395 
1396 	case oHost:
1397 		if (cmdline)
1398 			fatal("Host directive not supported as a command-line "
1399 			    "option");
1400 		*activep = 0;
1401 		arg2 = NULL;
1402 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1403 			if ((flags & SSHCONF_NEVERMATCH) != 0)
1404 				break;
1405 			negated = *arg == '!';
1406 			if (negated)
1407 				arg++;
1408 			if (match_pattern(host, arg)) {
1409 				if (negated) {
1410 					debug("%.200s line %d: Skipping Host "
1411 					    "block because of negated match "
1412 					    "for %.100s", filename, linenum,
1413 					    arg);
1414 					*activep = 0;
1415 					break;
1416 				}
1417 				if (!*activep)
1418 					arg2 = arg; /* logged below */
1419 				*activep = 1;
1420 			}
1421 		}
1422 		if (*activep)
1423 			debug("%.200s line %d: Applying options for %.100s",
1424 			    filename, linenum, arg2);
1425 		/* Avoid garbage check below, as strdelim is done. */
1426 		return 0;
1427 
1428 	case oMatch:
1429 		if (cmdline)
1430 			fatal("Host directive not supported as a command-line "
1431 			    "option");
1432 		value = match_cfg_line(options, &s, pw, host, original_host,
1433 		    flags & SSHCONF_FINAL, want_final_pass,
1434 		    filename, linenum);
1435 		if (value < 0)
1436 			fatal("%.200s line %d: Bad Match condition", filename,
1437 			    linenum);
1438 		*activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1439 		break;
1440 
1441 	case oEscapeChar:
1442 		intptr = &options->escape_char;
1443 		arg = strdelim(&s);
1444 		if (!arg || *arg == '\0')
1445 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1446 		if (strcmp(arg, "none") == 0)
1447 			value = SSH_ESCAPECHAR_NONE;
1448 		else if (arg[1] == '\0')
1449 			value = (u_char) arg[0];
1450 		else if (arg[0] == '^' && arg[2] == 0 &&
1451 		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1452 			value = (u_char) arg[1] & 31;
1453 		else {
1454 			fatal("%.200s line %d: Bad escape character.",
1455 			    filename, linenum);
1456 			/* NOTREACHED */
1457 			value = 0;	/* Avoid compiler warning. */
1458 		}
1459 		if (*activep && *intptr == -1)
1460 			*intptr = value;
1461 		break;
1462 
1463 	case oAddressFamily:
1464 		intptr = &options->address_family;
1465 		multistate_ptr = multistate_addressfamily;
1466 		goto parse_multistate;
1467 
1468 	case oEnableSSHKeysign:
1469 		intptr = &options->enable_ssh_keysign;
1470 		goto parse_flag;
1471 
1472 	case oIdentitiesOnly:
1473 		intptr = &options->identities_only;
1474 		goto parse_flag;
1475 
1476 	case oServerAliveInterval:
1477 		intptr = &options->server_alive_interval;
1478 		goto parse_time;
1479 
1480 	case oServerAliveCountMax:
1481 		intptr = &options->server_alive_count_max;
1482 		goto parse_int;
1483 
1484 	case oSendEnv:
1485 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1486 			if (strchr(arg, '=') != NULL)
1487 				fatal("%s line %d: Invalid environment name.",
1488 				    filename, linenum);
1489 			if (!*activep)
1490 				continue;
1491 			if (*arg == '-') {
1492 				/* Removing an env var */
1493 				rm_env(options, arg, filename, linenum);
1494 				continue;
1495 			} else {
1496 				/* Adding an env var */
1497 				if (options->num_send_env >= INT_MAX)
1498 					fatal("%s line %d: too many send env.",
1499 					    filename, linenum);
1500 				options->send_env = xrecallocarray(
1501 				    options->send_env, options->num_send_env,
1502 				    options->num_send_env + 1,
1503 				    sizeof(*options->send_env));
1504 				options->send_env[options->num_send_env++] =
1505 				    xstrdup(arg);
1506 			}
1507 		}
1508 		break;
1509 
1510 	case oSetEnv:
1511 		value = options->num_setenv;
1512 		while ((arg = strdelimw(&s)) != NULL && *arg != '\0') {
1513 			if (strchr(arg, '=') == NULL)
1514 				fatal("%s line %d: Invalid SetEnv.",
1515 				    filename, linenum);
1516 			if (!*activep || value != 0)
1517 				continue;
1518 			/* Adding a setenv var */
1519 			if (options->num_setenv >= INT_MAX)
1520 				fatal("%s line %d: too many SetEnv.",
1521 				    filename, linenum);
1522 			options->setenv = xrecallocarray(
1523 			    options->setenv, options->num_setenv,
1524 			    options->num_setenv + 1, sizeof(*options->setenv));
1525 			options->setenv[options->num_setenv++] = xstrdup(arg);
1526 		}
1527 		break;
1528 
1529 	case oControlPath:
1530 		charptr = &options->control_path;
1531 		goto parse_string;
1532 
1533 	case oControlMaster:
1534 		intptr = &options->control_master;
1535 		multistate_ptr = multistate_controlmaster;
1536 		goto parse_multistate;
1537 
1538 	case oControlPersist:
1539 		/* no/false/yes/true, or a time spec */
1540 		intptr = &options->control_persist;
1541 		arg = strdelim(&s);
1542 		if (!arg || *arg == '\0')
1543 			fatal("%.200s line %d: Missing ControlPersist"
1544 			    " argument.", filename, linenum);
1545 		value = 0;
1546 		value2 = 0;	/* timeout */
1547 		if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1548 			value = 0;
1549 		else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1550 			value = 1;
1551 		else if ((value2 = convtime(arg)) >= 0)
1552 			value = 1;
1553 		else
1554 			fatal("%.200s line %d: Bad ControlPersist argument.",
1555 			    filename, linenum);
1556 		if (*activep && *intptr == -1) {
1557 			*intptr = value;
1558 			options->control_persist_timeout = value2;
1559 		}
1560 		break;
1561 
1562 	case oHashKnownHosts:
1563 		intptr = &options->hash_known_hosts;
1564 		goto parse_flag;
1565 
1566 	case oTunnel:
1567 		intptr = &options->tun_open;
1568 		multistate_ptr = multistate_tunnel;
1569 		goto parse_multistate;
1570 
1571 	case oTunnelDevice:
1572 		arg = strdelim(&s);
1573 		if (!arg || *arg == '\0')
1574 			fatal("%.200s line %d: Missing argument.", filename, linenum);
1575 		value = a2tun(arg, &value2);
1576 		if (value == SSH_TUNID_ERR)
1577 			fatal("%.200s line %d: Bad tun device.", filename, linenum);
1578 		if (*activep) {
1579 			options->tun_local = value;
1580 			options->tun_remote = value2;
1581 		}
1582 		break;
1583 
1584 	case oLocalCommand:
1585 		charptr = &options->local_command;
1586 		goto parse_command;
1587 
1588 	case oPermitLocalCommand:
1589 		intptr = &options->permit_local_command;
1590 		goto parse_flag;
1591 
1592 	case oRemoteCommand:
1593 		charptr = &options->remote_command;
1594 		goto parse_command;
1595 
1596 	case oVisualHostKey:
1597 		intptr = &options->visual_host_key;
1598 		goto parse_flag;
1599 
1600 	case oInclude:
1601 		if (cmdline)
1602 			fatal("Include directive not supported as a "
1603 			    "command-line option");
1604 		value = 0;
1605 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1606 			/*
1607 			 * Ensure all paths are anchored. User configuration
1608 			 * files may begin with '~/' but system configurations
1609 			 * must not. If the path is relative, then treat it
1610 			 * as living in ~/.ssh for user configurations or
1611 			 * /etc/ssh for system ones.
1612 			 */
1613 			if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1614 				fatal("%.200s line %d: bad include path %s.",
1615 				    filename, linenum, arg);
1616 			if (!path_absolute(arg) && *arg != '~') {
1617 				xasprintf(&arg2, "%s/%s",
1618 				    (flags & SSHCONF_USERCONF) ?
1619 				    "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1620 			} else
1621 				arg2 = xstrdup(arg);
1622 			memset(&gl, 0, sizeof(gl));
1623 			r = glob(arg2, GLOB_TILDE, NULL, &gl);
1624 			if (r == GLOB_NOMATCH) {
1625 				debug("%.200s line %d: include %s matched no "
1626 				    "files",filename, linenum, arg2);
1627 				free(arg2);
1628 				continue;
1629 			} else if (r != 0)
1630 				fatal("%.200s line %d: glob failed for %s.",
1631 				    filename, linenum, arg2);
1632 			free(arg2);
1633 			oactive = *activep;
1634 			for (i = 0; i < gl.gl_pathc; i++) {
1635 				debug3("%.200s line %d: Including file %s "
1636 				    "depth %d%s", filename, linenum,
1637 				    gl.gl_pathv[i], depth,
1638 				    oactive ? "" : " (parse only)");
1639 				r = read_config_file_depth(gl.gl_pathv[i],
1640 				    pw, host, original_host, options,
1641 				    flags | SSHCONF_CHECKPERM |
1642 				    (oactive ? 0 : SSHCONF_NEVERMATCH),
1643 				    activep, want_final_pass, depth + 1);
1644 				if (r != 1 && errno != ENOENT) {
1645 					fatal("Can't open user config file "
1646 					    "%.100s: %.100s", gl.gl_pathv[i],
1647 					    strerror(errno));
1648 				}
1649 				/*
1650 				 * don't let Match in includes clobber the
1651 				 * containing file's Match state.
1652 				 */
1653 				*activep = oactive;
1654 				if (r != 1)
1655 					value = -1;
1656 			}
1657 			globfree(&gl);
1658 		}
1659 		if (value != 0)
1660 			return value;
1661 		break;
1662 
1663 	case oIPQoS:
1664 		arg = strdelim(&s);
1665 		if ((value = parse_ipqos(arg)) == -1)
1666 			fatal("%s line %d: Bad IPQoS value: %s",
1667 			    filename, linenum, arg);
1668 		arg = strdelim(&s);
1669 		if (arg == NULL)
1670 			value2 = value;
1671 		else if ((value2 = parse_ipqos(arg)) == -1)
1672 			fatal("%s line %d: Bad IPQoS value: %s",
1673 			    filename, linenum, arg);
1674 		if (*activep) {
1675 			options->ip_qos_interactive = value;
1676 			options->ip_qos_bulk = value2;
1677 		}
1678 		break;
1679 
1680 	case oRequestTTY:
1681 		intptr = &options->request_tty;
1682 		multistate_ptr = multistate_requesttty;
1683 		goto parse_multistate;
1684 
1685 	case oIgnoreUnknown:
1686 		charptr = &options->ignored_unknown;
1687 		goto parse_string;
1688 
1689 	case oProxyUseFdpass:
1690 		intptr = &options->proxy_use_fdpass;
1691 		goto parse_flag;
1692 
1693 	case oCanonicalDomains:
1694 		value = options->num_canonical_domains != 0;
1695 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1696 			if (!valid_domain(arg, 1, &errstr)) {
1697 				fatal("%s line %d: %s", filename, linenum,
1698 				    errstr);
1699 			}
1700 			if (!*activep || value)
1701 				continue;
1702 			if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1703 				fatal("%s line %d: too many hostname suffixes.",
1704 				    filename, linenum);
1705 			options->canonical_domains[
1706 			    options->num_canonical_domains++] = xstrdup(arg);
1707 		}
1708 		break;
1709 
1710 	case oCanonicalizePermittedCNAMEs:
1711 		value = options->num_permitted_cnames != 0;
1712 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1713 			/* Either '*' for everything or 'list:list' */
1714 			if (strcmp(arg, "*") == 0)
1715 				arg2 = arg;
1716 			else {
1717 				lowercase(arg);
1718 				if ((arg2 = strchr(arg, ':')) == NULL ||
1719 				    arg2[1] == '\0') {
1720 					fatal("%s line %d: "
1721 					    "Invalid permitted CNAME \"%s\"",
1722 					    filename, linenum, arg);
1723 				}
1724 				*arg2 = '\0';
1725 				arg2++;
1726 			}
1727 			if (!*activep || value)
1728 				continue;
1729 			if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1730 				fatal("%s line %d: too many permitted CNAMEs.",
1731 				    filename, linenum);
1732 			cname = options->permitted_cnames +
1733 			    options->num_permitted_cnames++;
1734 			cname->source_list = xstrdup(arg);
1735 			cname->target_list = xstrdup(arg2);
1736 		}
1737 		break;
1738 
1739 	case oCanonicalizeHostname:
1740 		intptr = &options->canonicalize_hostname;
1741 		multistate_ptr = multistate_canonicalizehostname;
1742 		goto parse_multistate;
1743 
1744 	case oCanonicalizeMaxDots:
1745 		intptr = &options->canonicalize_max_dots;
1746 		goto parse_int;
1747 
1748 	case oCanonicalizeFallbackLocal:
1749 		intptr = &options->canonicalize_fallback_local;
1750 		goto parse_flag;
1751 
1752 	case oStreamLocalBindMask:
1753 		arg = strdelim(&s);
1754 		if (!arg || *arg == '\0')
1755 			fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1756 		/* Parse mode in octal format */
1757 		value = strtol(arg, &endofnumber, 8);
1758 		if (arg == endofnumber || value < 0 || value > 0777)
1759 			fatal("%.200s line %d: Bad mask.", filename, linenum);
1760 		options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1761 		break;
1762 
1763 	case oStreamLocalBindUnlink:
1764 		intptr = &options->fwd_opts.streamlocal_bind_unlink;
1765 		goto parse_flag;
1766 
1767 	case oRevokedHostKeys:
1768 		charptr = &options->revoked_host_keys;
1769 		goto parse_string;
1770 
1771 	case oFingerprintHash:
1772 		intptr = &options->fingerprint_hash;
1773 		arg = strdelim(&s);
1774 		if (!arg || *arg == '\0')
1775 			fatal("%.200s line %d: Missing argument.",
1776 			    filename, linenum);
1777 		if ((value = ssh_digest_alg_by_name(arg)) == -1)
1778 			fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1779 			    filename, linenum, arg);
1780 		if (*activep && *intptr == -1)
1781 			*intptr = value;
1782 		break;
1783 
1784 	case oUpdateHostkeys:
1785 		intptr = &options->update_hostkeys;
1786 		multistate_ptr = multistate_yesnoask;
1787 		goto parse_multistate;
1788 
1789 	case oHostbasedKeyTypes:
1790 		charptr = &options->hostbased_key_types;
1791 		goto parse_keytypes;
1792 
1793 	case oPubkeyAcceptedKeyTypes:
1794 		charptr = &options->pubkey_key_types;
1795 		goto parse_keytypes;
1796 
1797 	case oAddKeysToAgent:
1798 		arg = strdelim(&s);
1799 		arg2 = strdelim(&s);
1800 		value = parse_multistate_value(arg, filename, linenum,
1801 		     multistate_yesnoaskconfirm);
1802 		value2 = 0; /* unlimited lifespan by default */
1803 		if (value == 3 && arg2 != NULL) {
1804 			/* allow "AddKeysToAgent confirm 5m" */
1805 			if ((value2 = convtime(arg2)) == -1 || value2 > INT_MAX)
1806 				fatal("%s line %d: invalid time value.",
1807 				    filename, linenum);
1808 		} else if (value == -1 && arg2 == NULL) {
1809 			if ((value2 = convtime(arg)) == -1 || value2 > INT_MAX)
1810 				fatal("%s line %d: unsupported option",
1811 				    filename, linenum);
1812 			value = 1; /* yes */
1813 		} else if (value == -1 || arg2 != NULL) {
1814 			fatal("%s line %d: unsupported option",
1815 			    filename, linenum);
1816 		}
1817 		if (*activep && options->add_keys_to_agent == -1) {
1818 			options->add_keys_to_agent = value;
1819 			options->add_keys_to_agent_lifespan = value2;
1820 		}
1821 		break;
1822 
1823 	case oIdentityAgent:
1824 		charptr = &options->identity_agent;
1825 		arg = strdelim(&s);
1826 		if (!arg || *arg == '\0')
1827 			fatal("%.200s line %d: Missing argument.",
1828 			    filename, linenum);
1829   parse_agent_path:
1830 		/* Extra validation if the string represents an env var. */
1831 		if ((arg2 = dollar_expand(&r, arg)) == NULL || r)
1832 			fatal("%.200s line %d: Invalid environment expansion "
1833 			    "%s.", filename, linenum, arg);
1834 		free(arg2);
1835 		/* check for legacy environment format */
1836 		if (arg[0] == '$' && arg[1] != '{' && !valid_env_name(arg + 1)) {
1837 			fatal("%.200s line %d: Invalid environment name %s.",
1838 			    filename, linenum, arg);
1839 		}
1840 		if (*activep && *charptr == NULL)
1841 			*charptr = xstrdup(arg);
1842 		break;
1843 
1844 	case oDeprecated:
1845 		debug("%s line %d: Deprecated option \"%s\"",
1846 		    filename, linenum, keyword);
1847 		return 0;
1848 
1849 	case oUnsupported:
1850 		error("%s line %d: Unsupported option \"%s\"",
1851 		    filename, linenum, keyword);
1852 		return 0;
1853 
1854 	default:
1855 		fatal("%s: Unimplemented opcode %d", __func__, opcode);
1856 	}
1857 
1858 	/* Check that there is no garbage at end of line. */
1859 	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1860 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1861 		    filename, linenum, arg);
1862 	}
1863 	return 0;
1864 }
1865 
1866 /*
1867  * Reads the config file and modifies the options accordingly.  Options
1868  * should already be initialized before this call.  This never returns if
1869  * there is an error.  If the file does not exist, this returns 0.
1870  */
1871 int
1872 read_config_file(const char *filename, struct passwd *pw, const char *host,
1873     const char *original_host, Options *options, int flags,
1874     int *want_final_pass)
1875 {
1876 	int active = 1;
1877 
1878 	return read_config_file_depth(filename, pw, host, original_host,
1879 	    options, flags, &active, want_final_pass, 0);
1880 }
1881 
1882 #define READCONF_MAX_DEPTH	16
1883 static int
1884 read_config_file_depth(const char *filename, struct passwd *pw,
1885     const char *host, const char *original_host, Options *options,
1886     int flags, int *activep, int *want_final_pass, int depth)
1887 {
1888 	FILE *f;
1889 	char *line = NULL;
1890 	size_t linesize = 0;
1891 	int linenum;
1892 	int bad_options = 0;
1893 
1894 	if (depth < 0 || depth > READCONF_MAX_DEPTH)
1895 		fatal("Too many recursive configuration includes");
1896 
1897 	if ((f = fopen(filename, "r")) == NULL)
1898 		return 0;
1899 
1900 	if (flags & SSHCONF_CHECKPERM) {
1901 		struct stat sb;
1902 
1903 		if (fstat(fileno(f), &sb) == -1)
1904 			fatal("fstat %s: %s", filename, strerror(errno));
1905 		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1906 		    (sb.st_mode & 022) != 0))
1907 			fatal("Bad owner or permissions on %s", filename);
1908 	}
1909 
1910 	debug("Reading configuration data %.200s", filename);
1911 
1912 	/*
1913 	 * Mark that we are now processing the options.  This flag is turned
1914 	 * on/off by Host specifications.
1915 	 */
1916 	linenum = 0;
1917 	while (getline(&line, &linesize, f) != -1) {
1918 		/* Update line number counter. */
1919 		linenum++;
1920 		if (process_config_line_depth(options, pw, host, original_host,
1921 		    line, filename, linenum, activep, flags, want_final_pass,
1922 		    depth) != 0)
1923 			bad_options++;
1924 	}
1925 	free(line);
1926 	fclose(f);
1927 	if (bad_options > 0)
1928 		fatal("%s: terminating, %d bad configuration options",
1929 		    filename, bad_options);
1930 	return 1;
1931 }
1932 
1933 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1934 int
1935 option_clear_or_none(const char *o)
1936 {
1937 	return o == NULL || strcasecmp(o, "none") == 0;
1938 }
1939 
1940 /*
1941  * Initializes options to special values that indicate that they have not yet
1942  * been set.  Read_config_file will only set options with this value. Options
1943  * are processed in the following order: command line, user config file,
1944  * system config file.  Last, fill_default_options is called.
1945  */
1946 
1947 void
1948 initialize_options(Options * options)
1949 {
1950 	memset(options, 'X', sizeof(*options));
1951 	options->forward_agent = -1;
1952 	options->forward_agent_sock_path = NULL;
1953 	options->forward_x11 = -1;
1954 	options->forward_x11_trusted = -1;
1955 	options->forward_x11_timeout = -1;
1956 	options->stdio_forward_host = NULL;
1957 	options->stdio_forward_port = 0;
1958 	options->clear_forwardings = -1;
1959 	options->exit_on_forward_failure = -1;
1960 	options->xauth_location = NULL;
1961 	options->fwd_opts.gateway_ports = -1;
1962 	options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1963 	options->fwd_opts.streamlocal_bind_unlink = -1;
1964 	options->pubkey_authentication = -1;
1965 	options->challenge_response_authentication = -1;
1966 	options->gss_authentication = -1;
1967 	options->gss_deleg_creds = -1;
1968 	options->password_authentication = -1;
1969 	options->kbd_interactive_authentication = -1;
1970 	options->kbd_interactive_devices = NULL;
1971 	options->hostbased_authentication = -1;
1972 	options->batch_mode = -1;
1973 	options->check_host_ip = -1;
1974 	options->strict_host_key_checking = -1;
1975 	options->compression = -1;
1976 	options->tcp_keep_alive = -1;
1977 	options->port = -1;
1978 	options->address_family = -1;
1979 	options->connection_attempts = -1;
1980 	options->connection_timeout = -1;
1981 	options->number_of_password_prompts = -1;
1982 	options->ciphers = NULL;
1983 	options->macs = NULL;
1984 	options->kex_algorithms = NULL;
1985 	options->hostkeyalgorithms = NULL;
1986 	options->ca_sign_algorithms = NULL;
1987 	options->num_identity_files = 0;
1988 	options->num_certificate_files = 0;
1989 	options->hostname = NULL;
1990 	options->host_key_alias = NULL;
1991 	options->proxy_command = NULL;
1992 	options->jump_user = NULL;
1993 	options->jump_host = NULL;
1994 	options->jump_port = -1;
1995 	options->jump_extra = NULL;
1996 	options->user = NULL;
1997 	options->escape_char = -1;
1998 	options->num_system_hostfiles = 0;
1999 	options->num_user_hostfiles = 0;
2000 	options->local_forwards = NULL;
2001 	options->num_local_forwards = 0;
2002 	options->remote_forwards = NULL;
2003 	options->num_remote_forwards = 0;
2004 	options->log_facility = SYSLOG_FACILITY_NOT_SET;
2005 	options->log_level = SYSLOG_LEVEL_NOT_SET;
2006 	options->num_log_verbose = 0;
2007 	options->log_verbose = NULL;
2008 	options->preferred_authentications = NULL;
2009 	options->bind_address = NULL;
2010 	options->bind_interface = NULL;
2011 	options->pkcs11_provider = NULL;
2012 	options->sk_provider = NULL;
2013 	options->enable_ssh_keysign = - 1;
2014 	options->no_host_authentication_for_localhost = - 1;
2015 	options->identities_only = - 1;
2016 	options->rekey_limit = - 1;
2017 	options->rekey_interval = -1;
2018 	options->verify_host_key_dns = -1;
2019 	options->server_alive_interval = -1;
2020 	options->server_alive_count_max = -1;
2021 	options->send_env = NULL;
2022 	options->num_send_env = 0;
2023 	options->setenv = NULL;
2024 	options->num_setenv = 0;
2025 	options->control_path = NULL;
2026 	options->control_master = -1;
2027 	options->control_persist = -1;
2028 	options->control_persist_timeout = 0;
2029 	options->hash_known_hosts = -1;
2030 	options->tun_open = -1;
2031 	options->tun_local = -1;
2032 	options->tun_remote = -1;
2033 	options->local_command = NULL;
2034 	options->permit_local_command = -1;
2035 	options->remote_command = NULL;
2036 	options->add_keys_to_agent = -1;
2037 	options->add_keys_to_agent_lifespan = -1;
2038 	options->identity_agent = NULL;
2039 	options->visual_host_key = -1;
2040 	options->ip_qos_interactive = -1;
2041 	options->ip_qos_bulk = -1;
2042 	options->request_tty = -1;
2043 	options->proxy_use_fdpass = -1;
2044 	options->ignored_unknown = NULL;
2045 	options->num_canonical_domains = 0;
2046 	options->num_permitted_cnames = 0;
2047 	options->canonicalize_max_dots = -1;
2048 	options->canonicalize_fallback_local = -1;
2049 	options->canonicalize_hostname = -1;
2050 	options->revoked_host_keys = NULL;
2051 	options->fingerprint_hash = -1;
2052 	options->update_hostkeys = -1;
2053 	options->hostbased_key_types = NULL;
2054 	options->pubkey_key_types = NULL;
2055 }
2056 
2057 /*
2058  * A petite version of fill_default_options() that just fills the options
2059  * needed for hostname canonicalization to proceed.
2060  */
2061 void
2062 fill_default_options_for_canonicalization(Options *options)
2063 {
2064 	if (options->canonicalize_max_dots == -1)
2065 		options->canonicalize_max_dots = 1;
2066 	if (options->canonicalize_fallback_local == -1)
2067 		options->canonicalize_fallback_local = 1;
2068 	if (options->canonicalize_hostname == -1)
2069 		options->canonicalize_hostname = SSH_CANONICALISE_NO;
2070 }
2071 
2072 /*
2073  * Called after processing other sources of option data, this fills those
2074  * options for which no value has been specified with their default values.
2075  */
2076 void
2077 fill_default_options(Options * options)
2078 {
2079 	char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
2080 	char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig;
2081 	int r;
2082 
2083 	if (options->forward_agent == -1)
2084 		options->forward_agent = 0;
2085 	if (options->forward_x11 == -1)
2086 		options->forward_x11 = 0;
2087 	if (options->forward_x11_trusted == -1)
2088 		options->forward_x11_trusted = 0;
2089 	if (options->forward_x11_timeout == -1)
2090 		options->forward_x11_timeout = 1200;
2091 	/*
2092 	 * stdio forwarding (-W) changes the default for these but we defer
2093 	 * setting the values so they can be overridden.
2094 	 */
2095 	if (options->exit_on_forward_failure == -1)
2096 		options->exit_on_forward_failure =
2097 		    options->stdio_forward_host != NULL ? 1 : 0;
2098 	if (options->clear_forwardings == -1)
2099 		options->clear_forwardings =
2100 		    options->stdio_forward_host != NULL ? 1 : 0;
2101 	if (options->clear_forwardings == 1)
2102 		clear_forwardings(options);
2103 
2104 	if (options->xauth_location == NULL)
2105 		options->xauth_location = _PATH_XAUTH;
2106 	if (options->fwd_opts.gateway_ports == -1)
2107 		options->fwd_opts.gateway_ports = 0;
2108 	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
2109 		options->fwd_opts.streamlocal_bind_mask = 0177;
2110 	if (options->fwd_opts.streamlocal_bind_unlink == -1)
2111 		options->fwd_opts.streamlocal_bind_unlink = 0;
2112 	if (options->pubkey_authentication == -1)
2113 		options->pubkey_authentication = 1;
2114 	if (options->challenge_response_authentication == -1)
2115 		options->challenge_response_authentication = 1;
2116 	if (options->gss_authentication == -1)
2117 		options->gss_authentication = 0;
2118 	if (options->gss_deleg_creds == -1)
2119 		options->gss_deleg_creds = 0;
2120 	if (options->password_authentication == -1)
2121 		options->password_authentication = 1;
2122 	if (options->kbd_interactive_authentication == -1)
2123 		options->kbd_interactive_authentication = 1;
2124 	if (options->hostbased_authentication == -1)
2125 		options->hostbased_authentication = 0;
2126 	if (options->batch_mode == -1)
2127 		options->batch_mode = 0;
2128 	if (options->check_host_ip == -1)
2129 		options->check_host_ip = 1;
2130 	if (options->strict_host_key_checking == -1)
2131 		options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
2132 	if (options->compression == -1)
2133 		options->compression = 0;
2134 	if (options->tcp_keep_alive == -1)
2135 		options->tcp_keep_alive = 1;
2136 	if (options->port == -1)
2137 		options->port = 0;	/* Filled in ssh_connect. */
2138 	if (options->address_family == -1)
2139 		options->address_family = AF_UNSPEC;
2140 	if (options->connection_attempts == -1)
2141 		options->connection_attempts = 1;
2142 	if (options->number_of_password_prompts == -1)
2143 		options->number_of_password_prompts = 3;
2144 	/* options->hostkeyalgorithms, default set in myproposals.h */
2145 	if (options->add_keys_to_agent == -1) {
2146 		options->add_keys_to_agent = 0;
2147 		options->add_keys_to_agent_lifespan = 0;
2148 	}
2149 	if (options->num_identity_files == 0) {
2150 		add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
2151 		add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
2152 		add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
2153 		add_identity_file(options, "~/",
2154 		    _PATH_SSH_CLIENT_ID_ECDSA_SK, 0);
2155 		add_identity_file(options, "~/",
2156 		    _PATH_SSH_CLIENT_ID_ED25519, 0);
2157 		add_identity_file(options, "~/",
2158 		    _PATH_SSH_CLIENT_ID_ED25519_SK, 0);
2159 		add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0);
2160 	}
2161 	if (options->escape_char == -1)
2162 		options->escape_char = '~';
2163 	if (options->num_system_hostfiles == 0) {
2164 		options->system_hostfiles[options->num_system_hostfiles++] =
2165 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
2166 		options->system_hostfiles[options->num_system_hostfiles++] =
2167 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
2168 	}
2169 	if (options->update_hostkeys == -1) {
2170 		if (options->verify_host_key_dns <= 0 &&
2171 		    (options->num_user_hostfiles == 0 ||
2172 		    (options->num_user_hostfiles == 1 && strcmp(options->
2173 		    user_hostfiles[0], _PATH_SSH_USER_HOSTFILE) == 0)))
2174 			options->update_hostkeys = SSH_UPDATE_HOSTKEYS_YES;
2175 		else
2176 			options->update_hostkeys = SSH_UPDATE_HOSTKEYS_NO;
2177 	}
2178 	if (options->num_user_hostfiles == 0) {
2179 		options->user_hostfiles[options->num_user_hostfiles++] =
2180 		    xstrdup(_PATH_SSH_USER_HOSTFILE);
2181 		options->user_hostfiles[options->num_user_hostfiles++] =
2182 		    xstrdup(_PATH_SSH_USER_HOSTFILE2);
2183 	}
2184 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
2185 		options->log_level = SYSLOG_LEVEL_INFO;
2186 	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
2187 		options->log_facility = SYSLOG_FACILITY_USER;
2188 	if (options->no_host_authentication_for_localhost == - 1)
2189 		options->no_host_authentication_for_localhost = 0;
2190 	if (options->identities_only == -1)
2191 		options->identities_only = 0;
2192 	if (options->enable_ssh_keysign == -1)
2193 		options->enable_ssh_keysign = 0;
2194 	if (options->rekey_limit == -1)
2195 		options->rekey_limit = 0;
2196 	if (options->rekey_interval == -1)
2197 		options->rekey_interval = 0;
2198 	if (options->verify_host_key_dns == -1)
2199 		options->verify_host_key_dns = 0;
2200 	if (options->server_alive_interval == -1)
2201 		options->server_alive_interval = 0;
2202 	if (options->server_alive_count_max == -1)
2203 		options->server_alive_count_max = 3;
2204 	if (options->control_master == -1)
2205 		options->control_master = 0;
2206 	if (options->control_persist == -1) {
2207 		options->control_persist = 0;
2208 		options->control_persist_timeout = 0;
2209 	}
2210 	if (options->hash_known_hosts == -1)
2211 		options->hash_known_hosts = 0;
2212 	if (options->tun_open == -1)
2213 		options->tun_open = SSH_TUNMODE_NO;
2214 	if (options->tun_local == -1)
2215 		options->tun_local = SSH_TUNID_ANY;
2216 	if (options->tun_remote == -1)
2217 		options->tun_remote = SSH_TUNID_ANY;
2218 	if (options->permit_local_command == -1)
2219 		options->permit_local_command = 0;
2220 	if (options->visual_host_key == -1)
2221 		options->visual_host_key = 0;
2222 	if (options->ip_qos_interactive == -1)
2223 		options->ip_qos_interactive = IPTOS_DSCP_AF21;
2224 	if (options->ip_qos_bulk == -1)
2225 		options->ip_qos_bulk = IPTOS_DSCP_CS1;
2226 	if (options->request_tty == -1)
2227 		options->request_tty = REQUEST_TTY_AUTO;
2228 	if (options->proxy_use_fdpass == -1)
2229 		options->proxy_use_fdpass = 0;
2230 	if (options->canonicalize_max_dots == -1)
2231 		options->canonicalize_max_dots = 1;
2232 	if (options->canonicalize_fallback_local == -1)
2233 		options->canonicalize_fallback_local = 1;
2234 	if (options->canonicalize_hostname == -1)
2235 		options->canonicalize_hostname = SSH_CANONICALISE_NO;
2236 	if (options->fingerprint_hash == -1)
2237 		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2238 	if (options->sk_provider == NULL)
2239 		options->sk_provider = xstrdup("internal");
2240 
2241 	/* Expand KEX name lists */
2242 	all_cipher = cipher_alg_list(',', 0);
2243 	all_mac = mac_alg_list(',');
2244 	all_kex = kex_alg_list(',');
2245 	all_key = sshkey_alg_list(0, 0, 1, ',');
2246 	all_sig = sshkey_alg_list(0, 1, 1, ',');
2247 	/* remove unsupported algos from default lists */
2248 	def_cipher = match_filter_allowlist(KEX_CLIENT_ENCRYPT, all_cipher);
2249 	def_mac = match_filter_allowlist(KEX_CLIENT_MAC, all_mac);
2250 	def_kex = match_filter_allowlist(KEX_CLIENT_KEX, all_kex);
2251 	def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
2252 	def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
2253 #define ASSEMBLE(what, defaults, all) \
2254 	do { \
2255 		if ((r = kex_assemble_names(&options->what, \
2256 		    defaults, all)) != 0) \
2257 			fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \
2258 	} while (0)
2259 	ASSEMBLE(ciphers, def_cipher, all_cipher);
2260 	ASSEMBLE(macs, def_mac, all_mac);
2261 	ASSEMBLE(kex_algorithms, def_kex, all_kex);
2262 	ASSEMBLE(hostbased_key_types, def_key, all_key);
2263 	ASSEMBLE(pubkey_key_types, def_key, all_key);
2264 	ASSEMBLE(ca_sign_algorithms, def_sig, all_sig);
2265 #undef ASSEMBLE
2266 	free(all_cipher);
2267 	free(all_mac);
2268 	free(all_kex);
2269 	free(all_key);
2270 	free(all_sig);
2271 	free(def_cipher);
2272 	free(def_mac);
2273 	free(def_kex);
2274 	kex_default_pk_alg_filtered = def_key; /* save for later use */
2275 	free(def_sig);
2276 
2277 #define CLEAR_ON_NONE(v) \
2278 	do { \
2279 		if (option_clear_or_none(v)) { \
2280 			free(v); \
2281 			v = NULL; \
2282 		} \
2283 	} while(0)
2284 	CLEAR_ON_NONE(options->local_command);
2285 	CLEAR_ON_NONE(options->remote_command);
2286 	CLEAR_ON_NONE(options->proxy_command);
2287 	CLEAR_ON_NONE(options->control_path);
2288 	CLEAR_ON_NONE(options->revoked_host_keys);
2289 	CLEAR_ON_NONE(options->pkcs11_provider);
2290 	CLEAR_ON_NONE(options->sk_provider);
2291 	if (options->jump_host != NULL &&
2292 	    strcmp(options->jump_host, "none") == 0 &&
2293 	    options->jump_port == 0 && options->jump_user == NULL) {
2294 		free(options->jump_host);
2295 		options->jump_host = NULL;
2296 	}
2297 	/* options->identity_agent distinguishes NULL from 'none' */
2298 	/* options->user will be set in the main program if appropriate */
2299 	/* options->hostname will be set in the main program if appropriate */
2300 	/* options->host_key_alias should not be set by default */
2301 	/* options->preferred_authentications will be set in ssh */
2302 }
2303 
2304 struct fwdarg {
2305 	char *arg;
2306 	int ispath;
2307 };
2308 
2309 /*
2310  * parse_fwd_field
2311  * parses the next field in a port forwarding specification.
2312  * sets fwd to the parsed field and advances p past the colon
2313  * or sets it to NULL at end of string.
2314  * returns 0 on success, else non-zero.
2315  */
2316 static int
2317 parse_fwd_field(char **p, struct fwdarg *fwd)
2318 {
2319 	char *ep, *cp = *p;
2320 	int ispath = 0;
2321 
2322 	if (*cp == '\0') {
2323 		*p = NULL;
2324 		return -1;	/* end of string */
2325 	}
2326 
2327 	/*
2328 	 * A field escaped with square brackets is used literally.
2329 	 * XXX - allow ']' to be escaped via backslash?
2330 	 */
2331 	if (*cp == '[') {
2332 		/* find matching ']' */
2333 		for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2334 			if (*ep == '/')
2335 				ispath = 1;
2336 		}
2337 		/* no matching ']' or not at end of field. */
2338 		if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2339 			return -1;
2340 		/* NUL terminate the field and advance p past the colon */
2341 		*ep++ = '\0';
2342 		if (*ep != '\0')
2343 			*ep++ = '\0';
2344 		fwd->arg = cp + 1;
2345 		fwd->ispath = ispath;
2346 		*p = ep;
2347 		return 0;
2348 	}
2349 
2350 	for (cp = *p; *cp != '\0'; cp++) {
2351 		switch (*cp) {
2352 		case '\\':
2353 			memmove(cp, cp + 1, strlen(cp + 1) + 1);
2354 			if (*cp == '\0')
2355 				return -1;
2356 			break;
2357 		case '/':
2358 			ispath = 1;
2359 			break;
2360 		case ':':
2361 			*cp++ = '\0';
2362 			goto done;
2363 		}
2364 	}
2365 done:
2366 	fwd->arg = *p;
2367 	fwd->ispath = ispath;
2368 	*p = cp;
2369 	return 0;
2370 }
2371 
2372 /*
2373  * parse_forward
2374  * parses a string containing a port forwarding specification of the form:
2375  *   dynamicfwd == 0
2376  *	[listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2377  *	listenpath:connectpath
2378  *   dynamicfwd == 1
2379  *	[listenhost:]listenport
2380  * returns number of arguments parsed or zero on error
2381  */
2382 int
2383 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2384 {
2385 	struct fwdarg fwdargs[4];
2386 	char *p, *cp;
2387 	int i, err;
2388 
2389 	memset(fwd, 0, sizeof(*fwd));
2390 	memset(fwdargs, 0, sizeof(fwdargs));
2391 
2392 	/*
2393 	 * We expand environment variables before checking if we think they're
2394 	 * paths so that if ${VAR} expands to a fully qualified path it is
2395 	 * treated as a path.
2396 	 */
2397 	cp = p = dollar_expand(&err, fwdspec);
2398 	if (p == NULL || err)
2399 		return 0;
2400 
2401 	/* skip leading spaces */
2402 	while (isspace((u_char)*cp))
2403 		cp++;
2404 
2405 	for (i = 0; i < 4; ++i) {
2406 		if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2407 			break;
2408 	}
2409 
2410 	/* Check for trailing garbage */
2411 	if (cp != NULL && *cp != '\0') {
2412 		i = 0;	/* failure */
2413 	}
2414 
2415 	switch (i) {
2416 	case 1:
2417 		if (fwdargs[0].ispath) {
2418 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2419 			fwd->listen_port = PORT_STREAMLOCAL;
2420 		} else {
2421 			fwd->listen_host = NULL;
2422 			fwd->listen_port = a2port(fwdargs[0].arg);
2423 		}
2424 		fwd->connect_host = xstrdup("socks");
2425 		break;
2426 
2427 	case 2:
2428 		if (fwdargs[0].ispath && fwdargs[1].ispath) {
2429 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2430 			fwd->listen_port = PORT_STREAMLOCAL;
2431 			fwd->connect_path = xstrdup(fwdargs[1].arg);
2432 			fwd->connect_port = PORT_STREAMLOCAL;
2433 		} else if (fwdargs[1].ispath) {
2434 			fwd->listen_host = NULL;
2435 			fwd->listen_port = a2port(fwdargs[0].arg);
2436 			fwd->connect_path = xstrdup(fwdargs[1].arg);
2437 			fwd->connect_port = PORT_STREAMLOCAL;
2438 		} else {
2439 			fwd->listen_host = xstrdup(fwdargs[0].arg);
2440 			fwd->listen_port = a2port(fwdargs[1].arg);
2441 			fwd->connect_host = xstrdup("socks");
2442 		}
2443 		break;
2444 
2445 	case 3:
2446 		if (fwdargs[0].ispath) {
2447 			fwd->listen_path = xstrdup(fwdargs[0].arg);
2448 			fwd->listen_port = PORT_STREAMLOCAL;
2449 			fwd->connect_host = xstrdup(fwdargs[1].arg);
2450 			fwd->connect_port = a2port(fwdargs[2].arg);
2451 		} else if (fwdargs[2].ispath) {
2452 			fwd->listen_host = xstrdup(fwdargs[0].arg);
2453 			fwd->listen_port = a2port(fwdargs[1].arg);
2454 			fwd->connect_path = xstrdup(fwdargs[2].arg);
2455 			fwd->connect_port = PORT_STREAMLOCAL;
2456 		} else {
2457 			fwd->listen_host = NULL;
2458 			fwd->listen_port = a2port(fwdargs[0].arg);
2459 			fwd->connect_host = xstrdup(fwdargs[1].arg);
2460 			fwd->connect_port = a2port(fwdargs[2].arg);
2461 		}
2462 		break;
2463 
2464 	case 4:
2465 		fwd->listen_host = xstrdup(fwdargs[0].arg);
2466 		fwd->listen_port = a2port(fwdargs[1].arg);
2467 		fwd->connect_host = xstrdup(fwdargs[2].arg);
2468 		fwd->connect_port = a2port(fwdargs[3].arg);
2469 		break;
2470 	default:
2471 		i = 0; /* failure */
2472 	}
2473 
2474 	free(p);
2475 
2476 	if (dynamicfwd) {
2477 		if (!(i == 1 || i == 2))
2478 			goto fail_free;
2479 	} else {
2480 		if (!(i == 3 || i == 4)) {
2481 			if (fwd->connect_path == NULL &&
2482 			    fwd->listen_path == NULL)
2483 				goto fail_free;
2484 		}
2485 		if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2486 			goto fail_free;
2487 	}
2488 
2489 	if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2490 	    (!remotefwd && fwd->listen_port == 0))
2491 		goto fail_free;
2492 	if (fwd->connect_host != NULL &&
2493 	    strlen(fwd->connect_host) >= NI_MAXHOST)
2494 		goto fail_free;
2495 	/* XXX - if connecting to a remote socket, max sun len may not match this host */
2496 	if (fwd->connect_path != NULL &&
2497 	    strlen(fwd->connect_path) >= PATH_MAX_SUN)
2498 		goto fail_free;
2499 	if (fwd->listen_host != NULL &&
2500 	    strlen(fwd->listen_host) >= NI_MAXHOST)
2501 		goto fail_free;
2502 	if (fwd->listen_path != NULL &&
2503 	    strlen(fwd->listen_path) >= PATH_MAX_SUN)
2504 		goto fail_free;
2505 
2506 	return (i);
2507 
2508  fail_free:
2509 	free(fwd->connect_host);
2510 	fwd->connect_host = NULL;
2511 	free(fwd->connect_path);
2512 	fwd->connect_path = NULL;
2513 	free(fwd->listen_host);
2514 	fwd->listen_host = NULL;
2515 	free(fwd->listen_path);
2516 	fwd->listen_path = NULL;
2517 	return (0);
2518 }
2519 
2520 int
2521 parse_jump(const char *s, Options *o, int active)
2522 {
2523 	char *orig, *sdup, *cp;
2524 	char *host = NULL, *user = NULL;
2525 	int ret = -1, port = -1, first;
2526 
2527 	active &= o->proxy_command == NULL && o->jump_host == NULL;
2528 
2529 	orig = sdup = xstrdup(s);
2530 	first = active;
2531 	do {
2532 		if (strcasecmp(s, "none") == 0)
2533 			break;
2534 		if ((cp = strrchr(sdup, ',')) == NULL)
2535 			cp = sdup; /* last */
2536 		else
2537 			*cp++ = '\0';
2538 
2539 		if (first) {
2540 			/* First argument and configuration is active */
2541 			if (parse_ssh_uri(cp, &user, &host, &port) == -1 ||
2542 			    parse_user_host_port(cp, &user, &host, &port) != 0)
2543 				goto out;
2544 		} else {
2545 			/* Subsequent argument or inactive configuration */
2546 			if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 ||
2547 			    parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2548 				goto out;
2549 		}
2550 		first = 0; /* only check syntax for subsequent hosts */
2551 	} while (cp != sdup);
2552 	/* success */
2553 	if (active) {
2554 		if (strcasecmp(s, "none") == 0) {
2555 			o->jump_host = xstrdup("none");
2556 			o->jump_port = 0;
2557 		} else {
2558 			o->jump_user = user;
2559 			o->jump_host = host;
2560 			o->jump_port = port;
2561 			o->proxy_command = xstrdup("none");
2562 			user = host = NULL;
2563 			if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2564 				o->jump_extra = xstrdup(s);
2565 				o->jump_extra[cp - s] = '\0';
2566 			}
2567 		}
2568 	}
2569 	ret = 0;
2570  out:
2571 	free(orig);
2572 	free(user);
2573 	free(host);
2574 	return ret;
2575 }
2576 
2577 int
2578 parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
2579 {
2580 	char *path;
2581 	int r;
2582 
2583 	r = parse_uri("ssh", uri, userp, hostp, portp, &path);
2584 	if (r == 0 && path != NULL)
2585 		r = -1;		/* path not allowed */
2586 	return r;
2587 }
2588 
2589 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2590 static const char *
2591 fmt_multistate_int(int val, const struct multistate *m)
2592 {
2593 	u_int i;
2594 
2595 	for (i = 0; m[i].key != NULL; i++) {
2596 		if (m[i].value == val)
2597 			return m[i].key;
2598 	}
2599 	return "UNKNOWN";
2600 }
2601 
2602 static const char *
2603 fmt_intarg(OpCodes code, int val)
2604 {
2605 	if (val == -1)
2606 		return "unset";
2607 	switch (code) {
2608 	case oAddressFamily:
2609 		return fmt_multistate_int(val, multistate_addressfamily);
2610 	case oVerifyHostKeyDNS:
2611 	case oUpdateHostkeys:
2612 		return fmt_multistate_int(val, multistate_yesnoask);
2613 	case oStrictHostKeyChecking:
2614 		return fmt_multistate_int(val, multistate_strict_hostkey);
2615 	case oControlMaster:
2616 		return fmt_multistate_int(val, multistate_controlmaster);
2617 	case oTunnel:
2618 		return fmt_multistate_int(val, multistate_tunnel);
2619 	case oRequestTTY:
2620 		return fmt_multistate_int(val, multistate_requesttty);
2621 	case oCanonicalizeHostname:
2622 		return fmt_multistate_int(val, multistate_canonicalizehostname);
2623 	case oAddKeysToAgent:
2624 		return fmt_multistate_int(val, multistate_yesnoaskconfirm);
2625 	case oFingerprintHash:
2626 		return ssh_digest_alg_name(val);
2627 	default:
2628 		switch (val) {
2629 		case 0:
2630 			return "no";
2631 		case 1:
2632 			return "yes";
2633 		default:
2634 			return "UNKNOWN";
2635 		}
2636 	}
2637 }
2638 
2639 static const char *
2640 lookup_opcode_name(OpCodes code)
2641 {
2642 	u_int i;
2643 
2644 	for (i = 0; keywords[i].name != NULL; i++)
2645 		if (keywords[i].opcode == code)
2646 			return(keywords[i].name);
2647 	return "UNKNOWN";
2648 }
2649 
2650 static void
2651 dump_cfg_int(OpCodes code, int val)
2652 {
2653 	printf("%s %d\n", lookup_opcode_name(code), val);
2654 }
2655 
2656 static void
2657 dump_cfg_fmtint(OpCodes code, int val)
2658 {
2659 	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2660 }
2661 
2662 static void
2663 dump_cfg_string(OpCodes code, const char *val)
2664 {
2665 	if (val == NULL)
2666 		return;
2667 	printf("%s %s\n", lookup_opcode_name(code), val);
2668 }
2669 
2670 static void
2671 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2672 {
2673 	u_int i;
2674 
2675 	for (i = 0; i < count; i++)
2676 		printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2677 }
2678 
2679 static void
2680 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2681 {
2682 	u_int i;
2683 
2684 	printf("%s", lookup_opcode_name(code));
2685 	for (i = 0; i < count; i++)
2686 		printf(" %s",  vals[i]);
2687 	printf("\n");
2688 }
2689 
2690 static void
2691 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2692 {
2693 	const struct Forward *fwd;
2694 	u_int i;
2695 
2696 	/* oDynamicForward */
2697 	for (i = 0; i < count; i++) {
2698 		fwd = &fwds[i];
2699 		if (code == oDynamicForward && fwd->connect_host != NULL &&
2700 		    strcmp(fwd->connect_host, "socks") != 0)
2701 			continue;
2702 		if (code == oLocalForward && fwd->connect_host != NULL &&
2703 		    strcmp(fwd->connect_host, "socks") == 0)
2704 			continue;
2705 		printf("%s", lookup_opcode_name(code));
2706 		if (fwd->listen_port == PORT_STREAMLOCAL)
2707 			printf(" %s", fwd->listen_path);
2708 		else if (fwd->listen_host == NULL)
2709 			printf(" %d", fwd->listen_port);
2710 		else {
2711 			printf(" [%s]:%d",
2712 			    fwd->listen_host, fwd->listen_port);
2713 		}
2714 		if (code != oDynamicForward) {
2715 			if (fwd->connect_port == PORT_STREAMLOCAL)
2716 				printf(" %s", fwd->connect_path);
2717 			else if (fwd->connect_host == NULL)
2718 				printf(" %d", fwd->connect_port);
2719 			else {
2720 				printf(" [%s]:%d",
2721 				    fwd->connect_host, fwd->connect_port);
2722 			}
2723 		}
2724 		printf("\n");
2725 	}
2726 }
2727 
2728 void
2729 dump_client_config(Options *o, const char *host)
2730 {
2731 	int i, r;
2732 	char buf[8], *all_key;
2733 
2734 	/*
2735 	 * Expand HostKeyAlgorithms name lists. This isn't handled in
2736 	 * fill_default_options() like the other algorithm lists because
2737 	 * the host key algorithms are by default dynamically chosen based
2738 	 * on the host's keys found in known_hosts.
2739 	 */
2740 	all_key = sshkey_alg_list(0, 0, 1, ',');
2741 	if ((r = kex_assemble_names(&o->hostkeyalgorithms, kex_default_pk_alg(),
2742 	    all_key)) != 0)
2743 		fatal("%s: expand HostKeyAlgorithms: %s", __func__, ssh_err(r));
2744 	free(all_key);
2745 
2746 	/* Most interesting options first: user, host, port */
2747 	dump_cfg_string(oUser, o->user);
2748 	dump_cfg_string(oHostname, host);
2749 	dump_cfg_int(oPort, o->port);
2750 
2751 	/* Flag options */
2752 	dump_cfg_fmtint(oAddressFamily, o->address_family);
2753 	dump_cfg_fmtint(oBatchMode, o->batch_mode);
2754 	dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2755 	dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2756 	dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2757 	dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2758 	dump_cfg_fmtint(oCompression, o->compression);
2759 	dump_cfg_fmtint(oControlMaster, o->control_master);
2760 	dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2761 	dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2762 	dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2763 	dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2764 	dump_cfg_fmtint(oForwardX11, o->forward_x11);
2765 	dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2766 	dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2767 #ifdef GSSAPI
2768 	dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2769 	dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2770 #endif /* GSSAPI */
2771 	dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2772 	dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2773 	dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2774 	dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2775 	dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2776 	dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2777 	dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2778 	dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2779 	dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2780 	dump_cfg_fmtint(oRequestTTY, o->request_tty);
2781 	dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2782 	dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2783 	dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2784 	dump_cfg_fmtint(oTunnel, o->tun_open);
2785 	dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2786 	dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2787 	dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2788 
2789 	/* Integer options */
2790 	dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2791 	dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2792 	dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2793 	dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2794 	dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2795 	dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2796 
2797 	/* String options */
2798 	dump_cfg_string(oBindAddress, o->bind_address);
2799 	dump_cfg_string(oBindInterface, o->bind_interface);
2800 	dump_cfg_string(oCiphers, o->ciphers);
2801 	dump_cfg_string(oControlPath, o->control_path);
2802 	dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2803 	dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2804 	dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2805 	dump_cfg_string(oIdentityAgent, o->identity_agent);
2806 	dump_cfg_string(oIgnoreUnknown, o->ignored_unknown);
2807 	dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2808 	dump_cfg_string(oKexAlgorithms, o->kex_algorithms);
2809 	dump_cfg_string(oCASignatureAlgorithms, o->ca_sign_algorithms);
2810 	dump_cfg_string(oLocalCommand, o->local_command);
2811 	dump_cfg_string(oRemoteCommand, o->remote_command);
2812 	dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2813 	dump_cfg_string(oMacs, o->macs);
2814 #ifdef ENABLE_PKCS11
2815 	dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2816 #endif
2817 	dump_cfg_string(oSecurityKeyProvider, o->sk_provider);
2818 	dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2819 	dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2820 	dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2821 	dump_cfg_string(oXAuthLocation, o->xauth_location);
2822 
2823 	/* Forwards */
2824 	dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2825 	dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2826 	dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2827 
2828 	/* String array options */
2829 	dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2830 	dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2831 	dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files);
2832 	dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2833 	dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2834 	dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2835 	dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv);
2836 	dump_cfg_strarray_oneline(oLogVerbose,
2837 	    o->num_log_verbose, o->log_verbose);
2838 
2839 	/* Special cases */
2840 
2841 	/* AddKeysToAgent */
2842 	if (o->add_keys_to_agent_lifespan <= 0)
2843 		dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
2844 	else {
2845 		printf("addkeystoagent%s %d\n",
2846 		    o->add_keys_to_agent == 3 ? " confirm" : "",
2847 		    o->add_keys_to_agent_lifespan);
2848 	}
2849 
2850 	/* oForwardAgent */
2851 	if (o->forward_agent_sock_path == NULL)
2852 		dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2853 	else
2854 		dump_cfg_string(oForwardAgent, o->forward_agent_sock_path);
2855 
2856 	/* oConnectTimeout */
2857 	if (o->connection_timeout == -1)
2858 		printf("connecttimeout none\n");
2859 	else
2860 		dump_cfg_int(oConnectTimeout, o->connection_timeout);
2861 
2862 	/* oTunnelDevice */
2863 	printf("tunneldevice");
2864 	if (o->tun_local == SSH_TUNID_ANY)
2865 		printf(" any");
2866 	else
2867 		printf(" %d", o->tun_local);
2868 	if (o->tun_remote == SSH_TUNID_ANY)
2869 		printf(":any");
2870 	else
2871 		printf(":%d", o->tun_remote);
2872 	printf("\n");
2873 
2874 	/* oCanonicalizePermittedCNAMEs */
2875 	if ( o->num_permitted_cnames > 0) {
2876 		printf("canonicalizePermittedcnames");
2877 		for (i = 0; i < o->num_permitted_cnames; i++) {
2878 			printf(" %s:%s", o->permitted_cnames[i].source_list,
2879 			    o->permitted_cnames[i].target_list);
2880 		}
2881 		printf("\n");
2882 	}
2883 
2884 	/* oControlPersist */
2885 	if (o->control_persist == 0 || o->control_persist_timeout == 0)
2886 		dump_cfg_fmtint(oControlPersist, o->control_persist);
2887 	else
2888 		dump_cfg_int(oControlPersist, o->control_persist_timeout);
2889 
2890 	/* oEscapeChar */
2891 	if (o->escape_char == SSH_ESCAPECHAR_NONE)
2892 		printf("escapechar none\n");
2893 	else {
2894 		vis(buf, o->escape_char, VIS_WHITE, 0);
2895 		printf("escapechar %s\n", buf);
2896 	}
2897 
2898 	/* oIPQoS */
2899 	printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2900 	printf("%s\n", iptos2str(o->ip_qos_bulk));
2901 
2902 	/* oRekeyLimit */
2903 	printf("rekeylimit %llu %d\n",
2904 	    (unsigned long long)o->rekey_limit, o->rekey_interval);
2905 
2906 	/* oStreamLocalBindMask */
2907 	printf("streamlocalbindmask 0%o\n",
2908 	    o->fwd_opts.streamlocal_bind_mask);
2909 
2910 	/* oLogFacility */
2911 	printf("syslogfacility %s\n", log_facility_name(o->log_facility));
2912 
2913 	/* oProxyCommand / oProxyJump */
2914 	if (o->jump_host == NULL)
2915 		dump_cfg_string(oProxyCommand, o->proxy_command);
2916 	else {
2917 		/* Check for numeric addresses */
2918 		i = strchr(o->jump_host, ':') != NULL ||
2919 		    strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2920 		snprintf(buf, sizeof(buf), "%d", o->jump_port);
2921 		printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2922 		    /* optional additional jump spec */
2923 		    o->jump_extra == NULL ? "" : o->jump_extra,
2924 		    o->jump_extra == NULL ? "" : ",",
2925 		    /* optional user */
2926 		    o->jump_user == NULL ? "" : o->jump_user,
2927 		    o->jump_user == NULL ? "" : "@",
2928 		    /* opening [ if hostname is numeric */
2929 		    i ? "[" : "",
2930 		    /* mandatory hostname */
2931 		    o->jump_host,
2932 		    /* closing ] if hostname is numeric */
2933 		    i ? "]" : "",
2934 		    /* optional port number */
2935 		    o->jump_port <= 0 ? "" : ":",
2936 		    o->jump_port <= 0 ? "" : buf);
2937 	}
2938 }
2939