xref: /openbsd-src/usr.bin/ssh/readconf.c (revision 3a3fbb3f2e2521ab7c4a56b7ff7462ebd9095ec5)
1 /*
2  * Author: Tatu Ylonen <ylo@cs.hut.fi>
3  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4  *                    All rights reserved
5  * Functions for reading the configuration files.
6  *
7  * As far as I am concerned, the code I have written for this software
8  * can be used freely for any purpose.  Any derived versions of this
9  * software must be clearly marked as such, and if the derived work is
10  * incompatible with the protocol description in the RFC file, it must be
11  * called by a name other than "ssh" or "Secure Shell".
12  */
13 
14 #include "includes.h"
15 RCSID("$OpenBSD: readconf.c,v 1.93 2001/12/19 07:18:56 deraadt Exp $");
16 
17 #include "ssh.h"
18 #include "xmalloc.h"
19 #include "compat.h"
20 #include "cipher.h"
21 #include "pathnames.h"
22 #include "log.h"
23 #include "readconf.h"
24 #include "match.h"
25 #include "misc.h"
26 #include "kex.h"
27 #include "mac.h"
28 
29 /* Format of the configuration file:
30 
31    # Configuration data is parsed as follows:
32    #  1. command line options
33    #  2. user-specific file
34    #  3. system-wide file
35    # Any configuration value is only changed the first time it is set.
36    # Thus, host-specific definitions should be at the beginning of the
37    # configuration file, and defaults at the end.
38 
39    # Host-specific declarations.  These may override anything above.  A single
40    # host may match multiple declarations; these are processed in the order
41    # that they are given in.
42 
43    Host *.ngs.fi ngs.fi
44      FallBackToRsh no
45 
46    Host fake.com
47      HostName another.host.name.real.org
48      User blaah
49      Port 34289
50      ForwardX11 no
51      ForwardAgent no
52 
53    Host books.com
54      RemoteForward 9999 shadows.cs.hut.fi:9999
55      Cipher 3des
56 
57    Host fascist.blob.com
58      Port 23123
59      User tylonen
60      RhostsAuthentication no
61      PasswordAuthentication no
62 
63    Host puukko.hut.fi
64      User t35124p
65      ProxyCommand ssh-proxy %h %p
66 
67    Host *.fr
68      UseRsh yes
69 
70    Host *.su
71      Cipher none
72      PasswordAuthentication no
73 
74    # Defaults for various options
75    Host *
76      ForwardAgent no
77      ForwardX11 no
78      RhostsAuthentication yes
79      PasswordAuthentication yes
80      RSAAuthentication yes
81      RhostsRSAAuthentication yes
82      FallBackToRsh no
83      UseRsh no
84      StrictHostKeyChecking yes
85      KeepAlives no
86      IdentityFile ~/.ssh/identity
87      Port 22
88      EscapeChar ~
89 
90 */
91 
92 /* Keyword tokens. */
93 
94 typedef enum {
95 	oBadOption,
96 	oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
97 	oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
98 	oChallengeResponseAuthentication, oXAuthLocation,
99 #if defined(KRB4) || defined(KRB5)
100 	oKerberosAuthentication,
101 #endif
102 #if defined(AFS) || defined(KRB5)
103 	oKerberosTgtPassing,
104 #endif
105 #ifdef AFS
106 	oAFSTokenPassing,
107 #endif
108 	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
109 	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
110 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
111 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
112 	oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
113 	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
114 	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
115 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
116 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
117 	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
118 	oClearAllForwardings, oNoHostAuthenticationForLocalhost
119 } OpCodes;
120 
121 /* Textual representations of the tokens. */
122 
123 static struct {
124 	const char *name;
125 	OpCodes opcode;
126 } keywords[] = {
127 	{ "forwardagent", oForwardAgent },
128 	{ "forwardx11", oForwardX11 },
129 	{ "xauthlocation", oXAuthLocation },
130 	{ "gatewayports", oGatewayPorts },
131 	{ "useprivilegedport", oUsePrivilegedPort },
132 	{ "rhostsauthentication", oRhostsAuthentication },
133 	{ "passwordauthentication", oPasswordAuthentication },
134 	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
135 	{ "kbdinteractivedevices", oKbdInteractiveDevices },
136 	{ "rsaauthentication", oRSAAuthentication },
137 	{ "pubkeyauthentication", oPubkeyAuthentication },
138 	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
139 	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
140 	{ "hostbasedauthentication", oHostbasedAuthentication },
141 	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
142 	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
143 	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
144 #if defined(KRB4) || defined(KRB5)
145 	{ "kerberosauthentication", oKerberosAuthentication },
146 #endif
147 #if defined(AFS) || defined(KRB5)
148 	{ "kerberostgtpassing", oKerberosTgtPassing },
149 #endif
150 #ifdef AFS
151 	{ "afstokenpassing", oAFSTokenPassing },
152 #endif
153 	{ "fallbacktorsh", oFallBackToRsh },
154 	{ "usersh", oUseRsh },
155 	{ "identityfile", oIdentityFile },
156 	{ "identityfile2", oIdentityFile },			/* alias */
157 	{ "hostname", oHostName },
158 	{ "hostkeyalias", oHostKeyAlias },
159 	{ "proxycommand", oProxyCommand },
160 	{ "port", oPort },
161 	{ "cipher", oCipher },
162 	{ "ciphers", oCiphers },
163 	{ "macs", oMacs },
164 	{ "protocol", oProtocol },
165 	{ "remoteforward", oRemoteForward },
166 	{ "localforward", oLocalForward },
167 	{ "user", oUser },
168 	{ "host", oHost },
169 	{ "escapechar", oEscapeChar },
170 	{ "globalknownhostsfile", oGlobalKnownHostsFile },
171 	{ "userknownhostsfile", oUserKnownHostsFile },		/* obsolete */
172 	{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },
173 	{ "userknownhostsfile2", oUserKnownHostsFile2 },	/* obsolete */
174 	{ "connectionattempts", oConnectionAttempts },
175 	{ "batchmode", oBatchMode },
176 	{ "checkhostip", oCheckHostIP },
177 	{ "stricthostkeychecking", oStrictHostKeyChecking },
178 	{ "compression", oCompression },
179 	{ "compressionlevel", oCompressionLevel },
180 	{ "keepalive", oKeepAlives },
181 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
182 	{ "loglevel", oLogLevel },
183 	{ "dynamicforward", oDynamicForward },
184 	{ "preferredauthentications", oPreferredAuthentications },
185 	{ "hostkeyalgorithms", oHostKeyAlgorithms },
186 	{ "bindaddress", oBindAddress },
187 	{ "smartcarddevice", oSmartcardDevice },
188 	{ "clearallforwardings", oClearAllForwardings },
189 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
190 	{ NULL, oBadOption }
191 };
192 
193 /*
194  * Adds a local TCP/IP port forward to options.  Never returns if there is an
195  * error.
196  */
197 
198 void
199 add_local_forward(Options *options, u_short port, const char *host,
200 		  u_short host_port)
201 {
202 	Forward *fwd;
203 	extern uid_t original_real_uid;
204 	if (port < IPPORT_RESERVED && original_real_uid != 0)
205 		fatal("Privileged ports can only be forwarded by root.");
206 	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
207 		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
208 	fwd = &options->local_forwards[options->num_local_forwards++];
209 	fwd->port = port;
210 	fwd->host = xstrdup(host);
211 	fwd->host_port = host_port;
212 }
213 
214 /*
215  * Adds a remote TCP/IP port forward to options.  Never returns if there is
216  * an error.
217  */
218 
219 void
220 add_remote_forward(Options *options, u_short port, const char *host,
221 		   u_short host_port)
222 {
223 	Forward *fwd;
224 	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
225 		fatal("Too many remote forwards (max %d).",
226 		    SSH_MAX_FORWARDS_PER_DIRECTION);
227 	fwd = &options->remote_forwards[options->num_remote_forwards++];
228 	fwd->port = port;
229 	fwd->host = xstrdup(host);
230 	fwd->host_port = host_port;
231 }
232 
233 static void
234 clear_forwardings(Options *options)
235 {
236 	int i;
237 
238 	for (i = 0; i < options->num_local_forwards; i++)
239 		xfree(options->local_forwards[i].host);
240 	options->num_local_forwards = 0;
241 	for (i = 0; i < options->num_remote_forwards; i++)
242 		xfree(options->remote_forwards[i].host);
243 	options->num_remote_forwards = 0;
244 }
245 
246 /*
247  * Returns the number of the token pointed to by cp or oBadOption.
248  */
249 
250 static OpCodes
251 parse_token(const char *cp, const char *filename, int linenum)
252 {
253 	u_int i;
254 
255 	for (i = 0; keywords[i].name; i++)
256 		if (strcasecmp(cp, keywords[i].name) == 0)
257 			return keywords[i].opcode;
258 
259 	error("%s: line %d: Bad configuration option: %s",
260 	    filename, linenum, cp);
261 	return oBadOption;
262 }
263 
264 /*
265  * Processes a single option line as used in the configuration files. This
266  * only sets those values that have not already been set.
267  */
268 
269 int
270 process_config_line(Options *options, const char *host,
271 		    char *line, const char *filename, int linenum,
272 		    int *activep)
273 {
274 	char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
275 	int opcode, *intptr, value;
276 	u_short fwd_port, fwd_host_port;
277 	char sfwd_host_port[6];
278 
279 	s = line;
280 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
281 	keyword = strdelim(&s);
282 	/* Ignore leading whitespace. */
283 	if (*keyword == '\0')
284 		keyword = strdelim(&s);
285 	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
286 		return 0;
287 
288 	opcode = parse_token(keyword, filename, linenum);
289 
290 	switch (opcode) {
291 	case oBadOption:
292 		/* don't panic, but count bad options */
293 		return -1;
294 		/* NOTREACHED */
295 	case oForwardAgent:
296 		intptr = &options->forward_agent;
297 parse_flag:
298 		arg = strdelim(&s);
299 		if (!arg || *arg == '\0')
300 			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
301 		value = 0;	/* To avoid compiler warning... */
302 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
303 			value = 1;
304 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
305 			value = 0;
306 		else
307 			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
308 		if (*activep && *intptr == -1)
309 			*intptr = value;
310 		break;
311 
312 	case oForwardX11:
313 		intptr = &options->forward_x11;
314 		goto parse_flag;
315 
316 	case oGatewayPorts:
317 		intptr = &options->gateway_ports;
318 		goto parse_flag;
319 
320 	case oUsePrivilegedPort:
321 		intptr = &options->use_privileged_port;
322 		goto parse_flag;
323 
324 	case oRhostsAuthentication:
325 		intptr = &options->rhosts_authentication;
326 		goto parse_flag;
327 
328 	case oPasswordAuthentication:
329 		intptr = &options->password_authentication;
330 		goto parse_flag;
331 
332 	case oKbdInteractiveAuthentication:
333 		intptr = &options->kbd_interactive_authentication;
334 		goto parse_flag;
335 
336 	case oKbdInteractiveDevices:
337 		charptr = &options->kbd_interactive_devices;
338 		goto parse_string;
339 
340 	case oPubkeyAuthentication:
341 		intptr = &options->pubkey_authentication;
342 		goto parse_flag;
343 
344 	case oRSAAuthentication:
345 		intptr = &options->rsa_authentication;
346 		goto parse_flag;
347 
348 	case oRhostsRSAAuthentication:
349 		intptr = &options->rhosts_rsa_authentication;
350 		goto parse_flag;
351 
352 	case oHostbasedAuthentication:
353 		intptr = &options->hostbased_authentication;
354 		goto parse_flag;
355 
356 	case oChallengeResponseAuthentication:
357 		intptr = &options->challenge_response_authentication;
358 		goto parse_flag;
359 #if defined(KRB4) || defined(KRB5)
360 	case oKerberosAuthentication:
361 		intptr = &options->kerberos_authentication;
362 		goto parse_flag;
363 #endif
364 #if defined(AFS) || defined(KRB5)
365 	case oKerberosTgtPassing:
366 		intptr = &options->kerberos_tgt_passing;
367 		goto parse_flag;
368 #endif
369 #ifdef AFS
370 	case oAFSTokenPassing:
371 		intptr = &options->afs_token_passing;
372 		goto parse_flag;
373 #endif
374 	case oFallBackToRsh:
375 		intptr = &options->fallback_to_rsh;
376 		goto parse_flag;
377 
378 	case oUseRsh:
379 		intptr = &options->use_rsh;
380 		goto parse_flag;
381 
382 	case oBatchMode:
383 		intptr = &options->batch_mode;
384 		goto parse_flag;
385 
386 	case oCheckHostIP:
387 		intptr = &options->check_host_ip;
388 		goto parse_flag;
389 
390 	case oStrictHostKeyChecking:
391 		intptr = &options->strict_host_key_checking;
392 		arg = strdelim(&s);
393 		if (!arg || *arg == '\0')
394 			fatal("%.200s line %d: Missing yes/no/ask argument.",
395 			    filename, linenum);
396 		value = 0;	/* To avoid compiler warning... */
397 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
398 			value = 1;
399 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
400 			value = 0;
401 		else if (strcmp(arg, "ask") == 0)
402 			value = 2;
403 		else
404 			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
405 		if (*activep && *intptr == -1)
406 			*intptr = value;
407 		break;
408 
409 	case oCompression:
410 		intptr = &options->compression;
411 		goto parse_flag;
412 
413 	case oKeepAlives:
414 		intptr = &options->keepalives;
415 		goto parse_flag;
416 
417 	case oNoHostAuthenticationForLocalhost:
418 		intptr = &options->no_host_authentication_for_localhost;
419 		goto parse_flag;
420 
421 	case oNumberOfPasswordPrompts:
422 		intptr = &options->number_of_password_prompts;
423 		goto parse_int;
424 
425 	case oCompressionLevel:
426 		intptr = &options->compression_level;
427 		goto parse_int;
428 
429 	case oIdentityFile:
430 		arg = strdelim(&s);
431 		if (!arg || *arg == '\0')
432 			fatal("%.200s line %d: Missing argument.", filename, linenum);
433 		if (*activep) {
434 			intptr = &options->num_identity_files;
435 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
436 				fatal("%.200s line %d: Too many identity files specified (max %d).",
437 				    filename, linenum, SSH_MAX_IDENTITY_FILES);
438 			charptr =  &options->identity_files[*intptr];
439 			*charptr = xstrdup(arg);
440 			*intptr = *intptr + 1;
441 		}
442 		break;
443 
444 	case oXAuthLocation:
445 		charptr=&options->xauth_location;
446 		goto parse_string;
447 
448 	case oUser:
449 		charptr = &options->user;
450 parse_string:
451 		arg = strdelim(&s);
452 		if (!arg || *arg == '\0')
453 			fatal("%.200s line %d: Missing argument.", filename, linenum);
454 		if (*activep && *charptr == NULL)
455 			*charptr = xstrdup(arg);
456 		break;
457 
458 	case oGlobalKnownHostsFile:
459 		charptr = &options->system_hostfile;
460 		goto parse_string;
461 
462 	case oUserKnownHostsFile:
463 		charptr = &options->user_hostfile;
464 		goto parse_string;
465 
466 	case oGlobalKnownHostsFile2:
467 		charptr = &options->system_hostfile2;
468 		goto parse_string;
469 
470 	case oUserKnownHostsFile2:
471 		charptr = &options->user_hostfile2;
472 		goto parse_string;
473 
474 	case oHostName:
475 		charptr = &options->hostname;
476 		goto parse_string;
477 
478 	case oHostKeyAlias:
479 		charptr = &options->host_key_alias;
480 		goto parse_string;
481 
482 	case oPreferredAuthentications:
483 		charptr = &options->preferred_authentications;
484 		goto parse_string;
485 
486 	case oBindAddress:
487 		charptr = &options->bind_address;
488 		goto parse_string;
489 
490 	case oSmartcardDevice:
491 		charptr = &options->smartcard_device;
492 		goto parse_string;
493 
494 	case oProxyCommand:
495 		charptr = &options->proxy_command;
496 		string = xstrdup("");
497 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
498 			string = xrealloc(string, strlen(string) + strlen(arg) + 2);
499 			strcat(string, " ");
500 			strcat(string, arg);
501 		}
502 		if (*activep && *charptr == NULL)
503 			*charptr = string;
504 		else
505 			xfree(string);
506 		return 0;
507 
508 	case oPort:
509 		intptr = &options->port;
510 parse_int:
511 		arg = strdelim(&s);
512 		if (!arg || *arg == '\0')
513 			fatal("%.200s line %d: Missing argument.", filename, linenum);
514 		if (arg[0] < '0' || arg[0] > '9')
515 			fatal("%.200s line %d: Bad number.", filename, linenum);
516 
517 		/* Octal, decimal, or hex format? */
518 		value = strtol(arg, &endofnumber, 0);
519 		if (arg == endofnumber)
520 			fatal("%.200s line %d: Bad number.", filename, linenum);
521 		if (*activep && *intptr == -1)
522 			*intptr = value;
523 		break;
524 
525 	case oConnectionAttempts:
526 		intptr = &options->connection_attempts;
527 		goto parse_int;
528 
529 	case oCipher:
530 		intptr = &options->cipher;
531 		arg = strdelim(&s);
532 		if (!arg || *arg == '\0')
533 			fatal("%.200s line %d: Missing argument.", filename, linenum);
534 		value = cipher_number(arg);
535 		if (value == -1)
536 			fatal("%.200s line %d: Bad cipher '%s'.",
537 			    filename, linenum, arg ? arg : "<NONE>");
538 		if (*activep && *intptr == -1)
539 			*intptr = value;
540 		break;
541 
542 	case oCiphers:
543 		arg = strdelim(&s);
544 		if (!arg || *arg == '\0')
545 			fatal("%.200s line %d: Missing argument.", filename, linenum);
546 		if (!ciphers_valid(arg))
547 			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
548 			    filename, linenum, arg ? arg : "<NONE>");
549 		if (*activep && options->ciphers == NULL)
550 			options->ciphers = xstrdup(arg);
551 		break;
552 
553 	case oMacs:
554 		arg = strdelim(&s);
555 		if (!arg || *arg == '\0')
556 			fatal("%.200s line %d: Missing argument.", filename, linenum);
557 		if (!mac_valid(arg))
558 			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
559 			    filename, linenum, arg ? arg : "<NONE>");
560 		if (*activep && options->macs == NULL)
561 			options->macs = xstrdup(arg);
562 		break;
563 
564 	case oHostKeyAlgorithms:
565 		arg = strdelim(&s);
566 		if (!arg || *arg == '\0')
567 			fatal("%.200s line %d: Missing argument.", filename, linenum);
568 		if (!key_names_valid2(arg))
569 			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
570 			    filename, linenum, arg ? arg : "<NONE>");
571 		if (*activep && options->hostkeyalgorithms == NULL)
572 			options->hostkeyalgorithms = xstrdup(arg);
573 		break;
574 
575 	case oProtocol:
576 		intptr = &options->protocol;
577 		arg = strdelim(&s);
578 		if (!arg || *arg == '\0')
579 			fatal("%.200s line %d: Missing argument.", filename, linenum);
580 		value = proto_spec(arg);
581 		if (value == SSH_PROTO_UNKNOWN)
582 			fatal("%.200s line %d: Bad protocol spec '%s'.",
583 			    filename, linenum, arg ? arg : "<NONE>");
584 		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
585 			*intptr = value;
586 		break;
587 
588 	case oLogLevel:
589 		intptr = (int *) &options->log_level;
590 		arg = strdelim(&s);
591 		value = log_level_number(arg);
592 		if (value == (LogLevel) - 1)
593 			fatal("%.200s line %d: unsupported log level '%s'",
594 			    filename, linenum, arg ? arg : "<NONE>");
595 		if (*activep && (LogLevel) * intptr == -1)
596 			*intptr = (LogLevel) value;
597 		break;
598 
599 	case oLocalForward:
600 	case oRemoteForward:
601 		arg = strdelim(&s);
602 		if (!arg || *arg == '\0')
603 			fatal("%.200s line %d: Missing port argument.",
604 			    filename, linenum);
605 		if ((fwd_port = a2port(arg)) == 0)
606 			fatal("%.200s line %d: Bad listen port.",
607 			    filename, linenum);
608 		arg = strdelim(&s);
609 		if (!arg || *arg == '\0')
610 			fatal("%.200s line %d: Missing second argument.",
611 			    filename, linenum);
612 		if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
613 		    sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
614 			fatal("%.200s line %d: Bad forwarding specification.",
615 			    filename, linenum);
616 		if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
617 			fatal("%.200s line %d: Bad forwarding port.",
618 			    filename, linenum);
619 		if (*activep) {
620 			if (opcode == oLocalForward)
621 				add_local_forward(options, fwd_port, buf,
622 				    fwd_host_port);
623 			else if (opcode == oRemoteForward)
624 				add_remote_forward(options, fwd_port, buf,
625 				    fwd_host_port);
626 		}
627 		break;
628 
629 	case oDynamicForward:
630 		arg = strdelim(&s);
631 		if (!arg || *arg == '\0')
632 			fatal("%.200s line %d: Missing port argument.",
633 			    filename, linenum);
634 		fwd_port = a2port(arg);
635 		if (fwd_port == 0)
636 			fatal("%.200s line %d: Badly formatted port number.",
637 			    filename, linenum);
638 		if (*activep)
639 			add_local_forward(options, fwd_port, "socks4", 0);
640 		break;
641 
642 	case oClearAllForwardings:
643 		intptr = &options->clear_forwardings;
644 		goto parse_flag;
645 
646 	case oHost:
647 		*activep = 0;
648 		while ((arg = strdelim(&s)) != NULL && *arg != '\0')
649 			if (match_pattern(host, arg)) {
650 				debug("Applying options for %.100s", arg);
651 				*activep = 1;
652 				break;
653 			}
654 		/* Avoid garbage check below, as strdelim is done. */
655 		return 0;
656 
657 	case oEscapeChar:
658 		intptr = &options->escape_char;
659 		arg = strdelim(&s);
660 		if (!arg || *arg == '\0')
661 			fatal("%.200s line %d: Missing argument.", filename, linenum);
662 		if (arg[0] == '^' && arg[2] == 0 &&
663 		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
664 			value = (u_char) arg[1] & 31;
665 		else if (strlen(arg) == 1)
666 			value = (u_char) arg[0];
667 		else if (strcmp(arg, "none") == 0)
668 			value = SSH_ESCAPECHAR_NONE;
669 		else {
670 			fatal("%.200s line %d: Bad escape character.",
671 			    filename, linenum);
672 			/* NOTREACHED */
673 			value = 0;	/* Avoid compiler warning. */
674 		}
675 		if (*activep && *intptr == -1)
676 			*intptr = value;
677 		break;
678 
679 	default:
680 		fatal("process_config_line: Unimplemented opcode %d", opcode);
681 	}
682 
683 	/* Check that there is no garbage at end of line. */
684 	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
685 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
686 		     filename, linenum, arg);
687 	}
688 	return 0;
689 }
690 
691 
692 /*
693  * Reads the config file and modifies the options accordingly.  Options
694  * should already be initialized before this call.  This never returns if
695  * there is an error.  If the file does not exist, this returns 0.
696  */
697 
698 int
699 read_config_file(const char *filename, const char *host, Options *options)
700 {
701 	FILE *f;
702 	char line[1024];
703 	int active, linenum;
704 	int bad_options = 0;
705 
706 	/* Open the file. */
707 	f = fopen(filename, "r");
708 	if (!f)
709 		return 0;
710 
711 	debug("Reading configuration data %.200s", filename);
712 
713 	/*
714 	 * Mark that we are now processing the options.  This flag is turned
715 	 * on/off by Host specifications.
716 	 */
717 	active = 1;
718 	linenum = 0;
719 	while (fgets(line, sizeof(line), f)) {
720 		/* Update line number counter. */
721 		linenum++;
722 		if (process_config_line(options, host, line, filename, linenum, &active) != 0)
723 			bad_options++;
724 	}
725 	fclose(f);
726 	if (bad_options > 0)
727 		fatal("%s: terminating, %d bad configuration options",
728 		    filename, bad_options);
729 	return 1;
730 }
731 
732 /*
733  * Initializes options to special values that indicate that they have not yet
734  * been set.  Read_config_file will only set options with this value. Options
735  * are processed in the following order: command line, user config file,
736  * system config file.  Last, fill_default_options is called.
737  */
738 
739 void
740 initialize_options(Options * options)
741 {
742 	memset(options, 'X', sizeof(*options));
743 	options->forward_agent = -1;
744 	options->forward_x11 = -1;
745 	options->xauth_location = NULL;
746 	options->gateway_ports = -1;
747 	options->use_privileged_port = -1;
748 	options->rhosts_authentication = -1;
749 	options->rsa_authentication = -1;
750 	options->pubkey_authentication = -1;
751 	options->challenge_response_authentication = -1;
752 #if defined(KRB4) || defined(KRB5)
753 	options->kerberos_authentication = -1;
754 #endif
755 #if defined(AFS) || defined(KRB5)
756 	options->kerberos_tgt_passing = -1;
757 #endif
758 #ifdef AFS
759 	options->afs_token_passing = -1;
760 #endif
761 	options->password_authentication = -1;
762 	options->kbd_interactive_authentication = -1;
763 	options->kbd_interactive_devices = NULL;
764 	options->rhosts_rsa_authentication = -1;
765 	options->hostbased_authentication = -1;
766 	options->fallback_to_rsh = -1;
767 	options->use_rsh = -1;
768 	options->batch_mode = -1;
769 	options->check_host_ip = -1;
770 	options->strict_host_key_checking = -1;
771 	options->compression = -1;
772 	options->keepalives = -1;
773 	options->compression_level = -1;
774 	options->port = -1;
775 	options->connection_attempts = -1;
776 	options->number_of_password_prompts = -1;
777 	options->cipher = -1;
778 	options->ciphers = NULL;
779 	options->macs = NULL;
780 	options->hostkeyalgorithms = NULL;
781 	options->protocol = SSH_PROTO_UNKNOWN;
782 	options->num_identity_files = 0;
783 	options->hostname = NULL;
784 	options->host_key_alias = NULL;
785 	options->proxy_command = NULL;
786 	options->user = NULL;
787 	options->escape_char = -1;
788 	options->system_hostfile = NULL;
789 	options->user_hostfile = NULL;
790 	options->system_hostfile2 = NULL;
791 	options->user_hostfile2 = NULL;
792 	options->num_local_forwards = 0;
793 	options->num_remote_forwards = 0;
794 	options->clear_forwardings = -1;
795 	options->log_level = (LogLevel) - 1;
796 	options->preferred_authentications = NULL;
797 	options->bind_address = NULL;
798 	options->smartcard_device = NULL;
799 	options->no_host_authentication_for_localhost = - 1;
800 }
801 
802 /*
803  * Called after processing other sources of option data, this fills those
804  * options for which no value has been specified with their default values.
805  */
806 
807 void
808 fill_default_options(Options * options)
809 {
810 	int len;
811 
812 	if (options->forward_agent == -1)
813 		options->forward_agent = 0;
814 	if (options->forward_x11 == -1)
815 		options->forward_x11 = 0;
816 #ifdef _PATH_XAUTH
817 	if (options->xauth_location == NULL)
818 		options->xauth_location = _PATH_XAUTH;
819 #endif
820 	if (options->gateway_ports == -1)
821 		options->gateway_ports = 0;
822 	if (options->use_privileged_port == -1)
823 		options->use_privileged_port = 0;
824 	if (options->rhosts_authentication == -1)
825 		options->rhosts_authentication = 1;
826 	if (options->rsa_authentication == -1)
827 		options->rsa_authentication = 1;
828 	if (options->pubkey_authentication == -1)
829 		options->pubkey_authentication = 1;
830 	if (options->challenge_response_authentication == -1)
831 		options->challenge_response_authentication = 1;
832 #if defined(KRB4) || defined(KRB5)
833 	if (options->kerberos_authentication == -1)
834 		options->kerberos_authentication = 1;
835 #endif
836 #if defined(AFS) || defined(KRB5)
837 	if (options->kerberos_tgt_passing == -1)
838 		options->kerberos_tgt_passing = 1;
839 #endif
840 #ifdef AFS
841 	if (options->afs_token_passing == -1)
842 		options->afs_token_passing = 1;
843 #endif
844 	if (options->password_authentication == -1)
845 		options->password_authentication = 1;
846 	if (options->kbd_interactive_authentication == -1)
847 		options->kbd_interactive_authentication = 1;
848 	if (options->rhosts_rsa_authentication == -1)
849 		options->rhosts_rsa_authentication = 1;
850 	if (options->hostbased_authentication == -1)
851 		options->hostbased_authentication = 0;
852 	if (options->fallback_to_rsh == -1)
853 		options->fallback_to_rsh = 0;
854 	if (options->use_rsh == -1)
855 		options->use_rsh = 0;
856 	if (options->batch_mode == -1)
857 		options->batch_mode = 0;
858 	if (options->check_host_ip == -1)
859 		options->check_host_ip = 1;
860 	if (options->strict_host_key_checking == -1)
861 		options->strict_host_key_checking = 2;	/* 2 is default */
862 	if (options->compression == -1)
863 		options->compression = 0;
864 	if (options->keepalives == -1)
865 		options->keepalives = 1;
866 	if (options->compression_level == -1)
867 		options->compression_level = 6;
868 	if (options->port == -1)
869 		options->port = 0;	/* Filled in ssh_connect. */
870 	if (options->connection_attempts == -1)
871 		options->connection_attempts = 1;
872 	if (options->number_of_password_prompts == -1)
873 		options->number_of_password_prompts = 3;
874 	/* Selected in ssh_login(). */
875 	if (options->cipher == -1)
876 		options->cipher = SSH_CIPHER_NOT_SET;
877 	/* options->ciphers, default set in myproposals.h */
878 	/* options->macs, default set in myproposals.h */
879 	/* options->hostkeyalgorithms, default set in myproposals.h */
880 	if (options->protocol == SSH_PROTO_UNKNOWN)
881 		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
882 	if (options->num_identity_files == 0) {
883 		if (options->protocol & SSH_PROTO_1) {
884 			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
885 			options->identity_files[options->num_identity_files] =
886 			    xmalloc(len);
887 			snprintf(options->identity_files[options->num_identity_files++],
888 			    len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
889 		}
890 		if (options->protocol & SSH_PROTO_2) {
891 			len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
892 			options->identity_files[options->num_identity_files] =
893 			    xmalloc(len);
894 			snprintf(options->identity_files[options->num_identity_files++],
895 			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
896 
897 			len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
898 			options->identity_files[options->num_identity_files] =
899 			    xmalloc(len);
900 			snprintf(options->identity_files[options->num_identity_files++],
901 			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
902 		}
903 	}
904 	if (options->escape_char == -1)
905 		options->escape_char = '~';
906 	if (options->system_hostfile == NULL)
907 		options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
908 	if (options->user_hostfile == NULL)
909 		options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
910 	if (options->system_hostfile2 == NULL)
911 		options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
912 	if (options->user_hostfile2 == NULL)
913 		options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
914 	if (options->log_level == (LogLevel) - 1)
915 		options->log_level = SYSLOG_LEVEL_INFO;
916 	if (options->clear_forwardings == 1)
917 		clear_forwardings(options);
918 	if (options->no_host_authentication_for_localhost == - 1)
919 		options->no_host_authentication_for_localhost = 0;
920 	/* options->proxy_command should not be set by default */
921 	/* options->user will be set in the main program if appropriate */
922 	/* options->hostname will be set in the main program if appropriate */
923 	/* options->host_key_alias should not be set by default */
924 	/* options->preferred_authentications will be set in ssh */
925 }
926