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