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