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