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