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