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