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