readconf.c revision 192595
1/* $OpenBSD: readconf.c,v 1.176 2009/02/12 03:00:56 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: head/crypto/openssh/readconf.c 192595 2009-05-22 18:46:28Z des $");
17
18#include <sys/types.h>
19#include <sys/stat.h>
20#include <sys/socket.h>
21#include <sys/sysctl.h>
22
23#include <netinet/in.h>
24
25#include <ctype.h>
26#include <errno.h>
27#include <netdb.h>
28#include <signal.h>
29#include <stdarg.h>
30#include <stdio.h>
31#include <string.h>
32#include <unistd.h>
33
34#include "xmalloc.h"
35#include "ssh.h"
36#include "compat.h"
37#include "cipher.h"
38#include "pathnames.h"
39#include "log.h"
40#include "key.h"
41#include "readconf.h"
42#include "match.h"
43#include "misc.h"
44#include "buffer.h"
45#include "kex.h"
46#include "mac.h"
47#include "version.h"
48
49/* Format of the configuration file:
50
51   # Configuration data is parsed as follows:
52   #  1. command line options
53   #  2. user-specific file
54   #  3. system-wide file
55   # Any configuration value is only changed the first time it is set.
56   # Thus, host-specific definitions should be at the beginning of the
57   # configuration file, and defaults at the end.
58
59   # Host-specific declarations.  These may override anything above.  A single
60   # host may match multiple declarations; these are processed in the order
61   # that they are given in.
62
63   Host *.ngs.fi ngs.fi
64     User foo
65
66   Host fake.com
67     HostName another.host.name.real.org
68     User blaah
69     Port 34289
70     ForwardX11 no
71     ForwardAgent no
72
73   Host books.com
74     RemoteForward 9999 shadows.cs.hut.fi:9999
75     Cipher 3des
76
77   Host fascist.blob.com
78     Port 23123
79     User tylonen
80     PasswordAuthentication no
81
82   Host puukko.hut.fi
83     User t35124p
84     ProxyCommand ssh-proxy %h %p
85
86   Host *.fr
87     PublicKeyAuthentication no
88
89   Host *.su
90     Cipher none
91     PasswordAuthentication no
92
93   Host vpn.fake.com
94     Tunnel yes
95     TunnelDevice 3
96
97   # Defaults for various options
98   Host *
99     ForwardAgent no
100     ForwardX11 no
101     PasswordAuthentication yes
102     RSAAuthentication yes
103     RhostsRSAAuthentication yes
104     StrictHostKeyChecking yes
105     TcpKeepAlive no
106     IdentityFile ~/.ssh/identity
107     Port 22
108     EscapeChar ~
109
110*/
111
112/* Keyword tokens. */
113
114typedef enum {
115	oBadOption,
116	oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
117	oExitOnForwardFailure,
118	oPasswordAuthentication, oRSAAuthentication,
119	oChallengeResponseAuthentication, oXAuthLocation,
120	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
121	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
122	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
123	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
124	oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
125	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
126	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
127	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
128	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
129	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
130	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
131	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
132	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
133	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
134	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
135	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
136	oVisualHostKey, oZeroKnowledgePasswordAuthentication,
137	oVersionAddendum,
138	oDeprecated, oUnsupported
139} OpCodes;
140
141/* Textual representations of the tokens. */
142
143static struct {
144	const char *name;
145	OpCodes opcode;
146} keywords[] = {
147	{ "forwardagent", oForwardAgent },
148	{ "forwardx11", oForwardX11 },
149	{ "forwardx11trusted", oForwardX11Trusted },
150	{ "exitonforwardfailure", oExitOnForwardFailure },
151	{ "xauthlocation", oXAuthLocation },
152	{ "gatewayports", oGatewayPorts },
153	{ "useprivilegedport", oUsePrivilegedPort },
154	{ "rhostsauthentication", oDeprecated },
155	{ "passwordauthentication", oPasswordAuthentication },
156	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
157	{ "kbdinteractivedevices", oKbdInteractiveDevices },
158	{ "rsaauthentication", oRSAAuthentication },
159	{ "pubkeyauthentication", oPubkeyAuthentication },
160	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
161	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
162	{ "hostbasedauthentication", oHostbasedAuthentication },
163	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
164	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
165	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
166	{ "kerberosauthentication", oUnsupported },
167	{ "kerberostgtpassing", oUnsupported },
168	{ "afstokenpassing", oUnsupported },
169#if defined(GSSAPI)
170	{ "gssapiauthentication", oGssAuthentication },
171	{ "gssapidelegatecredentials", oGssDelegateCreds },
172#else
173	{ "gssapiauthentication", oUnsupported },
174	{ "gssapidelegatecredentials", oUnsupported },
175#endif
176	{ "fallbacktorsh", oDeprecated },
177	{ "usersh", oDeprecated },
178	{ "identityfile", oIdentityFile },
179	{ "identityfile2", oIdentityFile },			/* obsolete */
180	{ "identitiesonly", oIdentitiesOnly },
181	{ "hostname", oHostName },
182	{ "hostkeyalias", oHostKeyAlias },
183	{ "proxycommand", oProxyCommand },
184	{ "port", oPort },
185	{ "cipher", oCipher },
186	{ "ciphers", oCiphers },
187	{ "macs", oMacs },
188	{ "protocol", oProtocol },
189	{ "remoteforward", oRemoteForward },
190	{ "localforward", oLocalForward },
191	{ "user", oUser },
192	{ "host", oHost },
193	{ "escapechar", oEscapeChar },
194	{ "globalknownhostsfile", oGlobalKnownHostsFile },
195	{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },	/* obsolete */
196	{ "userknownhostsfile", oUserKnownHostsFile },
197	{ "userknownhostsfile2", oUserKnownHostsFile2 },	/* obsolete */
198	{ "connectionattempts", oConnectionAttempts },
199	{ "batchmode", oBatchMode },
200	{ "checkhostip", oCheckHostIP },
201	{ "stricthostkeychecking", oStrictHostKeyChecking },
202	{ "compression", oCompression },
203	{ "compressionlevel", oCompressionLevel },
204	{ "tcpkeepalive", oTCPKeepAlive },
205	{ "keepalive", oTCPKeepAlive },				/* obsolete */
206	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
207	{ "loglevel", oLogLevel },
208	{ "dynamicforward", oDynamicForward },
209	{ "preferredauthentications", oPreferredAuthentications },
210	{ "hostkeyalgorithms", oHostKeyAlgorithms },
211	{ "bindaddress", oBindAddress },
212#ifdef SMARTCARD
213	{ "smartcarddevice", oSmartcardDevice },
214#else
215	{ "smartcarddevice", oUnsupported },
216#endif
217	{ "clearallforwardings", oClearAllForwardings },
218	{ "enablesshkeysign", oEnableSSHKeysign },
219	{ "verifyhostkeydns", oVerifyHostKeyDNS },
220	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
221	{ "rekeylimit", oRekeyLimit },
222	{ "connecttimeout", oConnectTimeout },
223	{ "addressfamily", oAddressFamily },
224	{ "serveraliveinterval", oServerAliveInterval },
225	{ "serveralivecountmax", oServerAliveCountMax },
226	{ "sendenv", oSendEnv },
227	{ "controlpath", oControlPath },
228	{ "controlmaster", oControlMaster },
229	{ "hashknownhosts", oHashKnownHosts },
230	{ "tunnel", oTunnel },
231	{ "tunneldevice", oTunnelDevice },
232	{ "localcommand", oLocalCommand },
233	{ "permitlocalcommand", oPermitLocalCommand },
234	{ "visualhostkey", oVisualHostKey },
235#ifdef JPAKE
236	{ "zeroknowledgepasswordauthentication",
237	    oZeroKnowledgePasswordAuthentication },
238#else
239	{ "zeroknowledgepasswordauthentication", oUnsupported },
240#endif
241
242	{ "versionaddendum", oVersionAddendum },
243	{ NULL, oBadOption }
244};
245
246/*
247 * Adds a local TCP/IP port forward to options.  Never returns if there is an
248 * error.
249 */
250
251void
252add_local_forward(Options *options, const Forward *newfwd)
253{
254	Forward *fwd;
255#ifndef NO_IPPORT_RESERVED_CONCEPT
256	extern uid_t original_real_uid;
257	int ipport_reserved;
258#ifdef __FreeBSD__
259	size_t len_ipport_reserved = sizeof(ipport_reserved);
260
261	if (sysctlbyname("net.inet.ip.portrange.reservedhigh",
262	    &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0)
263		ipport_reserved = IPPORT_RESERVED;
264	else
265		ipport_reserved++;
266#else
267	ipport_reserved = IPPORT_RESERVED;
268#endif
269	if (newfwd->listen_port < ipport_reserved && original_real_uid != 0)
270		fatal("Privileged ports can only be forwarded by root.");
271#endif
272	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
273		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
274	fwd = &options->local_forwards[options->num_local_forwards++];
275
276	fwd->listen_host = newfwd->listen_host;
277	fwd->listen_port = newfwd->listen_port;
278	fwd->connect_host = newfwd->connect_host;
279	fwd->connect_port = newfwd->connect_port;
280}
281
282/*
283 * Adds a remote TCP/IP port forward to options.  Never returns if there is
284 * an error.
285 */
286
287void
288add_remote_forward(Options *options, const Forward *newfwd)
289{
290	Forward *fwd;
291	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
292		fatal("Too many remote forwards (max %d).",
293		    SSH_MAX_FORWARDS_PER_DIRECTION);
294	fwd = &options->remote_forwards[options->num_remote_forwards++];
295
296	fwd->listen_host = newfwd->listen_host;
297	fwd->listen_port = newfwd->listen_port;
298	fwd->connect_host = newfwd->connect_host;
299	fwd->connect_port = newfwd->connect_port;
300}
301
302static void
303clear_forwardings(Options *options)
304{
305	int i;
306
307	for (i = 0; i < options->num_local_forwards; i++) {
308		if (options->local_forwards[i].listen_host != NULL)
309			xfree(options->local_forwards[i].listen_host);
310		xfree(options->local_forwards[i].connect_host);
311	}
312	options->num_local_forwards = 0;
313	for (i = 0; i < options->num_remote_forwards; i++) {
314		if (options->remote_forwards[i].listen_host != NULL)
315			xfree(options->remote_forwards[i].listen_host);
316		xfree(options->remote_forwards[i].connect_host);
317	}
318	options->num_remote_forwards = 0;
319	options->tun_open = SSH_TUNMODE_NO;
320}
321
322/*
323 * Returns the number of the token pointed to by cp or oBadOption.
324 */
325
326static OpCodes
327parse_token(const char *cp, const char *filename, int linenum)
328{
329	u_int i;
330
331	for (i = 0; keywords[i].name; i++)
332		if (strcasecmp(cp, keywords[i].name) == 0)
333			return keywords[i].opcode;
334
335	error("%s: line %d: Bad configuration option: %s",
336	    filename, linenum, cp);
337	return oBadOption;
338}
339
340/*
341 * Processes a single option line as used in the configuration files. This
342 * only sets those values that have not already been set.
343 */
344#define WHITESPACE " \t\r\n"
345
346int
347process_config_line(Options *options, const char *host,
348		    char *line, const char *filename, int linenum,
349		    int *activep)
350{
351	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
352	int opcode, *intptr, value, value2, scale;
353	LogLevel *log_level_ptr;
354	long long orig, val64;
355	size_t len;
356	Forward fwd;
357
358	/* Strip trailing whitespace */
359	for (len = strlen(line) - 1; len > 0; len--) {
360		if (strchr(WHITESPACE, line[len]) == NULL)
361			break;
362		line[len] = '\0';
363	}
364
365	s = line;
366	/* Get the keyword. (Each line is supposed to begin with a keyword). */
367	if ((keyword = strdelim(&s)) == NULL)
368		return 0;
369	/* Ignore leading whitespace. */
370	if (*keyword == '\0')
371		keyword = strdelim(&s);
372	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
373		return 0;
374
375	opcode = parse_token(keyword, filename, linenum);
376
377	switch (opcode) {
378	case oBadOption:
379		/* don't panic, but count bad options */
380		return -1;
381		/* NOTREACHED */
382	case oConnectTimeout:
383		intptr = &options->connection_timeout;
384parse_time:
385		arg = strdelim(&s);
386		if (!arg || *arg == '\0')
387			fatal("%s line %d: missing time value.",
388			    filename, linenum);
389		if ((value = convtime(arg)) == -1)
390			fatal("%s line %d: invalid time value.",
391			    filename, linenum);
392		if (*activep && *intptr == -1)
393			*intptr = value;
394		break;
395
396	case oForwardAgent:
397		intptr = &options->forward_agent;
398parse_flag:
399		arg = strdelim(&s);
400		if (!arg || *arg == '\0')
401			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
402		value = 0;	/* To avoid compiler warning... */
403		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
404			value = 1;
405		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
406			value = 0;
407		else
408			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
409		if (*activep && *intptr == -1)
410			*intptr = value;
411		break;
412
413	case oForwardX11:
414		intptr = &options->forward_x11;
415		goto parse_flag;
416
417	case oForwardX11Trusted:
418		intptr = &options->forward_x11_trusted;
419		goto parse_flag;
420
421	case oGatewayPorts:
422		intptr = &options->gateway_ports;
423		goto parse_flag;
424
425	case oExitOnForwardFailure:
426		intptr = &options->exit_on_forward_failure;
427		goto parse_flag;
428
429	case oUsePrivilegedPort:
430		intptr = &options->use_privileged_port;
431		goto parse_flag;
432
433	case oPasswordAuthentication:
434		intptr = &options->password_authentication;
435		goto parse_flag;
436
437	case oZeroKnowledgePasswordAuthentication:
438		intptr = &options->zero_knowledge_password_authentication;
439		goto parse_flag;
440
441	case oKbdInteractiveAuthentication:
442		intptr = &options->kbd_interactive_authentication;
443		goto parse_flag;
444
445	case oKbdInteractiveDevices:
446		charptr = &options->kbd_interactive_devices;
447		goto parse_string;
448
449	case oPubkeyAuthentication:
450		intptr = &options->pubkey_authentication;
451		goto parse_flag;
452
453	case oRSAAuthentication:
454		intptr = &options->rsa_authentication;
455		goto parse_flag;
456
457	case oRhostsRSAAuthentication:
458		intptr = &options->rhosts_rsa_authentication;
459		goto parse_flag;
460
461	case oHostbasedAuthentication:
462		intptr = &options->hostbased_authentication;
463		goto parse_flag;
464
465	case oChallengeResponseAuthentication:
466		intptr = &options->challenge_response_authentication;
467		goto parse_flag;
468
469	case oGssAuthentication:
470		intptr = &options->gss_authentication;
471		goto parse_flag;
472
473	case oGssDelegateCreds:
474		intptr = &options->gss_deleg_creds;
475		goto parse_flag;
476
477	case oBatchMode:
478		intptr = &options->batch_mode;
479		goto parse_flag;
480
481	case oCheckHostIP:
482		intptr = &options->check_host_ip;
483		goto parse_flag;
484
485	case oVerifyHostKeyDNS:
486		intptr = &options->verify_host_key_dns;
487		goto parse_yesnoask;
488
489	case oStrictHostKeyChecking:
490		intptr = &options->strict_host_key_checking;
491parse_yesnoask:
492		arg = strdelim(&s);
493		if (!arg || *arg == '\0')
494			fatal("%.200s line %d: Missing yes/no/ask argument.",
495			    filename, linenum);
496		value = 0;	/* To avoid compiler warning... */
497		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
498			value = 1;
499		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
500			value = 0;
501		else if (strcmp(arg, "ask") == 0)
502			value = 2;
503		else
504			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
505		if (*activep && *intptr == -1)
506			*intptr = value;
507		break;
508
509	case oCompression:
510		intptr = &options->compression;
511		goto parse_flag;
512
513	case oTCPKeepAlive:
514		intptr = &options->tcp_keep_alive;
515		goto parse_flag;
516
517	case oNoHostAuthenticationForLocalhost:
518		intptr = &options->no_host_authentication_for_localhost;
519		goto parse_flag;
520
521	case oNumberOfPasswordPrompts:
522		intptr = &options->number_of_password_prompts;
523		goto parse_int;
524
525	case oCompressionLevel:
526		intptr = &options->compression_level;
527		goto parse_int;
528
529	case oRekeyLimit:
530		arg = strdelim(&s);
531		if (!arg || *arg == '\0')
532			fatal("%.200s line %d: Missing argument.", filename, linenum);
533		if (arg[0] < '0' || arg[0] > '9')
534			fatal("%.200s line %d: Bad number.", filename, linenum);
535		orig = val64 = strtoll(arg, &endofnumber, 10);
536		if (arg == endofnumber)
537			fatal("%.200s line %d: Bad number.", filename, linenum);
538		switch (toupper(*endofnumber)) {
539		case '\0':
540			scale = 1;
541			break;
542		case 'K':
543			scale = 1<<10;
544			break;
545		case 'M':
546			scale = 1<<20;
547			break;
548		case 'G':
549			scale = 1<<30;
550			break;
551		default:
552			fatal("%.200s line %d: Invalid RekeyLimit suffix",
553			    filename, linenum);
554		}
555		val64 *= scale;
556		/* detect integer wrap and too-large limits */
557		if ((val64 / scale) != orig || val64 > UINT_MAX)
558			fatal("%.200s line %d: RekeyLimit too large",
559			    filename, linenum);
560		if (val64 < 16)
561			fatal("%.200s line %d: RekeyLimit too small",
562			    filename, linenum);
563		if (*activep && options->rekey_limit == -1)
564			options->rekey_limit = (u_int32_t)val64;
565		break;
566
567	case oIdentityFile:
568		arg = strdelim(&s);
569		if (!arg || *arg == '\0')
570			fatal("%.200s line %d: Missing argument.", filename, linenum);
571		if (*activep) {
572			intptr = &options->num_identity_files;
573			if (*intptr >= SSH_MAX_IDENTITY_FILES)
574				fatal("%.200s line %d: Too many identity files specified (max %d).",
575				    filename, linenum, SSH_MAX_IDENTITY_FILES);
576			charptr = &options->identity_files[*intptr];
577			*charptr = xstrdup(arg);
578			*intptr = *intptr + 1;
579		}
580		break;
581
582	case oXAuthLocation:
583		charptr=&options->xauth_location;
584		goto parse_string;
585
586	case oUser:
587		charptr = &options->user;
588parse_string:
589		arg = strdelim(&s);
590		if (!arg || *arg == '\0')
591			fatal("%.200s line %d: Missing argument.", filename, linenum);
592		if (*activep && *charptr == NULL)
593			*charptr = xstrdup(arg);
594		break;
595
596	case oGlobalKnownHostsFile:
597		charptr = &options->system_hostfile;
598		goto parse_string;
599
600	case oUserKnownHostsFile:
601		charptr = &options->user_hostfile;
602		goto parse_string;
603
604	case oGlobalKnownHostsFile2:
605		charptr = &options->system_hostfile2;
606		goto parse_string;
607
608	case oUserKnownHostsFile2:
609		charptr = &options->user_hostfile2;
610		goto parse_string;
611
612	case oHostName:
613		charptr = &options->hostname;
614		goto parse_string;
615
616	case oHostKeyAlias:
617		charptr = &options->host_key_alias;
618		goto parse_string;
619
620	case oPreferredAuthentications:
621		charptr = &options->preferred_authentications;
622		goto parse_string;
623
624	case oBindAddress:
625		charptr = &options->bind_address;
626		goto parse_string;
627
628	case oSmartcardDevice:
629		charptr = &options->smartcard_device;
630		goto parse_string;
631
632	case oProxyCommand:
633		charptr = &options->proxy_command;
634parse_command:
635		if (s == NULL)
636			fatal("%.200s line %d: Missing argument.", filename, linenum);
637		len = strspn(s, WHITESPACE "=");
638		if (*activep && *charptr == NULL)
639			*charptr = xstrdup(s + len);
640		return 0;
641
642	case oPort:
643		intptr = &options->port;
644parse_int:
645		arg = strdelim(&s);
646		if (!arg || *arg == '\0')
647			fatal("%.200s line %d: Missing argument.", filename, linenum);
648		if (arg[0] < '0' || arg[0] > '9')
649			fatal("%.200s line %d: Bad number.", filename, linenum);
650
651		/* Octal, decimal, or hex format? */
652		value = strtol(arg, &endofnumber, 0);
653		if (arg == endofnumber)
654			fatal("%.200s line %d: Bad number.", filename, linenum);
655		if (*activep && *intptr == -1)
656			*intptr = value;
657		break;
658
659	case oConnectionAttempts:
660		intptr = &options->connection_attempts;
661		goto parse_int;
662
663	case oCipher:
664		intptr = &options->cipher;
665		arg = strdelim(&s);
666		if (!arg || *arg == '\0')
667			fatal("%.200s line %d: Missing argument.", filename, linenum);
668		value = cipher_number(arg);
669		if (value == -1)
670			fatal("%.200s line %d: Bad cipher '%s'.",
671			    filename, linenum, arg ? arg : "<NONE>");
672		if (*activep && *intptr == -1)
673			*intptr = value;
674		break;
675
676	case oCiphers:
677		arg = strdelim(&s);
678		if (!arg || *arg == '\0')
679			fatal("%.200s line %d: Missing argument.", filename, linenum);
680		if (!ciphers_valid(arg))
681			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
682			    filename, linenum, arg ? arg : "<NONE>");
683		if (*activep && options->ciphers == NULL)
684			options->ciphers = xstrdup(arg);
685		break;
686
687	case oMacs:
688		arg = strdelim(&s);
689		if (!arg || *arg == '\0')
690			fatal("%.200s line %d: Missing argument.", filename, linenum);
691		if (!mac_valid(arg))
692			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
693			    filename, linenum, arg ? arg : "<NONE>");
694		if (*activep && options->macs == NULL)
695			options->macs = xstrdup(arg);
696		break;
697
698	case oHostKeyAlgorithms:
699		arg = strdelim(&s);
700		if (!arg || *arg == '\0')
701			fatal("%.200s line %d: Missing argument.", filename, linenum);
702		if (!key_names_valid2(arg))
703			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
704			    filename, linenum, arg ? arg : "<NONE>");
705		if (*activep && options->hostkeyalgorithms == NULL)
706			options->hostkeyalgorithms = xstrdup(arg);
707		break;
708
709	case oProtocol:
710		intptr = &options->protocol;
711		arg = strdelim(&s);
712		if (!arg || *arg == '\0')
713			fatal("%.200s line %d: Missing argument.", filename, linenum);
714		value = proto_spec(arg);
715		if (value == SSH_PROTO_UNKNOWN)
716			fatal("%.200s line %d: Bad protocol spec '%s'.",
717			    filename, linenum, arg ? arg : "<NONE>");
718		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
719			*intptr = value;
720		break;
721
722	case oLogLevel:
723		log_level_ptr = &options->log_level;
724		arg = strdelim(&s);
725		value = log_level_number(arg);
726		if (value == SYSLOG_LEVEL_NOT_SET)
727			fatal("%.200s line %d: unsupported log level '%s'",
728			    filename, linenum, arg ? arg : "<NONE>");
729		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
730			*log_level_ptr = (LogLevel) value;
731		break;
732
733	case oLocalForward:
734	case oRemoteForward:
735	case oDynamicForward:
736		arg = strdelim(&s);
737		if (arg == NULL || *arg == '\0')
738			fatal("%.200s line %d: Missing port argument.",
739			    filename, linenum);
740
741		if (opcode == oLocalForward ||
742		    opcode == oRemoteForward) {
743			arg2 = strdelim(&s);
744			if (arg2 == NULL || *arg2 == '\0')
745				fatal("%.200s line %d: Missing target argument.",
746				    filename, linenum);
747
748			/* construct a string for parse_forward */
749			snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
750		} else if (opcode == oDynamicForward) {
751			strlcpy(fwdarg, arg, sizeof(fwdarg));
752		}
753
754		if (parse_forward(&fwd, fwdarg,
755		    opcode == oDynamicForward ? 1 : 0,
756		    opcode == oRemoteForward ? 1 : 0) == 0)
757			fatal("%.200s line %d: Bad forwarding specification.",
758			    filename, linenum);
759
760		if (*activep) {
761			if (opcode == oLocalForward ||
762			    opcode == oDynamicForward)
763				add_local_forward(options, &fwd);
764			else if (opcode == oRemoteForward)
765				add_remote_forward(options, &fwd);
766		}
767		break;
768
769	case oClearAllForwardings:
770		intptr = &options->clear_forwardings;
771		goto parse_flag;
772
773	case oHost:
774		*activep = 0;
775		while ((arg = strdelim(&s)) != NULL && *arg != '\0')
776			if (match_pattern(host, arg)) {
777				debug("Applying options for %.100s", arg);
778				*activep = 1;
779				break;
780			}
781		/* Avoid garbage check below, as strdelim is done. */
782		return 0;
783
784	case oEscapeChar:
785		intptr = &options->escape_char;
786		arg = strdelim(&s);
787		if (!arg || *arg == '\0')
788			fatal("%.200s line %d: Missing argument.", filename, linenum);
789		if (arg[0] == '^' && arg[2] == 0 &&
790		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
791			value = (u_char) arg[1] & 31;
792		else if (strlen(arg) == 1)
793			value = (u_char) arg[0];
794		else if (strcmp(arg, "none") == 0)
795			value = SSH_ESCAPECHAR_NONE;
796		else {
797			fatal("%.200s line %d: Bad escape character.",
798			    filename, linenum);
799			/* NOTREACHED */
800			value = 0;	/* Avoid compiler warning. */
801		}
802		if (*activep && *intptr == -1)
803			*intptr = value;
804		break;
805
806	case oAddressFamily:
807		arg = strdelim(&s);
808		if (!arg || *arg == '\0')
809			fatal("%s line %d: missing address family.",
810			    filename, linenum);
811		intptr = &options->address_family;
812		if (strcasecmp(arg, "inet") == 0)
813			value = AF_INET;
814		else if (strcasecmp(arg, "inet6") == 0)
815			value = AF_INET6;
816		else if (strcasecmp(arg, "any") == 0)
817			value = AF_UNSPEC;
818		else
819			fatal("Unsupported AddressFamily \"%s\"", arg);
820		if (*activep && *intptr == -1)
821			*intptr = value;
822		break;
823
824	case oEnableSSHKeysign:
825		intptr = &options->enable_ssh_keysign;
826		goto parse_flag;
827
828	case oIdentitiesOnly:
829		intptr = &options->identities_only;
830		goto parse_flag;
831
832	case oServerAliveInterval:
833		intptr = &options->server_alive_interval;
834		goto parse_time;
835
836	case oServerAliveCountMax:
837		intptr = &options->server_alive_count_max;
838		goto parse_int;
839
840	case oSendEnv:
841		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
842			if (strchr(arg, '=') != NULL)
843				fatal("%s line %d: Invalid environment name.",
844				    filename, linenum);
845			if (!*activep)
846				continue;
847			if (options->num_send_env >= MAX_SEND_ENV)
848				fatal("%s line %d: too many send env.",
849				    filename, linenum);
850			options->send_env[options->num_send_env++] =
851			    xstrdup(arg);
852		}
853		break;
854
855	case oControlPath:
856		charptr = &options->control_path;
857		goto parse_string;
858
859	case oControlMaster:
860		intptr = &options->control_master;
861		arg = strdelim(&s);
862		if (!arg || *arg == '\0')
863			fatal("%.200s line %d: Missing ControlMaster argument.",
864			    filename, linenum);
865		value = 0;	/* To avoid compiler warning... */
866		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
867			value = SSHCTL_MASTER_YES;
868		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
869			value = SSHCTL_MASTER_NO;
870		else if (strcmp(arg, "auto") == 0)
871			value = SSHCTL_MASTER_AUTO;
872		else if (strcmp(arg, "ask") == 0)
873			value = SSHCTL_MASTER_ASK;
874		else if (strcmp(arg, "autoask") == 0)
875			value = SSHCTL_MASTER_AUTO_ASK;
876		else
877			fatal("%.200s line %d: Bad ControlMaster argument.",
878			    filename, linenum);
879		if (*activep && *intptr == -1)
880			*intptr = value;
881		break;
882
883	case oHashKnownHosts:
884		intptr = &options->hash_known_hosts;
885		goto parse_flag;
886
887	case oTunnel:
888		intptr = &options->tun_open;
889		arg = strdelim(&s);
890		if (!arg || *arg == '\0')
891			fatal("%s line %d: Missing yes/point-to-point/"
892			    "ethernet/no argument.", filename, linenum);
893		value = 0;	/* silence compiler */
894		if (strcasecmp(arg, "ethernet") == 0)
895			value = SSH_TUNMODE_ETHERNET;
896		else if (strcasecmp(arg, "point-to-point") == 0)
897			value = SSH_TUNMODE_POINTOPOINT;
898		else if (strcasecmp(arg, "yes") == 0)
899			value = SSH_TUNMODE_DEFAULT;
900		else if (strcasecmp(arg, "no") == 0)
901			value = SSH_TUNMODE_NO;
902		else
903			fatal("%s line %d: Bad yes/point-to-point/ethernet/"
904			    "no argument: %s", filename, linenum, arg);
905		if (*activep)
906			*intptr = value;
907		break;
908
909	case oTunnelDevice:
910		arg = strdelim(&s);
911		if (!arg || *arg == '\0')
912			fatal("%.200s line %d: Missing argument.", filename, linenum);
913		value = a2tun(arg, &value2);
914		if (value == SSH_TUNID_ERR)
915			fatal("%.200s line %d: Bad tun device.", filename, linenum);
916		if (*activep) {
917			options->tun_local = value;
918			options->tun_remote = value2;
919		}
920		break;
921
922	case oLocalCommand:
923		charptr = &options->local_command;
924		goto parse_command;
925
926	case oPermitLocalCommand:
927		intptr = &options->permit_local_command;
928		goto parse_flag;
929
930	case oVisualHostKey:
931		intptr = &options->visual_host_key;
932		goto parse_flag;
933
934	case oVersionAddendum:
935		ssh_version_set_addendum(strtok(s, "\n"));
936		do {
937			arg = strdelim(&s);
938		} while (arg != NULL && *arg != '\0');
939		break;
940
941	case oDeprecated:
942		debug("%s line %d: Deprecated option \"%s\"",
943		    filename, linenum, keyword);
944		return 0;
945
946	case oUnsupported:
947		error("%s line %d: Unsupported option \"%s\"",
948		    filename, linenum, keyword);
949		return 0;
950
951	default:
952		fatal("process_config_line: Unimplemented opcode %d", opcode);
953	}
954
955	/* Check that there is no garbage at end of line. */
956	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
957		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
958		    filename, linenum, arg);
959	}
960	return 0;
961}
962
963
964/*
965 * Reads the config file and modifies the options accordingly.  Options
966 * should already be initialized before this call.  This never returns if
967 * there is an error.  If the file does not exist, this returns 0.
968 */
969
970int
971read_config_file(const char *filename, const char *host, Options *options,
972    int checkperm)
973{
974	FILE *f;
975	char line[1024];
976	int active, linenum;
977	int bad_options = 0;
978
979	if ((f = fopen(filename, "r")) == NULL)
980		return 0;
981
982	if (checkperm) {
983		struct stat sb;
984
985		if (fstat(fileno(f), &sb) == -1)
986			fatal("fstat %s: %s", filename, strerror(errno));
987		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
988		    (sb.st_mode & 022) != 0))
989			fatal("Bad owner or permissions on %s", filename);
990	}
991
992	debug("Reading configuration data %.200s", filename);
993
994	/*
995	 * Mark that we are now processing the options.  This flag is turned
996	 * on/off by Host specifications.
997	 */
998	active = 1;
999	linenum = 0;
1000	while (fgets(line, sizeof(line), f)) {
1001		/* Update line number counter. */
1002		linenum++;
1003		if (process_config_line(options, host, line, filename, linenum, &active) != 0)
1004			bad_options++;
1005	}
1006	fclose(f);
1007	if (bad_options > 0)
1008		fatal("%s: terminating, %d bad configuration options",
1009		    filename, bad_options);
1010	return 1;
1011}
1012
1013/*
1014 * Initializes options to special values that indicate that they have not yet
1015 * been set.  Read_config_file will only set options with this value. Options
1016 * are processed in the following order: command line, user config file,
1017 * system config file.  Last, fill_default_options is called.
1018 */
1019
1020void
1021initialize_options(Options * options)
1022{
1023	memset(options, 'X', sizeof(*options));
1024	options->forward_agent = -1;
1025	options->forward_x11 = -1;
1026	options->forward_x11_trusted = -1;
1027	options->exit_on_forward_failure = -1;
1028	options->xauth_location = NULL;
1029	options->gateway_ports = -1;
1030	options->use_privileged_port = -1;
1031	options->rsa_authentication = -1;
1032	options->pubkey_authentication = -1;
1033	options->challenge_response_authentication = -1;
1034	options->gss_authentication = -1;
1035	options->gss_deleg_creds = -1;
1036	options->password_authentication = -1;
1037	options->kbd_interactive_authentication = -1;
1038	options->kbd_interactive_devices = NULL;
1039	options->rhosts_rsa_authentication = -1;
1040	options->hostbased_authentication = -1;
1041	options->batch_mode = -1;
1042	options->check_host_ip = -1;
1043	options->strict_host_key_checking = -1;
1044	options->compression = -1;
1045	options->tcp_keep_alive = -1;
1046	options->compression_level = -1;
1047	options->port = -1;
1048	options->address_family = -1;
1049	options->connection_attempts = -1;
1050	options->connection_timeout = -1;
1051	options->number_of_password_prompts = -1;
1052	options->cipher = -1;
1053	options->ciphers = NULL;
1054	options->macs = NULL;
1055	options->hostkeyalgorithms = NULL;
1056	options->protocol = SSH_PROTO_UNKNOWN;
1057	options->num_identity_files = 0;
1058	options->hostname = NULL;
1059	options->host_key_alias = NULL;
1060	options->proxy_command = NULL;
1061	options->user = NULL;
1062	options->escape_char = -1;
1063	options->system_hostfile = NULL;
1064	options->user_hostfile = NULL;
1065	options->system_hostfile2 = NULL;
1066	options->user_hostfile2 = NULL;
1067	options->num_local_forwards = 0;
1068	options->num_remote_forwards = 0;
1069	options->clear_forwardings = -1;
1070	options->log_level = SYSLOG_LEVEL_NOT_SET;
1071	options->preferred_authentications = NULL;
1072	options->bind_address = NULL;
1073	options->smartcard_device = NULL;
1074	options->enable_ssh_keysign = - 1;
1075	options->no_host_authentication_for_localhost = - 1;
1076	options->identities_only = - 1;
1077	options->rekey_limit = - 1;
1078	options->verify_host_key_dns = -1;
1079	options->server_alive_interval = -1;
1080	options->server_alive_count_max = -1;
1081	options->num_send_env = 0;
1082	options->control_path = NULL;
1083	options->control_master = -1;
1084	options->hash_known_hosts = -1;
1085	options->tun_open = -1;
1086	options->tun_local = -1;
1087	options->tun_remote = -1;
1088	options->local_command = NULL;
1089	options->permit_local_command = -1;
1090	options->visual_host_key = -1;
1091	options->zero_knowledge_password_authentication = -1;
1092}
1093
1094/*
1095 * Called after processing other sources of option data, this fills those
1096 * options for which no value has been specified with their default values.
1097 */
1098
1099void
1100fill_default_options(Options * options)
1101{
1102	int len;
1103
1104	if (options->forward_agent == -1)
1105		options->forward_agent = 0;
1106	if (options->forward_x11 == -1)
1107		options->forward_x11 = 0;
1108	if (options->forward_x11_trusted == -1)
1109		options->forward_x11_trusted = 0;
1110	if (options->exit_on_forward_failure == -1)
1111		options->exit_on_forward_failure = 0;
1112	if (options->xauth_location == NULL)
1113		options->xauth_location = _PATH_XAUTH;
1114	if (options->gateway_ports == -1)
1115		options->gateway_ports = 0;
1116	if (options->use_privileged_port == -1)
1117		options->use_privileged_port = 0;
1118	if (options->rsa_authentication == -1)
1119		options->rsa_authentication = 1;
1120	if (options->pubkey_authentication == -1)
1121		options->pubkey_authentication = 1;
1122	if (options->challenge_response_authentication == -1)
1123		options->challenge_response_authentication = 1;
1124	if (options->gss_authentication == -1)
1125		options->gss_authentication = 0;
1126	if (options->gss_deleg_creds == -1)
1127		options->gss_deleg_creds = 0;
1128	if (options->password_authentication == -1)
1129		options->password_authentication = 1;
1130	if (options->kbd_interactive_authentication == -1)
1131		options->kbd_interactive_authentication = 1;
1132	if (options->rhosts_rsa_authentication == -1)
1133		options->rhosts_rsa_authentication = 0;
1134	if (options->hostbased_authentication == -1)
1135		options->hostbased_authentication = 0;
1136	if (options->batch_mode == -1)
1137		options->batch_mode = 0;
1138	if (options->check_host_ip == -1)
1139		options->check_host_ip = 0;
1140	if (options->strict_host_key_checking == -1)
1141		options->strict_host_key_checking = 2;	/* 2 is default */
1142	if (options->compression == -1)
1143		options->compression = 0;
1144	if (options->tcp_keep_alive == -1)
1145		options->tcp_keep_alive = 1;
1146	if (options->compression_level == -1)
1147		options->compression_level = 6;
1148	if (options->port == -1)
1149		options->port = 0;	/* Filled in ssh_connect. */
1150	if (options->address_family == -1)
1151		options->address_family = AF_UNSPEC;
1152	if (options->connection_attempts == -1)
1153		options->connection_attempts = 1;
1154	if (options->number_of_password_prompts == -1)
1155		options->number_of_password_prompts = 3;
1156	/* Selected in ssh_login(). */
1157	if (options->cipher == -1)
1158		options->cipher = SSH_CIPHER_NOT_SET;
1159	/* options->ciphers, default set in myproposals.h */
1160	/* options->macs, default set in myproposals.h */
1161	/* options->hostkeyalgorithms, default set in myproposals.h */
1162	if (options->protocol == SSH_PROTO_UNKNOWN)
1163		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
1164	if (options->num_identity_files == 0) {
1165		if (options->protocol & SSH_PROTO_1) {
1166			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
1167			options->identity_files[options->num_identity_files] =
1168			    xmalloc(len);
1169			snprintf(options->identity_files[options->num_identity_files++],
1170			    len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
1171		}
1172		if (options->protocol & SSH_PROTO_2) {
1173			len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1174			options->identity_files[options->num_identity_files] =
1175			    xmalloc(len);
1176			snprintf(options->identity_files[options->num_identity_files++],
1177			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1178
1179			len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
1180			options->identity_files[options->num_identity_files] =
1181			    xmalloc(len);
1182			snprintf(options->identity_files[options->num_identity_files++],
1183			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
1184		}
1185	}
1186	if (options->escape_char == -1)
1187		options->escape_char = '~';
1188	if (options->system_hostfile == NULL)
1189		options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
1190	if (options->user_hostfile == NULL)
1191		options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
1192	if (options->system_hostfile2 == NULL)
1193		options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
1194	if (options->user_hostfile2 == NULL)
1195		options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
1196	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1197		options->log_level = SYSLOG_LEVEL_INFO;
1198	if (options->clear_forwardings == 1)
1199		clear_forwardings(options);
1200	if (options->no_host_authentication_for_localhost == - 1)
1201		options->no_host_authentication_for_localhost = 0;
1202	if (options->identities_only == -1)
1203		options->identities_only = 0;
1204	if (options->enable_ssh_keysign == -1)
1205		options->enable_ssh_keysign = 0;
1206	if (options->rekey_limit == -1)
1207		options->rekey_limit = 0;
1208	if (options->verify_host_key_dns == -1)
1209		options->verify_host_key_dns = 0;
1210	if (options->server_alive_interval == -1)
1211		options->server_alive_interval = 0;
1212	if (options->server_alive_count_max == -1)
1213		options->server_alive_count_max = 3;
1214	if (options->control_master == -1)
1215		options->control_master = 0;
1216	if (options->hash_known_hosts == -1)
1217		options->hash_known_hosts = 0;
1218	if (options->tun_open == -1)
1219		options->tun_open = SSH_TUNMODE_NO;
1220	if (options->tun_local == -1)
1221		options->tun_local = SSH_TUNID_ANY;
1222	if (options->tun_remote == -1)
1223		options->tun_remote = SSH_TUNID_ANY;
1224	if (options->permit_local_command == -1)
1225		options->permit_local_command = 0;
1226	if (options->visual_host_key == -1)
1227		options->visual_host_key = 0;
1228	if (options->zero_knowledge_password_authentication == -1)
1229		options->zero_knowledge_password_authentication = 0;
1230	/* options->local_command should not be set by default */
1231	/* options->proxy_command should not be set by default */
1232	/* options->user will be set in the main program if appropriate */
1233	/* options->hostname will be set in the main program if appropriate */
1234	/* options->host_key_alias should not be set by default */
1235	/* options->preferred_authentications will be set in ssh */
1236}
1237
1238/*
1239 * parse_forward
1240 * parses a string containing a port forwarding specification of the form:
1241 *   dynamicfwd == 0
1242 *	[listenhost:]listenport:connecthost:connectport
1243 *   dynamicfwd == 1
1244 *	[listenhost:]listenport
1245 * returns number of arguments parsed or zero on error
1246 */
1247int
1248parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1249{
1250	int i;
1251	char *p, *cp, *fwdarg[4];
1252
1253	memset(fwd, '\0', sizeof(*fwd));
1254
1255	cp = p = xstrdup(fwdspec);
1256
1257	/* skip leading spaces */
1258	while (isspace(*cp))
1259		cp++;
1260
1261	for (i = 0; i < 4; ++i)
1262		if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1263			break;
1264
1265	/* Check for trailing garbage */
1266	if (cp != NULL)
1267		i = 0;	/* failure */
1268
1269	switch (i) {
1270	case 1:
1271		fwd->listen_host = NULL;
1272		fwd->listen_port = a2port(fwdarg[0]);
1273		fwd->connect_host = xstrdup("socks");
1274		break;
1275
1276	case 2:
1277		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1278		fwd->listen_port = a2port(fwdarg[1]);
1279		fwd->connect_host = xstrdup("socks");
1280		break;
1281
1282	case 3:
1283		fwd->listen_host = NULL;
1284		fwd->listen_port = a2port(fwdarg[0]);
1285		fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1286		fwd->connect_port = a2port(fwdarg[2]);
1287		break;
1288
1289	case 4:
1290		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1291		fwd->listen_port = a2port(fwdarg[1]);
1292		fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1293		fwd->connect_port = a2port(fwdarg[3]);
1294		break;
1295	default:
1296		i = 0; /* failure */
1297	}
1298
1299	xfree(p);
1300
1301	if (dynamicfwd) {
1302		if (!(i == 1 || i == 2))
1303			goto fail_free;
1304	} else {
1305		if (!(i == 3 || i == 4))
1306			goto fail_free;
1307		if (fwd->connect_port <= 0)
1308			goto fail_free;
1309	}
1310
1311	if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
1312		goto fail_free;
1313
1314	if (fwd->connect_host != NULL &&
1315	    strlen(fwd->connect_host) >= NI_MAXHOST)
1316		goto fail_free;
1317	if (fwd->listen_host != NULL &&
1318	    strlen(fwd->listen_host) >= NI_MAXHOST)
1319		goto fail_free;
1320
1321
1322	return (i);
1323
1324 fail_free:
1325	if (fwd->connect_host != NULL) {
1326		xfree(fwd->connect_host);
1327		fwd->connect_host = NULL;
1328	}
1329	if (fwd->listen_host != NULL) {
1330		xfree(fwd->listen_host);
1331		fwd->listen_host = NULL;
1332	}
1333	return (0);
1334}
1335