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