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