readconf.c revision 57565
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: head/crypto/openssh/readconf.c 57565 2000-02-28 19:03:50Z markm $
15 */
16
17#include "includes.h"
18RCSID("$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
90typedef 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
114static 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
174void
175add_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
195void
196add_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
214static OpCodes
215parse_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
233int
234process_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;
258parse_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;
398parse_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;
434parse_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
564void
565read_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
604void
605initialize_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
657void
658fill_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 = 1;
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