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