readconf.c revision 294666
1/* $OpenBSD: readconf.c,v 1.218 2014/02/23 20:11:36 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 294666 2016-01-24 15:44:57Z 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
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 <netdb.h>
33#ifdef HAVE_PATHS_H
34# include <paths.h>
35#endif
36#include <pwd.h>
37#include <signal.h>
38#include <stdarg.h>
39#include <stdio.h>
40#include <string.h>
41#include <unistd.h>
42#ifdef HAVE_UTIL_H
43#include <util.h>
44#endif
45
46#include "xmalloc.h"
47#include "ssh.h"
48#include "compat.h"
49#include "cipher.h"
50#include "pathnames.h"
51#include "log.h"
52#include "key.h"
53#include "readconf.h"
54#include "match.h"
55#include "misc.h"
56#include "buffer.h"
57#include "kex.h"
58#include "mac.h"
59#include "uidswap.h"
60#include "version.h"
61
62/* Format of the configuration file:
63
64   # Configuration data is parsed as follows:
65   #  1. command line options
66   #  2. user-specific file
67   #  3. system-wide file
68   # Any configuration value is only changed the first time it is set.
69   # Thus, host-specific definitions should be at the beginning of the
70   # configuration file, and defaults at the end.
71
72   # Host-specific declarations.  These may override anything above.  A single
73   # host may match multiple declarations; these are processed in the order
74   # that they are given in.
75
76   Host *.ngs.fi ngs.fi
77     User foo
78
79   Host fake.com
80     HostName another.host.name.real.org
81     User blaah
82     Port 34289
83     ForwardX11 no
84     ForwardAgent no
85
86   Host books.com
87     RemoteForward 9999 shadows.cs.hut.fi:9999
88     Cipher 3des
89
90   Host fascist.blob.com
91     Port 23123
92     User tylonen
93     PasswordAuthentication no
94
95   Host puukko.hut.fi
96     User t35124p
97     ProxyCommand ssh-proxy %h %p
98
99   Host *.fr
100     PublicKeyAuthentication no
101
102   Host *.su
103     Cipher none
104     PasswordAuthentication no
105
106   Host vpn.fake.com
107     Tunnel yes
108     TunnelDevice 3
109
110   # Defaults for various options
111   Host *
112     ForwardAgent no
113     ForwardX11 no
114     PasswordAuthentication yes
115     RSAAuthentication yes
116     RhostsRSAAuthentication yes
117     StrictHostKeyChecking yes
118     TcpKeepAlive no
119     IdentityFile ~/.ssh/identity
120     Port 22
121     EscapeChar ~
122
123*/
124
125/* Keyword tokens. */
126
127typedef enum {
128	oBadOption,
129	oHost, oMatch,
130	oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
131	oGatewayPorts, oExitOnForwardFailure,
132	oPasswordAuthentication, oRSAAuthentication,
133	oChallengeResponseAuthentication, oXAuthLocation,
134	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
135	oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
136	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
137	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
138	oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
139	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
140	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
141	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
142	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
143	oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
144	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
145	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
146	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
147	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
148	oSendEnv, oControlPath, oControlMaster, oControlPersist,
149	oHashKnownHosts,
150	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
151	oVisualHostKey, oUseRoaming,
152	oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
153	oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
154	oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
155	oIgnoredUnknownOption,
156	oHPNDisabled, oHPNBufferSize, oTcpRcvBufPoll, oTcpRcvBuf,
157#ifdef NONE_CIPHER_ENABLED
158	oNoneEnabled, oNoneSwitch,
159#endif
160	oVersionAddendum, oDeprecated, oUnsupported
161} OpCodes;
162
163/* Textual representations of the tokens. */
164
165static struct {
166	const char *name;
167	OpCodes opcode;
168} keywords[] = {
169	{ "forwardagent", oForwardAgent },
170	{ "forwardx11", oForwardX11 },
171	{ "forwardx11trusted", oForwardX11Trusted },
172	{ "forwardx11timeout", oForwardX11Timeout },
173	{ "exitonforwardfailure", oExitOnForwardFailure },
174	{ "xauthlocation", oXAuthLocation },
175	{ "gatewayports", oGatewayPorts },
176	{ "useprivilegedport", oUsePrivilegedPort },
177	{ "rhostsauthentication", oDeprecated },
178	{ "passwordauthentication", oPasswordAuthentication },
179	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
180	{ "kbdinteractivedevices", oKbdInteractiveDevices },
181	{ "rsaauthentication", oRSAAuthentication },
182	{ "pubkeyauthentication", oPubkeyAuthentication },
183	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
184	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
185	{ "hostbasedauthentication", oHostbasedAuthentication },
186	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
187	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
188	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
189	{ "kerberosauthentication", oUnsupported },
190	{ "kerberostgtpassing", oUnsupported },
191	{ "afstokenpassing", oUnsupported },
192#if defined(GSSAPI)
193	{ "gssapiauthentication", oGssAuthentication },
194	{ "gssapidelegatecredentials", oGssDelegateCreds },
195#else
196	{ "gssapiauthentication", oUnsupported },
197	{ "gssapidelegatecredentials", oUnsupported },
198#endif
199	{ "fallbacktorsh", oDeprecated },
200	{ "usersh", oDeprecated },
201	{ "identityfile", oIdentityFile },
202	{ "identityfile2", oIdentityFile },			/* obsolete */
203	{ "identitiesonly", oIdentitiesOnly },
204	{ "hostname", oHostName },
205	{ "hostkeyalias", oHostKeyAlias },
206	{ "proxycommand", oProxyCommand },
207	{ "port", oPort },
208	{ "cipher", oCipher },
209	{ "ciphers", oCiphers },
210	{ "macs", oMacs },
211	{ "protocol", oProtocol },
212	{ "remoteforward", oRemoteForward },
213	{ "localforward", oLocalForward },
214	{ "user", oUser },
215	{ "host", oHost },
216	{ "match", oMatch },
217	{ "escapechar", oEscapeChar },
218	{ "globalknownhostsfile", oGlobalKnownHostsFile },
219	{ "globalknownhostsfile2", oDeprecated },
220	{ "userknownhostsfile", oUserKnownHostsFile },
221	{ "userknownhostsfile2", oDeprecated },
222	{ "connectionattempts", oConnectionAttempts },
223	{ "batchmode", oBatchMode },
224	{ "checkhostip", oCheckHostIP },
225	{ "stricthostkeychecking", oStrictHostKeyChecking },
226	{ "compression", oCompression },
227	{ "compressionlevel", oCompressionLevel },
228	{ "tcpkeepalive", oTCPKeepAlive },
229	{ "keepalive", oTCPKeepAlive },				/* obsolete */
230	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
231	{ "loglevel", oLogLevel },
232	{ "dynamicforward", oDynamicForward },
233	{ "preferredauthentications", oPreferredAuthentications },
234	{ "hostkeyalgorithms", oHostKeyAlgorithms },
235	{ "bindaddress", oBindAddress },
236#ifdef ENABLE_PKCS11
237	{ "smartcarddevice", oPKCS11Provider },
238	{ "pkcs11provider", oPKCS11Provider },
239#else
240	{ "smartcarddevice", oUnsupported },
241	{ "pkcs11provider", oUnsupported },
242#endif
243	{ "clearallforwardings", oClearAllForwardings },
244	{ "enablesshkeysign", oEnableSSHKeysign },
245	{ "verifyhostkeydns", oVerifyHostKeyDNS },
246	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
247	{ "rekeylimit", oRekeyLimit },
248	{ "connecttimeout", oConnectTimeout },
249	{ "addressfamily", oAddressFamily },
250	{ "serveraliveinterval", oServerAliveInterval },
251	{ "serveralivecountmax", oServerAliveCountMax },
252	{ "sendenv", oSendEnv },
253	{ "controlpath", oControlPath },
254	{ "controlmaster", oControlMaster },
255	{ "controlpersist", oControlPersist },
256	{ "hashknownhosts", oHashKnownHosts },
257	{ "tunnel", oTunnel },
258	{ "tunneldevice", oTunnelDevice },
259	{ "localcommand", oLocalCommand },
260	{ "permitlocalcommand", oPermitLocalCommand },
261	{ "visualhostkey", oVisualHostKey },
262	{ "useroaming", oUseRoaming },
263	{ "kexalgorithms", oKexAlgorithms },
264	{ "ipqos", oIPQoS },
265	{ "requesttty", oRequestTTY },
266	{ "proxyusefdpass", oProxyUseFdpass },
267	{ "canonicaldomains", oCanonicalDomains },
268	{ "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
269	{ "canonicalizehostname", oCanonicalizeHostname },
270	{ "canonicalizemaxdots", oCanonicalizeMaxDots },
271	{ "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
272	{ "ignoreunknown", oIgnoreUnknown },
273	{ "hpndisabled", oHPNDisabled },
274	{ "hpnbuffersize", oHPNBufferSize },
275	{ "tcprcvbufpoll", oTcpRcvBufPoll },
276	{ "tcprcvbuf", oTcpRcvBuf },
277#ifdef	NONE_CIPHER_ENABLED
278	{ "noneenabled", oNoneEnabled },
279	{ "noneswitch", oNoneSwitch },
280#endif
281	{ "versionaddendum", oVersionAddendum },
282
283	{ NULL, oBadOption }
284};
285
286/*
287 * Adds a local TCP/IP port forward to options.  Never returns if there is an
288 * error.
289 */
290
291void
292add_local_forward(Options *options, const Forward *newfwd)
293{
294	Forward *fwd;
295#ifndef NO_IPPORT_RESERVED_CONCEPT
296	extern uid_t original_real_uid;
297	int ipport_reserved;
298#ifdef __FreeBSD__
299	size_t len_ipport_reserved = sizeof(ipport_reserved);
300
301	if (sysctlbyname("net.inet.ip.portrange.reservedhigh",
302	    &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0)
303		ipport_reserved = IPPORT_RESERVED;
304	else
305		ipport_reserved++;
306#else
307	ipport_reserved = IPPORT_RESERVED;
308#endif
309	if (newfwd->listen_port < ipport_reserved && original_real_uid != 0)
310		fatal("Privileged ports can only be forwarded by root.");
311#endif
312	options->local_forwards = xrealloc(options->local_forwards,
313	    options->num_local_forwards + 1,
314	    sizeof(*options->local_forwards));
315	fwd = &options->local_forwards[options->num_local_forwards++];
316
317	fwd->listen_host = newfwd->listen_host;
318	fwd->listen_port = newfwd->listen_port;
319	fwd->connect_host = newfwd->connect_host;
320	fwd->connect_port = newfwd->connect_port;
321}
322
323/*
324 * Adds a remote TCP/IP port forward to options.  Never returns if there is
325 * an error.
326 */
327
328void
329add_remote_forward(Options *options, const Forward *newfwd)
330{
331	Forward *fwd;
332
333	options->remote_forwards = xrealloc(options->remote_forwards,
334	    options->num_remote_forwards + 1,
335	    sizeof(*options->remote_forwards));
336	fwd = &options->remote_forwards[options->num_remote_forwards++];
337
338	fwd->listen_host = newfwd->listen_host;
339	fwd->listen_port = newfwd->listen_port;
340	fwd->connect_host = newfwd->connect_host;
341	fwd->connect_port = newfwd->connect_port;
342	fwd->handle = newfwd->handle;
343	fwd->allocated_port = 0;
344}
345
346static void
347clear_forwardings(Options *options)
348{
349	int i;
350
351	for (i = 0; i < options->num_local_forwards; i++) {
352		free(options->local_forwards[i].listen_host);
353		free(options->local_forwards[i].connect_host);
354	}
355	if (options->num_local_forwards > 0) {
356		free(options->local_forwards);
357		options->local_forwards = NULL;
358	}
359	options->num_local_forwards = 0;
360	for (i = 0; i < options->num_remote_forwards; i++) {
361		free(options->remote_forwards[i].listen_host);
362		free(options->remote_forwards[i].connect_host);
363	}
364	if (options->num_remote_forwards > 0) {
365		free(options->remote_forwards);
366		options->remote_forwards = NULL;
367	}
368	options->num_remote_forwards = 0;
369	options->tun_open = SSH_TUNMODE_NO;
370}
371
372void
373add_identity_file(Options *options, const char *dir, const char *filename,
374    int userprovided)
375{
376	char *path;
377
378	if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
379		fatal("Too many identity files specified (max %d)",
380		    SSH_MAX_IDENTITY_FILES);
381
382	if (dir == NULL) /* no dir, filename is absolute */
383		path = xstrdup(filename);
384	else
385		(void)xasprintf(&path, "%.100s%.100s", dir, filename);
386
387	options->identity_file_userprovided[options->num_identity_files] =
388	    userprovided;
389	options->identity_files[options->num_identity_files++] = path;
390}
391
392int
393default_ssh_port(void)
394{
395	static int port;
396	struct servent *sp;
397
398	if (port == 0) {
399		sp = getservbyname(SSH_SERVICE_NAME, "tcp");
400		port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
401	}
402	return port;
403}
404
405/*
406 * Execute a command in a shell.
407 * Return its exit status or -1 on abnormal exit.
408 */
409static int
410execute_in_shell(const char *cmd)
411{
412	char *shell, *command_string;
413	pid_t pid;
414	int devnull, status;
415	extern uid_t original_real_uid;
416
417	if ((shell = getenv("SHELL")) == NULL)
418		shell = _PATH_BSHELL;
419
420	/*
421	 * Use "exec" to avoid "sh -c" processes on some platforms
422	 * (e.g. Solaris)
423	 */
424	xasprintf(&command_string, "exec %s", cmd);
425
426	/* Need this to redirect subprocess stdin/out */
427	if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
428		fatal("open(/dev/null): %s", strerror(errno));
429
430	debug("Executing command: '%.500s'", cmd);
431
432	/* Fork and execute the command. */
433	if ((pid = fork()) == 0) {
434		char *argv[4];
435
436		/* Child.  Permanently give up superuser privileges. */
437		permanently_drop_suid(original_real_uid);
438
439		/* Redirect child stdin and stdout. Leave stderr */
440		if (dup2(devnull, STDIN_FILENO) == -1)
441			fatal("dup2: %s", strerror(errno));
442		if (dup2(devnull, STDOUT_FILENO) == -1)
443			fatal("dup2: %s", strerror(errno));
444		if (devnull > STDERR_FILENO)
445			close(devnull);
446		closefrom(STDERR_FILENO + 1);
447
448		argv[0] = shell;
449		argv[1] = "-c";
450		argv[2] = command_string;
451		argv[3] = NULL;
452
453		execv(argv[0], argv);
454		error("Unable to execute '%.100s': %s", cmd, strerror(errno));
455		/* Die with signal to make this error apparent to parent. */
456		signal(SIGTERM, SIG_DFL);
457		kill(getpid(), SIGTERM);
458		_exit(1);
459	}
460	/* Parent. */
461	if (pid < 0)
462		fatal("%s: fork: %.100s", __func__, strerror(errno));
463
464	close(devnull);
465	free(command_string);
466
467	while (waitpid(pid, &status, 0) == -1) {
468		if (errno != EINTR && errno != EAGAIN)
469			fatal("%s: waitpid: %s", __func__, strerror(errno));
470	}
471	if (!WIFEXITED(status)) {
472		error("command '%.100s' exited abnormally", cmd);
473		return -1;
474	}
475	debug3("command returned status %d", WEXITSTATUS(status));
476	return WEXITSTATUS(status);
477}
478
479/*
480 * Parse and execute a Match directive.
481 */
482static int
483match_cfg_line(Options *options, char **condition, struct passwd *pw,
484    const char *host_arg, const char *filename, int linenum)
485{
486	char *arg, *attrib, *cmd, *cp = *condition, *host;
487	const char *ruser;
488	int r, port, result = 1, attributes = 0;
489	size_t len;
490	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
491
492	/*
493	 * Configuration is likely to be incomplete at this point so we
494	 * must be prepared to use default values.
495	 */
496	port = options->port <= 0 ? default_ssh_port() : options->port;
497	ruser = options->user == NULL ? pw->pw_name : options->user;
498	if (options->hostname != NULL) {
499		/* NB. Please keep in sync with ssh.c:main() */
500		host = percent_expand(options->hostname,
501		    "h", host_arg, (char *)NULL);
502	} else
503		host = xstrdup(host_arg);
504
505	debug3("checking match for '%s' host %s", cp, host);
506	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
507		attributes++;
508		if (strcasecmp(attrib, "all") == 0) {
509			if (attributes != 1 ||
510			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
511				error("'all' cannot be combined with other "
512				    "Match attributes");
513				result = -1;
514				goto out;
515			}
516			*condition = cp;
517			result = 1;
518			goto out;
519		}
520		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
521			error("Missing Match criteria for %s", attrib);
522			result = -1;
523			goto out;
524		}
525		len = strlen(arg);
526		if (strcasecmp(attrib, "host") == 0) {
527			if (match_hostname(host, arg, len) != 1)
528				result = 0;
529			else
530				debug("%.200s line %d: matched 'Host %.100s' ",
531				    filename, linenum, host);
532		} else if (strcasecmp(attrib, "originalhost") == 0) {
533			if (match_hostname(host_arg, arg, len) != 1)
534				result = 0;
535			else
536				debug("%.200s line %d: matched "
537				    "'OriginalHost %.100s' ",
538				    filename, linenum, host_arg);
539		} else if (strcasecmp(attrib, "user") == 0) {
540			if (match_pattern_list(ruser, arg, len, 0) != 1)
541				result = 0;
542			else
543				debug("%.200s line %d: matched 'User %.100s' ",
544				    filename, linenum, ruser);
545		} else if (strcasecmp(attrib, "localuser") == 0) {
546			if (match_pattern_list(pw->pw_name, arg, len, 0) != 1)
547				result = 0;
548			else
549				debug("%.200s line %d: matched "
550				    "'LocalUser %.100s' ",
551				    filename, linenum, pw->pw_name);
552		} else if (strcasecmp(attrib, "exec") == 0) {
553			if (gethostname(thishost, sizeof(thishost)) == -1)
554				fatal("gethostname: %s", strerror(errno));
555			strlcpy(shorthost, thishost, sizeof(shorthost));
556			shorthost[strcspn(thishost, ".")] = '\0';
557			snprintf(portstr, sizeof(portstr), "%d", port);
558
559			cmd = percent_expand(arg,
560			    "L", shorthost,
561			    "d", pw->pw_dir,
562			    "h", host,
563			    "l", thishost,
564			    "n", host_arg,
565			    "p", portstr,
566			    "r", ruser,
567			    "u", pw->pw_name,
568			    (char *)NULL);
569			if (result != 1) {
570				/* skip execution if prior predicate failed */
571				debug("%.200s line %d: skipped exec \"%.100s\"",
572				    filename, linenum, cmd);
573			} else {
574				r = execute_in_shell(cmd);
575				if (r == -1) {
576					fatal("%.200s line %d: match exec "
577					    "'%.100s' error", filename,
578					    linenum, cmd);
579				} else if (r == 0) {
580					debug("%.200s line %d: matched "
581					    "'exec \"%.100s\"'", filename,
582					    linenum, cmd);
583				} else {
584					debug("%.200s line %d: no match "
585					    "'exec \"%.100s\"'", filename,
586					    linenum, cmd);
587					result = 0;
588				}
589			}
590			free(cmd);
591		} else {
592			error("Unsupported Match attribute %s", attrib);
593			result = -1;
594			goto out;
595		}
596	}
597	if (attributes == 0) {
598		error("One or more attributes required for Match");
599		result = -1;
600		goto out;
601	}
602	debug3("match %sfound", result ? "" : "not ");
603	*condition = cp;
604 out:
605	free(host);
606	return result;
607}
608
609/* Check and prepare a domain name: removes trailing '.' and lowercases */
610static void
611valid_domain(char *name, const char *filename, int linenum)
612{
613	size_t i, l = strlen(name);
614	u_char c, last = '\0';
615
616	if (l == 0)
617		fatal("%s line %d: empty hostname suffix", filename, linenum);
618	if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
619		fatal("%s line %d: hostname suffix \"%.100s\" "
620		    "starts with invalid character", filename, linenum, name);
621	for (i = 0; i < l; i++) {
622		c = tolower((u_char)name[i]);
623		name[i] = (char)c;
624		if (last == '.' && c == '.')
625			fatal("%s line %d: hostname suffix \"%.100s\" contains "
626			    "consecutive separators", filename, linenum, name);
627		if (c != '.' && c != '-' && !isalnum(c) &&
628		    c != '_') /* technically invalid, but common */
629			fatal("%s line %d: hostname suffix \"%.100s\" contains "
630			    "invalid characters", filename, linenum, name);
631		last = c;
632	}
633	if (name[l - 1] == '.')
634		name[l - 1] = '\0';
635}
636
637/*
638 * Returns the number of the token pointed to by cp or oBadOption.
639 */
640static OpCodes
641parse_token(const char *cp, const char *filename, int linenum,
642    const char *ignored_unknown)
643{
644	int i;
645
646	for (i = 0; keywords[i].name; i++)
647		if (strcmp(cp, keywords[i].name) == 0)
648			return keywords[i].opcode;
649	if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown,
650	    strlen(ignored_unknown), 1) == 1)
651		return oIgnoredUnknownOption;
652	error("%s: line %d: Bad configuration option: %s",
653	    filename, linenum, cp);
654	return oBadOption;
655}
656
657/* Multistate option parsing */
658struct multistate {
659	char *key;
660	int value;
661};
662static const struct multistate multistate_flag[] = {
663	{ "true",			1 },
664	{ "false",			0 },
665	{ "yes",			1 },
666	{ "no",				0 },
667	{ NULL, -1 }
668};
669static const struct multistate multistate_yesnoask[] = {
670	{ "true",			1 },
671	{ "false",			0 },
672	{ "yes",			1 },
673	{ "no",				0 },
674	{ "ask",			2 },
675	{ NULL, -1 }
676};
677static const struct multistate multistate_addressfamily[] = {
678	{ "inet",			AF_INET },
679	{ "inet6",			AF_INET6 },
680	{ "any",			AF_UNSPEC },
681	{ NULL, -1 }
682};
683static const struct multistate multistate_controlmaster[] = {
684	{ "true",			SSHCTL_MASTER_YES },
685	{ "yes",			SSHCTL_MASTER_YES },
686	{ "false",			SSHCTL_MASTER_NO },
687	{ "no",				SSHCTL_MASTER_NO },
688	{ "auto",			SSHCTL_MASTER_AUTO },
689	{ "ask",			SSHCTL_MASTER_ASK },
690	{ "autoask",			SSHCTL_MASTER_AUTO_ASK },
691	{ NULL, -1 }
692};
693static const struct multistate multistate_tunnel[] = {
694	{ "ethernet",			SSH_TUNMODE_ETHERNET },
695	{ "point-to-point",		SSH_TUNMODE_POINTOPOINT },
696	{ "true",			SSH_TUNMODE_DEFAULT },
697	{ "yes",			SSH_TUNMODE_DEFAULT },
698	{ "false",			SSH_TUNMODE_NO },
699	{ "no",				SSH_TUNMODE_NO },
700	{ NULL, -1 }
701};
702static const struct multistate multistate_requesttty[] = {
703	{ "true",			REQUEST_TTY_YES },
704	{ "yes",			REQUEST_TTY_YES },
705	{ "false",			REQUEST_TTY_NO },
706	{ "no",				REQUEST_TTY_NO },
707	{ "force",			REQUEST_TTY_FORCE },
708	{ "auto",			REQUEST_TTY_AUTO },
709	{ NULL, -1 }
710};
711static const struct multistate multistate_canonicalizehostname[] = {
712	{ "true",			SSH_CANONICALISE_YES },
713	{ "false",			SSH_CANONICALISE_NO },
714	{ "yes",			SSH_CANONICALISE_YES },
715	{ "no",				SSH_CANONICALISE_NO },
716	{ "always",			SSH_CANONICALISE_ALWAYS },
717	{ NULL, -1 }
718};
719
720/*
721 * Processes a single option line as used in the configuration files. This
722 * only sets those values that have not already been set.
723 */
724#define WHITESPACE " \t\r\n"
725int
726process_config_line(Options *options, struct passwd *pw, const char *host,
727    char *line, const char *filename, int linenum, int *activep, int userconfig)
728{
729	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
730	char **cpptr, fwdarg[256];
731	u_int i, *uintptr, max_entries = 0;
732	int negated, opcode, *intptr, value, value2, cmdline = 0;
733	LogLevel *log_level_ptr;
734	long long val64;
735	size_t len;
736	Forward fwd;
737	const struct multistate *multistate_ptr;
738	struct allowed_cname *cname;
739
740	if (activep == NULL) { /* We are processing a command line directive */
741		cmdline = 1;
742		activep = &cmdline;
743	}
744
745	/* Strip trailing whitespace */
746	for (len = strlen(line) - 1; len > 0; len--) {
747		if (strchr(WHITESPACE, line[len]) == NULL)
748			break;
749		line[len] = '\0';
750	}
751
752	s = line;
753	/* Get the keyword. (Each line is supposed to begin with a keyword). */
754	if ((keyword = strdelim(&s)) == NULL)
755		return 0;
756	/* Ignore leading whitespace. */
757	if (*keyword == '\0')
758		keyword = strdelim(&s);
759	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
760		return 0;
761	/* Match lowercase keyword */
762	lowercase(keyword);
763
764	opcode = parse_token(keyword, filename, linenum,
765	    options->ignored_unknown);
766
767	switch (opcode) {
768	case oBadOption:
769		/* don't panic, but count bad options */
770		return -1;
771		/* NOTREACHED */
772	case oIgnoredUnknownOption:
773		debug("%s line %d: Ignored unknown option \"%s\"",
774		    filename, linenum, keyword);
775		return 0;
776	case oConnectTimeout:
777		intptr = &options->connection_timeout;
778parse_time:
779		arg = strdelim(&s);
780		if (!arg || *arg == '\0')
781			fatal("%s line %d: missing time value.",
782			    filename, linenum);
783		if ((value = convtime(arg)) == -1)
784			fatal("%s line %d: invalid time value.",
785			    filename, linenum);
786		if (*activep && *intptr == -1)
787			*intptr = value;
788		break;
789
790	case oForwardAgent:
791		intptr = &options->forward_agent;
792 parse_flag:
793		multistate_ptr = multistate_flag;
794 parse_multistate:
795		arg = strdelim(&s);
796		if (!arg || *arg == '\0')
797			fatal("%s line %d: missing argument.",
798			    filename, linenum);
799		value = -1;
800		for (i = 0; multistate_ptr[i].key != NULL; i++) {
801			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
802				value = multistate_ptr[i].value;
803				break;
804			}
805		}
806		if (value == -1)
807			fatal("%s line %d: unsupported option \"%s\".",
808			    filename, linenum, arg);
809		if (*activep && *intptr == -1)
810			*intptr = value;
811		break;
812
813	case oForwardX11:
814		intptr = &options->forward_x11;
815		goto parse_flag;
816
817	case oForwardX11Trusted:
818		intptr = &options->forward_x11_trusted;
819		goto parse_flag;
820
821	case oForwardX11Timeout:
822		intptr = &options->forward_x11_timeout;
823		goto parse_time;
824
825	case oGatewayPorts:
826		intptr = &options->gateway_ports;
827		goto parse_flag;
828
829	case oExitOnForwardFailure:
830		intptr = &options->exit_on_forward_failure;
831		goto parse_flag;
832
833	case oUsePrivilegedPort:
834		intptr = &options->use_privileged_port;
835		goto parse_flag;
836
837	case oPasswordAuthentication:
838		intptr = &options->password_authentication;
839		goto parse_flag;
840
841	case oKbdInteractiveAuthentication:
842		intptr = &options->kbd_interactive_authentication;
843		goto parse_flag;
844
845	case oKbdInteractiveDevices:
846		charptr = &options->kbd_interactive_devices;
847		goto parse_string;
848
849	case oPubkeyAuthentication:
850		intptr = &options->pubkey_authentication;
851		goto parse_flag;
852
853	case oRSAAuthentication:
854		intptr = &options->rsa_authentication;
855		goto parse_flag;
856
857	case oRhostsRSAAuthentication:
858		intptr = &options->rhosts_rsa_authentication;
859		goto parse_flag;
860
861	case oHostbasedAuthentication:
862		intptr = &options->hostbased_authentication;
863		goto parse_flag;
864
865	case oChallengeResponseAuthentication:
866		intptr = &options->challenge_response_authentication;
867		goto parse_flag;
868
869	case oGssAuthentication:
870		intptr = &options->gss_authentication;
871		goto parse_flag;
872
873	case oGssDelegateCreds:
874		intptr = &options->gss_deleg_creds;
875		goto parse_flag;
876
877	case oBatchMode:
878		intptr = &options->batch_mode;
879		goto parse_flag;
880
881	case oCheckHostIP:
882		intptr = &options->check_host_ip;
883		goto parse_flag;
884
885	case oVerifyHostKeyDNS:
886		intptr = &options->verify_host_key_dns;
887		multistate_ptr = multistate_yesnoask;
888		goto parse_multistate;
889
890	case oStrictHostKeyChecking:
891		intptr = &options->strict_host_key_checking;
892		multistate_ptr = multistate_yesnoask;
893		goto parse_multistate;
894
895	case oCompression:
896		intptr = &options->compression;
897		goto parse_flag;
898
899	case oTCPKeepAlive:
900		intptr = &options->tcp_keep_alive;
901		goto parse_flag;
902
903	case oNoHostAuthenticationForLocalhost:
904		intptr = &options->no_host_authentication_for_localhost;
905		goto parse_flag;
906
907	case oNumberOfPasswordPrompts:
908		intptr = &options->number_of_password_prompts;
909		goto parse_int;
910
911	case oCompressionLevel:
912		intptr = &options->compression_level;
913		goto parse_int;
914
915	case oRekeyLimit:
916		arg = strdelim(&s);
917		if (!arg || *arg == '\0')
918			fatal("%.200s line %d: Missing argument.", filename,
919			    linenum);
920		if (strcmp(arg, "default") == 0) {
921			val64 = 0;
922		} else {
923			if (scan_scaled(arg, &val64) == -1)
924				fatal("%.200s line %d: Bad number '%s': %s",
925				    filename, linenum, arg, strerror(errno));
926			/* check for too-large or too-small limits */
927			if (val64 > UINT_MAX)
928				fatal("%.200s line %d: RekeyLimit too large",
929				    filename, linenum);
930			if (val64 != 0 && val64 < 16)
931				fatal("%.200s line %d: RekeyLimit too small",
932				    filename, linenum);
933		}
934		if (*activep && options->rekey_limit == -1)
935			options->rekey_limit = (u_int32_t)val64;
936		if (s != NULL) { /* optional rekey interval present */
937			if (strcmp(s, "none") == 0) {
938				(void)strdelim(&s);	/* discard */
939				break;
940			}
941			intptr = &options->rekey_interval;
942			goto parse_time;
943		}
944		break;
945
946	case oIdentityFile:
947		arg = strdelim(&s);
948		if (!arg || *arg == '\0')
949			fatal("%.200s line %d: Missing argument.", filename, linenum);
950		if (*activep) {
951			intptr = &options->num_identity_files;
952			if (*intptr >= SSH_MAX_IDENTITY_FILES)
953				fatal("%.200s line %d: Too many identity files specified (max %d).",
954				    filename, linenum, SSH_MAX_IDENTITY_FILES);
955			add_identity_file(options, NULL, arg, userconfig);
956		}
957		break;
958
959	case oXAuthLocation:
960		charptr=&options->xauth_location;
961		goto parse_string;
962
963	case oUser:
964		charptr = &options->user;
965parse_string:
966		arg = strdelim(&s);
967		if (!arg || *arg == '\0')
968			fatal("%.200s line %d: Missing argument.",
969			    filename, linenum);
970		if (*activep && *charptr == NULL)
971			*charptr = xstrdup(arg);
972		break;
973
974	case oGlobalKnownHostsFile:
975		cpptr = (char **)&options->system_hostfiles;
976		uintptr = &options->num_system_hostfiles;
977		max_entries = SSH_MAX_HOSTS_FILES;
978parse_char_array:
979		if (*activep && *uintptr == 0) {
980			while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
981				if ((*uintptr) >= max_entries)
982					fatal("%s line %d: "
983					    "too many authorized keys files.",
984					    filename, linenum);
985				cpptr[(*uintptr)++] = xstrdup(arg);
986			}
987		}
988		return 0;
989
990	case oUserKnownHostsFile:
991		cpptr = (char **)&options->user_hostfiles;
992		uintptr = &options->num_user_hostfiles;
993		max_entries = SSH_MAX_HOSTS_FILES;
994		goto parse_char_array;
995
996	case oHostName:
997		charptr = &options->hostname;
998		goto parse_string;
999
1000	case oHostKeyAlias:
1001		charptr = &options->host_key_alias;
1002		goto parse_string;
1003
1004	case oPreferredAuthentications:
1005		charptr = &options->preferred_authentications;
1006		goto parse_string;
1007
1008	case oBindAddress:
1009		charptr = &options->bind_address;
1010		goto parse_string;
1011
1012	case oPKCS11Provider:
1013		charptr = &options->pkcs11_provider;
1014		goto parse_string;
1015
1016	case oProxyCommand:
1017		charptr = &options->proxy_command;
1018parse_command:
1019		if (s == NULL)
1020			fatal("%.200s line %d: Missing argument.", filename, linenum);
1021		len = strspn(s, WHITESPACE "=");
1022		if (*activep && *charptr == NULL)
1023			*charptr = xstrdup(s + len);
1024		return 0;
1025
1026	case oPort:
1027		intptr = &options->port;
1028parse_int:
1029		arg = strdelim(&s);
1030		if (!arg || *arg == '\0')
1031			fatal("%.200s line %d: Missing argument.", filename, linenum);
1032		if (arg[0] < '0' || arg[0] > '9')
1033			fatal("%.200s line %d: Bad number.", filename, linenum);
1034
1035		/* Octal, decimal, or hex format? */
1036		value = strtol(arg, &endofnumber, 0);
1037		if (arg == endofnumber)
1038			fatal("%.200s line %d: Bad number.", filename, linenum);
1039		if (*activep && *intptr == -1)
1040			*intptr = value;
1041		break;
1042
1043	case oConnectionAttempts:
1044		intptr = &options->connection_attempts;
1045		goto parse_int;
1046
1047	case oCipher:
1048		intptr = &options->cipher;
1049		arg = strdelim(&s);
1050		if (!arg || *arg == '\0')
1051			fatal("%.200s line %d: Missing argument.", filename, linenum);
1052		value = cipher_number(arg);
1053		if (value == -1)
1054			fatal("%.200s line %d: Bad cipher '%s'.",
1055			    filename, linenum, arg ? arg : "<NONE>");
1056		if (*activep && *intptr == -1)
1057			*intptr = value;
1058		break;
1059
1060	case oCiphers:
1061		arg = strdelim(&s);
1062		if (!arg || *arg == '\0')
1063			fatal("%.200s line %d: Missing argument.", filename, linenum);
1064		if (!ciphers_valid(arg))
1065			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1066			    filename, linenum, arg ? arg : "<NONE>");
1067		if (*activep && options->ciphers == NULL)
1068			options->ciphers = xstrdup(arg);
1069		break;
1070
1071	case oMacs:
1072		arg = strdelim(&s);
1073		if (!arg || *arg == '\0')
1074			fatal("%.200s line %d: Missing argument.", filename, linenum);
1075		if (!mac_valid(arg))
1076			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1077			    filename, linenum, arg ? arg : "<NONE>");
1078		if (*activep && options->macs == NULL)
1079			options->macs = xstrdup(arg);
1080		break;
1081
1082	case oKexAlgorithms:
1083		arg = strdelim(&s);
1084		if (!arg || *arg == '\0')
1085			fatal("%.200s line %d: Missing argument.",
1086			    filename, linenum);
1087		if (!kex_names_valid(arg))
1088			fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1089			    filename, linenum, arg ? arg : "<NONE>");
1090		if (*activep && options->kex_algorithms == NULL)
1091			options->kex_algorithms = xstrdup(arg);
1092		break;
1093
1094	case oHostKeyAlgorithms:
1095		arg = strdelim(&s);
1096		if (!arg || *arg == '\0')
1097			fatal("%.200s line %d: Missing argument.", filename, linenum);
1098		if (!key_names_valid2(arg))
1099			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
1100			    filename, linenum, arg ? arg : "<NONE>");
1101		if (*activep && options->hostkeyalgorithms == NULL)
1102			options->hostkeyalgorithms = xstrdup(arg);
1103		break;
1104
1105	case oProtocol:
1106		intptr = &options->protocol;
1107		arg = strdelim(&s);
1108		if (!arg || *arg == '\0')
1109			fatal("%.200s line %d: Missing argument.", filename, linenum);
1110		value = proto_spec(arg);
1111		if (value == SSH_PROTO_UNKNOWN)
1112			fatal("%.200s line %d: Bad protocol spec '%s'.",
1113			    filename, linenum, arg ? arg : "<NONE>");
1114		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1115			*intptr = value;
1116		break;
1117
1118	case oLogLevel:
1119		log_level_ptr = &options->log_level;
1120		arg = strdelim(&s);
1121		value = log_level_number(arg);
1122		if (value == SYSLOG_LEVEL_NOT_SET)
1123			fatal("%.200s line %d: unsupported log level '%s'",
1124			    filename, linenum, arg ? arg : "<NONE>");
1125		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1126			*log_level_ptr = (LogLevel) value;
1127		break;
1128
1129	case oLocalForward:
1130	case oRemoteForward:
1131	case oDynamicForward:
1132		arg = strdelim(&s);
1133		if (arg == NULL || *arg == '\0')
1134			fatal("%.200s line %d: Missing port argument.",
1135			    filename, linenum);
1136
1137		if (opcode == oLocalForward ||
1138		    opcode == oRemoteForward) {
1139			arg2 = strdelim(&s);
1140			if (arg2 == NULL || *arg2 == '\0')
1141				fatal("%.200s line %d: Missing target argument.",
1142				    filename, linenum);
1143
1144			/* construct a string for parse_forward */
1145			snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1146		} else if (opcode == oDynamicForward) {
1147			strlcpy(fwdarg, arg, sizeof(fwdarg));
1148		}
1149
1150		if (parse_forward(&fwd, fwdarg,
1151		    opcode == oDynamicForward ? 1 : 0,
1152		    opcode == oRemoteForward ? 1 : 0) == 0)
1153			fatal("%.200s line %d: Bad forwarding specification.",
1154			    filename, linenum);
1155
1156		if (*activep) {
1157			if (opcode == oLocalForward ||
1158			    opcode == oDynamicForward)
1159				add_local_forward(options, &fwd);
1160			else if (opcode == oRemoteForward)
1161				add_remote_forward(options, &fwd);
1162		}
1163		break;
1164
1165	case oClearAllForwardings:
1166		intptr = &options->clear_forwardings;
1167		goto parse_flag;
1168
1169	case oHost:
1170		if (cmdline)
1171			fatal("Host directive not supported as a command-line "
1172			    "option");
1173		*activep = 0;
1174		arg2 = NULL;
1175		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1176			negated = *arg == '!';
1177			if (negated)
1178				arg++;
1179			if (match_pattern(host, arg)) {
1180				if (negated) {
1181					debug("%.200s line %d: Skipping Host "
1182					    "block because of negated match "
1183					    "for %.100s", filename, linenum,
1184					    arg);
1185					*activep = 0;
1186					break;
1187				}
1188				if (!*activep)
1189					arg2 = arg; /* logged below */
1190				*activep = 1;
1191			}
1192		}
1193		if (*activep)
1194			debug("%.200s line %d: Applying options for %.100s",
1195			    filename, linenum, arg2);
1196		/* Avoid garbage check below, as strdelim is done. */
1197		return 0;
1198
1199	case oMatch:
1200		if (cmdline)
1201			fatal("Host directive not supported as a command-line "
1202			    "option");
1203		value = match_cfg_line(options, &s, pw, host,
1204		    filename, linenum);
1205		if (value < 0)
1206			fatal("%.200s line %d: Bad Match condition", filename,
1207			    linenum);
1208		*activep = value;
1209		break;
1210
1211	case oEscapeChar:
1212		intptr = &options->escape_char;
1213		arg = strdelim(&s);
1214		if (!arg || *arg == '\0')
1215			fatal("%.200s line %d: Missing argument.", filename, linenum);
1216		if (arg[0] == '^' && arg[2] == 0 &&
1217		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1218			value = (u_char) arg[1] & 31;
1219		else if (strlen(arg) == 1)
1220			value = (u_char) arg[0];
1221		else if (strcmp(arg, "none") == 0)
1222			value = SSH_ESCAPECHAR_NONE;
1223		else {
1224			fatal("%.200s line %d: Bad escape character.",
1225			    filename, linenum);
1226			/* NOTREACHED */
1227			value = 0;	/* Avoid compiler warning. */
1228		}
1229		if (*activep && *intptr == -1)
1230			*intptr = value;
1231		break;
1232
1233	case oAddressFamily:
1234		intptr = &options->address_family;
1235		multistate_ptr = multistate_addressfamily;
1236		goto parse_multistate;
1237
1238	case oEnableSSHKeysign:
1239		intptr = &options->enable_ssh_keysign;
1240		goto parse_flag;
1241
1242	case oIdentitiesOnly:
1243		intptr = &options->identities_only;
1244		goto parse_flag;
1245
1246	case oServerAliveInterval:
1247		intptr = &options->server_alive_interval;
1248		goto parse_time;
1249
1250	case oServerAliveCountMax:
1251		intptr = &options->server_alive_count_max;
1252		goto parse_int;
1253
1254	case oSendEnv:
1255		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1256			if (strchr(arg, '=') != NULL)
1257				fatal("%s line %d: Invalid environment name.",
1258				    filename, linenum);
1259			if (!*activep)
1260				continue;
1261			if (options->num_send_env >= MAX_SEND_ENV)
1262				fatal("%s line %d: too many send env.",
1263				    filename, linenum);
1264			options->send_env[options->num_send_env++] =
1265			    xstrdup(arg);
1266		}
1267		break;
1268
1269	case oControlPath:
1270		charptr = &options->control_path;
1271		goto parse_string;
1272
1273	case oControlMaster:
1274		intptr = &options->control_master;
1275		multistate_ptr = multistate_controlmaster;
1276		goto parse_multistate;
1277
1278	case oControlPersist:
1279		/* no/false/yes/true, or a time spec */
1280		intptr = &options->control_persist;
1281		arg = strdelim(&s);
1282		if (!arg || *arg == '\0')
1283			fatal("%.200s line %d: Missing ControlPersist"
1284			    " argument.", filename, linenum);
1285		value = 0;
1286		value2 = 0;	/* timeout */
1287		if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1288			value = 0;
1289		else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1290			value = 1;
1291		else if ((value2 = convtime(arg)) >= 0)
1292			value = 1;
1293		else
1294			fatal("%.200s line %d: Bad ControlPersist argument.",
1295			    filename, linenum);
1296		if (*activep && *intptr == -1) {
1297			*intptr = value;
1298			options->control_persist_timeout = value2;
1299		}
1300		break;
1301
1302	case oHashKnownHosts:
1303		intptr = &options->hash_known_hosts;
1304		goto parse_flag;
1305
1306	case oTunnel:
1307		intptr = &options->tun_open;
1308		multistate_ptr = multistate_tunnel;
1309		goto parse_multistate;
1310
1311	case oTunnelDevice:
1312		arg = strdelim(&s);
1313		if (!arg || *arg == '\0')
1314			fatal("%.200s line %d: Missing argument.", filename, linenum);
1315		value = a2tun(arg, &value2);
1316		if (value == SSH_TUNID_ERR)
1317			fatal("%.200s line %d: Bad tun device.", filename, linenum);
1318		if (*activep) {
1319			options->tun_local = value;
1320			options->tun_remote = value2;
1321		}
1322		break;
1323
1324	case oLocalCommand:
1325		charptr = &options->local_command;
1326		goto parse_command;
1327
1328	case oPermitLocalCommand:
1329		intptr = &options->permit_local_command;
1330		goto parse_flag;
1331
1332	case oVisualHostKey:
1333		intptr = &options->visual_host_key;
1334		goto parse_flag;
1335
1336	case oIPQoS:
1337		arg = strdelim(&s);
1338		if ((value = parse_ipqos(arg)) == -1)
1339			fatal("%s line %d: Bad IPQoS value: %s",
1340			    filename, linenum, arg);
1341		arg = strdelim(&s);
1342		if (arg == NULL)
1343			value2 = value;
1344		else if ((value2 = parse_ipqos(arg)) == -1)
1345			fatal("%s line %d: Bad IPQoS value: %s",
1346			    filename, linenum, arg);
1347		if (*activep) {
1348			options->ip_qos_interactive = value;
1349			options->ip_qos_bulk = value2;
1350		}
1351		break;
1352
1353	case oUseRoaming:
1354		intptr = &options->use_roaming;
1355		goto parse_flag;
1356
1357	case oRequestTTY:
1358		intptr = &options->request_tty;
1359		multistate_ptr = multistate_requesttty;
1360		goto parse_multistate;
1361
1362	case oHPNDisabled:
1363		intptr = &options->hpn_disabled;
1364		goto parse_flag;
1365
1366	case oHPNBufferSize:
1367		intptr = &options->hpn_buffer_size;
1368		goto parse_int;
1369
1370	case oTcpRcvBufPoll:
1371		intptr = &options->tcp_rcv_buf_poll;
1372		goto parse_flag;
1373
1374	case oTcpRcvBuf:
1375		intptr = &options->tcp_rcv_buf;
1376		goto parse_int;
1377
1378#ifdef	NONE_CIPHER_ENABLED
1379	case oNoneEnabled:
1380		intptr = &options->none_enabled;
1381		goto parse_flag;
1382
1383	/*
1384	 * We check to see if the command comes from the command line or not.
1385	 * If it does then enable it otherwise fail.  NONE must never be a
1386	 * default configuration.
1387	 */
1388	case oNoneSwitch:
1389		if (strcmp(filename,"command-line") == 0) {
1390			intptr = &options->none_switch;
1391			goto parse_flag;
1392		} else {
1393			debug("NoneSwitch directive found in %.200s.",
1394			    filename);
1395			error("NoneSwitch is found in %.200s.\n"
1396			    "You may only use this configuration option "
1397			    "from the command line", filename);
1398			error("Continuing...");
1399			return 0;
1400		}
1401#endif
1402
1403	case oVersionAddendum:
1404		if (s == NULL)
1405			fatal("%.200s line %d: Missing argument.", filename,
1406			    linenum);
1407		len = strspn(s, WHITESPACE);
1408		if (*activep && options->version_addendum == NULL) {
1409			if (strcasecmp(s + len, "none") == 0)
1410				options->version_addendum = xstrdup("");
1411			else if (strchr(s + len, '\r') != NULL)
1412				fatal("%.200s line %d: Invalid argument",
1413				    filename, linenum);
1414			else
1415				options->version_addendum = xstrdup(s + len);
1416		}
1417		return 0;
1418
1419	case oIgnoreUnknown:
1420		charptr = &options->ignored_unknown;
1421		goto parse_string;
1422
1423	case oProxyUseFdpass:
1424		intptr = &options->proxy_use_fdpass;
1425		goto parse_flag;
1426
1427	case oCanonicalDomains:
1428		value = options->num_canonical_domains != 0;
1429		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1430			valid_domain(arg, filename, linenum);
1431			if (!*activep || value)
1432				continue;
1433			if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1434				fatal("%s line %d: too many hostname suffixes.",
1435				    filename, linenum);
1436			options->canonical_domains[
1437			    options->num_canonical_domains++] = xstrdup(arg);
1438		}
1439		break;
1440
1441	case oCanonicalizePermittedCNAMEs:
1442		value = options->num_permitted_cnames != 0;
1443		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1444			/* Either '*' for everything or 'list:list' */
1445			if (strcmp(arg, "*") == 0)
1446				arg2 = arg;
1447			else {
1448				lowercase(arg);
1449				if ((arg2 = strchr(arg, ':')) == NULL ||
1450				    arg2[1] == '\0') {
1451					fatal("%s line %d: "
1452					    "Invalid permitted CNAME \"%s\"",
1453					    filename, linenum, arg);
1454				}
1455				*arg2 = '\0';
1456				arg2++;
1457			}
1458			if (!*activep || value)
1459				continue;
1460			if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1461				fatal("%s line %d: too many permitted CNAMEs.",
1462				    filename, linenum);
1463			cname = options->permitted_cnames +
1464			    options->num_permitted_cnames++;
1465			cname->source_list = xstrdup(arg);
1466			cname->target_list = xstrdup(arg2);
1467		}
1468		break;
1469
1470	case oCanonicalizeHostname:
1471		intptr = &options->canonicalize_hostname;
1472		multistate_ptr = multistate_canonicalizehostname;
1473		goto parse_multistate;
1474
1475	case oCanonicalizeMaxDots:
1476		intptr = &options->canonicalize_max_dots;
1477		goto parse_int;
1478
1479	case oCanonicalizeFallbackLocal:
1480		intptr = &options->canonicalize_fallback_local;
1481		goto parse_flag;
1482
1483	case oDeprecated:
1484		debug("%s line %d: Deprecated option \"%s\"",
1485		    filename, linenum, keyword);
1486		return 0;
1487
1488	case oUnsupported:
1489		error("%s line %d: Unsupported option \"%s\"",
1490		    filename, linenum, keyword);
1491		return 0;
1492
1493	default:
1494		fatal("process_config_line: Unimplemented opcode %d", opcode);
1495	}
1496
1497	/* Check that there is no garbage at end of line. */
1498	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1499		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1500		    filename, linenum, arg);
1501	}
1502	return 0;
1503}
1504
1505
1506/*
1507 * Reads the config file and modifies the options accordingly.  Options
1508 * should already be initialized before this call.  This never returns if
1509 * there is an error.  If the file does not exist, this returns 0.
1510 */
1511
1512int
1513read_config_file(const char *filename, struct passwd *pw, const char *host,
1514    Options *options, int flags)
1515{
1516	FILE *f;
1517	char line[1024];
1518	int active, linenum;
1519	int bad_options = 0;
1520
1521	if ((f = fopen(filename, "r")) == NULL)
1522		return 0;
1523
1524	if (flags & SSHCONF_CHECKPERM) {
1525		struct stat sb;
1526
1527		if (fstat(fileno(f), &sb) == -1)
1528			fatal("fstat %s: %s", filename, strerror(errno));
1529		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1530		    (sb.st_mode & 022) != 0))
1531			fatal("Bad owner or permissions on %s", filename);
1532	}
1533
1534	debug("Reading configuration data %.200s", filename);
1535
1536	/*
1537	 * Mark that we are now processing the options.  This flag is turned
1538	 * on/off by Host specifications.
1539	 */
1540	active = 1;
1541	linenum = 0;
1542	while (fgets(line, sizeof(line), f)) {
1543		/* Update line number counter. */
1544		linenum++;
1545		if (process_config_line(options, pw, host, line, filename,
1546		    linenum, &active, flags & SSHCONF_USERCONF) != 0)
1547			bad_options++;
1548	}
1549	fclose(f);
1550	if (bad_options > 0)
1551		fatal("%s: terminating, %d bad configuration options",
1552		    filename, bad_options);
1553	return 1;
1554}
1555
1556/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1557int
1558option_clear_or_none(const char *o)
1559{
1560	return o == NULL || strcasecmp(o, "none") == 0;
1561}
1562
1563/*
1564 * Initializes options to special values that indicate that they have not yet
1565 * been set.  Read_config_file will only set options with this value. Options
1566 * are processed in the following order: command line, user config file,
1567 * system config file.  Last, fill_default_options is called.
1568 */
1569
1570void
1571initialize_options(Options * options)
1572{
1573	memset(options, 'X', sizeof(*options));
1574	options->forward_agent = -1;
1575	options->forward_x11 = -1;
1576	options->forward_x11_trusted = -1;
1577	options->forward_x11_timeout = -1;
1578	options->exit_on_forward_failure = -1;
1579	options->xauth_location = NULL;
1580	options->gateway_ports = -1;
1581	options->use_privileged_port = -1;
1582	options->rsa_authentication = -1;
1583	options->pubkey_authentication = -1;
1584	options->challenge_response_authentication = -1;
1585	options->gss_authentication = -1;
1586	options->gss_deleg_creds = -1;
1587	options->password_authentication = -1;
1588	options->kbd_interactive_authentication = -1;
1589	options->kbd_interactive_devices = NULL;
1590	options->rhosts_rsa_authentication = -1;
1591	options->hostbased_authentication = -1;
1592	options->batch_mode = -1;
1593	options->check_host_ip = -1;
1594	options->strict_host_key_checking = -1;
1595	options->compression = -1;
1596	options->tcp_keep_alive = -1;
1597	options->compression_level = -1;
1598	options->port = -1;
1599	options->address_family = -1;
1600	options->connection_attempts = -1;
1601	options->connection_timeout = -1;
1602	options->number_of_password_prompts = -1;
1603	options->cipher = -1;
1604	options->ciphers = NULL;
1605	options->macs = NULL;
1606	options->kex_algorithms = NULL;
1607	options->hostkeyalgorithms = NULL;
1608	options->protocol = SSH_PROTO_UNKNOWN;
1609	options->num_identity_files = 0;
1610	options->hostname = NULL;
1611	options->host_key_alias = NULL;
1612	options->proxy_command = NULL;
1613	options->user = NULL;
1614	options->escape_char = -1;
1615	options->num_system_hostfiles = 0;
1616	options->num_user_hostfiles = 0;
1617	options->local_forwards = NULL;
1618	options->num_local_forwards = 0;
1619	options->remote_forwards = NULL;
1620	options->num_remote_forwards = 0;
1621	options->clear_forwardings = -1;
1622	options->log_level = SYSLOG_LEVEL_NOT_SET;
1623	options->preferred_authentications = NULL;
1624	options->bind_address = NULL;
1625	options->pkcs11_provider = NULL;
1626	options->enable_ssh_keysign = - 1;
1627	options->no_host_authentication_for_localhost = - 1;
1628	options->identities_only = - 1;
1629	options->rekey_limit = - 1;
1630	options->rekey_interval = -1;
1631	options->verify_host_key_dns = -1;
1632	options->server_alive_interval = -1;
1633	options->server_alive_count_max = -1;
1634	options->num_send_env = 0;
1635	options->control_path = NULL;
1636	options->control_master = -1;
1637	options->control_persist = -1;
1638	options->control_persist_timeout = 0;
1639	options->hash_known_hosts = -1;
1640	options->tun_open = -1;
1641	options->tun_local = -1;
1642	options->tun_remote = -1;
1643	options->local_command = NULL;
1644	options->permit_local_command = -1;
1645	options->use_roaming = 0;
1646	options->visual_host_key = -1;
1647	options->ip_qos_interactive = -1;
1648	options->ip_qos_bulk = -1;
1649	options->request_tty = -1;
1650	options->proxy_use_fdpass = -1;
1651	options->ignored_unknown = NULL;
1652	options->num_canonical_domains = 0;
1653	options->num_permitted_cnames = 0;
1654	options->canonicalize_max_dots = -1;
1655	options->canonicalize_fallback_local = -1;
1656	options->canonicalize_hostname = -1;
1657	options->version_addendum = NULL;
1658	options->hpn_disabled = -1;
1659	options->hpn_buffer_size = -1;
1660	options->tcp_rcv_buf_poll = -1;
1661	options->tcp_rcv_buf = -1;
1662#ifdef NONE_CIPHER_ENABLED
1663	options->none_enabled = -1;
1664	options->none_switch = -1;
1665#endif
1666}
1667
1668/*
1669 * A petite version of fill_default_options() that just fills the options
1670 * needed for hostname canonicalization to proceed.
1671 */
1672void
1673fill_default_options_for_canonicalization(Options *options)
1674{
1675	if (options->canonicalize_max_dots == -1)
1676		options->canonicalize_max_dots = 1;
1677	if (options->canonicalize_fallback_local == -1)
1678		options->canonicalize_fallback_local = 1;
1679	if (options->canonicalize_hostname == -1)
1680		options->canonicalize_hostname = SSH_CANONICALISE_NO;
1681}
1682
1683/*
1684 * Called after processing other sources of option data, this fills those
1685 * options for which no value has been specified with their default values.
1686 */
1687void
1688fill_default_options(Options * options)
1689{
1690	if (options->forward_agent == -1)
1691		options->forward_agent = 0;
1692	if (options->forward_x11 == -1)
1693		options->forward_x11 = 0;
1694	if (options->forward_x11_trusted == -1)
1695		options->forward_x11_trusted = 0;
1696	if (options->forward_x11_timeout == -1)
1697		options->forward_x11_timeout = 1200;
1698	if (options->exit_on_forward_failure == -1)
1699		options->exit_on_forward_failure = 0;
1700	if (options->xauth_location == NULL)
1701		options->xauth_location = _PATH_XAUTH;
1702	if (options->gateway_ports == -1)
1703		options->gateway_ports = 0;
1704	if (options->use_privileged_port == -1)
1705		options->use_privileged_port = 0;
1706	if (options->rsa_authentication == -1)
1707		options->rsa_authentication = 1;
1708	if (options->pubkey_authentication == -1)
1709		options->pubkey_authentication = 1;
1710	if (options->challenge_response_authentication == -1)
1711		options->challenge_response_authentication = 1;
1712	if (options->gss_authentication == -1)
1713		options->gss_authentication = 0;
1714	if (options->gss_deleg_creds == -1)
1715		options->gss_deleg_creds = 0;
1716	if (options->password_authentication == -1)
1717		options->password_authentication = 1;
1718	if (options->kbd_interactive_authentication == -1)
1719		options->kbd_interactive_authentication = 1;
1720	if (options->rhosts_rsa_authentication == -1)
1721		options->rhosts_rsa_authentication = 0;
1722	if (options->hostbased_authentication == -1)
1723		options->hostbased_authentication = 0;
1724	if (options->batch_mode == -1)
1725		options->batch_mode = 0;
1726	if (options->check_host_ip == -1)
1727		options->check_host_ip = 0;
1728	if (options->strict_host_key_checking == -1)
1729		options->strict_host_key_checking = 2;	/* 2 is default */
1730	if (options->compression == -1)
1731		options->compression = 0;
1732	if (options->tcp_keep_alive == -1)
1733		options->tcp_keep_alive = 1;
1734	if (options->compression_level == -1)
1735		options->compression_level = 6;
1736	if (options->port == -1)
1737		options->port = 0;	/* Filled in ssh_connect. */
1738	if (options->address_family == -1)
1739		options->address_family = AF_UNSPEC;
1740	if (options->connection_attempts == -1)
1741		options->connection_attempts = 1;
1742	if (options->number_of_password_prompts == -1)
1743		options->number_of_password_prompts = 3;
1744	/* Selected in ssh_login(). */
1745	if (options->cipher == -1)
1746		options->cipher = SSH_CIPHER_NOT_SET;
1747	/* options->ciphers, default set in myproposals.h */
1748	/* options->macs, default set in myproposals.h */
1749	/* options->kex_algorithms, default set in myproposals.h */
1750	/* options->hostkeyalgorithms, default set in myproposals.h */
1751	if (options->protocol == SSH_PROTO_UNKNOWN)
1752		options->protocol = SSH_PROTO_2;
1753	if (options->num_identity_files == 0) {
1754		if (options->protocol & SSH_PROTO_1) {
1755			add_identity_file(options, "~/",
1756			    _PATH_SSH_CLIENT_IDENTITY, 0);
1757		}
1758		if (options->protocol & SSH_PROTO_2) {
1759			add_identity_file(options, "~/",
1760			    _PATH_SSH_CLIENT_ID_RSA, 0);
1761			add_identity_file(options, "~/",
1762			    _PATH_SSH_CLIENT_ID_DSA, 0);
1763#ifdef OPENSSL_HAS_ECC
1764			add_identity_file(options, "~/",
1765			    _PATH_SSH_CLIENT_ID_ECDSA, 0);
1766#endif
1767			add_identity_file(options, "~/",
1768			    _PATH_SSH_CLIENT_ID_ED25519, 0);
1769		}
1770	}
1771	if (options->escape_char == -1)
1772		options->escape_char = '~';
1773	if (options->num_system_hostfiles == 0) {
1774		options->system_hostfiles[options->num_system_hostfiles++] =
1775		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1776		options->system_hostfiles[options->num_system_hostfiles++] =
1777		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1778	}
1779	if (options->num_user_hostfiles == 0) {
1780		options->user_hostfiles[options->num_user_hostfiles++] =
1781		    xstrdup(_PATH_SSH_USER_HOSTFILE);
1782		options->user_hostfiles[options->num_user_hostfiles++] =
1783		    xstrdup(_PATH_SSH_USER_HOSTFILE2);
1784	}
1785	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1786		options->log_level = SYSLOG_LEVEL_INFO;
1787	if (options->clear_forwardings == 1)
1788		clear_forwardings(options);
1789	if (options->no_host_authentication_for_localhost == - 1)
1790		options->no_host_authentication_for_localhost = 0;
1791	if (options->identities_only == -1)
1792		options->identities_only = 0;
1793	if (options->enable_ssh_keysign == -1)
1794		options->enable_ssh_keysign = 0;
1795	if (options->rekey_limit == -1)
1796		options->rekey_limit = 0;
1797	if (options->rekey_interval == -1)
1798		options->rekey_interval = 0;
1799#if HAVE_LDNS
1800	if (options->verify_host_key_dns == -1)
1801		/* automatically trust a verified SSHFP record */
1802		options->verify_host_key_dns = 1;
1803#else
1804	if (options->verify_host_key_dns == -1)
1805		options->verify_host_key_dns = 0;
1806#endif
1807	if (options->server_alive_interval == -1)
1808		options->server_alive_interval = 0;
1809	if (options->server_alive_count_max == -1)
1810		options->server_alive_count_max = 3;
1811	if (options->control_master == -1)
1812		options->control_master = 0;
1813	if (options->control_persist == -1) {
1814		options->control_persist = 0;
1815		options->control_persist_timeout = 0;
1816	}
1817	if (options->hash_known_hosts == -1)
1818		options->hash_known_hosts = 0;
1819	if (options->tun_open == -1)
1820		options->tun_open = SSH_TUNMODE_NO;
1821	if (options->tun_local == -1)
1822		options->tun_local = SSH_TUNID_ANY;
1823	if (options->tun_remote == -1)
1824		options->tun_remote = SSH_TUNID_ANY;
1825	if (options->permit_local_command == -1)
1826		options->permit_local_command = 0;
1827	options->use_roaming = 0;
1828	if (options->visual_host_key == -1)
1829		options->visual_host_key = 0;
1830	if (options->ip_qos_interactive == -1)
1831		options->ip_qos_interactive = IPTOS_LOWDELAY;
1832	if (options->ip_qos_bulk == -1)
1833		options->ip_qos_bulk = IPTOS_THROUGHPUT;
1834	if (options->request_tty == -1)
1835		options->request_tty = REQUEST_TTY_AUTO;
1836	if (options->proxy_use_fdpass == -1)
1837		options->proxy_use_fdpass = 0;
1838	if (options->canonicalize_max_dots == -1)
1839		options->canonicalize_max_dots = 1;
1840	if (options->canonicalize_fallback_local == -1)
1841		options->canonicalize_fallback_local = 1;
1842	if (options->canonicalize_hostname == -1)
1843		options->canonicalize_hostname = SSH_CANONICALISE_NO;
1844#define CLEAR_ON_NONE(v) \
1845	do { \
1846		if (option_clear_or_none(v)) { \
1847			free(v); \
1848			v = NULL; \
1849		} \
1850	} while(0)
1851	CLEAR_ON_NONE(options->local_command);
1852	CLEAR_ON_NONE(options->proxy_command);
1853	CLEAR_ON_NONE(options->control_path);
1854	/* options->user will be set in the main program if appropriate */
1855	/* options->hostname will be set in the main program if appropriate */
1856	/* options->host_key_alias should not be set by default */
1857	/* options->preferred_authentications will be set in ssh */
1858	if (options->version_addendum == NULL)
1859		options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
1860	if (options->hpn_disabled == -1)
1861		options->hpn_disabled = 0;
1862	if (options->hpn_buffer_size > -1)
1863	{
1864		u_int maxlen;
1865
1866		/* If a user tries to set the size to 0 set it to 1KB. */
1867		if (options->hpn_buffer_size == 0)
1868			options->hpn_buffer_size = 1024;
1869		/* Limit the buffer to BUFFER_MAX_LEN. */
1870		maxlen = buffer_get_max_len();
1871		if (options->hpn_buffer_size > (maxlen / 1024)) {
1872			debug("User requested buffer larger than %ub: %ub. "
1873			    "Request reverted to %ub", maxlen,
1874			    options->hpn_buffer_size * 1024, maxlen);
1875			options->hpn_buffer_size = maxlen;
1876		}
1877		debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
1878	}
1879	if (options->tcp_rcv_buf == 0)
1880		options->tcp_rcv_buf = 1;
1881	if (options->tcp_rcv_buf > -1)
1882		options->tcp_rcv_buf *= 1024;
1883	if (options->tcp_rcv_buf_poll == -1)
1884		options->tcp_rcv_buf_poll = 1;
1885#ifdef	NONE_CIPHER_ENABLED
1886	/* options->none_enabled must not be set by default */
1887	if (options->none_switch == -1)
1888		options->none_switch = 0;
1889#endif
1890}
1891
1892/*
1893 * parse_forward
1894 * parses a string containing a port forwarding specification of the form:
1895 *   dynamicfwd == 0
1896 *	[listenhost:]listenport:connecthost:connectport
1897 *   dynamicfwd == 1
1898 *	[listenhost:]listenport
1899 * returns number of arguments parsed or zero on error
1900 */
1901int
1902parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1903{
1904	int i;
1905	char *p, *cp, *fwdarg[4];
1906
1907	memset(fwd, '\0', sizeof(*fwd));
1908
1909	cp = p = xstrdup(fwdspec);
1910
1911	/* skip leading spaces */
1912	while (isspace((u_char)*cp))
1913		cp++;
1914
1915	for (i = 0; i < 4; ++i)
1916		if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1917			break;
1918
1919	/* Check for trailing garbage */
1920	if (cp != NULL)
1921		i = 0;	/* failure */
1922
1923	switch (i) {
1924	case 1:
1925		fwd->listen_host = NULL;
1926		fwd->listen_port = a2port(fwdarg[0]);
1927		fwd->connect_host = xstrdup("socks");
1928		break;
1929
1930	case 2:
1931		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1932		fwd->listen_port = a2port(fwdarg[1]);
1933		fwd->connect_host = xstrdup("socks");
1934		break;
1935
1936	case 3:
1937		fwd->listen_host = NULL;
1938		fwd->listen_port = a2port(fwdarg[0]);
1939		fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1940		fwd->connect_port = a2port(fwdarg[2]);
1941		break;
1942
1943	case 4:
1944		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1945		fwd->listen_port = a2port(fwdarg[1]);
1946		fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1947		fwd->connect_port = a2port(fwdarg[3]);
1948		break;
1949	default:
1950		i = 0; /* failure */
1951	}
1952
1953	free(p);
1954
1955	if (dynamicfwd) {
1956		if (!(i == 1 || i == 2))
1957			goto fail_free;
1958	} else {
1959		if (!(i == 3 || i == 4))
1960			goto fail_free;
1961		if (fwd->connect_port <= 0)
1962			goto fail_free;
1963	}
1964
1965	if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
1966		goto fail_free;
1967
1968	if (fwd->connect_host != NULL &&
1969	    strlen(fwd->connect_host) >= NI_MAXHOST)
1970		goto fail_free;
1971	if (fwd->listen_host != NULL &&
1972	    strlen(fwd->listen_host) >= NI_MAXHOST)
1973		goto fail_free;
1974
1975
1976	return (i);
1977
1978 fail_free:
1979	free(fwd->connect_host);
1980	fwd->connect_host = NULL;
1981	free(fwd->listen_host);
1982	fwd->listen_host = NULL;
1983	return (0);
1984}
1985