xref: /freebsd/crypto/openssh/readconf.c (revision c17d43407fe04133a94055b0dbc7ea8965654a9f)
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.95 2002/02/04 12:15:25 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      FallBackToRsh no
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      UseRsh yes
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      FallBackToRsh no
84      UseRsh no
85      StrictHostKeyChecking yes
86      KeepAlives no
87      IdentityFile ~/.ssh/identity
88      Port 22
89      EscapeChar ~
90 
91 */
92 
93 /* Keyword tokens. */
94 
95 typedef enum {
96 	oBadOption,
97 	oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
98 	oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
99 	oChallengeResponseAuthentication, oXAuthLocation,
100 #if defined(KRB4) || defined(KRB5)
101 	oKerberosAuthentication,
102 #endif
103 #if defined(AFS) || defined(KRB5)
104 	oKerberosTgtPassing,
105 #endif
106 #ifdef AFS
107 	oAFSTokenPassing,
108 #endif
109 	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
110 	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
111 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
112 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
113 	oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
114 	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
115 	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
116 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
117 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
118 	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
119 	oClearAllForwardings, oNoHostAuthenticationForLocalhost
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", oFallBackToRsh },
155 	{ "usersh", oUseRsh },
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 	{ NULL, oBadOption }
192 };
193 
194 /*
195  * Adds a local TCP/IP port forward to options.  Never returns if there is an
196  * error.
197  */
198 
199 void
200 add_local_forward(Options *options, u_short port, const char *host,
201 		  u_short host_port)
202 {
203 	Forward *fwd;
204 	extern uid_t original_real_uid;
205 	if (port < IPPORT_RESERVED && original_real_uid != 0)
206 		fatal("Privileged ports can only be forwarded by root.");
207 	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
208 		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
209 	fwd = &options->local_forwards[options->num_local_forwards++];
210 	fwd->port = port;
211 	fwd->host = xstrdup(host);
212 	fwd->host_port = host_port;
213 }
214 
215 /*
216  * Adds a remote TCP/IP port forward to options.  Never returns if there is
217  * an error.
218  */
219 
220 void
221 add_remote_forward(Options *options, u_short port, const char *host,
222 		   u_short host_port)
223 {
224 	Forward *fwd;
225 	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
226 		fatal("Too many remote forwards (max %d).",
227 		    SSH_MAX_FORWARDS_PER_DIRECTION);
228 	fwd = &options->remote_forwards[options->num_remote_forwards++];
229 	fwd->port = port;
230 	fwd->host = xstrdup(host);
231 	fwd->host_port = host_port;
232 }
233 
234 static void
235 clear_forwardings(Options *options)
236 {
237 	int i;
238 
239 	for (i = 0; i < options->num_local_forwards; i++)
240 		xfree(options->local_forwards[i].host);
241 	options->num_local_forwards = 0;
242 	for (i = 0; i < options->num_remote_forwards; i++)
243 		xfree(options->remote_forwards[i].host);
244 	options->num_remote_forwards = 0;
245 }
246 
247 /*
248  * Returns the number of the token pointed to by cp or oBadOption.
249  */
250 
251 static OpCodes
252 parse_token(const char *cp, const char *filename, int linenum)
253 {
254 	u_int i;
255 
256 	for (i = 0; keywords[i].name; i++)
257 		if (strcasecmp(cp, keywords[i].name) == 0)
258 			return keywords[i].opcode;
259 
260 	error("%s: line %d: Bad configuration option: %s",
261 	    filename, linenum, cp);
262 	return oBadOption;
263 }
264 
265 /*
266  * Processes a single option line as used in the configuration files. This
267  * only sets those values that have not already been set.
268  */
269 
270 int
271 process_config_line(Options *options, const char *host,
272 		    char *line, const char *filename, int linenum,
273 		    int *activep)
274 {
275 	char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
276 	int opcode, *intptr, value;
277 	u_short fwd_port, fwd_host_port;
278 	char sfwd_host_port[6];
279 
280 	s = line;
281 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
282 	keyword = strdelim(&s);
283 	/* Ignore leading whitespace. */
284 	if (*keyword == '\0')
285 		keyword = strdelim(&s);
286 	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
287 		return 0;
288 
289 	opcode = parse_token(keyword, filename, linenum);
290 
291 	switch (opcode) {
292 	case oBadOption:
293 		/* don't panic, but count bad options */
294 		return -1;
295 		/* NOTREACHED */
296 	case oForwardAgent:
297 		intptr = &options->forward_agent;
298 parse_flag:
299 		arg = strdelim(&s);
300 		if (!arg || *arg == '\0')
301 			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
302 		value = 0;	/* To avoid compiler warning... */
303 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
304 			value = 1;
305 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
306 			value = 0;
307 		else
308 			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
309 		if (*activep && *intptr == -1)
310 			*intptr = value;
311 		break;
312 
313 	case oForwardX11:
314 		intptr = &options->forward_x11;
315 		goto parse_flag;
316 
317 	case oGatewayPorts:
318 		intptr = &options->gateway_ports;
319 		goto parse_flag;
320 
321 	case oUsePrivilegedPort:
322 		intptr = &options->use_privileged_port;
323 		goto parse_flag;
324 
325 	case oRhostsAuthentication:
326 		intptr = &options->rhosts_authentication;
327 		goto parse_flag;
328 
329 	case oPasswordAuthentication:
330 		intptr = &options->password_authentication;
331 		goto parse_flag;
332 
333 	case oKbdInteractiveAuthentication:
334 		intptr = &options->kbd_interactive_authentication;
335 		goto parse_flag;
336 
337 	case oKbdInteractiveDevices:
338 		charptr = &options->kbd_interactive_devices;
339 		goto parse_string;
340 
341 	case oPubkeyAuthentication:
342 		intptr = &options->pubkey_authentication;
343 		goto parse_flag;
344 
345 	case oRSAAuthentication:
346 		intptr = &options->rsa_authentication;
347 		goto parse_flag;
348 
349 	case oRhostsRSAAuthentication:
350 		intptr = &options->rhosts_rsa_authentication;
351 		goto parse_flag;
352 
353 	case oHostbasedAuthentication:
354 		intptr = &options->hostbased_authentication;
355 		goto parse_flag;
356 
357 	case oChallengeResponseAuthentication:
358 		intptr = &options->challenge_response_authentication;
359 		goto parse_flag;
360 #if defined(KRB4) || defined(KRB5)
361 	case oKerberosAuthentication:
362 		intptr = &options->kerberos_authentication;
363 		goto parse_flag;
364 #endif
365 #if defined(AFS) || defined(KRB5)
366 	case oKerberosTgtPassing:
367 		intptr = &options->kerberos_tgt_passing;
368 		goto parse_flag;
369 #endif
370 #ifdef AFS
371 	case oAFSTokenPassing:
372 		intptr = &options->afs_token_passing;
373 		goto parse_flag;
374 #endif
375 	case oFallBackToRsh:
376 		intptr = &options->fallback_to_rsh;
377 		goto parse_flag;
378 
379 	case oUseRsh:
380 		intptr = &options->use_rsh;
381 		goto parse_flag;
382 
383 	case oBatchMode:
384 		intptr = &options->batch_mode;
385 		goto parse_flag;
386 
387 	case oCheckHostIP:
388 		intptr = &options->check_host_ip;
389 		goto parse_flag;
390 
391 	case oStrictHostKeyChecking:
392 		intptr = &options->strict_host_key_checking;
393 		arg = strdelim(&s);
394 		if (!arg || *arg == '\0')
395 			fatal("%.200s line %d: Missing yes/no/ask argument.",
396 			    filename, linenum);
397 		value = 0;	/* To avoid compiler warning... */
398 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
399 			value = 1;
400 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
401 			value = 0;
402 		else if (strcmp(arg, "ask") == 0)
403 			value = 2;
404 		else
405 			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
406 		if (*activep && *intptr == -1)
407 			*intptr = value;
408 		break;
409 
410 	case oCompression:
411 		intptr = &options->compression;
412 		goto parse_flag;
413 
414 	case oKeepAlives:
415 		intptr = &options->keepalives;
416 		goto parse_flag;
417 
418 	case oNoHostAuthenticationForLocalhost:
419 		intptr = &options->no_host_authentication_for_localhost;
420 		goto parse_flag;
421 
422 	case oNumberOfPasswordPrompts:
423 		intptr = &options->number_of_password_prompts;
424 		goto parse_int;
425 
426 	case oCompressionLevel:
427 		intptr = &options->compression_level;
428 		goto parse_int;
429 
430 	case oIdentityFile:
431 		arg = strdelim(&s);
432 		if (!arg || *arg == '\0')
433 			fatal("%.200s line %d: Missing argument.", filename, linenum);
434 		if (*activep) {
435 			intptr = &options->num_identity_files;
436 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
437 				fatal("%.200s line %d: Too many identity files specified (max %d).",
438 				    filename, linenum, SSH_MAX_IDENTITY_FILES);
439 			charptr =  &options->identity_files[*intptr];
440 			*charptr = xstrdup(arg);
441 			*intptr = *intptr + 1;
442 		}
443 		break;
444 
445 	case oXAuthLocation:
446 		charptr=&options->xauth_location;
447 		goto parse_string;
448 
449 	case oUser:
450 		charptr = &options->user;
451 parse_string:
452 		arg = strdelim(&s);
453 		if (!arg || *arg == '\0')
454 			fatal("%.200s line %d: Missing argument.", filename, linenum);
455 		if (*activep && *charptr == NULL)
456 			*charptr = xstrdup(arg);
457 		break;
458 
459 	case oGlobalKnownHostsFile:
460 		charptr = &options->system_hostfile;
461 		goto parse_string;
462 
463 	case oUserKnownHostsFile:
464 		charptr = &options->user_hostfile;
465 		goto parse_string;
466 
467 	case oGlobalKnownHostsFile2:
468 		charptr = &options->system_hostfile2;
469 		goto parse_string;
470 
471 	case oUserKnownHostsFile2:
472 		charptr = &options->user_hostfile2;
473 		goto parse_string;
474 
475 	case oHostName:
476 		charptr = &options->hostname;
477 		goto parse_string;
478 
479 	case oHostKeyAlias:
480 		charptr = &options->host_key_alias;
481 		goto parse_string;
482 
483 	case oPreferredAuthentications:
484 		charptr = &options->preferred_authentications;
485 		goto parse_string;
486 
487 	case oBindAddress:
488 		charptr = &options->bind_address;
489 		goto parse_string;
490 
491 	case oSmartcardDevice:
492 		charptr = &options->smartcard_device;
493 		goto parse_string;
494 
495 	case oProxyCommand:
496 		charptr = &options->proxy_command;
497 		string = xstrdup("");
498 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
499 			string = xrealloc(string, strlen(string) + strlen(arg) + 2);
500 			strcat(string, " ");
501 			strcat(string, arg);
502 		}
503 		if (*activep && *charptr == NULL)
504 			*charptr = string;
505 		else
506 			xfree(string);
507 		return 0;
508 
509 	case oPort:
510 		intptr = &options->port;
511 parse_int:
512 		arg = strdelim(&s);
513 		if (!arg || *arg == '\0')
514 			fatal("%.200s line %d: Missing argument.", filename, linenum);
515 		if (arg[0] < '0' || arg[0] > '9')
516 			fatal("%.200s line %d: Bad number.", filename, linenum);
517 
518 		/* Octal, decimal, or hex format? */
519 		value = strtol(arg, &endofnumber, 0);
520 		if (arg == endofnumber)
521 			fatal("%.200s line %d: Bad number.", filename, linenum);
522 		if (*activep && *intptr == -1)
523 			*intptr = value;
524 		break;
525 
526 	case oConnectionAttempts:
527 		intptr = &options->connection_attempts;
528 		goto parse_int;
529 
530 	case oCipher:
531 		intptr = &options->cipher;
532 		arg = strdelim(&s);
533 		if (!arg || *arg == '\0')
534 			fatal("%.200s line %d: Missing argument.", filename, linenum);
535 		value = cipher_number(arg);
536 		if (value == -1)
537 			fatal("%.200s line %d: Bad cipher '%s'.",
538 			    filename, linenum, arg ? arg : "<NONE>");
539 		if (*activep && *intptr == -1)
540 			*intptr = value;
541 		break;
542 
543 	case oCiphers:
544 		arg = strdelim(&s);
545 		if (!arg || *arg == '\0')
546 			fatal("%.200s line %d: Missing argument.", filename, linenum);
547 		if (!ciphers_valid(arg))
548 			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
549 			    filename, linenum, arg ? arg : "<NONE>");
550 		if (*activep && options->ciphers == NULL)
551 			options->ciphers = xstrdup(arg);
552 		break;
553 
554 	case oMacs:
555 		arg = strdelim(&s);
556 		if (!arg || *arg == '\0')
557 			fatal("%.200s line %d: Missing argument.", filename, linenum);
558 		if (!mac_valid(arg))
559 			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
560 			    filename, linenum, arg ? arg : "<NONE>");
561 		if (*activep && options->macs == NULL)
562 			options->macs = xstrdup(arg);
563 		break;
564 
565 	case oHostKeyAlgorithms:
566 		arg = strdelim(&s);
567 		if (!arg || *arg == '\0')
568 			fatal("%.200s line %d: Missing argument.", filename, linenum);
569 		if (!key_names_valid2(arg))
570 			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
571 			    filename, linenum, arg ? arg : "<NONE>");
572 		if (*activep && options->hostkeyalgorithms == NULL)
573 			options->hostkeyalgorithms = xstrdup(arg);
574 		break;
575 
576 	case oProtocol:
577 		intptr = &options->protocol;
578 		arg = strdelim(&s);
579 		if (!arg || *arg == '\0')
580 			fatal("%.200s line %d: Missing argument.", filename, linenum);
581 		value = proto_spec(arg);
582 		if (value == SSH_PROTO_UNKNOWN)
583 			fatal("%.200s line %d: Bad protocol spec '%s'.",
584 			    filename, linenum, arg ? arg : "<NONE>");
585 		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
586 			*intptr = value;
587 		break;
588 
589 	case oLogLevel:
590 		intptr = (int *) &options->log_level;
591 		arg = strdelim(&s);
592 		value = log_level_number(arg);
593 		if (value == SYSLOG_LEVEL_NOT_SET)
594 			fatal("%.200s line %d: unsupported log level '%s'",
595 			    filename, linenum, arg ? arg : "<NONE>");
596 		if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
597 			*intptr = (LogLevel) value;
598 		break;
599 
600 	case oLocalForward:
601 	case oRemoteForward:
602 		arg = strdelim(&s);
603 		if (!arg || *arg == '\0')
604 			fatal("%.200s line %d: Missing port argument.",
605 			    filename, linenum);
606 		if ((fwd_port = a2port(arg)) == 0)
607 			fatal("%.200s line %d: Bad listen port.",
608 			    filename, linenum);
609 		arg = strdelim(&s);
610 		if (!arg || *arg == '\0')
611 			fatal("%.200s line %d: Missing second argument.",
612 			    filename, linenum);
613 		if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
614 		    sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
615 			fatal("%.200s line %d: Bad forwarding specification.",
616 			    filename, linenum);
617 		if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
618 			fatal("%.200s line %d: Bad forwarding port.",
619 			    filename, linenum);
620 		if (*activep) {
621 			if (opcode == oLocalForward)
622 				add_local_forward(options, fwd_port, buf,
623 				    fwd_host_port);
624 			else if (opcode == oRemoteForward)
625 				add_remote_forward(options, fwd_port, buf,
626 				    fwd_host_port);
627 		}
628 		break;
629 
630 	case oDynamicForward:
631 		arg = strdelim(&s);
632 		if (!arg || *arg == '\0')
633 			fatal("%.200s line %d: Missing port argument.",
634 			    filename, linenum);
635 		fwd_port = a2port(arg);
636 		if (fwd_port == 0)
637 			fatal("%.200s line %d: Badly formatted port number.",
638 			    filename, linenum);
639 		if (*activep)
640 			add_local_forward(options, fwd_port, "socks4", 0);
641 		break;
642 
643 	case oClearAllForwardings:
644 		intptr = &options->clear_forwardings;
645 		goto parse_flag;
646 
647 	case oHost:
648 		*activep = 0;
649 		while ((arg = strdelim(&s)) != NULL && *arg != '\0')
650 			if (match_pattern(host, arg)) {
651 				debug("Applying options for %.100s", arg);
652 				*activep = 1;
653 				break;
654 			}
655 		/* Avoid garbage check below, as strdelim is done. */
656 		return 0;
657 
658 	case oEscapeChar:
659 		intptr = &options->escape_char;
660 		arg = strdelim(&s);
661 		if (!arg || *arg == '\0')
662 			fatal("%.200s line %d: Missing argument.", filename, linenum);
663 		if (arg[0] == '^' && arg[2] == 0 &&
664 		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
665 			value = (u_char) arg[1] & 31;
666 		else if (strlen(arg) == 1)
667 			value = (u_char) arg[0];
668 		else if (strcmp(arg, "none") == 0)
669 			value = SSH_ESCAPECHAR_NONE;
670 		else {
671 			fatal("%.200s line %d: Bad escape character.",
672 			    filename, linenum);
673 			/* NOTREACHED */
674 			value = 0;	/* Avoid compiler warning. */
675 		}
676 		if (*activep && *intptr == -1)
677 			*intptr = value;
678 		break;
679 
680 	default:
681 		fatal("process_config_line: Unimplemented opcode %d", opcode);
682 	}
683 
684 	/* Check that there is no garbage at end of line. */
685 	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
686 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
687 		     filename, linenum, arg);
688 	}
689 	return 0;
690 }
691 
692 
693 /*
694  * Reads the config file and modifies the options accordingly.  Options
695  * should already be initialized before this call.  This never returns if
696  * there is an error.  If the file does not exist, this returns 0.
697  */
698 
699 int
700 read_config_file(const char *filename, const char *host, Options *options)
701 {
702 	FILE *f;
703 	char line[1024];
704 	int active, linenum;
705 	int bad_options = 0;
706 
707 	/* Open the file. */
708 	f = fopen(filename, "r");
709 	if (!f)
710 		return 0;
711 
712 	debug("Reading configuration data %.200s", filename);
713 
714 	/*
715 	 * Mark that we are now processing the options.  This flag is turned
716 	 * on/off by Host specifications.
717 	 */
718 	active = 1;
719 	linenum = 0;
720 	while (fgets(line, sizeof(line), f)) {
721 		/* Update line number counter. */
722 		linenum++;
723 		if (process_config_line(options, host, line, filename, linenum, &active) != 0)
724 			bad_options++;
725 	}
726 	fclose(f);
727 	if (bad_options > 0)
728 		fatal("%s: terminating, %d bad configuration options",
729 		    filename, bad_options);
730 	return 1;
731 }
732 
733 /*
734  * Initializes options to special values that indicate that they have not yet
735  * been set.  Read_config_file will only set options with this value. Options
736  * are processed in the following order: command line, user config file,
737  * system config file.  Last, fill_default_options is called.
738  */
739 
740 void
741 initialize_options(Options * options)
742 {
743 	memset(options, 'X', sizeof(*options));
744 	options->forward_agent = -1;
745 	options->forward_x11 = -1;
746 	options->xauth_location = NULL;
747 	options->gateway_ports = -1;
748 	options->use_privileged_port = -1;
749 	options->rhosts_authentication = -1;
750 	options->rsa_authentication = -1;
751 	options->pubkey_authentication = -1;
752 	options->challenge_response_authentication = -1;
753 #if defined(KRB4) || defined(KRB5)
754 	options->kerberos_authentication = -1;
755 #endif
756 #if defined(AFS) || defined(KRB5)
757 	options->kerberos_tgt_passing = -1;
758 #endif
759 #ifdef AFS
760 	options->afs_token_passing = -1;
761 #endif
762 	options->password_authentication = -1;
763 	options->kbd_interactive_authentication = -1;
764 	options->kbd_interactive_devices = NULL;
765 	options->rhosts_rsa_authentication = -1;
766 	options->hostbased_authentication = -1;
767 	options->fallback_to_rsh = -1;
768 	options->use_rsh = -1;
769 	options->batch_mode = -1;
770 	options->check_host_ip = -1;
771 	options->strict_host_key_checking = -1;
772 	options->compression = -1;
773 	options->keepalives = -1;
774 	options->compression_level = -1;
775 	options->port = -1;
776 	options->connection_attempts = -1;
777 	options->number_of_password_prompts = -1;
778 	options->cipher = -1;
779 	options->ciphers = NULL;
780 	options->macs = NULL;
781 	options->hostkeyalgorithms = NULL;
782 	options->protocol = SSH_PROTO_UNKNOWN;
783 	options->num_identity_files = 0;
784 	options->hostname = NULL;
785 	options->host_key_alias = NULL;
786 	options->proxy_command = NULL;
787 	options->user = NULL;
788 	options->escape_char = -1;
789 	options->system_hostfile = NULL;
790 	options->user_hostfile = NULL;
791 	options->system_hostfile2 = NULL;
792 	options->user_hostfile2 = NULL;
793 	options->num_local_forwards = 0;
794 	options->num_remote_forwards = 0;
795 	options->clear_forwardings = -1;
796 	options->log_level = SYSLOG_LEVEL_NOT_SET;
797 	options->preferred_authentications = NULL;
798 	options->bind_address = NULL;
799 	options->smartcard_device = NULL;
800 	options->no_host_authentication_for_localhost = - 1;
801 }
802 
803 /*
804  * Called after processing other sources of option data, this fills those
805  * options for which no value has been specified with their default values.
806  */
807 
808 void
809 fill_default_options(Options * options)
810 {
811 	int len;
812 
813 	if (options->forward_agent == -1)
814 		options->forward_agent = 0;
815 	if (options->forward_x11 == -1)
816 		options->forward_x11 = 0;
817 	if (options->xauth_location == NULL)
818 		options->xauth_location = _PATH_XAUTH;
819 	if (options->gateway_ports == -1)
820 		options->gateway_ports = 0;
821 	if (options->use_privileged_port == -1)
822 		options->use_privileged_port = 0;
823 	if (options->rhosts_authentication == -1)
824 		options->rhosts_authentication = 1;
825 	if (options->rsa_authentication == -1)
826 		options->rsa_authentication = 1;
827 	if (options->pubkey_authentication == -1)
828 		options->pubkey_authentication = 1;
829 	if (options->challenge_response_authentication == -1)
830 		options->challenge_response_authentication = 1;
831 #if defined(KRB4) || defined(KRB5)
832 	if (options->kerberos_authentication == -1)
833 		options->kerberos_authentication = 1;
834 #endif
835 #if defined(AFS) || defined(KRB5)
836 	if (options->kerberos_tgt_passing == -1)
837 		options->kerberos_tgt_passing = 1;
838 #endif
839 #ifdef AFS
840 	if (options->afs_token_passing == -1)
841 		options->afs_token_passing = 1;
842 #endif
843 	if (options->password_authentication == -1)
844 		options->password_authentication = 1;
845 	if (options->kbd_interactive_authentication == -1)
846 		options->kbd_interactive_authentication = 1;
847 	if (options->rhosts_rsa_authentication == -1)
848 		options->rhosts_rsa_authentication = 1;
849 	if (options->hostbased_authentication == -1)
850 		options->hostbased_authentication = 0;
851 	if (options->fallback_to_rsh == -1)
852 		options->fallback_to_rsh = 0;
853 	if (options->use_rsh == -1)
854 		options->use_rsh = 0;
855 	if (options->batch_mode == -1)
856 		options->batch_mode = 0;
857 	if (options->check_host_ip == -1)
858 		options->check_host_ip = 0;
859 	if (options->strict_host_key_checking == -1)
860 		options->strict_host_key_checking = 2;	/* 2 is default */
861 	if (options->compression == -1)
862 		options->compression = 0;
863 	if (options->keepalives == -1)
864 		options->keepalives = 1;
865 	if (options->compression_level == -1)
866 		options->compression_level = 6;
867 	if (options->port == -1)
868 		options->port = 0;	/* Filled in ssh_connect. */
869 	if (options->connection_attempts == -1)
870 		options->connection_attempts = 1;
871 	if (options->number_of_password_prompts == -1)
872 		options->number_of_password_prompts = 3;
873 	/* Selected in ssh_login(). */
874 	if (options->cipher == -1)
875 		options->cipher = SSH_CIPHER_NOT_SET;
876 	/* options->ciphers, default set in myproposals.h */
877 	/* options->macs, default set in myproposals.h */
878 	/* options->hostkeyalgorithms, default set in myproposals.h */
879 	if (options->protocol == SSH_PROTO_UNKNOWN)
880 		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
881 	if (options->num_identity_files == 0) {
882 		if (options->protocol & SSH_PROTO_1) {
883 			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
884 			options->identity_files[options->num_identity_files] =
885 			    xmalloc(len);
886 			snprintf(options->identity_files[options->num_identity_files++],
887 			    len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
888 		}
889 		if (options->protocol & SSH_PROTO_2) {
890 			len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
891 			options->identity_files[options->num_identity_files] =
892 			    xmalloc(len);
893 			snprintf(options->identity_files[options->num_identity_files++],
894 			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
895 
896 			len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
897 			options->identity_files[options->num_identity_files] =
898 			    xmalloc(len);
899 			snprintf(options->identity_files[options->num_identity_files++],
900 			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
901 		}
902 	}
903 	if (options->escape_char == -1)
904 		options->escape_char = '~';
905 	if (options->system_hostfile == NULL)
906 		options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
907 	if (options->user_hostfile == NULL)
908 		options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
909 	if (options->system_hostfile2 == NULL)
910 		options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
911 	if (options->user_hostfile2 == NULL)
912 		options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
913 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
914 		options->log_level = SYSLOG_LEVEL_INFO;
915 	if (options->clear_forwardings == 1)
916 		clear_forwardings(options);
917 	if (options->no_host_authentication_for_localhost == - 1)
918 		options->no_host_authentication_for_localhost = 0;
919 	/* options->proxy_command should not be set by default */
920 	/* options->user will be set in the main program if appropriate */
921 	/* options->hostname will be set in the main program if appropriate */
922 	/* options->host_key_alias should not be set by default */
923 	/* options->preferred_authentications will be set in ssh */
924 }
925