xref: /freebsd/crypto/openssh/readconf.c (revision b52b9d56d4e96089873a75f9e29062eec19fabba)
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.100 2002/06/19 00:27:55 deraadt 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 	oVersionAddendum,
119 	oDeprecated
120 } OpCodes;
121 
122 /* Textual representations of the tokens. */
123 
124 static struct {
125 	const char *name;
126 	OpCodes opcode;
127 } keywords[] = {
128 	{ "forwardagent", oForwardAgent },
129 	{ "forwardx11", oForwardX11 },
130 	{ "xauthlocation", oXAuthLocation },
131 	{ "gatewayports", oGatewayPorts },
132 	{ "useprivilegedport", oUsePrivilegedPort },
133 	{ "rhostsauthentication", oRhostsAuthentication },
134 	{ "passwordauthentication", oPasswordAuthentication },
135 	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
136 	{ "kbdinteractivedevices", oKbdInteractiveDevices },
137 	{ "rsaauthentication", oRSAAuthentication },
138 	{ "pubkeyauthentication", oPubkeyAuthentication },
139 	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
140 	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
141 	{ "hostbasedauthentication", oHostbasedAuthentication },
142 	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
143 	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
144 	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
145 #if defined(KRB4) || defined(KRB5)
146 	{ "kerberosauthentication", oKerberosAuthentication },
147 #endif
148 #if defined(AFS) || defined(KRB5)
149 	{ "kerberostgtpassing", oKerberosTgtPassing },
150 #endif
151 #ifdef AFS
152 	{ "afstokenpassing", oAFSTokenPassing },
153 #endif
154 	{ "fallbacktorsh", oDeprecated },
155 	{ "usersh", oDeprecated },
156 	{ "identityfile", oIdentityFile },
157 	{ "identityfile2", oIdentityFile },			/* alias */
158 	{ "hostname", oHostName },
159 	{ "hostkeyalias", oHostKeyAlias },
160 	{ "proxycommand", oProxyCommand },
161 	{ "port", oPort },
162 	{ "cipher", oCipher },
163 	{ "ciphers", oCiphers },
164 	{ "macs", oMacs },
165 	{ "protocol", oProtocol },
166 	{ "remoteforward", oRemoteForward },
167 	{ "localforward", oLocalForward },
168 	{ "user", oUser },
169 	{ "host", oHost },
170 	{ "escapechar", oEscapeChar },
171 	{ "globalknownhostsfile", oGlobalKnownHostsFile },
172 	{ "userknownhostsfile", oUserKnownHostsFile },		/* obsolete */
173 	{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },
174 	{ "userknownhostsfile2", oUserKnownHostsFile2 },	/* obsolete */
175 	{ "connectionattempts", oConnectionAttempts },
176 	{ "batchmode", oBatchMode },
177 	{ "checkhostip", oCheckHostIP },
178 	{ "stricthostkeychecking", oStrictHostKeyChecking },
179 	{ "compression", oCompression },
180 	{ "compressionlevel", oCompressionLevel },
181 	{ "keepalive", oKeepAlives },
182 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
183 	{ "loglevel", oLogLevel },
184 	{ "dynamicforward", oDynamicForward },
185 	{ "preferredauthentications", oPreferredAuthentications },
186 	{ "hostkeyalgorithms", oHostKeyAlgorithms },
187 	{ "bindaddress", oBindAddress },
188 	{ "smartcarddevice", oSmartcardDevice },
189 	{ "clearallforwardings", oClearAllForwardings },
190 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
191 	{ "versionaddendum", oVersionAddendum },
192 	{ NULL, oBadOption }
193 };
194 
195 /*
196  * Adds a local TCP/IP port forward to options.  Never returns if there is an
197  * error.
198  */
199 
200 void
201 add_local_forward(Options *options, u_short port, const char *host,
202 		  u_short host_port)
203 {
204 	Forward *fwd;
205 #ifndef HAVE_CYGWIN
206 	extern uid_t original_real_uid;
207 	if (port < IPPORT_RESERVED && original_real_uid != 0)
208 		fatal("Privileged ports can only be forwarded by root.");
209 #endif
210 	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
211 		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
212 	fwd = &options->local_forwards[options->num_local_forwards++];
213 	fwd->port = port;
214 	fwd->host = xstrdup(host);
215 	fwd->host_port = host_port;
216 }
217 
218 /*
219  * Adds a remote TCP/IP port forward to options.  Never returns if there is
220  * an error.
221  */
222 
223 void
224 add_remote_forward(Options *options, u_short port, const char *host,
225 		   u_short host_port)
226 {
227 	Forward *fwd;
228 	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
229 		fatal("Too many remote forwards (max %d).",
230 		    SSH_MAX_FORWARDS_PER_DIRECTION);
231 	fwd = &options->remote_forwards[options->num_remote_forwards++];
232 	fwd->port = port;
233 	fwd->host = xstrdup(host);
234 	fwd->host_port = host_port;
235 }
236 
237 static void
238 clear_forwardings(Options *options)
239 {
240 	int i;
241 
242 	for (i = 0; i < options->num_local_forwards; i++)
243 		xfree(options->local_forwards[i].host);
244 	options->num_local_forwards = 0;
245 	for (i = 0; i < options->num_remote_forwards; i++)
246 		xfree(options->remote_forwards[i].host);
247 	options->num_remote_forwards = 0;
248 }
249 
250 /*
251  * Returns the number of the token pointed to by cp or oBadOption.
252  */
253 
254 static OpCodes
255 parse_token(const char *cp, const char *filename, int linenum)
256 {
257 	u_int i;
258 
259 	for (i = 0; keywords[i].name; i++)
260 		if (strcasecmp(cp, keywords[i].name) == 0)
261 			return keywords[i].opcode;
262 
263 	error("%s: line %d: Bad configuration option: %s",
264 	    filename, linenum, cp);
265 	return oBadOption;
266 }
267 
268 /*
269  * Processes a single option line as used in the configuration files. This
270  * only sets those values that have not already been set.
271  */
272 
273 int
274 process_config_line(Options *options, const char *host,
275 		    char *line, const char *filename, int linenum,
276 		    int *activep)
277 {
278 	char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
279 	int opcode, *intptr, value;
280 	u_short fwd_port, fwd_host_port;
281 	char sfwd_host_port[6];
282 
283 	s = line;
284 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
285 	keyword = strdelim(&s);
286 	/* Ignore leading whitespace. */
287 	if (*keyword == '\0')
288 		keyword = strdelim(&s);
289 	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
290 		return 0;
291 
292 	opcode = parse_token(keyword, filename, linenum);
293 
294 	switch (opcode) {
295 	case oBadOption:
296 		/* don't panic, but count bad options */
297 		return -1;
298 		/* NOTREACHED */
299 	case oForwardAgent:
300 		intptr = &options->forward_agent;
301 parse_flag:
302 		arg = strdelim(&s);
303 		if (!arg || *arg == '\0')
304 			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
305 		value = 0;	/* To avoid compiler warning... */
306 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
307 			value = 1;
308 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
309 			value = 0;
310 		else
311 			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
312 		if (*activep && *intptr == -1)
313 			*intptr = value;
314 		break;
315 
316 	case oForwardX11:
317 		intptr = &options->forward_x11;
318 		goto parse_flag;
319 
320 	case oGatewayPorts:
321 		intptr = &options->gateway_ports;
322 		goto parse_flag;
323 
324 	case oUsePrivilegedPort:
325 		intptr = &options->use_privileged_port;
326 		goto parse_flag;
327 
328 	case oRhostsAuthentication:
329 		intptr = &options->rhosts_authentication;
330 		goto parse_flag;
331 
332 	case oPasswordAuthentication:
333 		intptr = &options->password_authentication;
334 		goto parse_flag;
335 
336 	case oKbdInteractiveAuthentication:
337 		intptr = &options->kbd_interactive_authentication;
338 		goto parse_flag;
339 
340 	case oKbdInteractiveDevices:
341 		charptr = &options->kbd_interactive_devices;
342 		goto parse_string;
343 
344 	case oPubkeyAuthentication:
345 		intptr = &options->pubkey_authentication;
346 		goto parse_flag;
347 
348 	case oRSAAuthentication:
349 		intptr = &options->rsa_authentication;
350 		goto parse_flag;
351 
352 	case oRhostsRSAAuthentication:
353 		intptr = &options->rhosts_rsa_authentication;
354 		goto parse_flag;
355 
356 	case oHostbasedAuthentication:
357 		intptr = &options->hostbased_authentication;
358 		goto parse_flag;
359 
360 	case oChallengeResponseAuthentication:
361 		intptr = &options->challenge_response_authentication;
362 		goto parse_flag;
363 #if defined(KRB4) || defined(KRB5)
364 	case oKerberosAuthentication:
365 		intptr = &options->kerberos_authentication;
366 		goto parse_flag;
367 #endif
368 #if defined(AFS) || defined(KRB5)
369 	case oKerberosTgtPassing:
370 		intptr = &options->kerberos_tgt_passing;
371 		goto parse_flag;
372 #endif
373 #ifdef AFS
374 	case oAFSTokenPassing:
375 		intptr = &options->afs_token_passing;
376 		goto parse_flag;
377 #endif
378 	case oBatchMode:
379 		intptr = &options->batch_mode;
380 		goto parse_flag;
381 
382 	case oCheckHostIP:
383 		intptr = &options->check_host_ip;
384 		goto parse_flag;
385 
386 	case oStrictHostKeyChecking:
387 		intptr = &options->strict_host_key_checking;
388 		arg = strdelim(&s);
389 		if (!arg || *arg == '\0')
390 			fatal("%.200s line %d: Missing yes/no/ask argument.",
391 			    filename, linenum);
392 		value = 0;	/* To avoid compiler warning... */
393 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
394 			value = 1;
395 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
396 			value = 0;
397 		else if (strcmp(arg, "ask") == 0)
398 			value = 2;
399 		else
400 			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
401 		if (*activep && *intptr == -1)
402 			*intptr = value;
403 		break;
404 
405 	case oCompression:
406 		intptr = &options->compression;
407 		goto parse_flag;
408 
409 	case oKeepAlives:
410 		intptr = &options->keepalives;
411 		goto parse_flag;
412 
413 	case oNoHostAuthenticationForLocalhost:
414 		intptr = &options->no_host_authentication_for_localhost;
415 		goto parse_flag;
416 
417 	case oNumberOfPasswordPrompts:
418 		intptr = &options->number_of_password_prompts;
419 		goto parse_int;
420 
421 	case oCompressionLevel:
422 		intptr = &options->compression_level;
423 		goto parse_int;
424 
425 	case oIdentityFile:
426 		arg = strdelim(&s);
427 		if (!arg || *arg == '\0')
428 			fatal("%.200s line %d: Missing argument.", filename, linenum);
429 		if (*activep) {
430 			intptr = &options->num_identity_files;
431 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
432 				fatal("%.200s line %d: Too many identity files specified (max %d).",
433 				    filename, linenum, SSH_MAX_IDENTITY_FILES);
434 			charptr =  &options->identity_files[*intptr];
435 			*charptr = xstrdup(arg);
436 			*intptr = *intptr + 1;
437 		}
438 		break;
439 
440 	case oXAuthLocation:
441 		charptr=&options->xauth_location;
442 		goto parse_string;
443 
444 	case oUser:
445 		charptr = &options->user;
446 parse_string:
447 		arg = strdelim(&s);
448 		if (!arg || *arg == '\0')
449 			fatal("%.200s line %d: Missing argument.", filename, linenum);
450 		if (*activep && *charptr == NULL)
451 			*charptr = xstrdup(arg);
452 		break;
453 
454 	case oGlobalKnownHostsFile:
455 		charptr = &options->system_hostfile;
456 		goto parse_string;
457 
458 	case oUserKnownHostsFile:
459 		charptr = &options->user_hostfile;
460 		goto parse_string;
461 
462 	case oGlobalKnownHostsFile2:
463 		charptr = &options->system_hostfile2;
464 		goto parse_string;
465 
466 	case oUserKnownHostsFile2:
467 		charptr = &options->user_hostfile2;
468 		goto parse_string;
469 
470 	case oHostName:
471 		charptr = &options->hostname;
472 		goto parse_string;
473 
474 	case oHostKeyAlias:
475 		charptr = &options->host_key_alias;
476 		goto parse_string;
477 
478 	case oPreferredAuthentications:
479 		charptr = &options->preferred_authentications;
480 		goto parse_string;
481 
482 	case oBindAddress:
483 		charptr = &options->bind_address;
484 		goto parse_string;
485 
486 	case oSmartcardDevice:
487 		charptr = &options->smartcard_device;
488 		goto parse_string;
489 
490 	case oProxyCommand:
491 		charptr = &options->proxy_command;
492 		string = xstrdup("");
493 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
494 			string = xrealloc(string, strlen(string) + strlen(arg) + 2);
495 			strcat(string, " ");
496 			strcat(string, arg);
497 		}
498 		if (*activep && *charptr == NULL)
499 			*charptr = string;
500 		else
501 			xfree(string);
502 		return 0;
503 
504 	case oPort:
505 		intptr = &options->port;
506 parse_int:
507 		arg = strdelim(&s);
508 		if (!arg || *arg == '\0')
509 			fatal("%.200s line %d: Missing argument.", filename, linenum);
510 		if (arg[0] < '0' || arg[0] > '9')
511 			fatal("%.200s line %d: Bad number.", filename, linenum);
512 
513 		/* Octal, decimal, or hex format? */
514 		value = strtol(arg, &endofnumber, 0);
515 		if (arg == endofnumber)
516 			fatal("%.200s line %d: Bad number.", filename, linenum);
517 		if (*activep && *intptr == -1)
518 			*intptr = value;
519 		break;
520 
521 	case oConnectionAttempts:
522 		intptr = &options->connection_attempts;
523 		goto parse_int;
524 
525 	case oCipher:
526 		intptr = &options->cipher;
527 		arg = strdelim(&s);
528 		if (!arg || *arg == '\0')
529 			fatal("%.200s line %d: Missing argument.", filename, linenum);
530 		value = cipher_number(arg);
531 		if (value == -1)
532 			fatal("%.200s line %d: Bad cipher '%s'.",
533 			    filename, linenum, arg ? arg : "<NONE>");
534 		if (*activep && *intptr == -1)
535 			*intptr = value;
536 		break;
537 
538 	case oCiphers:
539 		arg = strdelim(&s);
540 		if (!arg || *arg == '\0')
541 			fatal("%.200s line %d: Missing argument.", filename, linenum);
542 		if (!ciphers_valid(arg))
543 			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
544 			    filename, linenum, arg ? arg : "<NONE>");
545 		if (*activep && options->ciphers == NULL)
546 			options->ciphers = xstrdup(arg);
547 		break;
548 
549 	case oMacs:
550 		arg = strdelim(&s);
551 		if (!arg || *arg == '\0')
552 			fatal("%.200s line %d: Missing argument.", filename, linenum);
553 		if (!mac_valid(arg))
554 			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
555 			    filename, linenum, arg ? arg : "<NONE>");
556 		if (*activep && options->macs == NULL)
557 			options->macs = xstrdup(arg);
558 		break;
559 
560 	case oHostKeyAlgorithms:
561 		arg = strdelim(&s);
562 		if (!arg || *arg == '\0')
563 			fatal("%.200s line %d: Missing argument.", filename, linenum);
564 		if (!key_names_valid2(arg))
565 			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
566 			    filename, linenum, arg ? arg : "<NONE>");
567 		if (*activep && options->hostkeyalgorithms == NULL)
568 			options->hostkeyalgorithms = xstrdup(arg);
569 		break;
570 
571 	case oProtocol:
572 		intptr = &options->protocol;
573 		arg = strdelim(&s);
574 		if (!arg || *arg == '\0')
575 			fatal("%.200s line %d: Missing argument.", filename, linenum);
576 		value = proto_spec(arg);
577 		if (value == SSH_PROTO_UNKNOWN)
578 			fatal("%.200s line %d: Bad protocol spec '%s'.",
579 			    filename, linenum, arg ? arg : "<NONE>");
580 		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
581 			*intptr = value;
582 		break;
583 
584 	case oLogLevel:
585 		intptr = (int *) &options->log_level;
586 		arg = strdelim(&s);
587 		value = log_level_number(arg);
588 		if (value == SYSLOG_LEVEL_NOT_SET)
589 			fatal("%.200s line %d: unsupported log level '%s'",
590 			    filename, linenum, arg ? arg : "<NONE>");
591 		if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
592 			*intptr = (LogLevel) value;
593 		break;
594 
595 	case oLocalForward:
596 	case oRemoteForward:
597 		arg = strdelim(&s);
598 		if (!arg || *arg == '\0')
599 			fatal("%.200s line %d: Missing port argument.",
600 			    filename, linenum);
601 		if ((fwd_port = a2port(arg)) == 0)
602 			fatal("%.200s line %d: Bad listen port.",
603 			    filename, linenum);
604 		arg = strdelim(&s);
605 		if (!arg || *arg == '\0')
606 			fatal("%.200s line %d: Missing second argument.",
607 			    filename, linenum);
608 		if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
609 		    sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
610 			fatal("%.200s line %d: Bad forwarding specification.",
611 			    filename, linenum);
612 		if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
613 			fatal("%.200s line %d: Bad forwarding port.",
614 			    filename, linenum);
615 		if (*activep) {
616 			if (opcode == oLocalForward)
617 				add_local_forward(options, fwd_port, buf,
618 				    fwd_host_port);
619 			else if (opcode == oRemoteForward)
620 				add_remote_forward(options, fwd_port, buf,
621 				    fwd_host_port);
622 		}
623 		break;
624 
625 	case oDynamicForward:
626 		arg = strdelim(&s);
627 		if (!arg || *arg == '\0')
628 			fatal("%.200s line %d: Missing port argument.",
629 			    filename, linenum);
630 		fwd_port = a2port(arg);
631 		if (fwd_port == 0)
632 			fatal("%.200s line %d: Badly formatted port number.",
633 			    filename, linenum);
634 		if (*activep)
635 			add_local_forward(options, fwd_port, "socks4", 0);
636 		break;
637 
638 	case oClearAllForwardings:
639 		intptr = &options->clear_forwardings;
640 		goto parse_flag;
641 
642 	case oHost:
643 		*activep = 0;
644 		while ((arg = strdelim(&s)) != NULL && *arg != '\0')
645 			if (match_pattern(host, arg)) {
646 				debug("Applying options for %.100s", arg);
647 				*activep = 1;
648 				break;
649 			}
650 		/* Avoid garbage check below, as strdelim is done. */
651 		return 0;
652 
653 	case oEscapeChar:
654 		intptr = &options->escape_char;
655 		arg = strdelim(&s);
656 		if (!arg || *arg == '\0')
657 			fatal("%.200s line %d: Missing argument.", filename, linenum);
658 		if (arg[0] == '^' && arg[2] == 0 &&
659 		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
660 			value = (u_char) arg[1] & 31;
661 		else if (strlen(arg) == 1)
662 			value = (u_char) arg[0];
663 		else if (strcmp(arg, "none") == 0)
664 			value = SSH_ESCAPECHAR_NONE;
665 		else {
666 			fatal("%.200s line %d: Bad escape character.",
667 			    filename, linenum);
668 			/* NOTREACHED */
669 			value = 0;	/* Avoid compiler warning. */
670 		}
671 		if (*activep && *intptr == -1)
672 			*intptr = value;
673 		break;
674 
675 	case oVersionAddendum:
676 		ssh_version_set_addendum(strtok(s, "\n"));
677 		do {
678 			arg = strdelim(&s);
679 		} while (arg != NULL && *arg != '\0');
680 		break;
681 
682 	case oDeprecated:
683 		debug("%s line %d: Deprecated option \"%s\"",
684 		    filename, linenum, keyword);
685 		return 0;
686 
687 	default:
688 		fatal("process_config_line: Unimplemented opcode %d", opcode);
689 	}
690 
691 	/* Check that there is no garbage at end of line. */
692 	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
693 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
694 		     filename, linenum, arg);
695 	}
696 	return 0;
697 }
698 
699 
700 /*
701  * Reads the config file and modifies the options accordingly.  Options
702  * should already be initialized before this call.  This never returns if
703  * there is an error.  If the file does not exist, this returns 0.
704  */
705 
706 int
707 read_config_file(const char *filename, const char *host, Options *options)
708 {
709 	FILE *f;
710 	char line[1024];
711 	int active, linenum;
712 	int bad_options = 0;
713 
714 	/* Open the file. */
715 	f = fopen(filename, "r");
716 	if (!f)
717 		return 0;
718 
719 	debug("Reading configuration data %.200s", filename);
720 
721 	/*
722 	 * Mark that we are now processing the options.  This flag is turned
723 	 * on/off by Host specifications.
724 	 */
725 	active = 1;
726 	linenum = 0;
727 	while (fgets(line, sizeof(line), f)) {
728 		/* Update line number counter. */
729 		linenum++;
730 		if (process_config_line(options, host, line, filename, linenum, &active) != 0)
731 			bad_options++;
732 	}
733 	fclose(f);
734 	if (bad_options > 0)
735 		fatal("%s: terminating, %d bad configuration options",
736 		    filename, bad_options);
737 	return 1;
738 }
739 
740 /*
741  * Initializes options to special values that indicate that they have not yet
742  * been set.  Read_config_file will only set options with this value. Options
743  * are processed in the following order: command line, user config file,
744  * system config file.  Last, fill_default_options is called.
745  */
746 
747 void
748 initialize_options(Options * options)
749 {
750 	memset(options, 'X', sizeof(*options));
751 	options->forward_agent = -1;
752 	options->forward_x11 = -1;
753 	options->xauth_location = NULL;
754 	options->gateway_ports = -1;
755 	options->use_privileged_port = -1;
756 	options->rhosts_authentication = -1;
757 	options->rsa_authentication = -1;
758 	options->pubkey_authentication = -1;
759 	options->challenge_response_authentication = -1;
760 #if defined(KRB4) || defined(KRB5)
761 	options->kerberos_authentication = -1;
762 #endif
763 #if defined(AFS) || defined(KRB5)
764 	options->kerberos_tgt_passing = -1;
765 #endif
766 #ifdef AFS
767 	options->afs_token_passing = -1;
768 #endif
769 	options->password_authentication = -1;
770 	options->kbd_interactive_authentication = -1;
771 	options->kbd_interactive_devices = NULL;
772 	options->rhosts_rsa_authentication = -1;
773 	options->hostbased_authentication = -1;
774 	options->batch_mode = -1;
775 	options->check_host_ip = -1;
776 	options->strict_host_key_checking = -1;
777 	options->compression = -1;
778 	options->keepalives = -1;
779 	options->compression_level = -1;
780 	options->port = -1;
781 	options->connection_attempts = -1;
782 	options->number_of_password_prompts = -1;
783 	options->cipher = -1;
784 	options->ciphers = NULL;
785 	options->macs = NULL;
786 	options->hostkeyalgorithms = NULL;
787 	options->protocol = SSH_PROTO_UNKNOWN;
788 	options->num_identity_files = 0;
789 	options->hostname = NULL;
790 	options->host_key_alias = NULL;
791 	options->proxy_command = NULL;
792 	options->user = NULL;
793 	options->escape_char = -1;
794 	options->system_hostfile = NULL;
795 	options->user_hostfile = NULL;
796 	options->system_hostfile2 = NULL;
797 	options->user_hostfile2 = NULL;
798 	options->num_local_forwards = 0;
799 	options->num_remote_forwards = 0;
800 	options->clear_forwardings = -1;
801 	options->log_level = SYSLOG_LEVEL_NOT_SET;
802 	options->preferred_authentications = NULL;
803 	options->bind_address = NULL;
804 	options->smartcard_device = NULL;
805 	options->no_host_authentication_for_localhost = - 1;
806 }
807 
808 /*
809  * Called after processing other sources of option data, this fills those
810  * options for which no value has been specified with their default values.
811  */
812 
813 void
814 fill_default_options(Options * options)
815 {
816 	int len;
817 
818 	if (options->forward_agent == -1)
819 		options->forward_agent = 0;
820 	if (options->forward_x11 == -1)
821 		options->forward_x11 = 0;
822 	if (options->xauth_location == NULL)
823 		options->xauth_location = _PATH_XAUTH;
824 	if (options->gateway_ports == -1)
825 		options->gateway_ports = 0;
826 	if (options->use_privileged_port == -1)
827 		options->use_privileged_port = 0;
828 	if (options->rhosts_authentication == -1)
829 		options->rhosts_authentication = 0;
830 	if (options->rsa_authentication == -1)
831 		options->rsa_authentication = 1;
832 	if (options->pubkey_authentication == -1)
833 		options->pubkey_authentication = 1;
834 	if (options->challenge_response_authentication == -1)
835 		options->challenge_response_authentication = 1;
836 #if defined(KRB4) || defined(KRB5)
837 	if (options->kerberos_authentication == -1)
838 		options->kerberos_authentication = 1;
839 #endif
840 #if defined(AFS) || defined(KRB5)
841 	if (options->kerberos_tgt_passing == -1)
842 		options->kerberos_tgt_passing = 1;
843 #endif
844 #ifdef AFS
845 	if (options->afs_token_passing == -1)
846 		options->afs_token_passing = 1;
847 #endif
848 	if (options->password_authentication == -1)
849 		options->password_authentication = 1;
850 	if (options->kbd_interactive_authentication == -1)
851 		options->kbd_interactive_authentication = 1;
852 	if (options->rhosts_rsa_authentication == -1)
853 		options->rhosts_rsa_authentication = 0;
854 	if (options->hostbased_authentication == -1)
855 		options->hostbased_authentication = 0;
856 	if (options->batch_mode == -1)
857 		options->batch_mode = 0;
858 	if (options->check_host_ip == -1)
859 		options->check_host_ip = 0;
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 == SYSLOG_LEVEL_NOT_SET)
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