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