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