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