blob: 96ad25a51032800588f711dd419451719406face [file] [log] [blame]
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001/*
Damien Miller95def091999-11-25 00:26:21 +11002 * Author: Tatu Ylonen <ylo@cs.hut.fi>
Damien Miller95def091999-11-25 00:26:21 +11003 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
Damien Miller95def091999-11-25 00:26:21 +11005 * Functions for reading the configuration files.
Damien Miller4af51302000-04-16 11:18:38 +10006 *
Damien Millere4340be2000-09-16 13:29:08 +11007 * As far as I am concerned, the code I have written for this software
8 * can be used freely for any purpose. Any derived versions of this
9 * software must be clearly marked as such, and if the derived work is
10 * incompatible with the protocol description in the RFC file, it must be
11 * called by a name other than "ssh" or "Secure Shell".
Damien Miller95def091999-11-25 00:26:21 +110012 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +100013
14#include "includes.h"
Darren Tucker1c52ee32003-08-13 20:38:36 +100015RCSID("$OpenBSD: readconf.c,v 1.117 2003/08/13 09:07:09 markus Exp $");
Damien Millerd4a8b7e1999-10-27 13:42:43 +100016
17#include "ssh.h"
Damien Millerd4a8b7e1999-10-27 13:42:43 +100018#include "xmalloc.h"
Damien Miller78928792000-04-12 20:17:38 +100019#include "compat.h"
Ben Lindstrom226cfa02001-01-22 05:34:40 +000020#include "cipher.h"
21#include "pathnames.h"
22#include "log.h"
23#include "readconf.h"
24#include "match.h"
25#include "misc.h"
Ben Lindstrom06b33aa2001-02-15 03:01:59 +000026#include "kex.h"
27#include "mac.h"
Damien Millerd4a8b7e1999-10-27 13:42:43 +100028
29/* Format of the configuration file:
30
31 # Configuration data is parsed as follows:
32 # 1. command line options
33 # 2. user-specific file
34 # 3. system-wide file
35 # Any configuration value is only changed the first time it is set.
36 # Thus, host-specific definitions should be at the beginning of the
37 # configuration file, and defaults at the end.
38
39 # Host-specific declarations. These may override anything above. A single
40 # host may match multiple declarations; these are processed in the order
41 # that they are given in.
42
43 Host *.ngs.fi ngs.fi
Ben Lindstrom4daea862002-06-09 20:04:02 +000044 User foo
Damien Millerd4a8b7e1999-10-27 13:42:43 +100045
46 Host fake.com
47 HostName another.host.name.real.org
48 User blaah
49 Port 34289
50 ForwardX11 no
51 ForwardAgent no
52
53 Host books.com
54 RemoteForward 9999 shadows.cs.hut.fi:9999
55 Cipher 3des
56
57 Host fascist.blob.com
58 Port 23123
59 User tylonen
Damien Millerd4a8b7e1999-10-27 13:42:43 +100060 PasswordAuthentication no
61
62 Host puukko.hut.fi
63 User t35124p
64 ProxyCommand ssh-proxy %h %p
65
66 Host *.fr
Ben Lindstrom4daea862002-06-09 20:04:02 +000067 PublicKeyAuthentication no
Damien Millerd4a8b7e1999-10-27 13:42:43 +100068
69 Host *.su
70 Cipher none
71 PasswordAuthentication no
72
73 # Defaults for various options
74 Host *
75 ForwardAgent no
Damien Miller0bc1bd82000-11-13 22:57:25 +110076 ForwardX11 no
Damien Millerd4a8b7e1999-10-27 13:42:43 +100077 PasswordAuthentication yes
78 RSAAuthentication yes
79 RhostsRSAAuthentication yes
Damien Millerd4a8b7e1999-10-27 13:42:43 +100080 StrictHostKeyChecking yes
81 KeepAlives no
82 IdentityFile ~/.ssh/identity
83 Port 22
84 EscapeChar ~
85
86*/
87
88/* Keyword tokens. */
89
Damien Miller95def091999-11-25 00:26:21 +110090typedef enum {
91 oBadOption,
Darren Tuckerec960f22003-08-13 20:37:05 +100092 oForwardAgent, oForwardX11, oGatewayPorts,
Ben Lindstromcb72e4f2002-06-21 00:41:51 +000093 oPasswordAuthentication, oRSAAuthentication,
Ben Lindstrom95fb2dd2001-01-23 03:12:10 +000094 oChallengeResponseAuthentication, oXAuthLocation,
Darren Tucker6aaa58c2003-08-02 22:24:49 +100095 oKerberosAuthentication, oKerberosTgtPassing,
Damien Miller95def091999-11-25 00:26:21 +110096 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
97 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
98 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
99 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
Ben Lindstrom95fb2dd2001-01-23 03:12:10 +0000100 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
Ben Lindstrom06b33aa2001-02-15 03:01:59 +0000101 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
Damien Miller0bc1bd82000-11-13 22:57:25 +1100102 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
Ben Lindstromb9be60a2001-03-11 01:49:19 +0000103 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
Ben Lindstrom982dbbc2001-04-17 18:11:36 +0000104 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
Ben Lindstrom2b7a0e92001-09-20 00:57:55 +0000105 oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
Ben Lindstrom4daea862002-06-09 20:04:02 +0000106 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
Damien Millerb78d5eb2003-05-16 11:39:04 +1000107 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
Damien Miller20a8f972003-05-18 20:50:30 +1000108 oAddressFamily,
Damien Millerf9b3feb2003-05-16 11:38:32 +1000109 oDeprecated, oUnsupported
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000110} OpCodes;
111
112/* Textual representations of the tokens. */
113
Damien Miller95def091999-11-25 00:26:21 +1100114static struct {
115 const char *name;
116 OpCodes opcode;
117} keywords[] = {
118 { "forwardagent", oForwardAgent },
119 { "forwardx11", oForwardX11 },
Damien Millerd3a18572000-06-07 19:55:44 +1000120 { "xauthlocation", oXAuthLocation },
Damien Miller95def091999-11-25 00:26:21 +1100121 { "gatewayports", oGatewayPorts },
122 { "useprivilegedport", oUsePrivilegedPort },
Darren Tuckerec960f22003-08-13 20:37:05 +1000123 { "rhostsauthentication", oDeprecated },
Damien Miller95def091999-11-25 00:26:21 +1100124 { "passwordauthentication", oPasswordAuthentication },
Damien Miller874d77b2000-10-14 16:23:11 +1100125 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
126 { "kbdinteractivedevices", oKbdInteractiveDevices },
Damien Miller95def091999-11-25 00:26:21 +1100127 { "rsaauthentication", oRSAAuthentication },
Damien Miller0bc1bd82000-11-13 22:57:25 +1100128 { "pubkeyauthentication", oPubkeyAuthentication },
Ben Lindstrom95fb2dd2001-01-23 03:12:10 +0000129 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
Ben Lindstrom5eabda32001-04-12 23:34:34 +0000130 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
Ben Lindstromd69dab32001-04-12 23:36:05 +0000131 { "hostbasedauthentication", oHostbasedAuthentication },
Ben Lindstrom95fb2dd2001-01-23 03:12:10 +0000132 { "challengeresponseauthentication", oChallengeResponseAuthentication },
133 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
134 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
Darren Tucker6aaa58c2003-08-02 22:24:49 +1000135#ifdef KRB5
Damien Miller95def091999-11-25 00:26:21 +1100136 { "kerberosauthentication", oKerberosAuthentication },
Damien Miller95def091999-11-25 00:26:21 +1100137 { "kerberostgtpassing", oKerberosTgtPassing },
Damien Millerf9b3feb2003-05-16 11:38:32 +1000138#else
139 { "kerberosauthentication", oUnsupported },
140 { "kerberostgtpassing", oUnsupported },
141#endif
Damien Millerf9b3feb2003-05-16 11:38:32 +1000142 { "afstokenpassing", oUnsupported },
Ben Lindstrom4daea862002-06-09 20:04:02 +0000143 { "fallbacktorsh", oDeprecated },
144 { "usersh", oDeprecated },
Damien Miller95def091999-11-25 00:26:21 +1100145 { "identityfile", oIdentityFile },
Damien Miller0bc1bd82000-11-13 22:57:25 +1100146 { "identityfile2", oIdentityFile }, /* alias */
Damien Miller95def091999-11-25 00:26:21 +1100147 { "hostname", oHostName },
Ben Lindstrom4dccfa52000-12-28 16:40:05 +0000148 { "hostkeyalias", oHostKeyAlias },
Damien Miller95def091999-11-25 00:26:21 +1100149 { "proxycommand", oProxyCommand },
150 { "port", oPort },
151 { "cipher", oCipher },
Damien Miller78928792000-04-12 20:17:38 +1000152 { "ciphers", oCiphers },
Ben Lindstrom06b33aa2001-02-15 03:01:59 +0000153 { "macs", oMacs },
Damien Miller78928792000-04-12 20:17:38 +1000154 { "protocol", oProtocol },
Damien Miller95def091999-11-25 00:26:21 +1100155 { "remoteforward", oRemoteForward },
156 { "localforward", oLocalForward },
157 { "user", oUser },
158 { "host", oHost },
159 { "escapechar", oEscapeChar },
Damien Miller95def091999-11-25 00:26:21 +1100160 { "globalknownhostsfile", oGlobalKnownHostsFile },
Ben Lindstromd6481ea2001-06-25 04:37:41 +0000161 { "userknownhostsfile", oUserKnownHostsFile }, /* obsolete */
Damien Millereba71ba2000-04-29 23:57:08 +1000162 { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
Ben Lindstromd6481ea2001-06-25 04:37:41 +0000163 { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */
Damien Miller95def091999-11-25 00:26:21 +1100164 { "connectionattempts", oConnectionAttempts },
165 { "batchmode", oBatchMode },
166 { "checkhostip", oCheckHostIP },
167 { "stricthostkeychecking", oStrictHostKeyChecking },
168 { "compression", oCompression },
169 { "compressionlevel", oCompressionLevel },
170 { "keepalive", oKeepAlives },
171 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
Damien Miller95def091999-11-25 00:26:21 +1100172 { "loglevel", oLogLevel },
Ben Lindstrom3bb4f9d2001-04-08 18:30:26 +0000173 { "dynamicforward", oDynamicForward },
Ben Lindstromb9be60a2001-03-11 01:49:19 +0000174 { "preferredauthentications", oPreferredAuthentications },
Ben Lindstrom982dbbc2001-04-17 18:11:36 +0000175 { "hostkeyalgorithms", oHostKeyAlgorithms },
Ben Lindstrome0f88042001-04-30 13:06:24 +0000176 { "bindaddress", oBindAddress },
Damien Millerf9b3feb2003-05-16 11:38:32 +1000177#ifdef SMARTCARD
Ben Lindstromae996bf2001-08-06 21:27:53 +0000178 { "smartcarddevice", oSmartcardDevice },
Damien Millerf9b3feb2003-05-16 11:38:32 +1000179#else
180 { "smartcarddevice", oUnsupported },
181#endif
Damien Miller9f0f5c62001-12-21 14:45:46 +1100182 { "clearallforwardings", oClearAllForwardings },
Ben Lindstromb6df73b2002-11-09 15:52:31 +0000183 { "enablesshkeysign", oEnableSSHKeysign },
Damien Millerf9b3feb2003-05-16 11:38:32 +1000184#ifdef DNS
Damien Miller37876e92003-05-15 10:19:46 +1000185 { "verifyhostkeydns", oVerifyHostKeyDNS },
Damien Millerf9b3feb2003-05-16 11:38:32 +1000186#else
187 { "verifyhostkeydns", oUnsupported },
188#endif
Damien Miller9f0f5c62001-12-21 14:45:46 +1100189 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
Damien Millera5539d22003-04-09 20:50:06 +1000190 { "rekeylimit", oRekeyLimit },
Damien Millerb78d5eb2003-05-16 11:39:04 +1000191 { "connecttimeout", oConnectTimeout },
Damien Miller20a8f972003-05-18 20:50:30 +1000192 { "addressfamily", oAddressFamily },
Ben Lindstrom65366a82001-12-06 16:32:47 +0000193 { NULL, oBadOption }
Damien Miller5ce662a1999-11-11 17:57:39 +1100194};
195
Damien Miller5428f641999-11-25 11:54:57 +1100196/*
197 * Adds a local TCP/IP port forward to options. Never returns if there is an
198 * error.
199 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000200
Damien Miller4af51302000-04-16 11:18:38 +1000201void
Damien Milleraae6c611999-12-06 11:47:28 +1100202add_local_forward(Options *options, u_short port, const char *host,
203 u_short host_port)
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000204{
Damien Miller95def091999-11-25 00:26:21 +1100205 Forward *fwd;
Ben Lindstrom99a4e142002-07-09 14:06:40 +0000206#ifndef NO_IPPORT_RESERVED_CONCEPT
Damien Miller95def091999-11-25 00:26:21 +1100207 extern uid_t original_real_uid;
Damien Miller95def091999-11-25 00:26:21 +1100208 if (port < IPPORT_RESERVED && original_real_uid != 0)
Ben Lindstrom6df8ef42001-03-05 07:47:23 +0000209 fatal("Privileged ports can only be forwarded by root.");
Damien Millerbac2d8a2000-09-05 16:13:06 +1100210#endif
Damien Miller95def091999-11-25 00:26:21 +1100211 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
212 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
213 fwd = &options->local_forwards[options->num_local_forwards++];
214 fwd->port = port;
215 fwd->host = xstrdup(host);
216 fwd->host_port = host_port;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000217}
218
Damien Miller5428f641999-11-25 11:54:57 +1100219/*
220 * Adds a remote TCP/IP port forward to options. Never returns if there is
221 * an error.
222 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000223
Damien Miller4af51302000-04-16 11:18:38 +1000224void
Damien Milleraae6c611999-12-06 11:47:28 +1100225add_remote_forward(Options *options, u_short port, const char *host,
226 u_short host_port)
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000227{
Damien Miller95def091999-11-25 00:26:21 +1100228 Forward *fwd;
229 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
230 fatal("Too many remote forwards (max %d).",
Damien Miller9f0f5c62001-12-21 14:45:46 +1100231 SSH_MAX_FORWARDS_PER_DIRECTION);
Damien Miller95def091999-11-25 00:26:21 +1100232 fwd = &options->remote_forwards[options->num_remote_forwards++];
233 fwd->port = port;
234 fwd->host = xstrdup(host);
235 fwd->host_port = host_port;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000236}
237
Ben Lindstrom2b7a0e92001-09-20 00:57:55 +0000238static void
239clear_forwardings(Options *options)
240{
241 int i;
242
243 for (i = 0; i < options->num_local_forwards; i++)
244 xfree(options->local_forwards[i].host);
245 options->num_local_forwards = 0;
246 for (i = 0; i < options->num_remote_forwards; i++)
247 xfree(options->remote_forwards[i].host);
248 options->num_remote_forwards = 0;
249}
250
Damien Miller5428f641999-11-25 11:54:57 +1100251/*
Ben Lindstrom3704c262001-04-02 18:20:03 +0000252 * Returns the number of the token pointed to by cp or oBadOption.
Damien Miller5428f641999-11-25 11:54:57 +1100253 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000254
Damien Miller4af51302000-04-16 11:18:38 +1000255static OpCodes
Damien Miller95def091999-11-25 00:26:21 +1100256parse_token(const char *cp, const char *filename, int linenum)
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000257{
Ben Lindstrom46c16222000-12-22 01:43:59 +0000258 u_int i;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000259
Damien Miller95def091999-11-25 00:26:21 +1100260 for (i = 0; keywords[i].name; i++)
Damien Miller5428f641999-11-25 11:54:57 +1100261 if (strcasecmp(cp, keywords[i].name) == 0)
Damien Miller95def091999-11-25 00:26:21 +1100262 return keywords[i].opcode;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000263
Ben Lindstromb5cdc662001-04-16 02:13:26 +0000264 error("%s: line %d: Bad configuration option: %s",
265 filename, linenum, cp);
Damien Miller95def091999-11-25 00:26:21 +1100266 return oBadOption;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000267}
268
Damien Miller5428f641999-11-25 11:54:57 +1100269/*
270 * Processes a single option line as used in the configuration files. This
271 * only sets those values that have not already been set.
272 */
Damien Miller61f08ac2003-02-24 11:56:27 +1100273#define WHITESPACE " \t\r\n"
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000274
Damien Miller2ccf6611999-11-15 15:25:10 +1100275int
276process_config_line(Options *options, const char *host,
Damien Miller95def091999-11-25 00:26:21 +1100277 char *line, const char *filename, int linenum,
278 int *activep)
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000279{
Damien Miller61f08ac2003-02-24 11:56:27 +1100280 char buf[256], *s, **charptr, *endofnumber, *keyword, *arg;
Damien Milleraae6c611999-12-06 11:47:28 +1100281 int opcode, *intptr, value;
Damien Miller61f08ac2003-02-24 11:56:27 +1100282 size_t len;
Damien Milleraae6c611999-12-06 11:47:28 +1100283 u_short fwd_port, fwd_host_port;
Ben Lindstrom62c25a42001-09-12 18:01:59 +0000284 char sfwd_host_port[6];
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000285
Damien Millerc652cac2003-05-14 13:40:54 +1000286 /* Strip trailing whitespace */
287 for(len = strlen(line) - 1; len > 0; len--) {
288 if (strchr(WHITESPACE, line[len]) == NULL)
289 break;
290 line[len] = '\0';
291 }
292
Damien Millerbe484b52000-07-15 14:14:16 +1000293 s = line;
294 /* Get the keyword. (Each line is supposed to begin with a keyword). */
295 keyword = strdelim(&s);
296 /* Ignore leading whitespace. */
297 if (*keyword == '\0')
298 keyword = strdelim(&s);
Ben Lindstrom226cfa02001-01-22 05:34:40 +0000299 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
Damien Miller95def091999-11-25 00:26:21 +1100300 return 0;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000301
Damien Miller37023962000-07-11 17:31:38 +1000302 opcode = parse_token(keyword, filename, linenum);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000303
Damien Miller95def091999-11-25 00:26:21 +1100304 switch (opcode) {
305 case oBadOption:
Damien Miller5428f641999-11-25 11:54:57 +1100306 /* don't panic, but count bad options */
307 return -1;
Damien Miller95def091999-11-25 00:26:21 +1100308 /* NOTREACHED */
Damien Millerb78d5eb2003-05-16 11:39:04 +1000309 case oConnectTimeout:
310 intptr = &options->connection_timeout;
311/* parse_time: */
312 arg = strdelim(&s);
313 if (!arg || *arg == '\0')
314 fatal("%s line %d: missing time value.",
315 filename, linenum);
316 if ((value = convtime(arg)) == -1)
317 fatal("%s line %d: invalid time value.",
318 filename, linenum);
319 if (*intptr == -1)
320 *intptr = value;
321 break;
322
Damien Miller95def091999-11-25 00:26:21 +1100323 case oForwardAgent:
324 intptr = &options->forward_agent;
325parse_flag:
Damien Millerbe484b52000-07-15 14:14:16 +1000326 arg = strdelim(&s);
Damien Miller37023962000-07-11 17:31:38 +1000327 if (!arg || *arg == '\0')
Damien Miller95def091999-11-25 00:26:21 +1100328 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
329 value = 0; /* To avoid compiler warning... */
Damien Miller37023962000-07-11 17:31:38 +1000330 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
Damien Miller95def091999-11-25 00:26:21 +1100331 value = 1;
Damien Miller37023962000-07-11 17:31:38 +1000332 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
Damien Miller95def091999-11-25 00:26:21 +1100333 value = 0;
334 else
335 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
336 if (*activep && *intptr == -1)
337 *intptr = value;
338 break;
339
340 case oForwardX11:
341 intptr = &options->forward_x11;
342 goto parse_flag;
343
344 case oGatewayPorts:
345 intptr = &options->gateway_ports;
346 goto parse_flag;
347
348 case oUsePrivilegedPort:
349 intptr = &options->use_privileged_port;
350 goto parse_flag;
351
Damien Miller95def091999-11-25 00:26:21 +1100352 case oPasswordAuthentication:
353 intptr = &options->password_authentication;
354 goto parse_flag;
355
Damien Miller874d77b2000-10-14 16:23:11 +1100356 case oKbdInteractiveAuthentication:
357 intptr = &options->kbd_interactive_authentication;
358 goto parse_flag;
359
360 case oKbdInteractiveDevices:
361 charptr = &options->kbd_interactive_devices;
362 goto parse_string;
363
Damien Miller0bc1bd82000-11-13 22:57:25 +1100364 case oPubkeyAuthentication:
365 intptr = &options->pubkey_authentication;
Damien Millere247cc42000-05-07 12:03:14 +1000366 goto parse_flag;
367
Damien Miller95def091999-11-25 00:26:21 +1100368 case oRSAAuthentication:
369 intptr = &options->rsa_authentication;
370 goto parse_flag;
371
372 case oRhostsRSAAuthentication:
373 intptr = &options->rhosts_rsa_authentication;
374 goto parse_flag;
375
Ben Lindstrom5eabda32001-04-12 23:34:34 +0000376 case oHostbasedAuthentication:
377 intptr = &options->hostbased_authentication;
378 goto parse_flag;
379
Ben Lindstrom95fb2dd2001-01-23 03:12:10 +0000380 case oChallengeResponseAuthentication:
Ben Lindstrom551ea372001-06-05 18:56:16 +0000381 intptr = &options->challenge_response_authentication;
Damien Miller95def091999-11-25 00:26:21 +1100382 goto parse_flag;
Damien Miller2aa0ab42003-05-15 12:05:28 +1000383
Damien Miller95def091999-11-25 00:26:21 +1100384 case oKerberosAuthentication:
385 intptr = &options->kerberos_authentication;
386 goto parse_flag;
Damien Miller2aa0ab42003-05-15 12:05:28 +1000387
Damien Miller95def091999-11-25 00:26:21 +1100388 case oKerberosTgtPassing:
389 intptr = &options->kerberos_tgt_passing;
390 goto parse_flag;
Damien Miller2aa0ab42003-05-15 12:05:28 +1000391
Damien Miller95def091999-11-25 00:26:21 +1100392 case oBatchMode:
393 intptr = &options->batch_mode;
394 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000395
Damien Miller95def091999-11-25 00:26:21 +1100396 case oCheckHostIP:
397 intptr = &options->check_host_ip;
398 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000399
Damien Miller37876e92003-05-15 10:19:46 +1000400 case oVerifyHostKeyDNS:
401 intptr = &options->verify_host_key_dns;
402 goto parse_flag;
403
Damien Miller95def091999-11-25 00:26:21 +1100404 case oStrictHostKeyChecking:
405 intptr = &options->strict_host_key_checking;
Damien Millerbe484b52000-07-15 14:14:16 +1000406 arg = strdelim(&s);
Damien Miller37023962000-07-11 17:31:38 +1000407 if (!arg || *arg == '\0')
Ben Lindstrom5ed8acd2001-01-29 08:00:54 +0000408 fatal("%.200s line %d: Missing yes/no/ask argument.",
Damien Miller9f0f5c62001-12-21 14:45:46 +1100409 filename, linenum);
Damien Miller95def091999-11-25 00:26:21 +1100410 value = 0; /* To avoid compiler warning... */
Damien Miller37023962000-07-11 17:31:38 +1000411 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
Damien Miller95def091999-11-25 00:26:21 +1100412 value = 1;
Damien Miller37023962000-07-11 17:31:38 +1000413 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
Damien Miller95def091999-11-25 00:26:21 +1100414 value = 0;
Damien Miller37023962000-07-11 17:31:38 +1000415 else if (strcmp(arg, "ask") == 0)
Damien Miller95def091999-11-25 00:26:21 +1100416 value = 2;
417 else
418 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
419 if (*activep && *intptr == -1)
420 *intptr = value;
421 break;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000422
Damien Miller95def091999-11-25 00:26:21 +1100423 case oCompression:
424 intptr = &options->compression;
425 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000426
Damien Miller95def091999-11-25 00:26:21 +1100427 case oKeepAlives:
428 intptr = &options->keepalives;
429 goto parse_flag;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000430
Ben Lindstrom3cecc9a2001-10-03 17:39:38 +0000431 case oNoHostAuthenticationForLocalhost:
432 intptr = &options->no_host_authentication_for_localhost;
433 goto parse_flag;
434
Damien Miller95def091999-11-25 00:26:21 +1100435 case oNumberOfPasswordPrompts:
436 intptr = &options->number_of_password_prompts;
437 goto parse_int;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000438
Damien Miller95def091999-11-25 00:26:21 +1100439 case oCompressionLevel:
440 intptr = &options->compression_level;
441 goto parse_int;
442
Damien Millera5539d22003-04-09 20:50:06 +1000443 case oRekeyLimit:
444 intptr = &options->rekey_limit;
445 arg = strdelim(&s);
446 if (!arg || *arg == '\0')
447 fatal("%.200s line %d: Missing argument.", filename, linenum);
448 if (arg[0] < '0' || arg[0] > '9')
449 fatal("%.200s line %d: Bad number.", filename, linenum);
450 value = strtol(arg, &endofnumber, 10);
451 if (arg == endofnumber)
452 fatal("%.200s line %d: Bad number.", filename, linenum);
453 switch (toupper(*endofnumber)) {
454 case 'K':
455 value *= 1<<10;
456 break;
457 case 'M':
458 value *= 1<<20;
459 break;
460 case 'G':
461 value *= 1<<30;
462 break;
463 }
464 if (*activep && *intptr == -1)
465 *intptr = value;
466 break;
467
Damien Miller95def091999-11-25 00:26:21 +1100468 case oIdentityFile:
Damien Millerbe484b52000-07-15 14:14:16 +1000469 arg = strdelim(&s);
Damien Miller37023962000-07-11 17:31:38 +1000470 if (!arg || *arg == '\0')
Damien Miller95def091999-11-25 00:26:21 +1100471 fatal("%.200s line %d: Missing argument.", filename, linenum);
472 if (*activep) {
Damien Miller0bc1bd82000-11-13 22:57:25 +1100473 intptr = &options->num_identity_files;
Damien Millereba71ba2000-04-29 23:57:08 +1000474 if (*intptr >= SSH_MAX_IDENTITY_FILES)
Damien Miller95def091999-11-25 00:26:21 +1100475 fatal("%.200s line %d: Too many identity files specified (max %d).",
Damien Miller9f0f5c62001-12-21 14:45:46 +1100476 filename, linenum, SSH_MAX_IDENTITY_FILES);
Damien Miller0bc1bd82000-11-13 22:57:25 +1100477 charptr = &options->identity_files[*intptr];
Damien Miller37023962000-07-11 17:31:38 +1000478 *charptr = xstrdup(arg);
Damien Millereba71ba2000-04-29 23:57:08 +1000479 *intptr = *intptr + 1;
Damien Miller95def091999-11-25 00:26:21 +1100480 }
481 break;
482
Damien Millerd3a18572000-06-07 19:55:44 +1000483 case oXAuthLocation:
484 charptr=&options->xauth_location;
485 goto parse_string;
486
Damien Miller95def091999-11-25 00:26:21 +1100487 case oUser:
488 charptr = &options->user;
489parse_string:
Damien Millerbe484b52000-07-15 14:14:16 +1000490 arg = strdelim(&s);
Damien Miller37023962000-07-11 17:31:38 +1000491 if (!arg || *arg == '\0')
Damien Miller95def091999-11-25 00:26:21 +1100492 fatal("%.200s line %d: Missing argument.", filename, linenum);
493 if (*activep && *charptr == NULL)
Damien Miller37023962000-07-11 17:31:38 +1000494 *charptr = xstrdup(arg);
Damien Miller95def091999-11-25 00:26:21 +1100495 break;
496
497 case oGlobalKnownHostsFile:
498 charptr = &options->system_hostfile;
499 goto parse_string;
500
501 case oUserKnownHostsFile:
502 charptr = &options->user_hostfile;
503 goto parse_string;
504
Damien Millereba71ba2000-04-29 23:57:08 +1000505 case oGlobalKnownHostsFile2:
506 charptr = &options->system_hostfile2;
507 goto parse_string;
508
509 case oUserKnownHostsFile2:
510 charptr = &options->user_hostfile2;
511 goto parse_string;
512
Damien Miller95def091999-11-25 00:26:21 +1100513 case oHostName:
514 charptr = &options->hostname;
515 goto parse_string;
516
Ben Lindstrom4dccfa52000-12-28 16:40:05 +0000517 case oHostKeyAlias:
518 charptr = &options->host_key_alias;
519 goto parse_string;
520
Ben Lindstromb9be60a2001-03-11 01:49:19 +0000521 case oPreferredAuthentications:
522 charptr = &options->preferred_authentications;
523 goto parse_string;
524
Ben Lindstrome0f88042001-04-30 13:06:24 +0000525 case oBindAddress:
526 charptr = &options->bind_address;
527 goto parse_string;
528
Ben Lindstromae996bf2001-08-06 21:27:53 +0000529 case oSmartcardDevice:
Ben Lindstromf7db3bb2001-08-06 21:35:51 +0000530 charptr = &options->smartcard_device;
531 goto parse_string;
Ben Lindstromae996bf2001-08-06 21:27:53 +0000532
Damien Miller95def091999-11-25 00:26:21 +1100533 case oProxyCommand:
Darren Tuckera99c1b72003-06-28 12:40:12 +1000534 if (s == NULL)
535 fatal("%.200s line %d: Missing argument.", filename, linenum);
Damien Miller95def091999-11-25 00:26:21 +1100536 charptr = &options->proxy_command;
Damien Miller61f08ac2003-02-24 11:56:27 +1100537 len = strspn(s, WHITESPACE "=");
Damien Miller95def091999-11-25 00:26:21 +1100538 if (*activep && *charptr == NULL)
Damien Miller61f08ac2003-02-24 11:56:27 +1100539 *charptr = xstrdup(s + len);
Damien Miller95def091999-11-25 00:26:21 +1100540 return 0;
541
542 case oPort:
543 intptr = &options->port;
544parse_int:
Damien Millerbe484b52000-07-15 14:14:16 +1000545 arg = strdelim(&s);
Damien Miller37023962000-07-11 17:31:38 +1000546 if (!arg || *arg == '\0')
Damien Miller95def091999-11-25 00:26:21 +1100547 fatal("%.200s line %d: Missing argument.", filename, linenum);
Damien Miller37023962000-07-11 17:31:38 +1000548 if (arg[0] < '0' || arg[0] > '9')
Damien Miller95def091999-11-25 00:26:21 +1100549 fatal("%.200s line %d: Bad number.", filename, linenum);
Damien Miller5428f641999-11-25 11:54:57 +1100550
551 /* Octal, decimal, or hex format? */
Damien Miller37023962000-07-11 17:31:38 +1000552 value = strtol(arg, &endofnumber, 0);
553 if (arg == endofnumber)
Damien Miller5428f641999-11-25 11:54:57 +1100554 fatal("%.200s line %d: Bad number.", filename, linenum);
Damien Miller95def091999-11-25 00:26:21 +1100555 if (*activep && *intptr == -1)
556 *intptr = value;
557 break;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000558
Damien Miller95def091999-11-25 00:26:21 +1100559 case oConnectionAttempts:
560 intptr = &options->connection_attempts;
561 goto parse_int;
Damien Miller5ce662a1999-11-11 17:57:39 +1100562
Damien Miller95def091999-11-25 00:26:21 +1100563 case oCipher:
564 intptr = &options->cipher;
Damien Millerbe484b52000-07-15 14:14:16 +1000565 arg = strdelim(&s);
Damien Miller37023962000-07-11 17:31:38 +1000566 if (!arg || *arg == '\0')
Damien Millerb1715dc2000-05-30 13:44:51 +1000567 fatal("%.200s line %d: Missing argument.", filename, linenum);
Damien Miller37023962000-07-11 17:31:38 +1000568 value = cipher_number(arg);
Damien Miller95def091999-11-25 00:26:21 +1100569 if (value == -1)
570 fatal("%.200s line %d: Bad cipher '%s'.",
Damien Miller9f0f5c62001-12-21 14:45:46 +1100571 filename, linenum, arg ? arg : "<NONE>");
Damien Miller95def091999-11-25 00:26:21 +1100572 if (*activep && *intptr == -1)
573 *intptr = value;
574 break;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000575
Damien Miller78928792000-04-12 20:17:38 +1000576 case oCiphers:
Damien Millerbe484b52000-07-15 14:14:16 +1000577 arg = strdelim(&s);
Damien Miller37023962000-07-11 17:31:38 +1000578 if (!arg || *arg == '\0')
Damien Millerb1715dc2000-05-30 13:44:51 +1000579 fatal("%.200s line %d: Missing argument.", filename, linenum);
Damien Miller37023962000-07-11 17:31:38 +1000580 if (!ciphers_valid(arg))
Damien Miller30c3d422000-05-09 11:02:59 +1000581 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
Damien Miller9f0f5c62001-12-21 14:45:46 +1100582 filename, linenum, arg ? arg : "<NONE>");
Damien Miller78928792000-04-12 20:17:38 +1000583 if (*activep && options->ciphers == NULL)
Damien Miller37023962000-07-11 17:31:38 +1000584 options->ciphers = xstrdup(arg);
Damien Miller78928792000-04-12 20:17:38 +1000585 break;
586
Ben Lindstrom06b33aa2001-02-15 03:01:59 +0000587 case oMacs:
588 arg = strdelim(&s);
589 if (!arg || *arg == '\0')
590 fatal("%.200s line %d: Missing argument.", filename, linenum);
591 if (!mac_valid(arg))
592 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
Damien Miller9f0f5c62001-12-21 14:45:46 +1100593 filename, linenum, arg ? arg : "<NONE>");
Ben Lindstrom06b33aa2001-02-15 03:01:59 +0000594 if (*activep && options->macs == NULL)
595 options->macs = xstrdup(arg);
596 break;
597
Ben Lindstrom982dbbc2001-04-17 18:11:36 +0000598 case oHostKeyAlgorithms:
599 arg = strdelim(&s);
600 if (!arg || *arg == '\0')
601 fatal("%.200s line %d: Missing argument.", filename, linenum);
602 if (!key_names_valid2(arg))
603 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
Damien Miller9f0f5c62001-12-21 14:45:46 +1100604 filename, linenum, arg ? arg : "<NONE>");
Ben Lindstrom982dbbc2001-04-17 18:11:36 +0000605 if (*activep && options->hostkeyalgorithms == NULL)
606 options->hostkeyalgorithms = xstrdup(arg);
607 break;
608
Damien Miller78928792000-04-12 20:17:38 +1000609 case oProtocol:
610 intptr = &options->protocol;
Damien Millerbe484b52000-07-15 14:14:16 +1000611 arg = strdelim(&s);
Damien Miller37023962000-07-11 17:31:38 +1000612 if (!arg || *arg == '\0')
Damien Millerb1715dc2000-05-30 13:44:51 +1000613 fatal("%.200s line %d: Missing argument.", filename, linenum);
Damien Miller37023962000-07-11 17:31:38 +1000614 value = proto_spec(arg);
Damien Miller78928792000-04-12 20:17:38 +1000615 if (value == SSH_PROTO_UNKNOWN)
616 fatal("%.200s line %d: Bad protocol spec '%s'.",
Damien Miller9f0f5c62001-12-21 14:45:46 +1100617 filename, linenum, arg ? arg : "<NONE>");
Damien Miller78928792000-04-12 20:17:38 +1000618 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
619 *intptr = value;
620 break;
621
Damien Miller95def091999-11-25 00:26:21 +1100622 case oLogLevel:
623 intptr = (int *) &options->log_level;
Damien Millerbe484b52000-07-15 14:14:16 +1000624 arg = strdelim(&s);
Damien Miller37023962000-07-11 17:31:38 +1000625 value = log_level_number(arg);
Damien Millerfcd93202002-02-05 12:26:34 +1100626 if (value == SYSLOG_LEVEL_NOT_SET)
Ben Lindstrom6df8ef42001-03-05 07:47:23 +0000627 fatal("%.200s line %d: unsupported log level '%s'",
Damien Miller9f0f5c62001-12-21 14:45:46 +1100628 filename, linenum, arg ? arg : "<NONE>");
Damien Millerfcd93202002-02-05 12:26:34 +1100629 if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
Damien Miller95def091999-11-25 00:26:21 +1100630 *intptr = (LogLevel) value;
631 break;
632
Ben Lindstrom62c25a42001-09-12 18:01:59 +0000633 case oLocalForward:
Damien Miller95def091999-11-25 00:26:21 +1100634 case oRemoteForward:
Damien Millerbe484b52000-07-15 14:14:16 +1000635 arg = strdelim(&s);
Damien Miller37023962000-07-11 17:31:38 +1000636 if (!arg || *arg == '\0')
Ben Lindstrom62c25a42001-09-12 18:01:59 +0000637 fatal("%.200s line %d: Missing port argument.",
638 filename, linenum);
639 if ((fwd_port = a2port(arg)) == 0)
640 fatal("%.200s line %d: Bad listen port.",
641 filename, linenum);
Damien Millerbe484b52000-07-15 14:14:16 +1000642 arg = strdelim(&s);
Damien Miller37023962000-07-11 17:31:38 +1000643 if (!arg || *arg == '\0')
Damien Miller95def091999-11-25 00:26:21 +1100644 fatal("%.200s line %d: Missing second argument.",
Ben Lindstrom62c25a42001-09-12 18:01:59 +0000645 filename, linenum);
646 if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
647 sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
648 fatal("%.200s line %d: Bad forwarding specification.",
649 filename, linenum);
650 if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
651 fatal("%.200s line %d: Bad forwarding port.",
652 filename, linenum);
653 if (*activep) {
654 if (opcode == oLocalForward)
655 add_local_forward(options, fwd_port, buf,
656 fwd_host_port);
657 else if (opcode == oRemoteForward)
658 add_remote_forward(options, fwd_port, buf,
659 fwd_host_port);
660 }
Damien Miller95def091999-11-25 00:26:21 +1100661 break;
662
Ben Lindstrom3bb4f9d2001-04-08 18:30:26 +0000663 case oDynamicForward:
664 arg = strdelim(&s);
665 if (!arg || *arg == '\0')
666 fatal("%.200s line %d: Missing port argument.",
667 filename, linenum);
Ben Lindstrom19066a12001-04-12 23:39:26 +0000668 fwd_port = a2port(arg);
669 if (fwd_port == 0)
Ben Lindstrom3bb4f9d2001-04-08 18:30:26 +0000670 fatal("%.200s line %d: Badly formatted port number.",
671 filename, linenum);
Ben Lindstrom525a0932001-09-12 17:35:27 +0000672 if (*activep)
Darren Tucker1c52ee32003-08-13 20:38:36 +1000673 add_local_forward(options, fwd_port, "socks", 0);
Ben Lindstrom5eabda32001-04-12 23:34:34 +0000674 break;
Ben Lindstrom3bb4f9d2001-04-08 18:30:26 +0000675
Ben Lindstrom2b7a0e92001-09-20 00:57:55 +0000676 case oClearAllForwardings:
677 intptr = &options->clear_forwardings;
678 goto parse_flag;
679
Damien Miller95def091999-11-25 00:26:21 +1100680 case oHost:
681 *activep = 0;
Damien Millerbe484b52000-07-15 14:14:16 +1000682 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
Damien Miller37023962000-07-11 17:31:38 +1000683 if (match_pattern(host, arg)) {
684 debug("Applying options for %.100s", arg);
Damien Miller95def091999-11-25 00:26:21 +1100685 *activep = 1;
686 break;
687 }
Damien Millerbe484b52000-07-15 14:14:16 +1000688 /* Avoid garbage check below, as strdelim is done. */
Damien Miller95def091999-11-25 00:26:21 +1100689 return 0;
690
691 case oEscapeChar:
692 intptr = &options->escape_char;
Damien Millerbe484b52000-07-15 14:14:16 +1000693 arg = strdelim(&s);
Damien Miller37023962000-07-11 17:31:38 +1000694 if (!arg || *arg == '\0')
Damien Miller95def091999-11-25 00:26:21 +1100695 fatal("%.200s line %d: Missing argument.", filename, linenum);
Damien Miller37023962000-07-11 17:31:38 +1000696 if (arg[0] == '^' && arg[2] == 0 &&
Ben Lindstrom46c16222000-12-22 01:43:59 +0000697 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
698 value = (u_char) arg[1] & 31;
Damien Miller37023962000-07-11 17:31:38 +1000699 else if (strlen(arg) == 1)
Ben Lindstrom46c16222000-12-22 01:43:59 +0000700 value = (u_char) arg[0];
Damien Miller37023962000-07-11 17:31:38 +1000701 else if (strcmp(arg, "none") == 0)
Ben Lindstrom2b1f71b2001-06-05 20:32:21 +0000702 value = SSH_ESCAPECHAR_NONE;
Damien Miller95def091999-11-25 00:26:21 +1100703 else {
704 fatal("%.200s line %d: Bad escape character.",
Damien Miller9f0f5c62001-12-21 14:45:46 +1100705 filename, linenum);
Damien Miller95def091999-11-25 00:26:21 +1100706 /* NOTREACHED */
707 value = 0; /* Avoid compiler warning. */
708 }
709 if (*activep && *intptr == -1)
710 *intptr = value;
711 break;
712
Damien Miller20a8f972003-05-18 20:50:30 +1000713 case oAddressFamily:
714 arg = strdelim(&s);
Darren Tucker0a4f04b2003-07-03 20:37:47 +1000715 intptr = &options->address_family;
Damien Miller20a8f972003-05-18 20:50:30 +1000716 if (strcasecmp(arg, "inet") == 0)
Darren Tucker0a4f04b2003-07-03 20:37:47 +1000717 value = AF_INET;
Damien Miller20a8f972003-05-18 20:50:30 +1000718 else if (strcasecmp(arg, "inet6") == 0)
Darren Tucker0a4f04b2003-07-03 20:37:47 +1000719 value = AF_INET6;
Damien Miller20a8f972003-05-18 20:50:30 +1000720 else if (strcasecmp(arg, "any") == 0)
Darren Tucker0a4f04b2003-07-03 20:37:47 +1000721 value = AF_UNSPEC;
Damien Miller20a8f972003-05-18 20:50:30 +1000722 else
723 fatal("Unsupported AddressFamily \"%s\"", arg);
Darren Tucker0a4f04b2003-07-03 20:37:47 +1000724 if (*activep && *intptr == -1)
725 *intptr = value;
Damien Miller20a8f972003-05-18 20:50:30 +1000726 break;
727
Ben Lindstromb6df73b2002-11-09 15:52:31 +0000728 case oEnableSSHKeysign:
729 intptr = &options->enable_ssh_keysign;
730 goto parse_flag;
731
Ben Lindstrom4daea862002-06-09 20:04:02 +0000732 case oDeprecated:
Ben Lindstrom2e17b082002-06-09 20:13:27 +0000733 debug("%s line %d: Deprecated option \"%s\"",
Ben Lindstrom4daea862002-06-09 20:04:02 +0000734 filename, linenum, keyword);
Ben Lindstrom2e17b082002-06-09 20:13:27 +0000735 return 0;
Ben Lindstrom4daea862002-06-09 20:04:02 +0000736
Damien Millerf9b3feb2003-05-16 11:38:32 +1000737 case oUnsupported:
738 error("%s line %d: Unsupported option \"%s\"",
739 filename, linenum, keyword);
740 return 0;
741
Damien Miller95def091999-11-25 00:26:21 +1100742 default:
743 fatal("process_config_line: Unimplemented opcode %d", opcode);
744 }
745
746 /* Check that there is no garbage at end of line. */
Ben Lindstrom226cfa02001-01-22 05:34:40 +0000747 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
Damien Miller37023962000-07-11 17:31:38 +1000748 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
Damien Miller9f0f5c62001-12-21 14:45:46 +1100749 filename, linenum, arg);
Damien Miller37023962000-07-11 17:31:38 +1000750 }
Damien Miller95def091999-11-25 00:26:21 +1100751 return 0;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000752}
753
754
Damien Miller5428f641999-11-25 11:54:57 +1100755/*
756 * Reads the config file and modifies the options accordingly. Options
757 * should already be initialized before this call. This never returns if
Ben Lindstromedc0cf22001-09-12 18:32:20 +0000758 * there is an error. If the file does not exist, this returns 0.
Damien Miller5428f641999-11-25 11:54:57 +1100759 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000760
Ben Lindstromedc0cf22001-09-12 18:32:20 +0000761int
Damien Miller95def091999-11-25 00:26:21 +1100762read_config_file(const char *filename, const char *host, Options *options)
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000763{
Damien Miller95def091999-11-25 00:26:21 +1100764 FILE *f;
765 char line[1024];
766 int active, linenum;
767 int bad_options = 0;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000768
Damien Miller95def091999-11-25 00:26:21 +1100769 /* Open the file. */
770 f = fopen(filename, "r");
771 if (!f)
Ben Lindstromedc0cf22001-09-12 18:32:20 +0000772 return 0;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000773
Damien Miller95def091999-11-25 00:26:21 +1100774 debug("Reading configuration data %.200s", filename);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000775
Damien Miller5428f641999-11-25 11:54:57 +1100776 /*
777 * Mark that we are now processing the options. This flag is turned
778 * on/off by Host specifications.
779 */
Damien Miller95def091999-11-25 00:26:21 +1100780 active = 1;
781 linenum = 0;
782 while (fgets(line, sizeof(line), f)) {
783 /* Update line number counter. */
784 linenum++;
785 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
786 bad_options++;
787 }
788 fclose(f);
789 if (bad_options > 0)
Ben Lindstrom6df8ef42001-03-05 07:47:23 +0000790 fatal("%s: terminating, %d bad configuration options",
Damien Miller9f0f5c62001-12-21 14:45:46 +1100791 filename, bad_options);
Ben Lindstromedc0cf22001-09-12 18:32:20 +0000792 return 1;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000793}
794
Damien Miller5428f641999-11-25 11:54:57 +1100795/*
796 * Initializes options to special values that indicate that they have not yet
797 * been set. Read_config_file will only set options with this value. Options
798 * are processed in the following order: command line, user config file,
799 * system config file. Last, fill_default_options is called.
800 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000801
Damien Miller4af51302000-04-16 11:18:38 +1000802void
Damien Miller95def091999-11-25 00:26:21 +1100803initialize_options(Options * options)
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000804{
Damien Miller95def091999-11-25 00:26:21 +1100805 memset(options, 'X', sizeof(*options));
806 options->forward_agent = -1;
807 options->forward_x11 = -1;
Damien Millerd3a18572000-06-07 19:55:44 +1000808 options->xauth_location = NULL;
Damien Miller95def091999-11-25 00:26:21 +1100809 options->gateway_ports = -1;
810 options->use_privileged_port = -1;
Damien Miller95def091999-11-25 00:26:21 +1100811 options->rsa_authentication = -1;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100812 options->pubkey_authentication = -1;
Ben Lindstrom551ea372001-06-05 18:56:16 +0000813 options->challenge_response_authentication = -1;
Damien Miller95def091999-11-25 00:26:21 +1100814 options->kerberos_authentication = -1;
Damien Miller95def091999-11-25 00:26:21 +1100815 options->kerberos_tgt_passing = -1;
Damien Miller95def091999-11-25 00:26:21 +1100816 options->password_authentication = -1;
Damien Miller874d77b2000-10-14 16:23:11 +1100817 options->kbd_interactive_authentication = -1;
818 options->kbd_interactive_devices = NULL;
Damien Miller95def091999-11-25 00:26:21 +1100819 options->rhosts_rsa_authentication = -1;
Ben Lindstrom5eabda32001-04-12 23:34:34 +0000820 options->hostbased_authentication = -1;
Damien Miller95def091999-11-25 00:26:21 +1100821 options->batch_mode = -1;
822 options->check_host_ip = -1;
823 options->strict_host_key_checking = -1;
824 options->compression = -1;
825 options->keepalives = -1;
826 options->compression_level = -1;
827 options->port = -1;
Darren Tucker0a4f04b2003-07-03 20:37:47 +1000828 options->address_family = -1;
Damien Miller95def091999-11-25 00:26:21 +1100829 options->connection_attempts = -1;
Damien Millerb78d5eb2003-05-16 11:39:04 +1000830 options->connection_timeout = -1;
Damien Miller95def091999-11-25 00:26:21 +1100831 options->number_of_password_prompts = -1;
832 options->cipher = -1;
Damien Miller78928792000-04-12 20:17:38 +1000833 options->ciphers = NULL;
Ben Lindstrom06b33aa2001-02-15 03:01:59 +0000834 options->macs = NULL;
Ben Lindstrom982dbbc2001-04-17 18:11:36 +0000835 options->hostkeyalgorithms = NULL;
Damien Miller78928792000-04-12 20:17:38 +1000836 options->protocol = SSH_PROTO_UNKNOWN;
Damien Miller95def091999-11-25 00:26:21 +1100837 options->num_identity_files = 0;
838 options->hostname = NULL;
Ben Lindstrom4dccfa52000-12-28 16:40:05 +0000839 options->host_key_alias = NULL;
Damien Miller95def091999-11-25 00:26:21 +1100840 options->proxy_command = NULL;
841 options->user = NULL;
842 options->escape_char = -1;
843 options->system_hostfile = NULL;
844 options->user_hostfile = NULL;
Damien Millereba71ba2000-04-29 23:57:08 +1000845 options->system_hostfile2 = NULL;
846 options->user_hostfile2 = NULL;
Damien Miller95def091999-11-25 00:26:21 +1100847 options->num_local_forwards = 0;
848 options->num_remote_forwards = 0;
Ben Lindstrom2b7a0e92001-09-20 00:57:55 +0000849 options->clear_forwardings = -1;
Damien Millerfcd93202002-02-05 12:26:34 +1100850 options->log_level = SYSLOG_LEVEL_NOT_SET;
Ben Lindstromb9be60a2001-03-11 01:49:19 +0000851 options->preferred_authentications = NULL;
Ben Lindstrome0f88042001-04-30 13:06:24 +0000852 options->bind_address = NULL;
Ben Lindstromf7db3bb2001-08-06 21:35:51 +0000853 options->smartcard_device = NULL;
Ben Lindstromb6df73b2002-11-09 15:52:31 +0000854 options->enable_ssh_keysign = - 1;
Ben Lindstrom3cecc9a2001-10-03 17:39:38 +0000855 options->no_host_authentication_for_localhost = - 1;
Damien Millera5539d22003-04-09 20:50:06 +1000856 options->rekey_limit = - 1;
Damien Miller37876e92003-05-15 10:19:46 +1000857 options->verify_host_key_dns = -1;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000858}
859
Damien Miller5428f641999-11-25 11:54:57 +1100860/*
861 * Called after processing other sources of option data, this fills those
862 * options for which no value has been specified with their default values.
863 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000864
Damien Miller4af51302000-04-16 11:18:38 +1000865void
Damien Miller95def091999-11-25 00:26:21 +1100866fill_default_options(Options * options)
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000867{
Ben Lindstrom4f7a64a2001-02-10 22:50:09 +0000868 int len;
869
Damien Miller95def091999-11-25 00:26:21 +1100870 if (options->forward_agent == -1)
Damien Millerb1715dc2000-05-30 13:44:51 +1000871 options->forward_agent = 0;
Damien Miller95def091999-11-25 00:26:21 +1100872 if (options->forward_x11 == -1)
Damien Miller98c7ad62000-03-09 21:27:49 +1100873 options->forward_x11 = 0;
Damien Millerd3a18572000-06-07 19:55:44 +1000874 if (options->xauth_location == NULL)
Ben Lindstrom1bf11f62001-06-09 01:48:01 +0000875 options->xauth_location = _PATH_XAUTH;
Damien Miller95def091999-11-25 00:26:21 +1100876 if (options->gateway_ports == -1)
877 options->gateway_ports = 0;
878 if (options->use_privileged_port == -1)
Ben Lindstromcebc8582001-03-08 03:39:10 +0000879 options->use_privileged_port = 0;
Damien Miller95def091999-11-25 00:26:21 +1100880 if (options->rsa_authentication == -1)
881 options->rsa_authentication = 1;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100882 if (options->pubkey_authentication == -1)
883 options->pubkey_authentication = 1;
Ben Lindstrom551ea372001-06-05 18:56:16 +0000884 if (options->challenge_response_authentication == -1)
Ben Lindstrom0076d752001-08-06 20:53:26 +0000885 options->challenge_response_authentication = 1;
Damien Miller95def091999-11-25 00:26:21 +1100886 if (options->kerberos_authentication == -1)
887 options->kerberos_authentication = 1;
Damien Miller95def091999-11-25 00:26:21 +1100888 if (options->kerberos_tgt_passing == -1)
889 options->kerberos_tgt_passing = 1;
Damien Miller95def091999-11-25 00:26:21 +1100890 if (options->password_authentication == -1)
891 options->password_authentication = 1;
Damien Miller874d77b2000-10-14 16:23:11 +1100892 if (options->kbd_interactive_authentication == -1)
Ben Lindstrom95fb2dd2001-01-23 03:12:10 +0000893 options->kbd_interactive_authentication = 1;
Damien Miller95def091999-11-25 00:26:21 +1100894 if (options->rhosts_rsa_authentication == -1)
Ben Lindstrom2bf82762002-06-11 15:53:05 +0000895 options->rhosts_rsa_authentication = 0;
Ben Lindstrom5eabda32001-04-12 23:34:34 +0000896 if (options->hostbased_authentication == -1)
897 options->hostbased_authentication = 0;
Damien Miller95def091999-11-25 00:26:21 +1100898 if (options->batch_mode == -1)
899 options->batch_mode = 0;
900 if (options->check_host_ip == -1)
901 options->check_host_ip = 1;
902 if (options->strict_host_key_checking == -1)
903 options->strict_host_key_checking = 2; /* 2 is default */
904 if (options->compression == -1)
905 options->compression = 0;
906 if (options->keepalives == -1)
907 options->keepalives = 1;
908 if (options->compression_level == -1)
909 options->compression_level = 6;
910 if (options->port == -1)
911 options->port = 0; /* Filled in ssh_connect. */
Darren Tucker0a4f04b2003-07-03 20:37:47 +1000912 if (options->address_family == -1)
913 options->address_family = AF_UNSPEC;
Damien Miller95def091999-11-25 00:26:21 +1100914 if (options->connection_attempts == -1)
Ben Lindstromf9cedb92001-08-06 21:07:11 +0000915 options->connection_attempts = 1;
Damien Miller95def091999-11-25 00:26:21 +1100916 if (options->number_of_password_prompts == -1)
917 options->number_of_password_prompts = 3;
918 /* Selected in ssh_login(). */
919 if (options->cipher == -1)
920 options->cipher = SSH_CIPHER_NOT_SET;
Damien Miller30c3d422000-05-09 11:02:59 +1000921 /* options->ciphers, default set in myproposals.h */
Ben Lindstrom06b33aa2001-02-15 03:01:59 +0000922 /* options->macs, default set in myproposals.h */
Ben Lindstrom982dbbc2001-04-17 18:11:36 +0000923 /* options->hostkeyalgorithms, default set in myproposals.h */
Damien Miller78928792000-04-12 20:17:38 +1000924 if (options->protocol == SSH_PROTO_UNKNOWN)
Ben Lindstrom6b776432001-03-22 01:24:04 +0000925 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
Damien Miller95def091999-11-25 00:26:21 +1100926 if (options->num_identity_files == 0) {
Damien Miller0bc1bd82000-11-13 22:57:25 +1100927 if (options->protocol & SSH_PROTO_1) {
Ben Lindstrom4f7a64a2001-02-10 22:50:09 +0000928 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100929 options->identity_files[options->num_identity_files] =
Ben Lindstrom4f7a64a2001-02-10 22:50:09 +0000930 xmalloc(len);
931 snprintf(options->identity_files[options->num_identity_files++],
932 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
Damien Miller0bc1bd82000-11-13 22:57:25 +1100933 }
934 if (options->protocol & SSH_PROTO_2) {
Ben Lindstromb00d4fb2001-03-05 06:03:03 +0000935 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
936 options->identity_files[options->num_identity_files] =
937 xmalloc(len);
938 snprintf(options->identity_files[options->num_identity_files++],
939 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
940
Ben Lindstrom4f7a64a2001-02-10 22:50:09 +0000941 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
Damien Miller0bc1bd82000-11-13 22:57:25 +1100942 options->identity_files[options->num_identity_files] =
Ben Lindstrom4f7a64a2001-02-10 22:50:09 +0000943 xmalloc(len);
944 snprintf(options->identity_files[options->num_identity_files++],
945 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
Damien Miller0bc1bd82000-11-13 22:57:25 +1100946 }
Damien Millereba71ba2000-04-29 23:57:08 +1000947 }
Damien Miller95def091999-11-25 00:26:21 +1100948 if (options->escape_char == -1)
949 options->escape_char = '~';
950 if (options->system_hostfile == NULL)
Ben Lindstrom226cfa02001-01-22 05:34:40 +0000951 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
Damien Miller95def091999-11-25 00:26:21 +1100952 if (options->user_hostfile == NULL)
Ben Lindstrom226cfa02001-01-22 05:34:40 +0000953 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
Damien Millereba71ba2000-04-29 23:57:08 +1000954 if (options->system_hostfile2 == NULL)
Ben Lindstrom226cfa02001-01-22 05:34:40 +0000955 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
Damien Millereba71ba2000-04-29 23:57:08 +1000956 if (options->user_hostfile2 == NULL)
Ben Lindstrom226cfa02001-01-22 05:34:40 +0000957 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
Damien Millerfcd93202002-02-05 12:26:34 +1100958 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
Ben Lindstromdb65e8f2001-01-19 04:26:52 +0000959 options->log_level = SYSLOG_LEVEL_INFO;
Ben Lindstrom2b7a0e92001-09-20 00:57:55 +0000960 if (options->clear_forwardings == 1)
961 clear_forwardings(options);
Ben Lindstrom3cecc9a2001-10-03 17:39:38 +0000962 if (options->no_host_authentication_for_localhost == - 1)
963 options->no_host_authentication_for_localhost = 0;
Ben Lindstromb6df73b2002-11-09 15:52:31 +0000964 if (options->enable_ssh_keysign == -1)
965 options->enable_ssh_keysign = 0;
Damien Millera5539d22003-04-09 20:50:06 +1000966 if (options->rekey_limit == -1)
967 options->rekey_limit = 0;
Damien Miller37876e92003-05-15 10:19:46 +1000968 if (options->verify_host_key_dns == -1)
969 options->verify_host_key_dns = 0;
Damien Miller95def091999-11-25 00:26:21 +1100970 /* options->proxy_command should not be set by default */
971 /* options->user will be set in the main program if appropriate */
972 /* options->hostname will be set in the main program if appropriate */
Ben Lindstrom4dccfa52000-12-28 16:40:05 +0000973 /* options->host_key_alias should not be set by default */
Ben Lindstromb9be60a2001-03-11 01:49:19 +0000974 /* options->preferred_authentications will be set in ssh */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000975}