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