readconf.c revision 128460
157429Smarkm/*
257429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi>
357429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
457429Smarkm *                    All rights reserved
557429Smarkm * Functions for reading the configuration files.
660576Skris *
765674Skris * As far as I am concerned, the code I have written for this software
865674Skris * can be used freely for any purpose.  Any derived versions of this
965674Skris * software must be clearly marked as such, and if the derived work is
1065674Skris * incompatible with the protocol description in the RFC file, it must be
1165674Skris * called by a name other than "ssh" or "Secure Shell".
1257429Smarkm */
1357429Smarkm
1457429Smarkm#include "includes.h"
15128460SdesRCSID("$FreeBSD: head/crypto/openssh/readconf.c 128460 2004-04-20 09:46:41Z des $");
16126277SdesRCSID("$OpenBSD: readconf.c,v 1.127 2003/12/16 15:49:51 markus Exp $");
1757429Smarkm
1857429Smarkm#include "ssh.h"
1976262Sgreen#include "xmalloc.h"
2076262Sgreen#include "compat.h"
2176262Sgreen#include "cipher.h"
2276262Sgreen#include "pathnames.h"
2376262Sgreen#include "log.h"
2457429Smarkm#include "readconf.h"
2560576Skris#include "match.h"
2676262Sgreen#include "misc.h"
2776262Sgreen#include "kex.h"
2876262Sgreen#include "mac.h"
2957429Smarkm
3057429Smarkm/* Format of the configuration file:
3157429Smarkm
3257429Smarkm   # Configuration data is parsed as follows:
3357429Smarkm   #  1. command line options
3457429Smarkm   #  2. user-specific file
3557429Smarkm   #  3. system-wide file
3657429Smarkm   # Any configuration value is only changed the first time it is set.
3757429Smarkm   # Thus, host-specific definitions should be at the beginning of the
3857429Smarkm   # configuration file, and defaults at the end.
3957429Smarkm
4057429Smarkm   # Host-specific declarations.  These may override anything above.  A single
4157429Smarkm   # host may match multiple declarations; these are processed in the order
4257429Smarkm   # that they are given in.
4357429Smarkm
4457429Smarkm   Host *.ngs.fi ngs.fi
4598684Sdes     User foo
4657429Smarkm
4757429Smarkm   Host fake.com
4857429Smarkm     HostName another.host.name.real.org
4957429Smarkm     User blaah
5057429Smarkm     Port 34289
5157429Smarkm     ForwardX11 no
5257429Smarkm     ForwardAgent no
5357429Smarkm
5457429Smarkm   Host books.com
5557429Smarkm     RemoteForward 9999 shadows.cs.hut.fi:9999
5657429Smarkm     Cipher 3des
5757429Smarkm
5857429Smarkm   Host fascist.blob.com
5957429Smarkm     Port 23123
6057429Smarkm     User tylonen
6157429Smarkm     PasswordAuthentication no
6257429Smarkm
6357429Smarkm   Host puukko.hut.fi
6457429Smarkm     User t35124p
6557429Smarkm     ProxyCommand ssh-proxy %h %p
6657429Smarkm
6757429Smarkm   Host *.fr
6898684Sdes     PublicKeyAuthentication no
6957429Smarkm
7057429Smarkm   Host *.su
7157429Smarkm     Cipher none
7257429Smarkm     PasswordAuthentication no
7357429Smarkm
7457429Smarkm   # Defaults for various options
7557429Smarkm   Host *
7657429Smarkm     ForwardAgent no
7776262Sgreen     ForwardX11 no
7857429Smarkm     PasswordAuthentication yes
7957429Smarkm     RSAAuthentication yes
8057429Smarkm     RhostsRSAAuthentication yes
8157429Smarkm     StrictHostKeyChecking yes
82126277Sdes     TcpKeepAlive no
8357429Smarkm     IdentityFile ~/.ssh/identity
8457429Smarkm     Port 22
8557429Smarkm     EscapeChar ~
8657429Smarkm
8757429Smarkm*/
8857429Smarkm
8957429Smarkm/* Keyword tokens. */
9057429Smarkm
9157429Smarkmtypedef enum {
9257429Smarkm	oBadOption,
93126277Sdes	oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
9498684Sdes	oPasswordAuthentication, oRSAAuthentication,
9576262Sgreen	oChallengeResponseAuthentication, oXAuthLocation,
9657429Smarkm	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
9757429Smarkm	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
9857429Smarkm	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
9957429Smarkm	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
100126277Sdes	oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
10176262Sgreen	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
10276262Sgreen	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
10376262Sgreen	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
10476262Sgreen	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
10592559Sdes	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
10693698Sdes	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
107124211Sdes	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
108124211Sdes	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
109128460Sdes<<<<<<< readconf.c
110126277Sdes	oServerAliveInterval, oServerAliveCountMax,
11199048Sdes	oVersionAddendum,
112128460Sdes=======
113128460Sdes	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
114128460Sdes>>>>>>> 1.1.1.15
115124211Sdes	oDeprecated, oUnsupported
11657429Smarkm} OpCodes;
11757429Smarkm
11857429Smarkm/* Textual representations of the tokens. */
11957429Smarkm
12057429Smarkmstatic struct {
12157429Smarkm	const char *name;
12257429Smarkm	OpCodes opcode;
12357429Smarkm} keywords[] = {
12457429Smarkm	{ "forwardagent", oForwardAgent },
12557429Smarkm	{ "forwardx11", oForwardX11 },
126126277Sdes	{ "forwardx11trusted", oForwardX11Trusted },
12765674Skris	{ "xauthlocation", oXAuthLocation },
12857429Smarkm	{ "gatewayports", oGatewayPorts },
12957429Smarkm	{ "useprivilegedport", oUsePrivilegedPort },
130124211Sdes	{ "rhostsauthentication", oDeprecated },
13157429Smarkm	{ "passwordauthentication", oPasswordAuthentication },
13269591Sgreen	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
13369591Sgreen	{ "kbdinteractivedevices", oKbdInteractiveDevices },
13457429Smarkm	{ "rsaauthentication", oRSAAuthentication },
13576262Sgreen	{ "pubkeyauthentication", oPubkeyAuthentication },
13676262Sgreen	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
13776262Sgreen	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
13876262Sgreen	{ "hostbasedauthentication", oHostbasedAuthentication },
13976262Sgreen	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
14076262Sgreen	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
14176262Sgreen	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
142124211Sdes	{ "kerberosauthentication", oUnsupported },
143124211Sdes	{ "kerberostgtpassing", oUnsupported },
144124211Sdes	{ "afstokenpassing", oUnsupported },
145124211Sdes#if defined(GSSAPI)
146124211Sdes	{ "gssapiauthentication", oGssAuthentication },
147124211Sdes	{ "gssapidelegatecredentials", oGssDelegateCreds },
148124211Sdes#else
149124211Sdes	{ "gssapiauthentication", oUnsupported },
150124211Sdes	{ "gssapidelegatecredentials", oUnsupported },
15192559Sdes#endif
15298684Sdes	{ "fallbacktorsh", oDeprecated },
15398684Sdes	{ "usersh", oDeprecated },
15457429Smarkm	{ "identityfile", oIdentityFile },
15576262Sgreen	{ "identityfile2", oIdentityFile },			/* alias */
156128460Sdes	{ "identitiesonly", oIdentitiesOnly },
15757429Smarkm	{ "hostname", oHostName },
15876262Sgreen	{ "hostkeyalias", oHostKeyAlias },
15957429Smarkm	{ "proxycommand", oProxyCommand },
16057429Smarkm	{ "port", oPort },
16157429Smarkm	{ "cipher", oCipher },
16260576Skris	{ "ciphers", oCiphers },
16376262Sgreen	{ "macs", oMacs },
16460576Skris	{ "protocol", oProtocol },
16557429Smarkm	{ "remoteforward", oRemoteForward },
16657429Smarkm	{ "localforward", oLocalForward },
16757429Smarkm	{ "user", oUser },
16857429Smarkm	{ "host", oHost },
16957429Smarkm	{ "escapechar", oEscapeChar },
17057429Smarkm	{ "globalknownhostsfile", oGlobalKnownHostsFile },
17192559Sdes	{ "userknownhostsfile", oUserKnownHostsFile },		/* obsolete */
17260576Skris	{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },
17392559Sdes	{ "userknownhostsfile2", oUserKnownHostsFile2 },	/* obsolete */
17457429Smarkm	{ "connectionattempts", oConnectionAttempts },
17557429Smarkm	{ "batchmode", oBatchMode },
17657429Smarkm	{ "checkhostip", oCheckHostIP },
17757429Smarkm	{ "stricthostkeychecking", oStrictHostKeyChecking },
17857429Smarkm	{ "compression", oCompression },
17957429Smarkm	{ "compressionlevel", oCompressionLevel },
180126277Sdes	{ "tcpkeepalive", oTCPKeepAlive },
181126277Sdes	{ "keepalive", oTCPKeepAlive },				/* obsolete */
18257429Smarkm	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
18357429Smarkm	{ "loglevel", oLogLevel },
18476262Sgreen	{ "dynamicforward", oDynamicForward },
18576262Sgreen	{ "preferredauthentications", oPreferredAuthentications },
18676262Sgreen	{ "hostkeyalgorithms", oHostKeyAlgorithms },
18792559Sdes	{ "bindaddress", oBindAddress },
188124211Sdes#ifdef SMARTCARD
18992559Sdes	{ "smartcarddevice", oSmartcardDevice },
190124211Sdes#else
191124211Sdes	{ "smartcarddevice", oUnsupported },
192124211Sdes#endif
19392559Sdes	{ "clearallforwardings", oClearAllForwardings },
194113911Sdes	{ "enablesshkeysign", oEnableSSHKeysign },
195124211Sdes	{ "verifyhostkeydns", oVerifyHostKeyDNS },
19692559Sdes	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
197124211Sdes	{ "rekeylimit", oRekeyLimit },
198124211Sdes	{ "connecttimeout", oConnectTimeout },
199124211Sdes	{ "addressfamily", oAddressFamily },
200126277Sdes	{ "serveraliveinterval", oServerAliveInterval },
201126277Sdes	{ "serveralivecountmax", oServerAliveCountMax },
20299048Sdes	{ "versionaddendum", oVersionAddendum },
20392559Sdes	{ NULL, oBadOption }
20457429Smarkm};
20557429Smarkm
20657429Smarkm/*
20757429Smarkm * Adds a local TCP/IP port forward to options.  Never returns if there is an
20857429Smarkm * error.
20957429Smarkm */
21057429Smarkm
21160576Skrisvoid
21257429Smarkmadd_local_forward(Options *options, u_short port, const char *host,
21357429Smarkm		  u_short host_port)
21457429Smarkm{
21557429Smarkm	Forward *fwd;
216106130Sdes#ifndef NO_IPPORT_RESERVED_CONCEPT
21757429Smarkm	extern uid_t original_real_uid;
21857429Smarkm	if (port < IPPORT_RESERVED && original_real_uid != 0)
21976262Sgreen		fatal("Privileged ports can only be forwarded by root.");
22098941Sdes#endif
22157429Smarkm	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
22257429Smarkm		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
22357429Smarkm	fwd = &options->local_forwards[options->num_local_forwards++];
22457429Smarkm	fwd->port = port;
22557429Smarkm	fwd->host = xstrdup(host);
22657429Smarkm	fwd->host_port = host_port;
22757429Smarkm}
22857429Smarkm
22957429Smarkm/*
23057429Smarkm * Adds a remote TCP/IP port forward to options.  Never returns if there is
23157429Smarkm * an error.
23257429Smarkm */
23357429Smarkm
23460576Skrisvoid
23557429Smarkmadd_remote_forward(Options *options, u_short port, const char *host,
23657429Smarkm		   u_short host_port)
23757429Smarkm{
23857429Smarkm	Forward *fwd;
23957429Smarkm	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
24057429Smarkm		fatal("Too many remote forwards (max %d).",
24192559Sdes		    SSH_MAX_FORWARDS_PER_DIRECTION);
24257429Smarkm	fwd = &options->remote_forwards[options->num_remote_forwards++];
24357429Smarkm	fwd->port = port;
24457429Smarkm	fwd->host = xstrdup(host);
24557429Smarkm	fwd->host_port = host_port;
24657429Smarkm}
24757429Smarkm
24892559Sdesstatic void
24992559Sdesclear_forwardings(Options *options)
25092559Sdes{
25192559Sdes	int i;
25292559Sdes
25392559Sdes	for (i = 0; i < options->num_local_forwards; i++)
25492559Sdes		xfree(options->local_forwards[i].host);
25592559Sdes	options->num_local_forwards = 0;
25692559Sdes	for (i = 0; i < options->num_remote_forwards; i++)
25792559Sdes		xfree(options->remote_forwards[i].host);
25892559Sdes	options->num_remote_forwards = 0;
25992559Sdes}
26092559Sdes
26157429Smarkm/*
26276262Sgreen * Returns the number of the token pointed to by cp or oBadOption.
26357429Smarkm */
26457429Smarkm
26560576Skrisstatic OpCodes
26657429Smarkmparse_token(const char *cp, const char *filename, int linenum)
26757429Smarkm{
26876262Sgreen	u_int i;
26957429Smarkm
27057429Smarkm	for (i = 0; keywords[i].name; i++)
27157429Smarkm		if (strcasecmp(cp, keywords[i].name) == 0)
27257429Smarkm			return keywords[i].opcode;
27357429Smarkm
27476262Sgreen	error("%s: line %d: Bad configuration option: %s",
27576262Sgreen	    filename, linenum, cp);
27657429Smarkm	return oBadOption;
27757429Smarkm}
27857429Smarkm
27957429Smarkm/*
28057429Smarkm * Processes a single option line as used in the configuration files. This
28157429Smarkm * only sets those values that have not already been set.
28257429Smarkm */
283113911Sdes#define WHITESPACE " \t\r\n"
28457429Smarkm
28557429Smarkmint
28657429Smarkmprocess_config_line(Options *options, const char *host,
28757429Smarkm		    char *line, const char *filename, int linenum,
28857429Smarkm		    int *activep)
28957429Smarkm{
290113911Sdes	char buf[256], *s, **charptr, *endofnumber, *keyword, *arg;
29157429Smarkm	int opcode, *intptr, value;
292113911Sdes	size_t len;
29357429Smarkm	u_short fwd_port, fwd_host_port;
29492559Sdes	char sfwd_host_port[6];
29557429Smarkm
296124211Sdes	/* Strip trailing whitespace */
297124211Sdes	for(len = strlen(line) - 1; len > 0; len--) {
298124211Sdes		if (strchr(WHITESPACE, line[len]) == NULL)
299124211Sdes			break;
300124211Sdes		line[len] = '\0';
301124211Sdes	}
302124211Sdes
30365674Skris	s = line;
30465674Skris	/* Get the keyword. (Each line is supposed to begin with a keyword). */
30565674Skris	keyword = strdelim(&s);
30665674Skris	/* Ignore leading whitespace. */
30765674Skris	if (*keyword == '\0')
30865674Skris		keyword = strdelim(&s);
30976262Sgreen	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
31057429Smarkm		return 0;
31157429Smarkm
31265674Skris	opcode = parse_token(keyword, filename, linenum);
31357429Smarkm
31457429Smarkm	switch (opcode) {
31557429Smarkm	case oBadOption:
31657429Smarkm		/* don't panic, but count bad options */
31757429Smarkm		return -1;
31857429Smarkm		/* NOTREACHED */
319124211Sdes	case oConnectTimeout:
320124211Sdes		intptr = &options->connection_timeout;
321126277Sdesparse_time:
322124211Sdes		arg = strdelim(&s);
323124211Sdes		if (!arg || *arg == '\0')
324124211Sdes			fatal("%s line %d: missing time value.",
325124211Sdes			    filename, linenum);
326124211Sdes		if ((value = convtime(arg)) == -1)
327124211Sdes			fatal("%s line %d: invalid time value.",
328124211Sdes			    filename, linenum);
329124211Sdes		if (*intptr == -1)
330124211Sdes			*intptr = value;
331124211Sdes		break;
332124211Sdes
33357429Smarkm	case oForwardAgent:
33457429Smarkm		intptr = &options->forward_agent;
33557429Smarkmparse_flag:
33665674Skris		arg = strdelim(&s);
33765674Skris		if (!arg || *arg == '\0')
33857429Smarkm			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
33957429Smarkm		value = 0;	/* To avoid compiler warning... */
34065674Skris		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
34157429Smarkm			value = 1;
34265674Skris		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
34357429Smarkm			value = 0;
34457429Smarkm		else
34557429Smarkm			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
34657429Smarkm		if (*activep && *intptr == -1)
34757429Smarkm			*intptr = value;
34857429Smarkm		break;
34957429Smarkm
35057429Smarkm	case oForwardX11:
35157429Smarkm		intptr = &options->forward_x11;
35257429Smarkm		goto parse_flag;
35357429Smarkm
354126277Sdes	case oForwardX11Trusted:
355126277Sdes		intptr = &options->forward_x11_trusted;
356126277Sdes		goto parse_flag;
357126277Sdes
35857429Smarkm	case oGatewayPorts:
35957429Smarkm		intptr = &options->gateway_ports;
36057429Smarkm		goto parse_flag;
36157429Smarkm
36257429Smarkm	case oUsePrivilegedPort:
36357429Smarkm		intptr = &options->use_privileged_port;
36457429Smarkm		goto parse_flag;
36557429Smarkm
36657429Smarkm	case oPasswordAuthentication:
36757429Smarkm		intptr = &options->password_authentication;
36857429Smarkm		goto parse_flag;
36957429Smarkm
37069591Sgreen	case oKbdInteractiveAuthentication:
37169591Sgreen		intptr = &options->kbd_interactive_authentication;
37269591Sgreen		goto parse_flag;
37369591Sgreen
37469591Sgreen	case oKbdInteractiveDevices:
37569591Sgreen		charptr = &options->kbd_interactive_devices;
37669591Sgreen		goto parse_string;
37769591Sgreen
37876262Sgreen	case oPubkeyAuthentication:
37976262Sgreen		intptr = &options->pubkey_authentication;
38060576Skris		goto parse_flag;
38160576Skris
38257429Smarkm	case oRSAAuthentication:
38357429Smarkm		intptr = &options->rsa_authentication;
38457429Smarkm		goto parse_flag;
38557429Smarkm
38657429Smarkm	case oRhostsRSAAuthentication:
38757429Smarkm		intptr = &options->rhosts_rsa_authentication;
38857429Smarkm		goto parse_flag;
38957429Smarkm
39076262Sgreen	case oHostbasedAuthentication:
39176262Sgreen		intptr = &options->hostbased_authentication;
39257429Smarkm		goto parse_flag;
39357429Smarkm
39492559Sdes	case oChallengeResponseAuthentication:
39592559Sdes		intptr = &options->challenge_response_authentication;
39692559Sdes		goto parse_flag;
397124211Sdes
398124211Sdes	case oGssAuthentication:
399124211Sdes		intptr = &options->gss_authentication;
40057429Smarkm		goto parse_flag;
401124211Sdes
402124211Sdes	case oGssDelegateCreds:
403124211Sdes		intptr = &options->gss_deleg_creds;
40476262Sgreen		goto parse_flag;
405124211Sdes
40657429Smarkm	case oBatchMode:
40757429Smarkm		intptr = &options->batch_mode;
40857429Smarkm		goto parse_flag;
40957429Smarkm
41057429Smarkm	case oCheckHostIP:
41157429Smarkm		intptr = &options->check_host_ip;
41257429Smarkm		goto parse_flag;
41357429Smarkm
414124211Sdes	case oVerifyHostKeyDNS:
415124211Sdes		intptr = &options->verify_host_key_dns;
416126277Sdes		goto parse_yesnoask;
417124211Sdes
41857429Smarkm	case oStrictHostKeyChecking:
41957429Smarkm		intptr = &options->strict_host_key_checking;
420126277Sdesparse_yesnoask:
42165674Skris		arg = strdelim(&s);
42265674Skris		if (!arg || *arg == '\0')
42376262Sgreen			fatal("%.200s line %d: Missing yes/no/ask argument.",
42492559Sdes			    filename, linenum);
42557429Smarkm		value = 0;	/* To avoid compiler warning... */
42665674Skris		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
42757429Smarkm			value = 1;
42865674Skris		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
42957429Smarkm			value = 0;
43065674Skris		else if (strcmp(arg, "ask") == 0)
43157429Smarkm			value = 2;
43257429Smarkm		else
43357429Smarkm			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
43457429Smarkm		if (*activep && *intptr == -1)
43557429Smarkm			*intptr = value;
43657429Smarkm		break;
43757429Smarkm
43857429Smarkm	case oCompression:
43957429Smarkm		intptr = &options->compression;
44057429Smarkm		goto parse_flag;
44157429Smarkm
442126277Sdes	case oTCPKeepAlive:
443126277Sdes		intptr = &options->tcp_keep_alive;
44457429Smarkm		goto parse_flag;
44557429Smarkm
44692559Sdes	case oNoHostAuthenticationForLocalhost:
44792559Sdes		intptr = &options->no_host_authentication_for_localhost;
44892559Sdes		goto parse_flag;
44992559Sdes
45057429Smarkm	case oNumberOfPasswordPrompts:
45157429Smarkm		intptr = &options->number_of_password_prompts;
45257429Smarkm		goto parse_int;
45357429Smarkm
45457429Smarkm	case oCompressionLevel:
45557429Smarkm		intptr = &options->compression_level;
45657429Smarkm		goto parse_int;
45757429Smarkm
458124211Sdes	case oRekeyLimit:
459124211Sdes		intptr = &options->rekey_limit;
460124211Sdes		arg = strdelim(&s);
461124211Sdes		if (!arg || *arg == '\0')
462124211Sdes			fatal("%.200s line %d: Missing argument.", filename, linenum);
463124211Sdes		if (arg[0] < '0' || arg[0] > '9')
464124211Sdes			fatal("%.200s line %d: Bad number.", filename, linenum);
465124211Sdes		value = strtol(arg, &endofnumber, 10);
466124211Sdes		if (arg == endofnumber)
467124211Sdes			fatal("%.200s line %d: Bad number.", filename, linenum);
468124211Sdes		switch (toupper(*endofnumber)) {
469124211Sdes		case 'K':
470124211Sdes			value *= 1<<10;
471124211Sdes			break;
472124211Sdes		case 'M':
473124211Sdes			value *= 1<<20;
474124211Sdes			break;
475124211Sdes		case 'G':
476124211Sdes			value *= 1<<30;
477124211Sdes			break;
478124211Sdes		}
479124211Sdes		if (*activep && *intptr == -1)
480124211Sdes			*intptr = value;
481124211Sdes		break;
482124211Sdes
48357429Smarkm	case oIdentityFile:
48465674Skris		arg = strdelim(&s);
48565674Skris		if (!arg || *arg == '\0')
48657429Smarkm			fatal("%.200s line %d: Missing argument.", filename, linenum);
48757429Smarkm		if (*activep) {
48876262Sgreen			intptr = &options->num_identity_files;
48960576Skris			if (*intptr >= SSH_MAX_IDENTITY_FILES)
49057429Smarkm				fatal("%.200s line %d: Too many identity files specified (max %d).",
49192559Sdes				    filename, linenum, SSH_MAX_IDENTITY_FILES);
49276262Sgreen			charptr =  &options->identity_files[*intptr];
49365674Skris			*charptr = xstrdup(arg);
49460576Skris			*intptr = *intptr + 1;
49557429Smarkm		}
49657429Smarkm		break;
49757429Smarkm
49865674Skris	case oXAuthLocation:
49965674Skris		charptr=&options->xauth_location;
50065674Skris		goto parse_string;
50165674Skris
50257429Smarkm	case oUser:
50357429Smarkm		charptr = &options->user;
50457429Smarkmparse_string:
50565674Skris		arg = strdelim(&s);
50665674Skris		if (!arg || *arg == '\0')
50757429Smarkm			fatal("%.200s line %d: Missing argument.", filename, linenum);
50857429Smarkm		if (*activep && *charptr == NULL)
50965674Skris			*charptr = xstrdup(arg);
51057429Smarkm		break;
51157429Smarkm
51257429Smarkm	case oGlobalKnownHostsFile:
51357429Smarkm		charptr = &options->system_hostfile;
51457429Smarkm		goto parse_string;
51557429Smarkm
51657429Smarkm	case oUserKnownHostsFile:
51757429Smarkm		charptr = &options->user_hostfile;
51857429Smarkm		goto parse_string;
51957429Smarkm
52060576Skris	case oGlobalKnownHostsFile2:
52160576Skris		charptr = &options->system_hostfile2;
52260576Skris		goto parse_string;
52360576Skris
52460576Skris	case oUserKnownHostsFile2:
52560576Skris		charptr = &options->user_hostfile2;
52660576Skris		goto parse_string;
52760576Skris
52857429Smarkm	case oHostName:
52957429Smarkm		charptr = &options->hostname;
53057429Smarkm		goto parse_string;
53157429Smarkm
53276262Sgreen	case oHostKeyAlias:
53376262Sgreen		charptr = &options->host_key_alias;
53476262Sgreen		goto parse_string;
53576262Sgreen
53676262Sgreen	case oPreferredAuthentications:
53776262Sgreen		charptr = &options->preferred_authentications;
53876262Sgreen		goto parse_string;
53976262Sgreen
54092559Sdes	case oBindAddress:
54192559Sdes		charptr = &options->bind_address;
54292559Sdes		goto parse_string;
54392559Sdes
54492559Sdes	case oSmartcardDevice:
54592559Sdes		charptr = &options->smartcard_device;
54692559Sdes		goto parse_string;
54792559Sdes
54857429Smarkm	case oProxyCommand:
549124211Sdes		if (s == NULL)
550124211Sdes			fatal("%.200s line %d: Missing argument.", filename, linenum);
55157429Smarkm		charptr = &options->proxy_command;
552113911Sdes		len = strspn(s, WHITESPACE "=");
55357429Smarkm		if (*activep && *charptr == NULL)
554113911Sdes			*charptr = xstrdup(s + len);
55557429Smarkm		return 0;
55657429Smarkm
55757429Smarkm	case oPort:
55857429Smarkm		intptr = &options->port;
55957429Smarkmparse_int:
56065674Skris		arg = strdelim(&s);
56165674Skris		if (!arg || *arg == '\0')
56257429Smarkm			fatal("%.200s line %d: Missing argument.", filename, linenum);
56365674Skris		if (arg[0] < '0' || arg[0] > '9')
56457429Smarkm			fatal("%.200s line %d: Bad number.", filename, linenum);
56557429Smarkm
56657429Smarkm		/* Octal, decimal, or hex format? */
56765674Skris		value = strtol(arg, &endofnumber, 0);
56865674Skris		if (arg == endofnumber)
56957429Smarkm			fatal("%.200s line %d: Bad number.", filename, linenum);
57057429Smarkm		if (*activep && *intptr == -1)
57157429Smarkm			*intptr = value;
57257429Smarkm		break;
57357429Smarkm
57457429Smarkm	case oConnectionAttempts:
57557429Smarkm		intptr = &options->connection_attempts;
57657429Smarkm		goto parse_int;
57757429Smarkm
57857429Smarkm	case oCipher:
57957429Smarkm		intptr = &options->cipher;
58065674Skris		arg = strdelim(&s);
58165674Skris		if (!arg || *arg == '\0')
58261203Skris			fatal("%.200s line %d: Missing argument.", filename, linenum);
58365674Skris		value = cipher_number(arg);
58457429Smarkm		if (value == -1)
58557429Smarkm			fatal("%.200s line %d: Bad cipher '%s'.",
58692559Sdes			    filename, linenum, arg ? arg : "<NONE>");
58757429Smarkm		if (*activep && *intptr == -1)
58857429Smarkm			*intptr = value;
58957429Smarkm		break;
59057429Smarkm
59160576Skris	case oCiphers:
59265674Skris		arg = strdelim(&s);
59365674Skris		if (!arg || *arg == '\0')
59461203Skris			fatal("%.200s line %d: Missing argument.", filename, linenum);
59565674Skris		if (!ciphers_valid(arg))
59660576Skris			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
59792559Sdes			    filename, linenum, arg ? arg : "<NONE>");
59860576Skris		if (*activep && options->ciphers == NULL)
59965674Skris			options->ciphers = xstrdup(arg);
60060576Skris		break;
60160576Skris
60276262Sgreen	case oMacs:
60376262Sgreen		arg = strdelim(&s);
60476262Sgreen		if (!arg || *arg == '\0')
60576262Sgreen			fatal("%.200s line %d: Missing argument.", filename, linenum);
60676262Sgreen		if (!mac_valid(arg))
60776262Sgreen			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
60892559Sdes			    filename, linenum, arg ? arg : "<NONE>");
60976262Sgreen		if (*activep && options->macs == NULL)
61076262Sgreen			options->macs = xstrdup(arg);
61176262Sgreen		break;
61276262Sgreen
61376262Sgreen	case oHostKeyAlgorithms:
61476262Sgreen		arg = strdelim(&s);
61576262Sgreen		if (!arg || *arg == '\0')
61676262Sgreen			fatal("%.200s line %d: Missing argument.", filename, linenum);
61776262Sgreen		if (!key_names_valid2(arg))
61876262Sgreen			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
61992559Sdes			    filename, linenum, arg ? arg : "<NONE>");
62076262Sgreen		if (*activep && options->hostkeyalgorithms == NULL)
62176262Sgreen			options->hostkeyalgorithms = xstrdup(arg);
62276262Sgreen		break;
62376262Sgreen
62460576Skris	case oProtocol:
62560576Skris		intptr = &options->protocol;
62665674Skris		arg = strdelim(&s);
62765674Skris		if (!arg || *arg == '\0')
62861203Skris			fatal("%.200s line %d: Missing argument.", filename, linenum);
62965674Skris		value = proto_spec(arg);
63060576Skris		if (value == SSH_PROTO_UNKNOWN)
63160576Skris			fatal("%.200s line %d: Bad protocol spec '%s'.",
63292559Sdes			    filename, linenum, arg ? arg : "<NONE>");
63360576Skris		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
63460576Skris			*intptr = value;
63560576Skris		break;
63660576Skris
63757429Smarkm	case oLogLevel:
63857429Smarkm		intptr = (int *) &options->log_level;
63965674Skris		arg = strdelim(&s);
64065674Skris		value = log_level_number(arg);
64192559Sdes		if (value == SYSLOG_LEVEL_NOT_SET)
64276262Sgreen			fatal("%.200s line %d: unsupported log level '%s'",
64392559Sdes			    filename, linenum, arg ? arg : "<NONE>");
64492559Sdes		if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
64557429Smarkm			*intptr = (LogLevel) value;
64657429Smarkm		break;
64757429Smarkm
64892559Sdes	case oLocalForward:
64957429Smarkm	case oRemoteForward:
65065674Skris		arg = strdelim(&s);
65165674Skris		if (!arg || *arg == '\0')
65292559Sdes			fatal("%.200s line %d: Missing port argument.",
65392559Sdes			    filename, linenum);
65492559Sdes		if ((fwd_port = a2port(arg)) == 0)
65592559Sdes			fatal("%.200s line %d: Bad listen port.",
65692559Sdes			    filename, linenum);
65765674Skris		arg = strdelim(&s);
65865674Skris		if (!arg || *arg == '\0')
65957429Smarkm			fatal("%.200s line %d: Missing second argument.",
66092559Sdes			    filename, linenum);
66192559Sdes		if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
66292559Sdes		    sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
66392559Sdes			fatal("%.200s line %d: Bad forwarding specification.",
66492559Sdes			    filename, linenum);
66592559Sdes		if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
66692559Sdes			fatal("%.200s line %d: Bad forwarding port.",
66792559Sdes			    filename, linenum);
66892559Sdes		if (*activep) {
66992559Sdes			if (opcode == oLocalForward)
67092559Sdes				add_local_forward(options, fwd_port, buf,
67192559Sdes				    fwd_host_port);
67292559Sdes			else if (opcode == oRemoteForward)
67392559Sdes				add_remote_forward(options, fwd_port, buf,
67492559Sdes				    fwd_host_port);
67592559Sdes		}
67657429Smarkm		break;
67757429Smarkm
67876262Sgreen	case oDynamicForward:
67976262Sgreen		arg = strdelim(&s);
68076262Sgreen		if (!arg || *arg == '\0')
68176262Sgreen			fatal("%.200s line %d: Missing port argument.",
68276262Sgreen			    filename, linenum);
68376262Sgreen		fwd_port = a2port(arg);
68476262Sgreen		if (fwd_port == 0)
68576262Sgreen			fatal("%.200s line %d: Badly formatted port number.",
68676262Sgreen			    filename, linenum);
68792559Sdes		if (*activep)
688124211Sdes			add_local_forward(options, fwd_port, "socks", 0);
68976262Sgreen		break;
69076262Sgreen
69192559Sdes	case oClearAllForwardings:
69292559Sdes		intptr = &options->clear_forwardings;
69392559Sdes		goto parse_flag;
69492559Sdes
69557429Smarkm	case oHost:
69657429Smarkm		*activep = 0;
69765674Skris		while ((arg = strdelim(&s)) != NULL && *arg != '\0')
69865674Skris			if (match_pattern(host, arg)) {
69965674Skris				debug("Applying options for %.100s", arg);
70057429Smarkm				*activep = 1;
70157429Smarkm				break;
70257429Smarkm			}
70365674Skris		/* Avoid garbage check below, as strdelim is done. */
70457429Smarkm		return 0;
70557429Smarkm
70657429Smarkm	case oEscapeChar:
70757429Smarkm		intptr = &options->escape_char;
70865674Skris		arg = strdelim(&s);
70965674Skris		if (!arg || *arg == '\0')
71057429Smarkm			fatal("%.200s line %d: Missing argument.", filename, linenum);
71165674Skris		if (arg[0] == '^' && arg[2] == 0 &&
71276262Sgreen		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
71376262Sgreen			value = (u_char) arg[1] & 31;
71465674Skris		else if (strlen(arg) == 1)
71576262Sgreen			value = (u_char) arg[0];
71665674Skris		else if (strcmp(arg, "none") == 0)
71792559Sdes			value = SSH_ESCAPECHAR_NONE;
71857429Smarkm		else {
71957429Smarkm			fatal("%.200s line %d: Bad escape character.",
72092559Sdes			    filename, linenum);
72157429Smarkm			/* NOTREACHED */
72257429Smarkm			value = 0;	/* Avoid compiler warning. */
72357429Smarkm		}
72457429Smarkm		if (*activep && *intptr == -1)
72557429Smarkm			*intptr = value;
72657429Smarkm		break;
72757429Smarkm
728124211Sdes	case oAddressFamily:
729124211Sdes		arg = strdelim(&s);
730124211Sdes		intptr = &options->address_family;
731124211Sdes		if (strcasecmp(arg, "inet") == 0)
732124211Sdes			value = AF_INET;
733124211Sdes		else if (strcasecmp(arg, "inet6") == 0)
734124211Sdes			value = AF_INET6;
735124211Sdes		else if (strcasecmp(arg, "any") == 0)
736124211Sdes			value = AF_UNSPEC;
737124211Sdes		else
738124211Sdes			fatal("Unsupported AddressFamily \"%s\"", arg);
739124211Sdes		if (*activep && *intptr == -1)
740124211Sdes			*intptr = value;
741124211Sdes		break;
742124211Sdes
743113911Sdes	case oEnableSSHKeysign:
744113911Sdes		intptr = &options->enable_ssh_keysign;
745113911Sdes		goto parse_flag;
746113911Sdes
747128460Sdes	case oIdentitiesOnly:
748128460Sdes		intptr = &options->identities_only;
749128460Sdes		goto parse_flag;
750128460Sdes
751126277Sdes	case oServerAliveInterval:
752126277Sdes		intptr = &options->server_alive_interval;
753126277Sdes		goto parse_time;
754126277Sdes
755126277Sdes	case oServerAliveCountMax:
756126277Sdes		intptr = &options->server_alive_count_max;
757126277Sdes		goto parse_int;
758126277Sdes
75999048Sdes	case oVersionAddendum:
76099048Sdes		ssh_version_set_addendum(strtok(s, "\n"));
76199048Sdes		do {
76299048Sdes			arg = strdelim(&s);
76399048Sdes		} while (arg != NULL && *arg != '\0');
76499048Sdes		break;
76599048Sdes
76698684Sdes	case oDeprecated:
76798684Sdes		debug("%s line %d: Deprecated option \"%s\"",
76898684Sdes		    filename, linenum, keyword);
76998684Sdes		return 0;
77098684Sdes
771124211Sdes	case oUnsupported:
772124211Sdes		error("%s line %d: Unsupported option \"%s\"",
773124211Sdes		    filename, linenum, keyword);
774124211Sdes		return 0;
775124211Sdes
77657429Smarkm	default:
77757429Smarkm		fatal("process_config_line: Unimplemented opcode %d", opcode);
77857429Smarkm	}
77957429Smarkm
78057429Smarkm	/* Check that there is no garbage at end of line. */
78176262Sgreen	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
78265674Skris		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
78392559Sdes		     filename, linenum, arg);
78465674Skris	}
78557429Smarkm	return 0;
78657429Smarkm}
78757429Smarkm
78857429Smarkm
78957429Smarkm/*
79057429Smarkm * Reads the config file and modifies the options accordingly.  Options
79157429Smarkm * should already be initialized before this call.  This never returns if
79292559Sdes * there is an error.  If the file does not exist, this returns 0.
79357429Smarkm */
79457429Smarkm
79592559Sdesint
79657429Smarkmread_config_file(const char *filename, const char *host, Options *options)
79757429Smarkm{
79857429Smarkm	FILE *f;
79957429Smarkm	char line[1024];
80057429Smarkm	int active, linenum;
80157429Smarkm	int bad_options = 0;
80257429Smarkm
80357429Smarkm	/* Open the file. */
80457429Smarkm	f = fopen(filename, "r");
80557429Smarkm	if (!f)
80692559Sdes		return 0;
80757429Smarkm
80857429Smarkm	debug("Reading configuration data %.200s", filename);
80957429Smarkm
81057429Smarkm	/*
81157429Smarkm	 * Mark that we are now processing the options.  This flag is turned
81257429Smarkm	 * on/off by Host specifications.
81357429Smarkm	 */
81457429Smarkm	active = 1;
81557429Smarkm	linenum = 0;
81657429Smarkm	while (fgets(line, sizeof(line), f)) {
81757429Smarkm		/* Update line number counter. */
81857429Smarkm		linenum++;
81957429Smarkm		if (process_config_line(options, host, line, filename, linenum, &active) != 0)
82057429Smarkm			bad_options++;
82157429Smarkm	}
82257429Smarkm	fclose(f);
82357429Smarkm	if (bad_options > 0)
82476262Sgreen		fatal("%s: terminating, %d bad configuration options",
82592559Sdes		    filename, bad_options);
82692559Sdes	return 1;
82757429Smarkm}
82857429Smarkm
82957429Smarkm/*
83057429Smarkm * Initializes options to special values that indicate that they have not yet
83157429Smarkm * been set.  Read_config_file will only set options with this value. Options
83257429Smarkm * are processed in the following order: command line, user config file,
83357429Smarkm * system config file.  Last, fill_default_options is called.
83457429Smarkm */
83557429Smarkm
83660576Skrisvoid
83757429Smarkminitialize_options(Options * options)
83857429Smarkm{
83957429Smarkm	memset(options, 'X', sizeof(*options));
84057429Smarkm	options->forward_agent = -1;
84157429Smarkm	options->forward_x11 = -1;
842126277Sdes	options->forward_x11_trusted = -1;
84365674Skris	options->xauth_location = NULL;
84457429Smarkm	options->gateway_ports = -1;
84557429Smarkm	options->use_privileged_port = -1;
84657429Smarkm	options->rsa_authentication = -1;
84776262Sgreen	options->pubkey_authentication = -1;
84892559Sdes	options->challenge_response_authentication = -1;
849124211Sdes	options->gss_authentication = -1;
850124211Sdes	options->gss_deleg_creds = -1;
85157429Smarkm	options->password_authentication = -1;
85269591Sgreen	options->kbd_interactive_authentication = -1;
85369591Sgreen	options->kbd_interactive_devices = NULL;
85457429Smarkm	options->rhosts_rsa_authentication = -1;
85576262Sgreen	options->hostbased_authentication = -1;
85657429Smarkm	options->batch_mode = -1;
85757429Smarkm	options->check_host_ip = -1;
85857429Smarkm	options->strict_host_key_checking = -1;
85957429Smarkm	options->compression = -1;
860126277Sdes	options->tcp_keep_alive = -1;
86157429Smarkm	options->compression_level = -1;
86257429Smarkm	options->port = -1;
863124211Sdes	options->address_family = -1;
86457429Smarkm	options->connection_attempts = -1;
865124211Sdes	options->connection_timeout = -1;
86657429Smarkm	options->number_of_password_prompts = -1;
86757429Smarkm	options->cipher = -1;
86860576Skris	options->ciphers = NULL;
86976262Sgreen	options->macs = NULL;
87076262Sgreen	options->hostkeyalgorithms = NULL;
87160576Skris	options->protocol = SSH_PROTO_UNKNOWN;
87257429Smarkm	options->num_identity_files = 0;
87357429Smarkm	options->hostname = NULL;
87476262Sgreen	options->host_key_alias = NULL;
87557429Smarkm	options->proxy_command = NULL;
87657429Smarkm	options->user = NULL;
87757429Smarkm	options->escape_char = -1;
87857429Smarkm	options->system_hostfile = NULL;
87957429Smarkm	options->user_hostfile = NULL;
88060576Skris	options->system_hostfile2 = NULL;
88160576Skris	options->user_hostfile2 = NULL;
88257429Smarkm	options->num_local_forwards = 0;
88357429Smarkm	options->num_remote_forwards = 0;
88492559Sdes	options->clear_forwardings = -1;
88592559Sdes	options->log_level = SYSLOG_LEVEL_NOT_SET;
88676262Sgreen	options->preferred_authentications = NULL;
88792559Sdes	options->bind_address = NULL;
88892559Sdes	options->smartcard_device = NULL;
889113911Sdes	options->enable_ssh_keysign = - 1;
89092559Sdes	options->no_host_authentication_for_localhost = - 1;
891128460Sdes	options->identities_only = - 1;
892124211Sdes	options->rekey_limit = - 1;
893124211Sdes	options->verify_host_key_dns = -1;
894126277Sdes	options->server_alive_interval = -1;
895126277Sdes	options->server_alive_count_max = -1;
89657429Smarkm}
89757429Smarkm
89857429Smarkm/*
89957429Smarkm * Called after processing other sources of option data, this fills those
90057429Smarkm * options for which no value has been specified with their default values.
90157429Smarkm */
90257429Smarkm
90360576Skrisvoid
90457429Smarkmfill_default_options(Options * options)
90557429Smarkm{
90676262Sgreen	int len;
90776262Sgreen
90857429Smarkm	if (options->forward_agent == -1)
90961203Skris		options->forward_agent = 0;
91057429Smarkm	if (options->forward_x11 == -1)
91157708Sgreen		options->forward_x11 = 0;
912126277Sdes	if (options->forward_x11_trusted == -1)
913126277Sdes		options->forward_x11_trusted = 0;
91465674Skris	if (options->xauth_location == NULL)
91592559Sdes		options->xauth_location = _PATH_XAUTH;
91657429Smarkm	if (options->gateway_ports == -1)
91757429Smarkm		options->gateway_ports = 0;
91857429Smarkm	if (options->use_privileged_port == -1)
91976262Sgreen		options->use_privileged_port = 0;
92057429Smarkm	if (options->rsa_authentication == -1)
92157429Smarkm		options->rsa_authentication = 1;
92276262Sgreen	if (options->pubkey_authentication == -1)
92376262Sgreen		options->pubkey_authentication = 1;
92492559Sdes	if (options->challenge_response_authentication == -1)
92592559Sdes		options->challenge_response_authentication = 1;
926124211Sdes	if (options->gss_authentication == -1)
927126277Sdes		options->gss_authentication = 0;
928124211Sdes	if (options->gss_deleg_creds == -1)
929124211Sdes		options->gss_deleg_creds = 0;
93057429Smarkm	if (options->password_authentication == -1)
93157429Smarkm		options->password_authentication = 1;
93269591Sgreen	if (options->kbd_interactive_authentication == -1)
93376262Sgreen		options->kbd_interactive_authentication = 1;
93457429Smarkm	if (options->rhosts_rsa_authentication == -1)
93598684Sdes		options->rhosts_rsa_authentication = 0;
93676262Sgreen	if (options->hostbased_authentication == -1)
93776262Sgreen		options->hostbased_authentication = 0;
93857429Smarkm	if (options->batch_mode == -1)
93957429Smarkm		options->batch_mode = 0;
94057429Smarkm	if (options->check_host_ip == -1)
94199048Sdes		options->check_host_ip = 0;
94257429Smarkm	if (options->strict_host_key_checking == -1)
94357429Smarkm		options->strict_host_key_checking = 2;	/* 2 is default */
94457429Smarkm	if (options->compression == -1)
94557429Smarkm		options->compression = 0;
946126277Sdes	if (options->tcp_keep_alive == -1)
947126277Sdes		options->tcp_keep_alive = 1;
94857429Smarkm	if (options->compression_level == -1)
94957429Smarkm		options->compression_level = 6;
95057429Smarkm	if (options->port == -1)
95157429Smarkm		options->port = 0;	/* Filled in ssh_connect. */
952124211Sdes	if (options->address_family == -1)
953124211Sdes		options->address_family = AF_UNSPEC;
95457429Smarkm	if (options->connection_attempts == -1)
95592559Sdes		options->connection_attempts = 1;
95657429Smarkm	if (options->number_of_password_prompts == -1)
95757429Smarkm		options->number_of_password_prompts = 3;
95857429Smarkm	/* Selected in ssh_login(). */
95957429Smarkm	if (options->cipher == -1)
96057429Smarkm		options->cipher = SSH_CIPHER_NOT_SET;
96160576Skris	/* options->ciphers, default set in myproposals.h */
96276262Sgreen	/* options->macs, default set in myproposals.h */
96376262Sgreen	/* options->hostkeyalgorithms, default set in myproposals.h */
96460576Skris	if (options->protocol == SSH_PROTO_UNKNOWN)
96576262Sgreen		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
96657429Smarkm	if (options->num_identity_files == 0) {
96776262Sgreen		if (options->protocol & SSH_PROTO_1) {
96876262Sgreen			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
96976262Sgreen			options->identity_files[options->num_identity_files] =
97076262Sgreen			    xmalloc(len);
97176262Sgreen			snprintf(options->identity_files[options->num_identity_files++],
97276262Sgreen			    len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
97376262Sgreen		}
97476262Sgreen		if (options->protocol & SSH_PROTO_2) {
97576262Sgreen			len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
97676262Sgreen			options->identity_files[options->num_identity_files] =
97776262Sgreen			    xmalloc(len);
97876262Sgreen			snprintf(options->identity_files[options->num_identity_files++],
97976262Sgreen			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
98076262Sgreen
98176262Sgreen			len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
98276262Sgreen			options->identity_files[options->num_identity_files] =
98376262Sgreen			    xmalloc(len);
98476262Sgreen			snprintf(options->identity_files[options->num_identity_files++],
98576262Sgreen			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
98676262Sgreen		}
98757429Smarkm	}
98857429Smarkm	if (options->escape_char == -1)
98957429Smarkm		options->escape_char = '~';
99057429Smarkm	if (options->system_hostfile == NULL)
99176262Sgreen		options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
99257429Smarkm	if (options->user_hostfile == NULL)
99376262Sgreen		options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
99460576Skris	if (options->system_hostfile2 == NULL)
99576262Sgreen		options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
99660576Skris	if (options->user_hostfile2 == NULL)
99776262Sgreen		options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
99892559Sdes	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
99957429Smarkm		options->log_level = SYSLOG_LEVEL_INFO;
100092559Sdes	if (options->clear_forwardings == 1)
100192559Sdes		clear_forwardings(options);
100292559Sdes	if (options->no_host_authentication_for_localhost == - 1)
100392559Sdes		options->no_host_authentication_for_localhost = 0;
1004128460Sdes	if (options->identities_only == -1)
1005128460Sdes		options->identities_only = 0;
1006113911Sdes	if (options->enable_ssh_keysign == -1)
1007113911Sdes		options->enable_ssh_keysign = 0;
1008124211Sdes	if (options->rekey_limit == -1)
1009124211Sdes		options->rekey_limit = 0;
1010124211Sdes	if (options->verify_host_key_dns == -1)
1011124211Sdes		options->verify_host_key_dns = 0;
1012126277Sdes	if (options->server_alive_interval == -1)
1013126277Sdes		options->server_alive_interval = 0;
1014126277Sdes	if (options->server_alive_count_max == -1)
1015126277Sdes		options->server_alive_count_max = 3;
101657429Smarkm	/* options->proxy_command should not be set by default */
101757429Smarkm	/* options->user will be set in the main program if appropriate */
101857429Smarkm	/* options->hostname will be set in the main program if appropriate */
101976262Sgreen	/* options->host_key_alias should not be set by default */
102076262Sgreen	/* options->preferred_authentications will be set in ssh */
102157429Smarkm}
1022