xref: /freebsd/crypto/openssh/readconf.c (revision 5dc73ebebeb64670a24b3db3934735b1859926b7)
1 /*
2  *
3  * readconf.c
4  *
5  * Author: Tatu Ylonen <ylo@cs.hut.fi>
6  *
7  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8  *                    All rights reserved
9  *
10  * Created: Sat Apr 22 00:03:10 1995 ylo
11  *
12  * Functions for reading the configuration files.
13  *
14  * $FreeBSD$
15  */
16 
17 #include "includes.h"
18 RCSID("$Id: readconf.c,v 1.23 2000/02/28 19:51:58 markus Exp $");
19 
20 #include "ssh.h"
21 #include "cipher.h"
22 #include "readconf.h"
23 #include "xmalloc.h"
24 
25 /* Format of the configuration file:
26 
27    # Configuration data is parsed as follows:
28    #  1. command line options
29    #  2. user-specific file
30    #  3. system-wide file
31    # Any configuration value is only changed the first time it is set.
32    # Thus, host-specific definitions should be at the beginning of the
33    # configuration file, and defaults at the end.
34 
35    # Host-specific declarations.  These may override anything above.  A single
36    # host may match multiple declarations; these are processed in the order
37    # that they are given in.
38 
39    Host *.ngs.fi ngs.fi
40      FallBackToRsh no
41 
42    Host fake.com
43      HostName another.host.name.real.org
44      User blaah
45      Port 34289
46      ForwardX11 no
47      ForwardAgent no
48 
49    Host books.com
50      RemoteForward 9999 shadows.cs.hut.fi:9999
51      Cipher 3des
52 
53    Host fascist.blob.com
54      Port 23123
55      User tylonen
56      RhostsAuthentication no
57      PasswordAuthentication no
58 
59    Host puukko.hut.fi
60      User t35124p
61      ProxyCommand ssh-proxy %h %p
62 
63    Host *.fr
64      UseRsh yes
65 
66    Host *.su
67      Cipher none
68      PasswordAuthentication no
69 
70    # Defaults for various options
71    Host *
72      ForwardAgent no
73      ForwardX11 yes
74      RhostsAuthentication yes
75      PasswordAuthentication yes
76      RSAAuthentication yes
77      RhostsRSAAuthentication yes
78      FallBackToRsh no
79      UseRsh no
80      StrictHostKeyChecking yes
81      KeepAlives no
82      IdentityFile ~/.ssh/identity
83      Port 22
84      EscapeChar ~
85 
86 */
87 
88 /* Keyword tokens. */
89 
90 typedef enum {
91 	oBadOption,
92 	oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
93 	oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
94 	oSkeyAuthentication,
95 #ifdef KRB4
96 	oKrb4Authentication,
97 #endif /* KRB4 */
98 #ifdef KRB5
99 	oKrb5Authentication, oKrb5TgtPassing,
100 #endif /* KRB5 */
101 #ifdef AFS
102 	oKrb4TgtPassing, oAFSTokenPassing,
103 #endif
104 	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
105 	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
106 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
107 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
108 	oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
109 	oUsePrivilegedPort, oLogLevel
110 } OpCodes;
111 
112 /* Textual representations of the tokens. */
113 
114 static struct {
115 	const char *name;
116 	OpCodes opcode;
117 } keywords[] = {
118 	{ "forwardagent", oForwardAgent },
119 	{ "forwardx11", oForwardX11 },
120 	{ "gatewayports", oGatewayPorts },
121 	{ "useprivilegedport", oUsePrivilegedPort },
122 	{ "rhostsauthentication", oRhostsAuthentication },
123 	{ "passwordauthentication", oPasswordAuthentication },
124 	{ "rsaauthentication", oRSAAuthentication },
125 	{ "skeyauthentication", oSkeyAuthentication },
126 #ifdef KRB4
127 	{ "kerberos4authentication", oKrb4Authentication },
128 #endif /* KRB4 */
129 #ifdef KRB5
130 	{ "kerberos5authentication", oKrb5Authentication },
131 	{ "kerberos5tgtpassing", oKrb5TgtPassing },
132 #endif /* KRB5 */
133 #ifdef AFS
134 	{ "kerberos4tgtpassing", oKrb4TgtPassing },
135 	{ "afstokenpassing", oAFSTokenPassing },
136 #endif
137 	{ "fallbacktorsh", oFallBackToRsh },
138 	{ "usersh", oUseRsh },
139 	{ "identityfile", oIdentityFile },
140 	{ "hostname", oHostName },
141 	{ "proxycommand", oProxyCommand },
142 	{ "port", oPort },
143 	{ "cipher", oCipher },
144 	{ "remoteforward", oRemoteForward },
145 	{ "localforward", oLocalForward },
146 	{ "user", oUser },
147 	{ "host", oHost },
148 	{ "escapechar", oEscapeChar },
149 	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
150 	{ "globalknownhostsfile", oGlobalKnownHostsFile },
151 	{ "userknownhostsfile", oUserKnownHostsFile },
152 	{ "connectionattempts", oConnectionAttempts },
153 	{ "batchmode", oBatchMode },
154 	{ "checkhostip", oCheckHostIP },
155 	{ "stricthostkeychecking", oStrictHostKeyChecking },
156 	{ "compression", oCompression },
157 	{ "compressionlevel", oCompressionLevel },
158 	{ "keepalive", oKeepAlives },
159 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
160 	{ "tisauthentication", oTISAuthentication },
161 	{ "loglevel", oLogLevel },
162 	{ NULL, 0 }
163 };
164 
165 /* Characters considered whitespace in strtok calls. */
166 #define WHITESPACE " \t\r\n"
167 
168 
169 /*
170  * Adds a local TCP/IP port forward to options.  Never returns if there is an
171  * error.
172  */
173 
174 void
175 add_local_forward(Options *options, u_short port, const char *host,
176 		  u_short host_port)
177 {
178 	Forward *fwd;
179 	extern uid_t original_real_uid;
180 	if (port < IPPORT_RESERVED && original_real_uid != 0)
181 		fatal("Privileged ports can only be forwarded by root.\n");
182 	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
183 		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
184 	fwd = &options->local_forwards[options->num_local_forwards++];
185 	fwd->port = port;
186 	fwd->host = xstrdup(host);
187 	fwd->host_port = host_port;
188 }
189 
190 /*
191  * Adds a remote TCP/IP port forward to options.  Never returns if there is
192  * an error.
193  */
194 
195 void
196 add_remote_forward(Options *options, u_short port, const char *host,
197 		   u_short host_port)
198 {
199 	Forward *fwd;
200 	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
201 		fatal("Too many remote forwards (max %d).",
202 		      SSH_MAX_FORWARDS_PER_DIRECTION);
203 	fwd = &options->remote_forwards[options->num_remote_forwards++];
204 	fwd->port = port;
205 	fwd->host = xstrdup(host);
206 	fwd->host_port = host_port;
207 }
208 
209 /*
210  * Returns the number of the token pointed to by cp of length len. Never
211  * returns if the token is not known.
212  */
213 
214 static OpCodes
215 parse_token(const char *cp, const char *filename, int linenum)
216 {
217 	unsigned int i;
218 
219 	for (i = 0; keywords[i].name; i++)
220 		if (strcasecmp(cp, keywords[i].name) == 0)
221 			return keywords[i].opcode;
222 
223 	fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
224 		filename, linenum, cp);
225 	return oBadOption;
226 }
227 
228 /*
229  * Processes a single option line as used in the configuration files. This
230  * only sets those values that have not already been set.
231  */
232 
233 int
234 process_config_line(Options *options, const char *host,
235 		    char *line, const char *filename, int linenum,
236 		    int *activep)
237 {
238 	char buf[256], *cp, *string, **charptr, *cp2;
239 	int opcode, *intptr, value;
240 	u_short fwd_port, fwd_host_port;
241 
242 	/* Skip leading whitespace. */
243 	cp = line + strspn(line, WHITESPACE);
244 	if (!*cp || *cp == '\n' || *cp == '#')
245 		return 0;
246 
247 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
248 	cp = strtok(cp, WHITESPACE);
249 	opcode = parse_token(cp, filename, linenum);
250 
251 	switch (opcode) {
252 	case oBadOption:
253 		/* don't panic, but count bad options */
254 		return -1;
255 		/* NOTREACHED */
256 	case oForwardAgent:
257 		intptr = &options->forward_agent;
258 parse_flag:
259 		cp = strtok(NULL, WHITESPACE);
260 		if (!cp)
261 			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
262 		value = 0;	/* To avoid compiler warning... */
263 		if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)
264 			value = 1;
265 		else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0)
266 			value = 0;
267 		else
268 			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
269 		if (*activep && *intptr == -1)
270 			*intptr = value;
271 		break;
272 
273 	case oForwardX11:
274 		intptr = &options->forward_x11;
275 		goto parse_flag;
276 
277 	case oGatewayPorts:
278 		intptr = &options->gateway_ports;
279 		goto parse_flag;
280 
281 	case oUsePrivilegedPort:
282 		intptr = &options->use_privileged_port;
283 		goto parse_flag;
284 
285 	case oRhostsAuthentication:
286 		intptr = &options->rhosts_authentication;
287 		goto parse_flag;
288 
289 	case oPasswordAuthentication:
290 		intptr = &options->password_authentication;
291 		goto parse_flag;
292 
293 	case oRSAAuthentication:
294 		intptr = &options->rsa_authentication;
295 		goto parse_flag;
296 
297 	case oRhostsRSAAuthentication:
298 		intptr = &options->rhosts_rsa_authentication;
299 		goto parse_flag;
300 
301 	case oTISAuthentication:
302 		/* fallthrough, there is no difference on the client side */
303 	case oSkeyAuthentication:
304 		intptr = &options->skey_authentication;
305 		goto parse_flag;
306 
307 #ifdef KRB4
308 	case oKrb4Authentication:
309 		intptr = &options->krb4_authentication;
310 		goto parse_flag;
311 #endif /* KRB4 */
312 
313 #ifdef KRB5
314 	case oKrb5Authentication:
315 		intptr = &options->krb5_authentication;
316 		goto parse_flag;
317 
318 	case oKrb5TgtPassing:
319 		intptr = &options->krb5_tgt_passing;
320 		goto parse_flag;
321 #endif /* KRB5 */
322 
323 #ifdef AFS
324 	case oKrb4TgtPassing:
325 		intptr = &options->krb4_tgt_passing;
326 		goto parse_flag;
327 
328 	case oAFSTokenPassing:
329 		intptr = &options->afs_token_passing;
330 		goto parse_flag;
331 #endif
332 
333 	case oFallBackToRsh:
334 		intptr = &options->fallback_to_rsh;
335 		goto parse_flag;
336 
337 	case oUseRsh:
338 		intptr = &options->use_rsh;
339 		goto parse_flag;
340 
341 	case oBatchMode:
342 		intptr = &options->batch_mode;
343 		goto parse_flag;
344 
345 	case oCheckHostIP:
346 		intptr = &options->check_host_ip;
347 		goto parse_flag;
348 
349 	case oStrictHostKeyChecking:
350 		intptr = &options->strict_host_key_checking;
351 		cp = strtok(NULL, WHITESPACE);
352 		if (!cp)
353 			fatal("%.200s line %d: Missing yes/no argument.",
354 			      filename, linenum);
355 		value = 0;	/* To avoid compiler warning... */
356 		if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)
357 			value = 1;
358 		else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0)
359 			value = 0;
360 		else if (strcmp(cp, "ask") == 0)
361 			value = 2;
362 		else
363 			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
364 		if (*activep && *intptr == -1)
365 			*intptr = value;
366 		break;
367 
368 	case oCompression:
369 		intptr = &options->compression;
370 		goto parse_flag;
371 
372 	case oKeepAlives:
373 		intptr = &options->keepalives;
374 		goto parse_flag;
375 
376 	case oNumberOfPasswordPrompts:
377 		intptr = &options->number_of_password_prompts;
378 		goto parse_int;
379 
380 	case oCompressionLevel:
381 		intptr = &options->compression_level;
382 		goto parse_int;
383 
384 	case oIdentityFile:
385 		cp = strtok(NULL, WHITESPACE);
386 		if (!cp)
387 			fatal("%.200s line %d: Missing argument.", filename, linenum);
388 		if (*activep) {
389 			if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
390 				fatal("%.200s line %d: Too many identity files specified (max %d).",
391 				      filename, linenum, SSH_MAX_IDENTITY_FILES);
392 			options->identity_files[options->num_identity_files++] = xstrdup(cp);
393 		}
394 		break;
395 
396 	case oUser:
397 		charptr = &options->user;
398 parse_string:
399 		cp = strtok(NULL, WHITESPACE);
400 		if (!cp)
401 			fatal("%.200s line %d: Missing argument.", filename, linenum);
402 		if (*activep && *charptr == NULL)
403 			*charptr = xstrdup(cp);
404 		break;
405 
406 	case oGlobalKnownHostsFile:
407 		charptr = &options->system_hostfile;
408 		goto parse_string;
409 
410 	case oUserKnownHostsFile:
411 		charptr = &options->user_hostfile;
412 		goto parse_string;
413 
414 	case oHostName:
415 		charptr = &options->hostname;
416 		goto parse_string;
417 
418 	case oProxyCommand:
419 		charptr = &options->proxy_command;
420 		string = xstrdup("");
421 		while ((cp = strtok(NULL, WHITESPACE)) != NULL) {
422 			string = xrealloc(string, strlen(string) + strlen(cp) + 2);
423 			strcat(string, " ");
424 			strcat(string, cp);
425 		}
426 		if (*activep && *charptr == NULL)
427 			*charptr = string;
428 		else
429 			xfree(string);
430 		return 0;
431 
432 	case oPort:
433 		intptr = &options->port;
434 parse_int:
435 		cp = strtok(NULL, WHITESPACE);
436 		if (!cp)
437 			fatal("%.200s line %d: Missing argument.", filename, linenum);
438 		if (cp[0] < '0' || cp[0] > '9')
439 			fatal("%.200s line %d: Bad number.", filename, linenum);
440 
441 		/* Octal, decimal, or hex format? */
442 		value = strtol(cp, &cp2, 0);
443 		if (cp == cp2)
444 			fatal("%.200s line %d: Bad number.", filename, linenum);
445 		if (*activep && *intptr == -1)
446 			*intptr = value;
447 		break;
448 
449 	case oConnectionAttempts:
450 		intptr = &options->connection_attempts;
451 		goto parse_int;
452 
453 	case oCipher:
454 		intptr = &options->cipher;
455 		cp = strtok(NULL, WHITESPACE);
456 		value = cipher_number(cp);
457 		if (value == -1)
458 			fatal("%.200s line %d: Bad cipher '%s'.",
459 			      filename, linenum, cp ? cp : "<NONE>");
460 		if (*activep && *intptr == -1)
461 			*intptr = value;
462 		break;
463 
464 	case oLogLevel:
465 		intptr = (int *) &options->log_level;
466 		cp = strtok(NULL, WHITESPACE);
467 		value = log_level_number(cp);
468 		if (value == (LogLevel) - 1)
469 			fatal("%.200s line %d: unsupported log level '%s'\n",
470 			      filename, linenum, cp ? cp : "<NONE>");
471 		if (*activep && (LogLevel) * intptr == -1)
472 			*intptr = (LogLevel) value;
473 		break;
474 
475 	case oRemoteForward:
476 		cp = strtok(NULL, WHITESPACE);
477 		if (!cp)
478 			fatal("%.200s line %d: Missing argument.", filename, linenum);
479 		if (cp[0] < '0' || cp[0] > '9')
480 			fatal("%.200s line %d: Badly formatted port number.",
481 			      filename, linenum);
482 		fwd_port = atoi(cp);
483 		cp = strtok(NULL, WHITESPACE);
484 		if (!cp)
485 			fatal("%.200s line %d: Missing second argument.",
486 			      filename, linenum);
487 		if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
488 			fatal("%.200s line %d: Badly formatted host:port.",
489 			      filename, linenum);
490 		if (*activep)
491 			add_remote_forward(options, fwd_port, buf, fwd_host_port);
492 		break;
493 
494 	case oLocalForward:
495 		cp = strtok(NULL, WHITESPACE);
496 		if (!cp)
497 			fatal("%.200s line %d: Missing argument.", filename, linenum);
498 		if (cp[0] < '0' || cp[0] > '9')
499 			fatal("%.200s line %d: Badly formatted port number.",
500 			      filename, linenum);
501 		fwd_port = atoi(cp);
502 		cp = strtok(NULL, WHITESPACE);
503 		if (!cp)
504 			fatal("%.200s line %d: Missing second argument.",
505 			      filename, linenum);
506 		if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
507 			fatal("%.200s line %d: Badly formatted host:port.",
508 			      filename, linenum);
509 		if (*activep)
510 			add_local_forward(options, fwd_port, buf, fwd_host_port);
511 		break;
512 
513 	case oHost:
514 		*activep = 0;
515 		while ((cp = strtok(NULL, WHITESPACE)) != NULL)
516 			if (match_pattern(host, cp)) {
517 				debug("Applying options for %.100s", cp);
518 				*activep = 1;
519 				break;
520 			}
521 		/* Avoid garbage check below, as strtok already returned NULL. */
522 		return 0;
523 
524 	case oEscapeChar:
525 		intptr = &options->escape_char;
526 		cp = strtok(NULL, WHITESPACE);
527 		if (!cp)
528 			fatal("%.200s line %d: Missing argument.", filename, linenum);
529 		if (cp[0] == '^' && cp[2] == 0 &&
530 		    (unsigned char) cp[1] >= 64 && (unsigned char) cp[1] < 128)
531 			value = (unsigned char) cp[1] & 31;
532 		else if (strlen(cp) == 1)
533 			value = (unsigned char) cp[0];
534 		else if (strcmp(cp, "none") == 0)
535 			value = -2;
536 		else {
537 			fatal("%.200s line %d: Bad escape character.",
538 			      filename, linenum);
539 			/* NOTREACHED */
540 			value = 0;	/* Avoid compiler warning. */
541 		}
542 		if (*activep && *intptr == -1)
543 			*intptr = value;
544 		break;
545 
546 	default:
547 		fatal("process_config_line: Unimplemented opcode %d", opcode);
548 	}
549 
550 	/* Check that there is no garbage at end of line. */
551 	if (strtok(NULL, WHITESPACE) != NULL)
552 		fatal("%.200s line %d: garbage at end of line.",
553 		      filename, linenum);
554 	return 0;
555 }
556 
557 
558 /*
559  * Reads the config file and modifies the options accordingly.  Options
560  * should already be initialized before this call.  This never returns if
561  * there is an error.  If the file does not exist, this returns immediately.
562  */
563 
564 void
565 read_config_file(const char *filename, const char *host, Options *options)
566 {
567 	FILE *f;
568 	char line[1024];
569 	int active, linenum;
570 	int bad_options = 0;
571 
572 	/* Open the file. */
573 	f = fopen(filename, "r");
574 	if (!f)
575 		return;
576 
577 	debug("Reading configuration data %.200s", filename);
578 
579 	/*
580 	 * Mark that we are now processing the options.  This flag is turned
581 	 * on/off by Host specifications.
582 	 */
583 	active = 1;
584 	linenum = 0;
585 	while (fgets(line, sizeof(line), f)) {
586 		/* Update line number counter. */
587 		linenum++;
588 		if (process_config_line(options, host, line, filename, linenum, &active) != 0)
589 			bad_options++;
590 	}
591 	fclose(f);
592 	if (bad_options > 0)
593 		fatal("%s: terminating, %d bad configuration options\n",
594 		      filename, bad_options);
595 }
596 
597 /*
598  * Initializes options to special values that indicate that they have not yet
599  * been set.  Read_config_file will only set options with this value. Options
600  * are processed in the following order: command line, user config file,
601  * system config file.  Last, fill_default_options is called.
602  */
603 
604 void
605 initialize_options(Options * options)
606 {
607 	memset(options, 'X', sizeof(*options));
608 	options->forward_agent = -1;
609 	options->forward_x11 = -1;
610 	options->gateway_ports = -1;
611 	options->use_privileged_port = -1;
612 	options->rhosts_authentication = -1;
613 	options->rsa_authentication = -1;
614 	options->skey_authentication = -1;
615 #ifdef KRB4
616 	options->krb4_authentication = -1;
617 #endif
618 #ifdef KRB5
619 	options->krb5_authentication = -1;
620 	options->krb5_tgt_passing = -1;
621 #endif /* KRB5 */
622 #ifdef AFS
623 	options->krb4_tgt_passing = -1;
624 	options->afs_token_passing = -1;
625 #endif
626 	options->password_authentication = -1;
627 	options->rhosts_rsa_authentication = -1;
628 	options->fallback_to_rsh = -1;
629 	options->use_rsh = -1;
630 	options->batch_mode = -1;
631 	options->check_host_ip = -1;
632 	options->strict_host_key_checking = -1;
633 	options->compression = -1;
634 	options->keepalives = -1;
635 	options->compression_level = -1;
636 	options->port = -1;
637 	options->connection_attempts = -1;
638 	options->number_of_password_prompts = -1;
639 	options->cipher = -1;
640 	options->num_identity_files = 0;
641 	options->hostname = NULL;
642 	options->proxy_command = NULL;
643 	options->user = NULL;
644 	options->escape_char = -1;
645 	options->system_hostfile = NULL;
646 	options->user_hostfile = NULL;
647 	options->num_local_forwards = 0;
648 	options->num_remote_forwards = 0;
649 	options->log_level = (LogLevel) - 1;
650 }
651 
652 /*
653  * Called after processing other sources of option data, this fills those
654  * options for which no value has been specified with their default values.
655  */
656 
657 void
658 fill_default_options(Options * options)
659 {
660 	if (options->forward_agent == -1)
661 		options->forward_agent = 1;
662 	if (options->forward_x11 == -1)
663 		options->forward_x11 = 0;
664 	if (options->gateway_ports == -1)
665 		options->gateway_ports = 0;
666 	if (options->use_privileged_port == -1)
667 		options->use_privileged_port = 1;
668 	if (options->rhosts_authentication == -1)
669 		options->rhosts_authentication = 1;
670 	if (options->rsa_authentication == -1)
671 		options->rsa_authentication = 1;
672 	if (options->skey_authentication == -1)
673 		options->skey_authentication = 0;
674 #ifdef KRB4
675 	if (options->krb4_authentication == -1)
676 		options->krb4_authentication = 1;
677 #endif /* KRB4 */
678 #ifdef KRB5
679 	if (options->krb5_authentication == -1)
680 		options->krb5_authentication = 1;
681 	if (options->krb5_tgt_passing == -1)
682 		options->krb5_tgt_passing = 1;
683 #endif /* KRB5 */
684 #ifdef AFS
685 	if (options->krb4_tgt_passing == -1)
686 		options->krb4_tgt_passing = 1;
687 	if (options->afs_token_passing == -1)
688 		options->afs_token_passing = 1;
689 #endif /* AFS */
690 	if (options->password_authentication == -1)
691 		options->password_authentication = 1;
692 	if (options->rhosts_rsa_authentication == -1)
693 		options->rhosts_rsa_authentication = 1;
694 	if (options->fallback_to_rsh == -1)
695 		options->fallback_to_rsh = 1;
696 	if (options->use_rsh == -1)
697 		options->use_rsh = 0;
698 	if (options->batch_mode == -1)
699 		options->batch_mode = 0;
700 	if (options->check_host_ip == -1)
701 		options->check_host_ip = 0;
702 	if (options->strict_host_key_checking == -1)
703 		options->strict_host_key_checking = 2;	/* 2 is default */
704 	if (options->compression == -1)
705 		options->compression = 0;
706 	if (options->keepalives == -1)
707 		options->keepalives = 1;
708 	if (options->compression_level == -1)
709 		options->compression_level = 6;
710 	if (options->port == -1)
711 		options->port = 0;	/* Filled in ssh_connect. */
712 	if (options->connection_attempts == -1)
713 		options->connection_attempts = 4;
714 	if (options->number_of_password_prompts == -1)
715 		options->number_of_password_prompts = 3;
716 	/* Selected in ssh_login(). */
717 	if (options->cipher == -1)
718 		options->cipher = SSH_CIPHER_NOT_SET;
719 	if (options->num_identity_files == 0) {
720 		options->identity_files[0] =
721 			xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1);
722 		sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY);
723 		options->num_identity_files = 1;
724 	}
725 	if (options->escape_char == -1)
726 		options->escape_char = '~';
727 	if (options->system_hostfile == NULL)
728 		options->system_hostfile = SSH_SYSTEM_HOSTFILE;
729 	if (options->user_hostfile == NULL)
730 		options->user_hostfile = SSH_USER_HOSTFILE;
731 	if (options->log_level == (LogLevel) - 1)
732 		options->log_level = SYSLOG_LEVEL_INFO;
733 	/* options->proxy_command should not be set by default */
734 	/* options->user will be set in the main program if appropriate */
735 	/* options->hostname will be set in the main program if appropriate */
736 }
737