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