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