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