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