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