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