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