xref: /openbsd-src/usr.bin/ssh/readconf.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
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.86 2001/08/01 22:03:33 markus Exp $");
16 
17 #include "ssh.h"
18 #include "xmalloc.h"
19 #include "compat.h"
20 #include "cipher.h"
21 #include "pathnames.h"
22 #include "log.h"
23 #include "readconf.h"
24 #include "match.h"
25 #include "misc.h"
26 #include "kex.h"
27 #include "mac.h"
28 
29 /* Format of the configuration file:
30 
31    # Configuration data is parsed as follows:
32    #  1. command line options
33    #  2. user-specific file
34    #  3. system-wide file
35    # Any configuration value is only changed the first time it is set.
36    # Thus, host-specific definitions should be at the beginning of the
37    # configuration file, and defaults at the end.
38 
39    # Host-specific declarations.  These may override anything above.  A single
40    # host may match multiple declarations; these are processed in the order
41    # that they are given in.
42 
43    Host *.ngs.fi ngs.fi
44      FallBackToRsh no
45 
46    Host fake.com
47      HostName another.host.name.real.org
48      User blaah
49      Port 34289
50      ForwardX11 no
51      ForwardAgent no
52 
53    Host books.com
54      RemoteForward 9999 shadows.cs.hut.fi:9999
55      Cipher 3des
56 
57    Host fascist.blob.com
58      Port 23123
59      User tylonen
60      RhostsAuthentication no
61      PasswordAuthentication no
62 
63    Host puukko.hut.fi
64      User t35124p
65      ProxyCommand ssh-proxy %h %p
66 
67    Host *.fr
68      UseRsh yes
69 
70    Host *.su
71      Cipher none
72      PasswordAuthentication no
73 
74    # Defaults for various options
75    Host *
76      ForwardAgent no
77      ForwardX11 no
78      RhostsAuthentication yes
79      PasswordAuthentication yes
80      RSAAuthentication yes
81      RhostsRSAAuthentication yes
82      FallBackToRsh no
83      UseRsh no
84      StrictHostKeyChecking yes
85      KeepAlives no
86      IdentityFile ~/.ssh/identity
87      Port 22
88      EscapeChar ~
89 
90 */
91 
92 /* Keyword tokens. */
93 
94 typedef enum {
95 	oBadOption,
96 	oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
97 	oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
98 	oChallengeResponseAuthentication, oXAuthLocation,
99 #if defined(KRB4) || defined(KRB5)
100 	oKerberosAuthentication,
101 #endif
102 #if defined(AFS) || defined(KRB5)
103 	oKerberosTgtPassing,
104 #endif
105 #ifdef AFS
106 	oAFSTokenPassing,
107 #endif
108 	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
109 	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
110 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
111 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
112 	oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
113 	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
114 	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
115 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
116 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
117 	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice
118 } OpCodes;
119 
120 /* Textual representations of the tokens. */
121 
122 static struct {
123 	const char *name;
124 	OpCodes opcode;
125 } keywords[] = {
126 	{ "forwardagent", oForwardAgent },
127 	{ "forwardx11", oForwardX11 },
128 	{ "xauthlocation", oXAuthLocation },
129 	{ "gatewayports", oGatewayPorts },
130 	{ "useprivilegedport", oUsePrivilegedPort },
131 	{ "rhostsauthentication", oRhostsAuthentication },
132 	{ "passwordauthentication", oPasswordAuthentication },
133 	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
134 	{ "kbdinteractivedevices", oKbdInteractiveDevices },
135 	{ "rsaauthentication", oRSAAuthentication },
136 	{ "pubkeyauthentication", oPubkeyAuthentication },
137 	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
138 	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
139 	{ "hostbasedauthentication", oHostbasedAuthentication },
140 	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
141 	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
142 	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
143 #if defined(KRB4) || defined(KRB5)
144 	{ "kerberosauthentication", oKerberosAuthentication },
145 #endif
146 #if defined(AFS) || defined(KRB5)
147 	{ "kerberostgtpassing", oKerberosTgtPassing },
148 #endif
149 #ifdef AFS
150 	{ "afstokenpassing", oAFSTokenPassing },
151 #endif
152 	{ "fallbacktorsh", oFallBackToRsh },
153 	{ "usersh", oUseRsh },
154 	{ "identityfile", oIdentityFile },
155 	{ "identityfile2", oIdentityFile },			/* alias */
156 	{ "hostname", oHostName },
157 	{ "hostkeyalias", oHostKeyAlias },
158 	{ "proxycommand", oProxyCommand },
159 	{ "port", oPort },
160 	{ "cipher", oCipher },
161 	{ "ciphers", oCiphers },
162 	{ "macs", oMacs },
163 	{ "protocol", oProtocol },
164 	{ "remoteforward", oRemoteForward },
165 	{ "localforward", oLocalForward },
166 	{ "user", oUser },
167 	{ "host", oHost },
168 	{ "escapechar", oEscapeChar },
169 	{ "globalknownhostsfile", oGlobalKnownHostsFile },
170 	{ "userknownhostsfile", oUserKnownHostsFile },		/* obsolete */
171 	{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },
172 	{ "userknownhostsfile2", oUserKnownHostsFile2 },	/* obsolete */
173 	{ "connectionattempts", oConnectionAttempts },
174 	{ "batchmode", oBatchMode },
175 	{ "checkhostip", oCheckHostIP },
176 	{ "stricthostkeychecking", oStrictHostKeyChecking },
177 	{ "compression", oCompression },
178 	{ "compressionlevel", oCompressionLevel },
179 	{ "keepalive", oKeepAlives },
180 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
181 	{ "loglevel", oLogLevel },
182 	{ "dynamicforward", oDynamicForward },
183 	{ "preferredauthentications", oPreferredAuthentications },
184 	{ "hostkeyalgorithms", oHostKeyAlgorithms },
185 	{ "bindaddress", oBindAddress },
186 	{ "smartcarddevice", oSmartcardDevice },
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 	case oChallengeResponseAuthentication:
340 		intptr = &options->challenge_response_authentication;
341 		goto parse_flag;
342 #if defined(KRB4) || defined(KRB5)
343 	case oKerberosAuthentication:
344 		intptr = &options->kerberos_authentication;
345 		goto parse_flag;
346 #endif
347 #if defined(AFS) || defined(KRB5)
348 	case oKerberosTgtPassing:
349 		intptr = &options->kerberos_tgt_passing;
350 		goto parse_flag;
351 #endif
352 #ifdef AFS
353 	case oAFSTokenPassing:
354 		intptr = &options->afs_token_passing;
355 		goto parse_flag;
356 #endif
357 	case oFallBackToRsh:
358 		intptr = &options->fallback_to_rsh;
359 		goto parse_flag;
360 
361 	case oUseRsh:
362 		intptr = &options->use_rsh;
363 		goto parse_flag;
364 
365 	case oBatchMode:
366 		intptr = &options->batch_mode;
367 		goto parse_flag;
368 
369 	case oCheckHostIP:
370 		intptr = &options->check_host_ip;
371 		goto parse_flag;
372 
373 	case oStrictHostKeyChecking:
374 		intptr = &options->strict_host_key_checking;
375 		arg = strdelim(&s);
376 		if (!arg || *arg == '\0')
377 			fatal("%.200s line %d: Missing yes/no/ask argument.",
378 			      filename, linenum);
379 		value = 0;	/* To avoid compiler warning... */
380 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
381 			value = 1;
382 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
383 			value = 0;
384 		else if (strcmp(arg, "ask") == 0)
385 			value = 2;
386 		else
387 			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
388 		if (*activep && *intptr == -1)
389 			*intptr = value;
390 		break;
391 
392 	case oCompression:
393 		intptr = &options->compression;
394 		goto parse_flag;
395 
396 	case oKeepAlives:
397 		intptr = &options->keepalives;
398 		goto parse_flag;
399 
400 	case oNumberOfPasswordPrompts:
401 		intptr = &options->number_of_password_prompts;
402 		goto parse_int;
403 
404 	case oCompressionLevel:
405 		intptr = &options->compression_level;
406 		goto parse_int;
407 
408 	case oIdentityFile:
409 		arg = strdelim(&s);
410 		if (!arg || *arg == '\0')
411 			fatal("%.200s line %d: Missing argument.", filename, linenum);
412 		if (*activep) {
413 			intptr = &options->num_identity_files;
414 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
415 				fatal("%.200s line %d: Too many identity files specified (max %d).",
416 				      filename, linenum, SSH_MAX_IDENTITY_FILES);
417 			charptr =  &options->identity_files[*intptr];
418 			*charptr = xstrdup(arg);
419 			*intptr = *intptr + 1;
420 		}
421 		break;
422 
423 	case oXAuthLocation:
424 		charptr=&options->xauth_location;
425 		goto parse_string;
426 
427 	case oUser:
428 		charptr = &options->user;
429 parse_string:
430 		arg = strdelim(&s);
431 		if (!arg || *arg == '\0')
432 			fatal("%.200s line %d: Missing argument.", filename, linenum);
433 		if (*activep && *charptr == NULL)
434 			*charptr = xstrdup(arg);
435 		break;
436 
437 	case oGlobalKnownHostsFile:
438 		charptr = &options->system_hostfile;
439 		goto parse_string;
440 
441 	case oUserKnownHostsFile:
442 		charptr = &options->user_hostfile;
443 		goto parse_string;
444 
445 	case oGlobalKnownHostsFile2:
446 		charptr = &options->system_hostfile2;
447 		goto parse_string;
448 
449 	case oUserKnownHostsFile2:
450 		charptr = &options->user_hostfile2;
451 		goto parse_string;
452 
453 	case oHostName:
454 		charptr = &options->hostname;
455 		goto parse_string;
456 
457 	case oHostKeyAlias:
458 		charptr = &options->host_key_alias;
459 		goto parse_string;
460 
461 	case oPreferredAuthentications:
462 		charptr = &options->preferred_authentications;
463 		goto parse_string;
464 
465 	case oBindAddress:
466 		charptr = &options->bind_address;
467 		goto parse_string;
468 
469 	case oSmartcardDevice:
470 		charptr = &options->smartcard_device;
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 = SSH_ESCAPECHAR_NONE;
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_response_authentication = -1;
733 #if defined(KRB4) || defined(KRB5)
734 	options->kerberos_authentication = -1;
735 #endif
736 #if defined(AFS) || defined(KRB5)
737 	options->kerberos_tgt_passing = -1;
738 #endif
739 #ifdef AFS
740 	options->afs_token_passing = -1;
741 #endif
742 	options->password_authentication = -1;
743 	options->kbd_interactive_authentication = -1;
744 	options->kbd_interactive_devices = NULL;
745 	options->rhosts_rsa_authentication = -1;
746 	options->hostbased_authentication = -1;
747 	options->fallback_to_rsh = -1;
748 	options->use_rsh = -1;
749 	options->batch_mode = -1;
750 	options->check_host_ip = -1;
751 	options->strict_host_key_checking = -1;
752 	options->compression = -1;
753 	options->keepalives = -1;
754 	options->compression_level = -1;
755 	options->port = -1;
756 	options->connection_attempts = -1;
757 	options->number_of_password_prompts = -1;
758 	options->cipher = -1;
759 	options->ciphers = NULL;
760 	options->macs = NULL;
761 	options->hostkeyalgorithms = NULL;
762 	options->protocol = SSH_PROTO_UNKNOWN;
763 	options->num_identity_files = 0;
764 	options->hostname = NULL;
765 	options->host_key_alias = NULL;
766 	options->proxy_command = NULL;
767 	options->user = NULL;
768 	options->escape_char = -1;
769 	options->system_hostfile = NULL;
770 	options->user_hostfile = NULL;
771 	options->system_hostfile2 = NULL;
772 	options->user_hostfile2 = NULL;
773 	options->num_local_forwards = 0;
774 	options->num_remote_forwards = 0;
775 	options->log_level = (LogLevel) - 1;
776 	options->preferred_authentications = NULL;
777 	options->bind_address = NULL;
778 	options->smartcard_device = NULL;
779 }
780 
781 /*
782  * Called after processing other sources of option data, this fills those
783  * options for which no value has been specified with their default values.
784  */
785 
786 void
787 fill_default_options(Options * options)
788 {
789 	int len;
790 
791 	if (options->forward_agent == -1)
792 		options->forward_agent = 0;
793 	if (options->forward_x11 == -1)
794 		options->forward_x11 = 0;
795 #ifdef _PATH_XAUTH
796 	if (options->xauth_location == NULL)
797 		options->xauth_location = _PATH_XAUTH;
798 #endif
799 	if (options->gateway_ports == -1)
800 		options->gateway_ports = 0;
801 	if (options->use_privileged_port == -1)
802 		options->use_privileged_port = 0;
803 	if (options->rhosts_authentication == -1)
804 		options->rhosts_authentication = 1;
805 	if (options->rsa_authentication == -1)
806 		options->rsa_authentication = 1;
807 	if (options->pubkey_authentication == -1)
808 		options->pubkey_authentication = 1;
809 	if (options->challenge_response_authentication == -1)
810 		options->challenge_response_authentication = 1;
811 #if defined(KRB4) || defined(KRB5)
812 	if (options->kerberos_authentication == -1)
813 		options->kerberos_authentication = 1;
814 #endif
815 #if defined(AFS) || defined(KRB5)
816 	if (options->kerberos_tgt_passing == -1)
817 		options->kerberos_tgt_passing = 1;
818 #endif
819 #ifdef AFS
820 	if (options->afs_token_passing == -1)
821 		options->afs_token_passing = 1;
822 #endif
823 	if (options->password_authentication == -1)
824 		options->password_authentication = 1;
825 	if (options->kbd_interactive_authentication == -1)
826 		options->kbd_interactive_authentication = 1;
827 	if (options->rhosts_rsa_authentication == -1)
828 		options->rhosts_rsa_authentication = 1;
829 	if (options->hostbased_authentication == -1)
830 		options->hostbased_authentication = 0;
831 	if (options->fallback_to_rsh == -1)
832 		options->fallback_to_rsh = 0;
833 	if (options->use_rsh == -1)
834 		options->use_rsh = 0;
835 	if (options->batch_mode == -1)
836 		options->batch_mode = 0;
837 	if (options->check_host_ip == -1)
838 		options->check_host_ip = 1;
839 	if (options->strict_host_key_checking == -1)
840 		options->strict_host_key_checking = 2;	/* 2 is default */
841 	if (options->compression == -1)
842 		options->compression = 0;
843 	if (options->keepalives == -1)
844 		options->keepalives = 1;
845 	if (options->compression_level == -1)
846 		options->compression_level = 6;
847 	if (options->port == -1)
848 		options->port = 0;	/* Filled in ssh_connect. */
849 	if (options->connection_attempts == -1)
850 		options->connection_attempts = 1;
851 	if (options->number_of_password_prompts == -1)
852 		options->number_of_password_prompts = 3;
853 	/* Selected in ssh_login(). */
854 	if (options->cipher == -1)
855 		options->cipher = SSH_CIPHER_NOT_SET;
856 	/* options->ciphers, default set in myproposals.h */
857 	/* options->macs, default set in myproposals.h */
858 	/* options->hostkeyalgorithms, default set in myproposals.h */
859 	if (options->protocol == SSH_PROTO_UNKNOWN)
860 		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
861 	if (options->num_identity_files == 0) {
862 		if (options->protocol & SSH_PROTO_1) {
863 			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
864 			options->identity_files[options->num_identity_files] =
865 			    xmalloc(len);
866 			snprintf(options->identity_files[options->num_identity_files++],
867 			    len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
868 		}
869 		if (options->protocol & SSH_PROTO_2) {
870 			len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
871 			options->identity_files[options->num_identity_files] =
872 			    xmalloc(len);
873 			snprintf(options->identity_files[options->num_identity_files++],
874 			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
875 
876 			len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
877 			options->identity_files[options->num_identity_files] =
878 			    xmalloc(len);
879 			snprintf(options->identity_files[options->num_identity_files++],
880 			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
881 		}
882 	}
883 	if (options->escape_char == -1)
884 		options->escape_char = '~';
885 	if (options->system_hostfile == NULL)
886 		options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
887 	if (options->user_hostfile == NULL)
888 		options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
889 	if (options->system_hostfile2 == NULL)
890 		options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
891 	if (options->user_hostfile2 == NULL)
892 		options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
893 	if (options->log_level == (LogLevel) - 1)
894 		options->log_level = SYSLOG_LEVEL_INFO;
895 	/* options->proxy_command should not be set by default */
896 	/* options->user will be set in the main program if appropriate */
897 	/* options->hostname will be set in the main program if appropriate */
898 	/* options->host_key_alias should not be set by default */
899 	/* options->preferred_authentications will be set in ssh */
900 }
901