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