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