xref: /freebsd/crypto/openssh/readconf.c (revision 099584266b3a508b982965708de56eaba461bee4)
1511b41d2SMark Murray /*
2511b41d2SMark Murray  * Author: Tatu Ylonen <ylo@cs.hut.fi>
3511b41d2SMark Murray  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4511b41d2SMark Murray  *                    All rights reserved
5511b41d2SMark Murray  * Functions for reading the configuration files.
6511b41d2SMark Murray  *
7c2d3a559SKris Kennaway  * As far as I am concerned, the code I have written for this software
8c2d3a559SKris Kennaway  * can be used freely for any purpose.  Any derived versions of this
9c2d3a559SKris Kennaway  * software must be clearly marked as such, and if the derived work is
10c2d3a559SKris Kennaway  * incompatible with the protocol description in the RFC file, it must be
11c2d3a559SKris Kennaway  * called by a name other than "ssh" or "Secure Shell".
12511b41d2SMark Murray  */
13511b41d2SMark Murray 
14511b41d2SMark Murray #include "includes.h"
1509958426SBrian Feldman RCSID("$OpenBSD: readconf.c,v 1.49 2000/10/11 20:27:23 markus Exp $");
16c2d3a559SKris Kennaway RCSID("$FreeBSD$");
17511b41d2SMark Murray 
18511b41d2SMark Murray #include "ssh.h"
19511b41d2SMark Murray #include "readconf.h"
20e8aafc91SKris Kennaway #include "match.h"
21511b41d2SMark Murray #include "xmalloc.h"
22e8aafc91SKris Kennaway #include "compat.h"
23511b41d2SMark Murray 
24511b41d2SMark Murray /* Format of the configuration file:
25511b41d2SMark Murray 
26511b41d2SMark Murray    # Configuration data is parsed as follows:
27511b41d2SMark Murray    #  1. command line options
28511b41d2SMark Murray    #  2. user-specific file
29511b41d2SMark Murray    #  3. system-wide file
30511b41d2SMark Murray    # Any configuration value is only changed the first time it is set.
31511b41d2SMark Murray    # Thus, host-specific definitions should be at the beginning of the
32511b41d2SMark Murray    # configuration file, and defaults at the end.
33511b41d2SMark Murray 
34511b41d2SMark Murray    # Host-specific declarations.  These may override anything above.  A single
35511b41d2SMark Murray    # host may match multiple declarations; these are processed in the order
36511b41d2SMark Murray    # that they are given in.
37511b41d2SMark Murray 
38511b41d2SMark Murray    Host *.ngs.fi ngs.fi
39511b41d2SMark Murray      FallBackToRsh no
40511b41d2SMark Murray 
41511b41d2SMark Murray    Host fake.com
42511b41d2SMark Murray      HostName another.host.name.real.org
43511b41d2SMark Murray      User blaah
44511b41d2SMark Murray      Port 34289
45511b41d2SMark Murray      ForwardX11 no
46511b41d2SMark Murray      ForwardAgent no
47511b41d2SMark Murray 
48511b41d2SMark Murray    Host books.com
49511b41d2SMark Murray      RemoteForward 9999 shadows.cs.hut.fi:9999
50511b41d2SMark Murray      Cipher 3des
51511b41d2SMark Murray 
52511b41d2SMark Murray    Host fascist.blob.com
53511b41d2SMark Murray      Port 23123
54511b41d2SMark Murray      User tylonen
55511b41d2SMark Murray      RhostsAuthentication no
56511b41d2SMark Murray      PasswordAuthentication no
57511b41d2SMark Murray 
58511b41d2SMark Murray    Host puukko.hut.fi
59511b41d2SMark Murray      User t35124p
60511b41d2SMark Murray      ProxyCommand ssh-proxy %h %p
61511b41d2SMark Murray 
62511b41d2SMark Murray    Host *.fr
63511b41d2SMark Murray      UseRsh yes
64511b41d2SMark Murray 
65511b41d2SMark Murray    Host *.su
66511b41d2SMark Murray      Cipher none
67511b41d2SMark Murray      PasswordAuthentication no
68511b41d2SMark Murray 
69511b41d2SMark Murray    # Defaults for various options
70511b41d2SMark Murray    Host *
71511b41d2SMark Murray      ForwardAgent no
72511b41d2SMark Murray      ForwardX11 yes
73511b41d2SMark Murray      RhostsAuthentication yes
74511b41d2SMark Murray      PasswordAuthentication yes
75511b41d2SMark Murray      RSAAuthentication yes
76511b41d2SMark Murray      RhostsRSAAuthentication yes
77511b41d2SMark Murray      FallBackToRsh no
78511b41d2SMark Murray      UseRsh no
79511b41d2SMark Murray      StrictHostKeyChecking yes
80511b41d2SMark Murray      KeepAlives no
81511b41d2SMark Murray      IdentityFile ~/.ssh/identity
82511b41d2SMark Murray      Port 22
83511b41d2SMark Murray      EscapeChar ~
84511b41d2SMark Murray 
85511b41d2SMark Murray */
86511b41d2SMark Murray 
87511b41d2SMark Murray /* Keyword tokens. */
88511b41d2SMark Murray 
89511b41d2SMark Murray typedef enum {
90511b41d2SMark Murray 	oBadOption,
91511b41d2SMark Murray 	oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
92511b41d2SMark Murray 	oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
93c2d3a559SKris Kennaway 	oSkeyAuthentication, oXAuthLocation,
94511b41d2SMark Murray #ifdef KRB4
95fe5fd017SMark Murray 	oKrb4Authentication,
96511b41d2SMark Murray #endif /* KRB4 */
97fe5fd017SMark Murray #ifdef KRB5
98fe5fd017SMark Murray 	oKrb5Authentication, oKrb5TgtPassing,
99fe5fd017SMark Murray #endif /* KRB5 */
100511b41d2SMark Murray #ifdef AFS
101fe5fd017SMark Murray 	oKrb4TgtPassing, oAFSTokenPassing,
102511b41d2SMark Murray #endif
103511b41d2SMark Murray 	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
104511b41d2SMark Murray 	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
105511b41d2SMark Murray 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
106511b41d2SMark Murray 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
107511b41d2SMark Murray 	oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
108e8aafc91SKris Kennaway 	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oIdentityFile2,
10909958426SBrian Feldman 	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oDSAAuthentication,
11009958426SBrian Feldman 	oKbdInteractiveAuthentication, oKbdInteractiveDevices
111511b41d2SMark Murray } OpCodes;
112511b41d2SMark Murray 
113511b41d2SMark Murray /* Textual representations of the tokens. */
114511b41d2SMark Murray 
115511b41d2SMark Murray static struct {
116511b41d2SMark Murray 	const char *name;
117511b41d2SMark Murray 	OpCodes opcode;
118511b41d2SMark Murray } keywords[] = {
119511b41d2SMark Murray 	{ "forwardagent", oForwardAgent },
120511b41d2SMark Murray 	{ "forwardx11", oForwardX11 },
121c2d3a559SKris Kennaway 	{ "xauthlocation", oXAuthLocation },
122511b41d2SMark Murray 	{ "gatewayports", oGatewayPorts },
123511b41d2SMark Murray 	{ "useprivilegedport", oUsePrivilegedPort },
124511b41d2SMark Murray 	{ "rhostsauthentication", oRhostsAuthentication },
125511b41d2SMark Murray 	{ "passwordauthentication", oPasswordAuthentication },
12609958426SBrian Feldman 	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
12709958426SBrian Feldman 	{ "kbdinteractivedevices", oKbdInteractiveDevices },
128511b41d2SMark Murray 	{ "rsaauthentication", oRSAAuthentication },
129e8aafc91SKris Kennaway 	{ "dsaauthentication", oDSAAuthentication },
130511b41d2SMark Murray 	{ "skeyauthentication", oSkeyAuthentication },
131511b41d2SMark Murray #ifdef KRB4
132fe5fd017SMark Murray 	{ "kerberos4authentication", oKrb4Authentication },
133511b41d2SMark Murray #endif /* KRB4 */
134fe5fd017SMark Murray #ifdef KRB5
135fe5fd017SMark Murray 	{ "kerberos5authentication", oKrb5Authentication },
136fe5fd017SMark Murray 	{ "kerberos5tgtpassing", oKrb5TgtPassing },
137fe5fd017SMark Murray #endif /* KRB5 */
138511b41d2SMark Murray #ifdef AFS
139fe5fd017SMark Murray 	{ "kerberos4tgtpassing", oKrb4TgtPassing },
140511b41d2SMark Murray 	{ "afstokenpassing", oAFSTokenPassing },
141511b41d2SMark Murray #endif
142511b41d2SMark Murray 	{ "fallbacktorsh", oFallBackToRsh },
143511b41d2SMark Murray 	{ "usersh", oUseRsh },
144511b41d2SMark Murray 	{ "identityfile", oIdentityFile },
145e8aafc91SKris Kennaway 	{ "identityfile2", oIdentityFile2 },
146511b41d2SMark Murray 	{ "hostname", oHostName },
147511b41d2SMark Murray 	{ "proxycommand", oProxyCommand },
148511b41d2SMark Murray 	{ "port", oPort },
149511b41d2SMark Murray 	{ "cipher", oCipher },
150e8aafc91SKris Kennaway 	{ "ciphers", oCiphers },
151e8aafc91SKris Kennaway 	{ "protocol", oProtocol },
152511b41d2SMark Murray 	{ "remoteforward", oRemoteForward },
153511b41d2SMark Murray 	{ "localforward", oLocalForward },
154511b41d2SMark Murray 	{ "user", oUser },
155511b41d2SMark Murray 	{ "host", oHost },
156511b41d2SMark Murray 	{ "escapechar", oEscapeChar },
157511b41d2SMark Murray 	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
158511b41d2SMark Murray 	{ "globalknownhostsfile", oGlobalKnownHostsFile },
159511b41d2SMark Murray 	{ "userknownhostsfile", oUserKnownHostsFile },
160e8aafc91SKris Kennaway 	{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },
161e8aafc91SKris Kennaway 	{ "userknownhostsfile2", oUserKnownHostsFile2 },
162511b41d2SMark Murray 	{ "connectionattempts", oConnectionAttempts },
163511b41d2SMark Murray 	{ "batchmode", oBatchMode },
164511b41d2SMark Murray 	{ "checkhostip", oCheckHostIP },
165511b41d2SMark Murray 	{ "stricthostkeychecking", oStrictHostKeyChecking },
166511b41d2SMark Murray 	{ "compression", oCompression },
167511b41d2SMark Murray 	{ "compressionlevel", oCompressionLevel },
168511b41d2SMark Murray 	{ "keepalive", oKeepAlives },
169511b41d2SMark Murray 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
170511b41d2SMark Murray 	{ "tisauthentication", oTISAuthentication },
171511b41d2SMark Murray 	{ "loglevel", oLogLevel },
172511b41d2SMark Murray 	{ NULL, 0 }
173511b41d2SMark Murray };
174511b41d2SMark Murray 
175511b41d2SMark Murray /*
176511b41d2SMark Murray  * Adds a local TCP/IP port forward to options.  Never returns if there is an
177511b41d2SMark Murray  * error.
178511b41d2SMark Murray  */
179511b41d2SMark Murray 
180511b41d2SMark Murray void
181511b41d2SMark Murray add_local_forward(Options *options, u_short port, const char *host,
182511b41d2SMark Murray 		  u_short host_port)
183511b41d2SMark Murray {
184511b41d2SMark Murray 	Forward *fwd;
185511b41d2SMark Murray 	extern uid_t original_real_uid;
186511b41d2SMark Murray 	if (port < IPPORT_RESERVED && original_real_uid != 0)
187511b41d2SMark Murray 		fatal("Privileged ports can only be forwarded by root.\n");
188511b41d2SMark Murray 	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
189511b41d2SMark Murray 		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
190511b41d2SMark Murray 	fwd = &options->local_forwards[options->num_local_forwards++];
191511b41d2SMark Murray 	fwd->port = port;
192511b41d2SMark Murray 	fwd->host = xstrdup(host);
193511b41d2SMark Murray 	fwd->host_port = host_port;
194511b41d2SMark Murray }
195511b41d2SMark Murray 
196511b41d2SMark Murray /*
197511b41d2SMark Murray  * Adds a remote TCP/IP port forward to options.  Never returns if there is
198511b41d2SMark Murray  * an error.
199511b41d2SMark Murray  */
200511b41d2SMark Murray 
201511b41d2SMark Murray void
202511b41d2SMark Murray add_remote_forward(Options *options, u_short port, const char *host,
203511b41d2SMark Murray 		   u_short host_port)
204511b41d2SMark Murray {
205511b41d2SMark Murray 	Forward *fwd;
206511b41d2SMark Murray 	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
207511b41d2SMark Murray 		fatal("Too many remote forwards (max %d).",
208511b41d2SMark Murray 		      SSH_MAX_FORWARDS_PER_DIRECTION);
209511b41d2SMark Murray 	fwd = &options->remote_forwards[options->num_remote_forwards++];
210511b41d2SMark Murray 	fwd->port = port;
211511b41d2SMark Murray 	fwd->host = xstrdup(host);
212511b41d2SMark Murray 	fwd->host_port = host_port;
213511b41d2SMark Murray }
214511b41d2SMark Murray 
215511b41d2SMark Murray /*
216511b41d2SMark Murray  * Returns the number of the token pointed to by cp of length len. Never
217511b41d2SMark Murray  * returns if the token is not known.
218511b41d2SMark Murray  */
219511b41d2SMark Murray 
220511b41d2SMark Murray static OpCodes
221511b41d2SMark Murray parse_token(const char *cp, const char *filename, int linenum)
222511b41d2SMark Murray {
223511b41d2SMark Murray 	unsigned int i;
224511b41d2SMark Murray 
225511b41d2SMark Murray 	for (i = 0; keywords[i].name; i++)
226511b41d2SMark Murray 		if (strcasecmp(cp, keywords[i].name) == 0)
227511b41d2SMark Murray 			return keywords[i].opcode;
228511b41d2SMark Murray 
229511b41d2SMark Murray 	fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
230511b41d2SMark Murray 		filename, linenum, cp);
231511b41d2SMark Murray 	return oBadOption;
232511b41d2SMark Murray }
233511b41d2SMark Murray 
234511b41d2SMark Murray /*
235511b41d2SMark Murray  * Processes a single option line as used in the configuration files. This
236511b41d2SMark Murray  * only sets those values that have not already been set.
237511b41d2SMark Murray  */
238511b41d2SMark Murray 
239511b41d2SMark Murray int
240511b41d2SMark Murray process_config_line(Options *options, const char *host,
241511b41d2SMark Murray 		    char *line, const char *filename, int linenum,
242511b41d2SMark Murray 		    int *activep)
243511b41d2SMark Murray {
244c2d3a559SKris Kennaway 	char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
245511b41d2SMark Murray 	int opcode, *intptr, value;
246511b41d2SMark Murray 	u_short fwd_port, fwd_host_port;
247511b41d2SMark Murray 
248c2d3a559SKris Kennaway 	s = line;
249c2d3a559SKris Kennaway 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
250c2d3a559SKris Kennaway 	keyword = strdelim(&s);
251c2d3a559SKris Kennaway 	/* Ignore leading whitespace. */
252c2d3a559SKris Kennaway 	if (*keyword == '\0')
253c2d3a559SKris Kennaway 		keyword = strdelim(&s);
254c2d3a559SKris Kennaway 	if (!*keyword || *keyword == '\n' || *keyword == '#')
255511b41d2SMark Murray 		return 0;
256511b41d2SMark Murray 
257c2d3a559SKris Kennaway 	opcode = parse_token(keyword, filename, linenum);
258511b41d2SMark Murray 
259511b41d2SMark Murray 	switch (opcode) {
260511b41d2SMark Murray 	case oBadOption:
261511b41d2SMark Murray 		/* don't panic, but count bad options */
262511b41d2SMark Murray 		return -1;
263511b41d2SMark Murray 		/* NOTREACHED */
264511b41d2SMark Murray 	case oForwardAgent:
265511b41d2SMark Murray 		intptr = &options->forward_agent;
266511b41d2SMark Murray parse_flag:
267c2d3a559SKris Kennaway 		arg = strdelim(&s);
268c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
269511b41d2SMark Murray 			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
270511b41d2SMark Murray 		value = 0;	/* To avoid compiler warning... */
271c2d3a559SKris Kennaway 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
272511b41d2SMark Murray 			value = 1;
273c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
274511b41d2SMark Murray 			value = 0;
275511b41d2SMark Murray 		else
276511b41d2SMark Murray 			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
277511b41d2SMark Murray 		if (*activep && *intptr == -1)
278511b41d2SMark Murray 			*intptr = value;
279511b41d2SMark Murray 		break;
280511b41d2SMark Murray 
281511b41d2SMark Murray 	case oForwardX11:
282511b41d2SMark Murray 		intptr = &options->forward_x11;
283511b41d2SMark Murray 		goto parse_flag;
284511b41d2SMark Murray 
285511b41d2SMark Murray 	case oGatewayPorts:
286511b41d2SMark Murray 		intptr = &options->gateway_ports;
287511b41d2SMark Murray 		goto parse_flag;
288511b41d2SMark Murray 
289511b41d2SMark Murray 	case oUsePrivilegedPort:
290511b41d2SMark Murray 		intptr = &options->use_privileged_port;
291511b41d2SMark Murray 		goto parse_flag;
292511b41d2SMark Murray 
293511b41d2SMark Murray 	case oRhostsAuthentication:
294511b41d2SMark Murray 		intptr = &options->rhosts_authentication;
295511b41d2SMark Murray 		goto parse_flag;
296511b41d2SMark Murray 
297511b41d2SMark Murray 	case oPasswordAuthentication:
298511b41d2SMark Murray 		intptr = &options->password_authentication;
299511b41d2SMark Murray 		goto parse_flag;
300511b41d2SMark Murray 
30109958426SBrian Feldman 	case oKbdInteractiveAuthentication:
30209958426SBrian Feldman 		intptr = &options->kbd_interactive_authentication;
30309958426SBrian Feldman 		goto parse_flag;
30409958426SBrian Feldman 
30509958426SBrian Feldman 	case oKbdInteractiveDevices:
30609958426SBrian Feldman 		charptr = &options->kbd_interactive_devices;
30709958426SBrian Feldman 		goto parse_string;
30809958426SBrian Feldman 
309e8aafc91SKris Kennaway 	case oDSAAuthentication:
310e8aafc91SKris Kennaway 		intptr = &options->dsa_authentication;
311e8aafc91SKris Kennaway 		goto parse_flag;
312e8aafc91SKris Kennaway 
313511b41d2SMark Murray 	case oRSAAuthentication:
314511b41d2SMark Murray 		intptr = &options->rsa_authentication;
315511b41d2SMark Murray 		goto parse_flag;
316511b41d2SMark Murray 
317511b41d2SMark Murray 	case oRhostsRSAAuthentication:
318511b41d2SMark Murray 		intptr = &options->rhosts_rsa_authentication;
319511b41d2SMark Murray 		goto parse_flag;
320511b41d2SMark Murray 
321511b41d2SMark Murray 	case oTISAuthentication:
322511b41d2SMark Murray 		/* fallthrough, there is no difference on the client side */
323511b41d2SMark Murray 	case oSkeyAuthentication:
324511b41d2SMark Murray 		intptr = &options->skey_authentication;
325511b41d2SMark Murray 		goto parse_flag;
326511b41d2SMark Murray 
327511b41d2SMark Murray #ifdef KRB4
328fe5fd017SMark Murray 	case oKrb4Authentication:
329fe5fd017SMark Murray 		intptr = &options->krb4_authentication;
330511b41d2SMark Murray 		goto parse_flag;
331511b41d2SMark Murray #endif /* KRB4 */
332511b41d2SMark Murray 
333fe5fd017SMark Murray #ifdef KRB5
334fe5fd017SMark Murray 	case oKrb5Authentication:
335fe5fd017SMark Murray 		intptr = &options->krb5_authentication;
336fe5fd017SMark Murray 		goto parse_flag;
337fe5fd017SMark Murray 
338fe5fd017SMark Murray 	case oKrb5TgtPassing:
339fe5fd017SMark Murray 		intptr = &options->krb5_tgt_passing;
340fe5fd017SMark Murray 		goto parse_flag;
341fe5fd017SMark Murray #endif /* KRB5 */
342fe5fd017SMark Murray 
343511b41d2SMark Murray #ifdef AFS
344fe5fd017SMark Murray 	case oKrb4TgtPassing:
345fe5fd017SMark Murray 		intptr = &options->krb4_tgt_passing;
346511b41d2SMark Murray 		goto parse_flag;
347511b41d2SMark Murray 
348511b41d2SMark Murray 	case oAFSTokenPassing:
349511b41d2SMark Murray 		intptr = &options->afs_token_passing;
350511b41d2SMark Murray 		goto parse_flag;
351511b41d2SMark Murray #endif
352511b41d2SMark Murray 
353511b41d2SMark Murray 	case oFallBackToRsh:
354511b41d2SMark Murray 		intptr = &options->fallback_to_rsh;
355511b41d2SMark Murray 		goto parse_flag;
356511b41d2SMark Murray 
357511b41d2SMark Murray 	case oUseRsh:
358511b41d2SMark Murray 		intptr = &options->use_rsh;
359511b41d2SMark Murray 		goto parse_flag;
360511b41d2SMark Murray 
361511b41d2SMark Murray 	case oBatchMode:
362511b41d2SMark Murray 		intptr = &options->batch_mode;
363511b41d2SMark Murray 		goto parse_flag;
364511b41d2SMark Murray 
365511b41d2SMark Murray 	case oCheckHostIP:
366511b41d2SMark Murray 		intptr = &options->check_host_ip;
367511b41d2SMark Murray 		goto parse_flag;
368511b41d2SMark Murray 
369511b41d2SMark Murray 	case oStrictHostKeyChecking:
370511b41d2SMark Murray 		intptr = &options->strict_host_key_checking;
371c2d3a559SKris Kennaway 		arg = strdelim(&s);
372c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
373511b41d2SMark Murray 			fatal("%.200s line %d: Missing yes/no argument.",
374511b41d2SMark Murray 			      filename, linenum);
375511b41d2SMark Murray 		value = 0;	/* To avoid compiler warning... */
376c2d3a559SKris Kennaway 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
377511b41d2SMark Murray 			value = 1;
378c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
379511b41d2SMark Murray 			value = 0;
380c2d3a559SKris Kennaway 		else if (strcmp(arg, "ask") == 0)
381511b41d2SMark Murray 			value = 2;
382511b41d2SMark Murray 		else
383511b41d2SMark Murray 			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
384511b41d2SMark Murray 		if (*activep && *intptr == -1)
385511b41d2SMark Murray 			*intptr = value;
386511b41d2SMark Murray 		break;
387511b41d2SMark Murray 
388511b41d2SMark Murray 	case oCompression:
389511b41d2SMark Murray 		intptr = &options->compression;
390511b41d2SMark Murray 		goto parse_flag;
391511b41d2SMark Murray 
392511b41d2SMark Murray 	case oKeepAlives:
393511b41d2SMark Murray 		intptr = &options->keepalives;
394511b41d2SMark Murray 		goto parse_flag;
395511b41d2SMark Murray 
396511b41d2SMark Murray 	case oNumberOfPasswordPrompts:
397511b41d2SMark Murray 		intptr = &options->number_of_password_prompts;
398511b41d2SMark Murray 		goto parse_int;
399511b41d2SMark Murray 
400511b41d2SMark Murray 	case oCompressionLevel:
401511b41d2SMark Murray 		intptr = &options->compression_level;
402511b41d2SMark Murray 		goto parse_int;
403511b41d2SMark Murray 
404511b41d2SMark Murray 	case oIdentityFile:
405e8aafc91SKris Kennaway 	case oIdentityFile2:
406c2d3a559SKris Kennaway 		arg = strdelim(&s);
407c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
408511b41d2SMark Murray 			fatal("%.200s line %d: Missing argument.", filename, linenum);
409511b41d2SMark Murray 		if (*activep) {
410e8aafc91SKris Kennaway 			intptr = (opcode == oIdentityFile) ?
411e8aafc91SKris Kennaway 			    &options->num_identity_files :
412e8aafc91SKris Kennaway 			    &options->num_identity_files2;
413e8aafc91SKris Kennaway 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
414511b41d2SMark Murray 				fatal("%.200s line %d: Too many identity files specified (max %d).",
415511b41d2SMark Murray 				      filename, linenum, SSH_MAX_IDENTITY_FILES);
416e8aafc91SKris Kennaway 			charptr = (opcode == oIdentityFile) ?
417e8aafc91SKris Kennaway 			    &options->identity_files[*intptr] :
418e8aafc91SKris Kennaway 			    &options->identity_files2[*intptr];
419c2d3a559SKris Kennaway 			*charptr = xstrdup(arg);
420e8aafc91SKris Kennaway 			*intptr = *intptr + 1;
421511b41d2SMark Murray 		}
422511b41d2SMark Murray 		break;
423511b41d2SMark Murray 
424c2d3a559SKris Kennaway 	case oXAuthLocation:
425c2d3a559SKris Kennaway 		charptr=&options->xauth_location;
426c2d3a559SKris Kennaway 		goto parse_string;
427c2d3a559SKris Kennaway 
428511b41d2SMark Murray 	case oUser:
429511b41d2SMark Murray 		charptr = &options->user;
430511b41d2SMark Murray parse_string:
431c2d3a559SKris Kennaway 		arg = strdelim(&s);
432c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
433511b41d2SMark Murray 			fatal("%.200s line %d: Missing argument.", filename, linenum);
434511b41d2SMark Murray 		if (*activep && *charptr == NULL)
435c2d3a559SKris Kennaway 			*charptr = xstrdup(arg);
436511b41d2SMark Murray 		break;
437511b41d2SMark Murray 
438511b41d2SMark Murray 	case oGlobalKnownHostsFile:
439511b41d2SMark Murray 		charptr = &options->system_hostfile;
440511b41d2SMark Murray 		goto parse_string;
441511b41d2SMark Murray 
442511b41d2SMark Murray 	case oUserKnownHostsFile:
443511b41d2SMark Murray 		charptr = &options->user_hostfile;
444511b41d2SMark Murray 		goto parse_string;
445511b41d2SMark Murray 
446e8aafc91SKris Kennaway 	case oGlobalKnownHostsFile2:
447e8aafc91SKris Kennaway 		charptr = &options->system_hostfile2;
448e8aafc91SKris Kennaway 		goto parse_string;
449e8aafc91SKris Kennaway 
450e8aafc91SKris Kennaway 	case oUserKnownHostsFile2:
451e8aafc91SKris Kennaway 		charptr = &options->user_hostfile2;
452e8aafc91SKris Kennaway 		goto parse_string;
453e8aafc91SKris Kennaway 
454511b41d2SMark Murray 	case oHostName:
455511b41d2SMark Murray 		charptr = &options->hostname;
456511b41d2SMark Murray 		goto parse_string;
457511b41d2SMark Murray 
458511b41d2SMark Murray 	case oProxyCommand:
459511b41d2SMark Murray 		charptr = &options->proxy_command;
460511b41d2SMark Murray 		string = xstrdup("");
461c2d3a559SKris Kennaway 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
462c2d3a559SKris Kennaway 			string = xrealloc(string, strlen(string) + strlen(arg) + 2);
463511b41d2SMark Murray 			strcat(string, " ");
464c2d3a559SKris Kennaway 			strcat(string, arg);
465511b41d2SMark Murray 		}
466511b41d2SMark Murray 		if (*activep && *charptr == NULL)
467511b41d2SMark Murray 			*charptr = string;
468511b41d2SMark Murray 		else
469511b41d2SMark Murray 			xfree(string);
470511b41d2SMark Murray 		return 0;
471511b41d2SMark Murray 
472511b41d2SMark Murray 	case oPort:
473511b41d2SMark Murray 		intptr = &options->port;
474511b41d2SMark Murray parse_int:
475c2d3a559SKris Kennaway 		arg = strdelim(&s);
476c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
477511b41d2SMark Murray 			fatal("%.200s line %d: Missing argument.", filename, linenum);
478c2d3a559SKris Kennaway 		if (arg[0] < '0' || arg[0] > '9')
479511b41d2SMark Murray 			fatal("%.200s line %d: Bad number.", filename, linenum);
480511b41d2SMark Murray 
481511b41d2SMark Murray 		/* Octal, decimal, or hex format? */
482c2d3a559SKris Kennaway 		value = strtol(arg, &endofnumber, 0);
483c2d3a559SKris Kennaway 		if (arg == endofnumber)
484511b41d2SMark Murray 			fatal("%.200s line %d: Bad number.", filename, linenum);
485511b41d2SMark Murray 		if (*activep && *intptr == -1)
486511b41d2SMark Murray 			*intptr = value;
487511b41d2SMark Murray 		break;
488511b41d2SMark Murray 
489511b41d2SMark Murray 	case oConnectionAttempts:
490511b41d2SMark Murray 		intptr = &options->connection_attempts;
491511b41d2SMark Murray 		goto parse_int;
492511b41d2SMark Murray 
493511b41d2SMark Murray 	case oCipher:
494511b41d2SMark Murray 		intptr = &options->cipher;
495c2d3a559SKris Kennaway 		arg = strdelim(&s);
496c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
497db1cb46cSKris Kennaway 			fatal("%.200s line %d: Missing argument.", filename, linenum);
498c2d3a559SKris Kennaway 		value = cipher_number(arg);
499511b41d2SMark Murray 		if (value == -1)
500511b41d2SMark Murray 			fatal("%.200s line %d: Bad cipher '%s'.",
501c2d3a559SKris Kennaway 			      filename, linenum, arg ? arg : "<NONE>");
502511b41d2SMark Murray 		if (*activep && *intptr == -1)
503511b41d2SMark Murray 			*intptr = value;
504511b41d2SMark Murray 		break;
505511b41d2SMark Murray 
506e8aafc91SKris Kennaway 	case oCiphers:
507c2d3a559SKris Kennaway 		arg = strdelim(&s);
508c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
509db1cb46cSKris Kennaway 			fatal("%.200s line %d: Missing argument.", filename, linenum);
510c2d3a559SKris Kennaway 		if (!ciphers_valid(arg))
511e8aafc91SKris Kennaway 			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
512c2d3a559SKris Kennaway 			      filename, linenum, arg ? arg : "<NONE>");
513e8aafc91SKris Kennaway 		if (*activep && options->ciphers == NULL)
514c2d3a559SKris Kennaway 			options->ciphers = xstrdup(arg);
515e8aafc91SKris Kennaway 		break;
516e8aafc91SKris Kennaway 
517e8aafc91SKris Kennaway 	case oProtocol:
518e8aafc91SKris Kennaway 		intptr = &options->protocol;
519c2d3a559SKris Kennaway 		arg = strdelim(&s);
520c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
521db1cb46cSKris Kennaway 			fatal("%.200s line %d: Missing argument.", filename, linenum);
522c2d3a559SKris Kennaway 		value = proto_spec(arg);
523e8aafc91SKris Kennaway 		if (value == SSH_PROTO_UNKNOWN)
524e8aafc91SKris Kennaway 			fatal("%.200s line %d: Bad protocol spec '%s'.",
525c2d3a559SKris Kennaway 			      filename, linenum, arg ? arg : "<NONE>");
526e8aafc91SKris Kennaway 		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
527e8aafc91SKris Kennaway 			*intptr = value;
528e8aafc91SKris Kennaway 		break;
529e8aafc91SKris Kennaway 
530511b41d2SMark Murray 	case oLogLevel:
531511b41d2SMark Murray 		intptr = (int *) &options->log_level;
532c2d3a559SKris Kennaway 		arg = strdelim(&s);
533c2d3a559SKris Kennaway 		value = log_level_number(arg);
534511b41d2SMark Murray 		if (value == (LogLevel) - 1)
535511b41d2SMark Murray 			fatal("%.200s line %d: unsupported log level '%s'\n",
536c2d3a559SKris Kennaway 			      filename, linenum, arg ? arg : "<NONE>");
537511b41d2SMark Murray 		if (*activep && (LogLevel) * intptr == -1)
538511b41d2SMark Murray 			*intptr = (LogLevel) value;
539511b41d2SMark Murray 		break;
540511b41d2SMark Murray 
541511b41d2SMark Murray 	case oRemoteForward:
542c2d3a559SKris Kennaway 		arg = strdelim(&s);
543c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
544511b41d2SMark Murray 			fatal("%.200s line %d: Missing argument.", filename, linenum);
545c2d3a559SKris Kennaway 		if (arg[0] < '0' || arg[0] > '9')
546511b41d2SMark Murray 			fatal("%.200s line %d: Badly formatted port number.",
547511b41d2SMark Murray 			      filename, linenum);
548c2d3a559SKris Kennaway 		fwd_port = atoi(arg);
549c2d3a559SKris Kennaway 		arg = strdelim(&s);
550c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
551511b41d2SMark Murray 			fatal("%.200s line %d: Missing second argument.",
552511b41d2SMark Murray 			      filename, linenum);
553c2d3a559SKris Kennaway 		if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
554511b41d2SMark Murray 			fatal("%.200s line %d: Badly formatted host:port.",
555511b41d2SMark Murray 			      filename, linenum);
556511b41d2SMark Murray 		if (*activep)
557511b41d2SMark Murray 			add_remote_forward(options, fwd_port, buf, fwd_host_port);
558511b41d2SMark Murray 		break;
559511b41d2SMark Murray 
560511b41d2SMark Murray 	case oLocalForward:
561c2d3a559SKris Kennaway 		arg = strdelim(&s);
562c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
563511b41d2SMark Murray 			fatal("%.200s line %d: Missing argument.", filename, linenum);
564c2d3a559SKris Kennaway 		if (arg[0] < '0' || arg[0] > '9')
565511b41d2SMark Murray 			fatal("%.200s line %d: Badly formatted port number.",
566511b41d2SMark Murray 			      filename, linenum);
567c2d3a559SKris Kennaway 		fwd_port = atoi(arg);
568c2d3a559SKris Kennaway 		arg = strdelim(&s);
569c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
570511b41d2SMark Murray 			fatal("%.200s line %d: Missing second argument.",
571511b41d2SMark Murray 			      filename, linenum);
572c2d3a559SKris Kennaway 		if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
573511b41d2SMark Murray 			fatal("%.200s line %d: Badly formatted host:port.",
574511b41d2SMark Murray 			      filename, linenum);
575511b41d2SMark Murray 		if (*activep)
576511b41d2SMark Murray 			add_local_forward(options, fwd_port, buf, fwd_host_port);
577511b41d2SMark Murray 		break;
578511b41d2SMark Murray 
579511b41d2SMark Murray 	case oHost:
580511b41d2SMark Murray 		*activep = 0;
581c2d3a559SKris Kennaway 		while ((arg = strdelim(&s)) != NULL && *arg != '\0')
582c2d3a559SKris Kennaway 			if (match_pattern(host, arg)) {
583c2d3a559SKris Kennaway 				debug("Applying options for %.100s", arg);
584511b41d2SMark Murray 				*activep = 1;
585511b41d2SMark Murray 				break;
586511b41d2SMark Murray 			}
587c2d3a559SKris Kennaway 		/* Avoid garbage check below, as strdelim is done. */
588511b41d2SMark Murray 		return 0;
589511b41d2SMark Murray 
590511b41d2SMark Murray 	case oEscapeChar:
591511b41d2SMark Murray 		intptr = &options->escape_char;
592c2d3a559SKris Kennaway 		arg = strdelim(&s);
593c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
594511b41d2SMark Murray 			fatal("%.200s line %d: Missing argument.", filename, linenum);
595c2d3a559SKris Kennaway 		if (arg[0] == '^' && arg[2] == 0 &&
596c2d3a559SKris Kennaway 		    (unsigned char) arg[1] >= 64 && (unsigned char) arg[1] < 128)
597c2d3a559SKris Kennaway 			value = (unsigned char) arg[1] & 31;
598c2d3a559SKris Kennaway 		else if (strlen(arg) == 1)
599c2d3a559SKris Kennaway 			value = (unsigned char) arg[0];
600c2d3a559SKris Kennaway 		else if (strcmp(arg, "none") == 0)
601511b41d2SMark Murray 			value = -2;
602511b41d2SMark Murray 		else {
603511b41d2SMark Murray 			fatal("%.200s line %d: Bad escape character.",
604511b41d2SMark Murray 			      filename, linenum);
605511b41d2SMark Murray 			/* NOTREACHED */
606511b41d2SMark Murray 			value = 0;	/* Avoid compiler warning. */
607511b41d2SMark Murray 		}
608511b41d2SMark Murray 		if (*activep && *intptr == -1)
609511b41d2SMark Murray 			*intptr = value;
610511b41d2SMark Murray 		break;
611511b41d2SMark Murray 
612511b41d2SMark Murray 	default:
613511b41d2SMark Murray 		fatal("process_config_line: Unimplemented opcode %d", opcode);
614511b41d2SMark Murray 	}
615511b41d2SMark Murray 
616511b41d2SMark Murray 	/* Check that there is no garbage at end of line. */
617c2d3a559SKris Kennaway 	if ((arg = strdelim(&s)) != NULL && *arg != '\0')
618c2d3a559SKris Kennaway 	{
619c2d3a559SKris Kennaway 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
620c2d3a559SKris Kennaway 		      filename, linenum, arg);
621c2d3a559SKris Kennaway 	}
622511b41d2SMark Murray 	return 0;
623511b41d2SMark Murray }
624511b41d2SMark Murray 
625511b41d2SMark Murray 
626511b41d2SMark Murray /*
627511b41d2SMark Murray  * Reads the config file and modifies the options accordingly.  Options
628511b41d2SMark Murray  * should already be initialized before this call.  This never returns if
629511b41d2SMark Murray  * there is an error.  If the file does not exist, this returns immediately.
630511b41d2SMark Murray  */
631511b41d2SMark Murray 
632511b41d2SMark Murray void
633511b41d2SMark Murray read_config_file(const char *filename, const char *host, Options *options)
634511b41d2SMark Murray {
635511b41d2SMark Murray 	FILE *f;
636511b41d2SMark Murray 	char line[1024];
637511b41d2SMark Murray 	int active, linenum;
638511b41d2SMark Murray 	int bad_options = 0;
639511b41d2SMark Murray 
640511b41d2SMark Murray 	/* Open the file. */
641511b41d2SMark Murray 	f = fopen(filename, "r");
642511b41d2SMark Murray 	if (!f)
643511b41d2SMark Murray 		return;
644511b41d2SMark Murray 
645511b41d2SMark Murray 	debug("Reading configuration data %.200s", filename);
646511b41d2SMark Murray 
647511b41d2SMark Murray 	/*
648511b41d2SMark Murray 	 * Mark that we are now processing the options.  This flag is turned
649511b41d2SMark Murray 	 * on/off by Host specifications.
650511b41d2SMark Murray 	 */
651511b41d2SMark Murray 	active = 1;
652511b41d2SMark Murray 	linenum = 0;
653511b41d2SMark Murray 	while (fgets(line, sizeof(line), f)) {
654511b41d2SMark Murray 		/* Update line number counter. */
655511b41d2SMark Murray 		linenum++;
656511b41d2SMark Murray 		if (process_config_line(options, host, line, filename, linenum, &active) != 0)
657511b41d2SMark Murray 			bad_options++;
658511b41d2SMark Murray 	}
659511b41d2SMark Murray 	fclose(f);
660511b41d2SMark Murray 	if (bad_options > 0)
661511b41d2SMark Murray 		fatal("%s: terminating, %d bad configuration options\n",
662511b41d2SMark Murray 		      filename, bad_options);
663511b41d2SMark Murray }
664511b41d2SMark Murray 
665511b41d2SMark Murray /*
666511b41d2SMark Murray  * Initializes options to special values that indicate that they have not yet
667511b41d2SMark Murray  * been set.  Read_config_file will only set options with this value. Options
668511b41d2SMark Murray  * are processed in the following order: command line, user config file,
669511b41d2SMark Murray  * system config file.  Last, fill_default_options is called.
670511b41d2SMark Murray  */
671511b41d2SMark Murray 
672511b41d2SMark Murray void
673511b41d2SMark Murray initialize_options(Options * options)
674511b41d2SMark Murray {
675511b41d2SMark Murray 	memset(options, 'X', sizeof(*options));
676511b41d2SMark Murray 	options->forward_agent = -1;
677511b41d2SMark Murray 	options->forward_x11 = -1;
678c2d3a559SKris Kennaway 	options->xauth_location = NULL;
679511b41d2SMark Murray 	options->gateway_ports = -1;
680511b41d2SMark Murray 	options->use_privileged_port = -1;
681511b41d2SMark Murray 	options->rhosts_authentication = -1;
682511b41d2SMark Murray 	options->rsa_authentication = -1;
683e8aafc91SKris Kennaway 	options->dsa_authentication = -1;
684511b41d2SMark Murray 	options->skey_authentication = -1;
685511b41d2SMark Murray #ifdef KRB4
686fe5fd017SMark Murray 	options->krb4_authentication = -1;
687511b41d2SMark Murray #endif
688fe5fd017SMark Murray #ifdef KRB5
689fe5fd017SMark Murray 	options->krb5_authentication = -1;
690fe5fd017SMark Murray 	options->krb5_tgt_passing = -1;
691fe5fd017SMark Murray #endif /* KRB5 */
692511b41d2SMark Murray #ifdef AFS
693fe5fd017SMark Murray 	options->krb4_tgt_passing = -1;
694511b41d2SMark Murray 	options->afs_token_passing = -1;
695511b41d2SMark Murray #endif
696511b41d2SMark Murray 	options->password_authentication = -1;
69709958426SBrian Feldman 	options->kbd_interactive_authentication = -1;
69809958426SBrian Feldman 	options->kbd_interactive_devices = NULL;
699511b41d2SMark Murray 	options->rhosts_rsa_authentication = -1;
700511b41d2SMark Murray 	options->fallback_to_rsh = -1;
701511b41d2SMark Murray 	options->use_rsh = -1;
702511b41d2SMark Murray 	options->batch_mode = -1;
703511b41d2SMark Murray 	options->check_host_ip = -1;
704511b41d2SMark Murray 	options->strict_host_key_checking = -1;
705511b41d2SMark Murray 	options->compression = -1;
706511b41d2SMark Murray 	options->keepalives = -1;
707511b41d2SMark Murray 	options->compression_level = -1;
708511b41d2SMark Murray 	options->port = -1;
709511b41d2SMark Murray 	options->connection_attempts = -1;
710511b41d2SMark Murray 	options->number_of_password_prompts = -1;
711511b41d2SMark Murray 	options->cipher = -1;
712e8aafc91SKris Kennaway 	options->ciphers = NULL;
713e8aafc91SKris Kennaway 	options->protocol = SSH_PROTO_UNKNOWN;
714511b41d2SMark Murray 	options->num_identity_files = 0;
715e8aafc91SKris Kennaway 	options->num_identity_files2 = 0;
716511b41d2SMark Murray 	options->hostname = NULL;
717511b41d2SMark Murray 	options->proxy_command = NULL;
718511b41d2SMark Murray 	options->user = NULL;
719511b41d2SMark Murray 	options->escape_char = -1;
720511b41d2SMark Murray 	options->system_hostfile = NULL;
721511b41d2SMark Murray 	options->user_hostfile = NULL;
722e8aafc91SKris Kennaway 	options->system_hostfile2 = NULL;
723e8aafc91SKris Kennaway 	options->user_hostfile2 = NULL;
724511b41d2SMark Murray 	options->num_local_forwards = 0;
725511b41d2SMark Murray 	options->num_remote_forwards = 0;
726511b41d2SMark Murray 	options->log_level = (LogLevel) - 1;
727511b41d2SMark Murray }
728511b41d2SMark Murray 
729511b41d2SMark Murray /*
730511b41d2SMark Murray  * Called after processing other sources of option data, this fills those
731511b41d2SMark Murray  * options for which no value has been specified with their default values.
732511b41d2SMark Murray  */
733511b41d2SMark Murray 
734511b41d2SMark Murray void
735511b41d2SMark Murray fill_default_options(Options * options)
736511b41d2SMark Murray {
737511b41d2SMark Murray 	if (options->forward_agent == -1)
738db1cb46cSKris Kennaway 		options->forward_agent = 0;
739511b41d2SMark Murray 	if (options->forward_x11 == -1)
7405dc73ebeSBrian Feldman 		options->forward_x11 = 0;
741c2d3a559SKris Kennaway #ifdef XAUTH_PATH
742c2d3a559SKris Kennaway 	if (options->xauth_location == NULL)
743c2d3a559SKris Kennaway 		options->xauth_location = XAUTH_PATH;
744c2d3a559SKris Kennaway #endif /* XAUTH_PATH */
745511b41d2SMark Murray 	if (options->gateway_ports == -1)
746511b41d2SMark Murray 		options->gateway_ports = 0;
747511b41d2SMark Murray 	if (options->use_privileged_port == -1)
748511b41d2SMark Murray 		options->use_privileged_port = 1;
749511b41d2SMark Murray 	if (options->rhosts_authentication == -1)
750511b41d2SMark Murray 		options->rhosts_authentication = 1;
751511b41d2SMark Murray 	if (options->rsa_authentication == -1)
752511b41d2SMark Murray 		options->rsa_authentication = 1;
753e8aafc91SKris Kennaway 	if (options->dsa_authentication == -1)
754e8aafc91SKris Kennaway 		options->dsa_authentication = 1;
755511b41d2SMark Murray 	if (options->skey_authentication == -1)
756511b41d2SMark Murray 		options->skey_authentication = 0;
757511b41d2SMark Murray #ifdef KRB4
758fe5fd017SMark Murray 	if (options->krb4_authentication == -1)
759fe5fd017SMark Murray 		options->krb4_authentication = 1;
760511b41d2SMark Murray #endif /* KRB4 */
761fe5fd017SMark Murray #ifdef KRB5
762fe5fd017SMark Murray 	if (options->krb5_authentication == -1)
763fe5fd017SMark Murray 		options->krb5_authentication = 1;
764fe5fd017SMark Murray 	if (options->krb5_tgt_passing == -1)
765fe5fd017SMark Murray 		options->krb5_tgt_passing = 1;
766fe5fd017SMark Murray #endif /* KRB5 */
767511b41d2SMark Murray #ifdef AFS
768fe5fd017SMark Murray 	if (options->krb4_tgt_passing == -1)
769fe5fd017SMark Murray 		options->krb4_tgt_passing = 1;
770511b41d2SMark Murray 	if (options->afs_token_passing == -1)
771511b41d2SMark Murray 		options->afs_token_passing = 1;
772511b41d2SMark Murray #endif /* AFS */
773511b41d2SMark Murray 	if (options->password_authentication == -1)
774511b41d2SMark Murray 		options->password_authentication = 1;
77509958426SBrian Feldman 	if (options->kbd_interactive_authentication == -1)
77609958426SBrian Feldman 		options->kbd_interactive_authentication = 0;
777511b41d2SMark Murray 	if (options->rhosts_rsa_authentication == -1)
778511b41d2SMark Murray 		options->rhosts_rsa_authentication = 1;
779511b41d2SMark Murray 	if (options->fallback_to_rsh == -1)
780a3d67969SPeter Wemm 		options->fallback_to_rsh = 0;
781511b41d2SMark Murray 	if (options->use_rsh == -1)
782511b41d2SMark Murray 		options->use_rsh = 0;
783511b41d2SMark Murray 	if (options->batch_mode == -1)
784511b41d2SMark Murray 		options->batch_mode = 0;
785511b41d2SMark Murray 	if (options->check_host_ip == -1)
786a95c1225SBrian Feldman 		options->check_host_ip = 0;
787511b41d2SMark Murray 	if (options->strict_host_key_checking == -1)
788511b41d2SMark Murray 		options->strict_host_key_checking = 2;	/* 2 is default */
789511b41d2SMark Murray 	if (options->compression == -1)
790511b41d2SMark Murray 		options->compression = 0;
791511b41d2SMark Murray 	if (options->keepalives == -1)
792511b41d2SMark Murray 		options->keepalives = 1;
793511b41d2SMark Murray 	if (options->compression_level == -1)
794511b41d2SMark Murray 		options->compression_level = 6;
795511b41d2SMark Murray 	if (options->port == -1)
796511b41d2SMark Murray 		options->port = 0;	/* Filled in ssh_connect. */
797511b41d2SMark Murray 	if (options->connection_attempts == -1)
798511b41d2SMark Murray 		options->connection_attempts = 4;
799511b41d2SMark Murray 	if (options->number_of_password_prompts == -1)
800511b41d2SMark Murray 		options->number_of_password_prompts = 3;
801511b41d2SMark Murray 	/* Selected in ssh_login(). */
802511b41d2SMark Murray 	if (options->cipher == -1)
803511b41d2SMark Murray 		options->cipher = SSH_CIPHER_NOT_SET;
804e8aafc91SKris Kennaway 	/* options->ciphers, default set in myproposals.h */
805e8aafc91SKris Kennaway 	if (options->protocol == SSH_PROTO_UNKNOWN)
806e8aafc91SKris Kennaway 		options->protocol = SSH_PROTO_1|SSH_PROTO_2|SSH_PROTO_1_PREFERRED;
807511b41d2SMark Murray 	if (options->num_identity_files == 0) {
808511b41d2SMark Murray 		options->identity_files[0] =
809511b41d2SMark Murray 			xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1);
810511b41d2SMark Murray 		sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY);
811511b41d2SMark Murray 		options->num_identity_files = 1;
812511b41d2SMark Murray 	}
813e8aafc91SKris Kennaway 	if (options->num_identity_files2 == 0) {
814e8aafc91SKris Kennaway 		options->identity_files2[0] =
815e8aafc91SKris Kennaway 			xmalloc(2 + strlen(SSH_CLIENT_ID_DSA) + 1);
816e8aafc91SKris Kennaway 		sprintf(options->identity_files2[0], "~/%.100s", SSH_CLIENT_ID_DSA);
817e8aafc91SKris Kennaway 		options->num_identity_files2 = 1;
818e8aafc91SKris Kennaway 	}
819511b41d2SMark Murray 	if (options->escape_char == -1)
820511b41d2SMark Murray 		options->escape_char = '~';
821511b41d2SMark Murray 	if (options->system_hostfile == NULL)
822511b41d2SMark Murray 		options->system_hostfile = SSH_SYSTEM_HOSTFILE;
823511b41d2SMark Murray 	if (options->user_hostfile == NULL)
824511b41d2SMark Murray 		options->user_hostfile = SSH_USER_HOSTFILE;
825e8aafc91SKris Kennaway 	if (options->system_hostfile2 == NULL)
826e8aafc91SKris Kennaway 		options->system_hostfile2 = SSH_SYSTEM_HOSTFILE2;
827e8aafc91SKris Kennaway 	if (options->user_hostfile2 == NULL)
828e8aafc91SKris Kennaway 		options->user_hostfile2 = SSH_USER_HOSTFILE2;
829511b41d2SMark Murray 	if (options->log_level == (LogLevel) - 1)
830511b41d2SMark Murray 		options->log_level = SYSLOG_LEVEL_INFO;
831511b41d2SMark Murray 	/* options->proxy_command should not be set by default */
832511b41d2SMark Murray 	/* options->user will be set in the main program if appropriate */
833511b41d2SMark Murray 	/* options->hostname will be set in the main program if appropriate */
834511b41d2SMark Murray }
835