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