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