config.c 232 KB
Newer Older
Roger Dingledine's avatar
Roger Dingledine committed
1
2
/* Copyright (c) 2001 Matej Pfajfar.
 * Copyright (c) 2001-2004, Roger Dingledine.
3
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4
 * Copyright (c) 2007-2011, The Tor Project, Inc. */
5
/* See LICENSE for licensing information */
6

Nick Mathewson's avatar
Nick Mathewson committed
7
/**
8
9
 * \file config.c
 * \brief Code to parse and interpret configuration files.
Nick Mathewson's avatar
Nick Mathewson committed
10
11
 **/

12
13
#define CONFIG_PRIVATE

Roger Dingledine's avatar
Roger Dingledine committed
14
#include "or.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
15
#include "circuitbuild.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
16
#include "circuitlist.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
17
#include "config.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
18
#include "connection.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
19
#include "connection_edge.h"
20
#include "connection_or.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
21
#include "control.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
22
#include "cpuworker.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
23
#include "dirserv.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
24
#include "dirvote.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
25
#include "dns.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
26
#include "geoip.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
27
#include "hibernate.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
28
#include "main.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
29
#include "networkstatus.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
30
#include "policies.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
31
#include "relay.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
32
#include "rendclient.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
33
#include "rendservice.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
34
#include "rephist.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
35
#include "router.h"
36
#include "util.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
37
#include "routerlist.h"
38
#include "transports.h"
39
40
41
#ifdef MS_WINDOWS
#include <shlobj.h>
#endif
Roger Dingledine's avatar
Roger Dingledine committed
42

43
44
45
46
47
#include "procmon.h"

/* From main.c */
extern int quiet_level;

Nick Mathewson's avatar
Nick Mathewson committed
48
49
/** Enumeration of types which option values can take */
typedef enum config_type_t {
50
  CONFIG_TYPE_STRING = 0,   /**< An arbitrary string. */
51
  CONFIG_TYPE_FILENAME,     /**< A filename: some prefixes get expanded. */
52
  CONFIG_TYPE_UINT,         /**< A non-negative integer less than MAX_INT */
53
54
  CONFIG_TYPE_PORT,         /**< A port from 1...65535, 0 for "not set", or
                             * "auto".  */
55
  CONFIG_TYPE_INTERVAL,     /**< A number of seconds, with optional units*/
56
57
  CONFIG_TYPE_MSEC_INTERVAL,/**< A number of milliseconds, with optional
                              * units */
58
  CONFIG_TYPE_MEMUNIT,      /**< A number of bytes, with optional units*/
59
60
  CONFIG_TYPE_DOUBLE,       /**< A floating-point value */
  CONFIG_TYPE_BOOL,         /**< A boolean value, expressed as 0 or 1. */
61
62
  CONFIG_TYPE_AUTOBOOL,     /**< A boolean+auto value, expressed 0 for false,
                             * 1 for true, and -1 for auto  */
Nick Mathewson's avatar
Nick Mathewson committed
63
  CONFIG_TYPE_ISOTIME,      /**< An ISO-formatted time relative to GMT. */
64
65
  CONFIG_TYPE_CSV,          /**< A list of strings, separated by commas and
                              * optional whitespace. */
66
  CONFIG_TYPE_LINELIST,     /**< Uninterpreted config lines */
67
68
69
70
71
  CONFIG_TYPE_LINELIST_S,   /**< Uninterpreted, context-sensitive config lines,
                             * mixed with other keywords. */
  CONFIG_TYPE_LINELIST_V,   /**< Catch-all "virtual" option to summarize
                             * context-sensitive config lines when fetching.
                             */
72
73
  CONFIG_TYPE_ROUTERSET,    /**< A list of router names, addrs, and fps,
                             * parsed into a routerset_t. */
74
  CONFIG_TYPE_OBSOLETE,     /**< Obsolete (ignored) option. */
Nick Mathewson's avatar
Nick Mathewson committed
75
} config_type_t;
76

77
/** An abbreviation for a configuration option allowed on the command line. */
78
typedef struct config_abbrev_t {
79
80
  const char *abbreviated;
  const char *full;
81
  int commandline_only;
82
  int warn;
83
84
} config_abbrev_t;

85
86
/* Handy macro for declaring "In the config file or on the command line,
 * you can abbreviate <b>tok</b>s as <b>tok</b>". */
87
#define PLURAL(tok) { #tok, #tok "s", 0, 0 }
88

89
90
/** A list of abbreviations and aliases to map command-line options, obsolete
 * option names, or alternative option names, to their current values. */
91
static config_abbrev_t _option_abbrevs[] = {
92
  PLURAL(ExitNode),
93
  PLURAL(EntryNode),
94
95
  PLURAL(ExcludeNode),
  PLURAL(FirewallPort),
96
  PLURAL(LongLivedPort),
97
98
  PLURAL(HiddenServiceNode),
  PLURAL(HiddenServiceExcludeNode),
99
  PLURAL(NumCPU),
100
101
  PLURAL(RendNode),
  PLURAL(RendExcludeNode),
102
103
  PLURAL(StrictEntryNode),
  PLURAL(StrictExitNode),
104
  PLURAL(StrictNode),
105
  { "l", "Log", 1, 0},
106
  { "AllowUnverifiedNodes", "AllowInvalidNodes", 0, 0},
107
108
  { "AutomapHostSuffixes", "AutomapHostsSuffixes", 0, 0},
  { "AutomapHostOnResolve", "AutomapHostsOnResolve", 0, 0},
109
110
111
112
  { "BandwidthRateBytes", "BandwidthRate", 0, 0},
  { "BandwidthBurstBytes", "BandwidthBurst", 0, 0},
  { "DirFetchPostPeriod", "StatusFetchPeriod", 0, 0},
  { "MaxConn", "ConnLimit", 0, 1},
113
114
115
  { "ORBindAddress", "ORListenAddress", 0, 0},
  { "DirBindAddress", "DirListenAddress", 0, 0},
  { "SocksBindAddress", "SocksListenAddress", 0, 0},
116
117
118
119
  { "UseHelperNodes", "UseEntryGuards", 0, 0},
  { "NumHelperNodes", "NumEntryGuards", 0, 0},
  { "UseEntryNodes", "UseEntryGuards", 0, 0},
  { "NumEntryNodes", "NumEntryGuards", 0, 0},
120
121
  { "ResolvConf", "ServerDNSResolvConfFile", 0, 1},
  { "SearchDomains", "ServerDNSSearchDomains", 0, 1},
122
  { "ServerDNSAllowBrokenResolvConf", "ServerDNSAllowBrokenConfig", 0, 0},
123
  { "PreferTunnelledDirConns", "PreferTunneledDirConns", 0, 0},
124
  { "BridgeAuthoritativeDirectory", "BridgeAuthoritativeDir", 0, 0},
125
  { "HashedControlPassword", "__HashedControlSessionPassword", 1, 0},
126
127
  { "StrictEntryNodes", "StrictNodes", 0, 1},
  { "StrictExitNodes", "StrictNodes", 0, 1},
128
129
  { NULL, NULL, 0, 0},
};
130
131

/** A list of state-file "abbreviations," for compatibility. */
132
static config_abbrev_t _state_abbrevs[] = {
133
  { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
134
135
136
137
138
139
  { "HelperNode", "EntryGuard", 0, 0 },
  { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
  { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
  { "EntryNode", "EntryGuard", 0, 0 },
  { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
  { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
140
  { NULL, NULL, 0, 0},
141
};
142
#undef PLURAL
143

144
/** A variable allowed in the configuration file or on the command line. */
145
typedef struct config_var_t {
146
  const char *name; /**< The full keyword (case insensitive). */
147
148
  config_type_t type; /**< How to interpret the type and turn it into a
                       * value. */
149
150
  off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
  const char *initvalue; /**< String (or null) describing initial value. */
151
152
} config_var_t;

Nick Mathewson's avatar
Nick Mathewson committed
153
154
155
156
/** An entry for config_vars: "The option <b>name</b> has type
 * CONFIG_TYPE_<b>conftype</b>, and corresponds to
 * or_options_t.<b>member</b>"
 */
157
158
#define VAR(name,conftype,member,initvalue)                             \
  { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), \
159
      initvalue }
160
161
162
/** As VAR, but the option name and member name are the same. */
#define V(member,conftype,initvalue)                                    \
  VAR(#member, conftype, member, initvalue)
Nick Mathewson's avatar
Nick Mathewson committed
163
/** An entry for config_vars: "The option <b>name</b> is obsolete." */
164
#define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
165

Nick Mathewson's avatar
Nick Mathewson committed
166
167
168
169
/** Array of configuration options.  Until we disallow nonstandard
 * abbreviations, order is significant, since the first matching option will
 * be chosen first.
 */
170
static config_var_t _option_vars[] = {
171
  OBSOLETE("AccountingMaxKB"),
172
173
174
  V(AccountingMax,               MEMUNIT,  "0 bytes"),
  V(AccountingStart,             STRING,   NULL),
  V(Address,                     STRING,   NULL),
175
  V(AllowDotExit,                BOOL,     "0"),
176
177
  V(AllowInvalidNodes,           CSV,      "middle,rendezvous"),
  V(AllowNonRFC953Hostnames,     BOOL,     "0"),
178
179
  V(AllowSingleHopCircuits,      BOOL,     "0"),
  V(AllowSingleHopExits,         BOOL,     "0"),
180
181
182
  V(AlternateBridgeAuthority,    LINELIST, NULL),
  V(AlternateDirAuthority,       LINELIST, NULL),
  V(AlternateHSAuthority,        LINELIST, NULL),
183
  V(AssumeReachable,             BOOL,     "0"),
184
  V(AuthDirBadDir,               LINELIST, NULL),
185
186
  V(AuthDirBadExit,              LINELIST, NULL),
  V(AuthDirInvalid,              LINELIST, NULL),
187
  V(AuthDirFastGuarantee,        MEMUNIT,  "100 KB"),
188
  V(AuthDirGuardBWGuarantee,     MEMUNIT,  "250 KB"),
189
190
  V(AuthDirReject,               LINELIST, NULL),
  V(AuthDirRejectUnlisted,       BOOL,     "0"),
191
  V(AuthDirListBadDirs,          BOOL,     "0"),
192
  V(AuthDirListBadExits,         BOOL,     "0"),
193
194
  V(AuthDirMaxServersPerAddr,    UINT,     "2"),
  V(AuthDirMaxServersPerAuthAddr,UINT,     "5"),
195
196
197
198
  VAR("AuthoritativeDirectory",  BOOL, AuthoritativeDir,    "0"),
  V(AutomapHostsOnResolve,       BOOL,     "0"),
  V(AutomapHostsSuffixes,        CSV,      ".onion,.exit"),
  V(AvoidDiskWrites,             BOOL,     "0"),
199
200
  V(BandwidthBurst,              MEMUNIT,  "10 MB"),
  V(BandwidthRate,               MEMUNIT,  "5 MB"),
201
202
  V(BridgeAuthoritativeDir,      BOOL,     "0"),
  VAR("Bridge",                  LINELIST, Bridges,    NULL),
203
  V(BridgePassword,              STRING,   NULL),
204
  V(BridgeRecordUsageByCountry,  BOOL,     "1"),
205
  V(BridgeRelay,                 BOOL,     "0"),
206
  V(CellStatistics,              BOOL,     "0"),
207
  V(LearnCircuitBuildTimeout,    BOOL,     "1"),
208
  V(CircuitBuildTimeout,         INTERVAL, "0"),
209
  V(CircuitIdleTimeout,          INTERVAL, "1 hour"),
210
  V(CircuitStreamTimeout,        INTERVAL, "0"),
211
  V(CircuitPriorityHalflife,     DOUBLE,  "-100.0"), /*negative:'Use default'*/
212
213
  V(ClientDNSRejectInternalAddresses, BOOL,"1"),
  V(ClientOnly,                  BOOL,     "0"),
214
  V(ClientRejectInternalAddresses, BOOL,   "1"),
215
  V(ClientTransportPlugin,       LINELIST, NULL),
216
  V(ConsensusParams,             STRING,   NULL),
217
  V(ConnLimit,                   UINT,     "1000"),
218
  V(ConnDirectionStatistics,     BOOL,     "0"),
219
220
221
222
  V(ConstrainedSockets,          BOOL,     "0"),
  V(ConstrainedSockSize,         MEMUNIT,  "8192"),
  V(ContactInfo,                 STRING,   NULL),
  V(ControlListenAddress,        LINELIST, NULL),
223
  V(ControlPort,                 LINELIST, NULL),
224
  V(ControlPortFileGroupReadable,BOOL,     "0"),
225
  V(ControlPortWriteToFile,      FILENAME, NULL),
226
  V(ControlSocket,               LINELIST, NULL),
227
  V(ControlSocketsGroupWritable, BOOL,     "0"),
228
229
230
  V(CookieAuthentication,        BOOL,     "0"),
  V(CookieAuthFileGroupReadable, BOOL,     "0"),
  V(CookieAuthFile,              STRING,   NULL),
231
  V(CountPrivateBandwidth,       BOOL,     "0"),
232
  V(DataDirectory,               FILENAME, NULL),
233
  OBSOLETE("DebugLogFile"),
234
  V(DisableNetwork,              BOOL,     "0"),
235
  V(DirAllowPrivateAddresses,    BOOL,     NULL),
236
  V(TestingAuthDirTimeToLearnReachability, INTERVAL, "30 minutes"),
237
  V(DirListenAddress,            LINELIST, NULL),
238
  OBSOLETE("DirFetchPeriod"),
239
  V(DirPolicy,                   LINELIST, NULL),
240
  V(DirPort,                     LINELIST, NULL),
241
  V(DirPortFrontPage,            FILENAME, NULL),
242
  OBSOLETE("DirPostPeriod"),
243
244
245
246
  OBSOLETE("DirRecordUsageByCountry"),
  OBSOLETE("DirRecordUsageGranularity"),
  OBSOLETE("DirRecordUsageRetainIPs"),
  OBSOLETE("DirRecordUsageSaveInterval"),
247
  V(DirReqStatistics,            BOOL,     "1"),
248
  VAR("DirServer",               LINELIST, DirServers, NULL),
249
  V(DisableAllSwap,              BOOL,     "0"),
250
  V(DisableDebuggerAttachment,   BOOL,     "1"),
251
  V(DisableIOCP,                 BOOL,     "1"),
252
  V(DynamicDHGroups,             BOOL,     "1"),
253
  V(DNSPort,                     LINELIST, NULL),
254
255
256
  V(DNSListenAddress,            LINELIST, NULL),
  V(DownloadExtraInfo,           BOOL,     "0"),
  V(EnforceDistinctSubnets,      BOOL,     "1"),
257
  V(EntryNodes,                  ROUTERSET,   NULL),
258
  V(EntryStatistics,             BOOL,     "0"),
259
  V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "10 minutes"),
260
261
  V(ExcludeNodes,                ROUTERSET, NULL),
  V(ExcludeExitNodes,            ROUTERSET, NULL),
262
  V(ExcludeSingleHopRelays,      BOOL,     "1"),
263
  V(ExitNodes,                   ROUTERSET, NULL),
264
265
  V(ExitPolicy,                  LINELIST, NULL),
  V(ExitPolicyRejectPrivate,     BOOL,     "1"),
266
  V(ExitPortStatistics,          BOOL,     "0"),
267
  V(ExtraInfoStatistics,         BOOL,     "1"),
268

valerino's avatar
valerino committed
269
270
271
#if defined (WINCE)
  V(FallbackNetworkstatusFile,   FILENAME, "fallback-consensus"),
#else
272
  V(FallbackNetworkstatusFile,   FILENAME,
273
    SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "fallback-consensus"),
valerino's avatar
valerino committed
274
#endif
275
276
277
  V(FascistFirewall,             BOOL,     "0"),
  V(FirewallPorts,               CSV,      ""),
  V(FastFirstHopPK,              BOOL,     "1"),
278
  V(FetchDirInfoEarly,           BOOL,     "0"),
279
  V(FetchDirInfoExtraEarly,      BOOL,     "0"),
280
281
282
  V(FetchServerDescriptors,      BOOL,     "1"),
  V(FetchHidServDescriptors,     BOOL,     "1"),
  V(FetchUselessDescriptors,     BOOL,     "0"),
283
  V(FetchV2Networkstatus,        BOOL,     "0"),
284
#ifdef WIN32
285
  V(GeoIPFile,                   FILENAME, "<default>"),
286
#else
287
288
  V(GeoIPFile,                   FILENAME,
    SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "geoip"),
289
#endif
290
291
  V(GiveGuardFlagTo_CVE_2011_2768_VulnerableRelays,
                                 BOOL,     "0"),
292
  OBSOLETE("Group"),
293
  V(HardwareAccel,               BOOL,     "0"),
294
  V(HeartbeatPeriod,             INTERVAL, "6 hours"),
295
296
  V(AccelName,                   STRING,   NULL),
  V(AccelDir,                    FILENAME, NULL),
297
  V(HashedControlPassword,       LINELIST, NULL),
298
  V(HidServDirectoryV2,          BOOL,     "1"),
Nick Mathewson's avatar
Nick Mathewson committed
299
  VAR("HiddenServiceDir",    LINELIST_S, RendConfigLines,    NULL),
300
301
  OBSOLETE("HiddenServiceExcludeNodes"),
  OBSOLETE("HiddenServiceNodes"),
Nick Mathewson's avatar
Nick Mathewson committed
302
303
  VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines,    NULL),
  VAR("HiddenServicePort",   LINELIST_S, RendConfigLines,    NULL),
304
  VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines,    NULL),
305
  VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL),
306
  V(HidServAuth,                 LINELIST, NULL),
307
  V(HSAuthoritativeDir,          BOOL,     "0"),
308
  OBSOLETE("HSAuthorityRecordStats"),
309
310
311
312
  V(HTTPProxy,                   STRING,   NULL),
  V(HTTPProxyAuthenticator,      STRING,   NULL),
  V(HTTPSProxy,                  STRING,   NULL),
  V(HTTPSProxyAuthenticator,     STRING,   NULL),
313
  VAR("ServerTransportPlugin",   LINELIST, ServerTransportPlugin,  NULL),
314
315
316
317
  V(Socks4Proxy,                 STRING,   NULL),
  V(Socks5Proxy,                 STRING,   NULL),
  V(Socks5ProxyUsername,         STRING,   NULL),
  V(Socks5ProxyPassword,         STRING,   NULL),
318
  OBSOLETE("IgnoreVersion"),
319
320
  V(KeepalivePeriod,             INTERVAL, "5 minutes"),
  VAR("Log",                     LINELIST, Logs,             NULL),
321
  V(LogMessageDomains,           BOOL,     "0"),
322
  OBSOLETE("LinkPadding"),
323
324
  OBSOLETE("LogLevel"),
  OBSOLETE("LogFile"),
325
  V(LogTimeGranularity,          MSEC_INTERVAL, "1 second"),
326
  V(LongLivedPorts,              CSV,
Nick Mathewson's avatar
Nick Mathewson committed
327
        "21,22,706,1863,5050,5190,5222,5223,6523,6667,6697,8300"),
328
329
330
  VAR("MapAddress",              LINELIST, AddressMap,           NULL),
  V(MaxAdvertisedBandwidth,      MEMUNIT,  "1 GB"),
  V(MaxCircuitDirtiness,         INTERVAL, "10 minutes"),
331
  V(MaxClientCircuitsPending,    UINT,     "32"),
332
  V(MaxOnionsPending,            UINT,     "100"),
333
  OBSOLETE("MonthlyAccountingStart"),
334
335
  V(MyFamily,                    STRING,   NULL),
  V(NewCircuitPeriod,            INTERVAL, "30 seconds"),
336
  VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "0"),
337
  V(NATDListenAddress,           LINELIST, NULL),
338
  V(NATDPort,                    LINELIST, NULL),
339
  V(Nickname,                    STRING,   NULL),
340
  V(WarnUnsafeSocks,              BOOL,     "1"),
Sebastian Hahn's avatar
Sebastian Hahn committed
341
  OBSOLETE("NoPublish"),
342
  VAR("NodeFamily",              LINELIST, NodeFamilies,         NULL),
343
  V(NumCPUs,                     UINT,     "0"),
344
345
  V(NumEntryGuards,              UINT,     "3"),
  V(ORListenAddress,             LINELIST, NULL),
346
  V(ORPort,                      LINELIST, NULL),
347
  V(OutboundBindAddress,         STRING,   NULL),
348
  OBSOLETE("PathlenCoinWeight"),
349
350
  V(PerConnBWBurst,              MEMUNIT,  "0"),
  V(PerConnBWRate,               MEMUNIT,  "0"),
351
  V(PidFile,                     STRING,   NULL),
352
  V(TestingTorNetwork,           BOOL,     "0"),
353
  V(OptimisticData,              AUTOBOOL, "auto"),
354
355
  V(PortForwarding,              BOOL,     "0"),
  V(PortForwardingHelper,        FILENAME, "tor-fw-helper"),
Roger Dingledine's avatar
Roger Dingledine committed
356
  V(PreferTunneledDirConns,      BOOL,     "1"),
357
  V(ProtocolWarnings,            BOOL,     "0"),
358
  V(PublishServerDescriptor,     CSV,      "1"),
359
360
361
362
363
364
365
  V(PublishHidServDescriptors,   BOOL,     "1"),
  V(ReachableAddresses,          LINELIST, NULL),
  V(ReachableDirAddresses,       LINELIST, NULL),
  V(ReachableORAddresses,        LINELIST, NULL),
  V(RecommendedVersions,         LINELIST, NULL),
  V(RecommendedClientVersions,   LINELIST, NULL),
  V(RecommendedServerVersions,   LINELIST, NULL),
366
  OBSOLETE("RedirectExit"),
367
  V(RefuseUnknownExits,          AUTOBOOL, "auto"),
368
  V(RejectPlaintextPorts,        CSV,      ""),
369
370
  V(RelayBandwidthBurst,         MEMUNIT,  "0"),
  V(RelayBandwidthRate,          MEMUNIT,  "0"),
371
372
  OBSOLETE("RendExcludeNodes"),
  OBSOLETE("RendNodes"),
373
374
  V(RendPostPeriod,              INTERVAL, "1 hour"),
  V(RephistTrackTime,            INTERVAL, "24 hours"),
375
  OBSOLETE("RouterFile"),
376
  V(RunAsDaemon,                 BOOL,     "0"),
377
378
//  V(RunTesting,                  BOOL,     "0"),
  OBSOLETE("RunTesting"), // currently unused
379
  V(SafeLogging,                 STRING,   "1"),
380
  V(SafeSocks,                   BOOL,     "0"),
381
  V(ServerDNSAllowBrokenConfig,  BOOL,     "1"),
382
383
  V(ServerDNSAllowNonRFC953Hostnames, BOOL,"0"),
  V(ServerDNSDetectHijacking,    BOOL,     "1"),
384
  V(ServerDNSRandomizeCase,      BOOL,     "1"),
385
386
387
  V(ServerDNSResolvConfFile,     STRING,   NULL),
  V(ServerDNSSearchDomains,      BOOL,     "0"),
  V(ServerDNSTestAddresses,      CSV,
388
      "www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"),
389
390
391
  V(ShutdownWaitLength,          INTERVAL, "30 seconds"),
  V(SocksListenAddress,          LINELIST, NULL),
  V(SocksPolicy,                 LINELIST, NULL),
392
  V(SocksPort,                   LINELIST, NULL),
393
  V(SocksTimeout,                INTERVAL, "2 minutes"),
394
  OBSOLETE("StatusFetchPeriod"),
395
  V(StrictNodes,                 BOOL,     "0"),
396
  OBSOLETE("SysLog"),
397
  V(TestSocks,                   BOOL,     "0"),
398
  OBSOLETE("TestVia"),
399
  V(TokenBucketRefillInterval,   MSEC_INTERVAL, "100 msec"),
400
  V(Tor2webMode,                 BOOL,     "0"),
401
402
  V(TrackHostExits,              CSV,      NULL),
  V(TrackHostExitsExpire,        INTERVAL, "30 minutes"),
403
  OBSOLETE("TrafficShaping"),
404
  V(TransListenAddress,          LINELIST, NULL),
405
  V(TransPort,                   LINELIST, NULL),
Roger Dingledine's avatar
Roger Dingledine committed
406
  V(TunnelDirConns,              BOOL,     "1"),
407
  V(UpdateBridgesFromAuthority,  BOOL,     "0"),
408
  V(UseBridges,                  BOOL,     "0"),
409
  V(UseEntryGuards,              BOOL,     "1"),
410
  V(UseMicrodescriptors,         AUTOBOOL, "auto"),
411
  V(User,                        STRING,   NULL),
412
  V(UserspaceIOCPBuffers,        BOOL,     "0"),
413
  VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir,   "0"),
414
  VAR("V2AuthoritativeDirectory",BOOL, V2AuthoritativeDir,   "0"),
415
  VAR("V3AuthoritativeDirectory",BOOL, V3AuthoritativeDir,   "0"),
416
417
418
  V(TestingV3AuthInitialVotingInterval, INTERVAL, "30 minutes"),
  V(TestingV3AuthInitialVoteDelay, INTERVAL, "5 minutes"),
  V(TestingV3AuthInitialDistDelay, INTERVAL, "5 minutes"),
419
420
421
422
  V(V3AuthVotingInterval,        INTERVAL, "1 hour"),
  V(V3AuthVoteDelay,             INTERVAL, "5 minutes"),
  V(V3AuthDistDelay,             INTERVAL, "5 minutes"),
  V(V3AuthNIntervalsValid,       UINT,     "3"),
423
  V(V3AuthUseLegacyKey,          BOOL,     "0"),
424
  V(V3BandwidthsFile,            FILENAME, NULL),
425
  VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
426
  V(VirtualAddrNetwork,          STRING,   "127.192.0.0/10"),
427
  V(WarnPlaintextPorts,          CSV,      "23,109,110,143"),
428
  V(_UseFilteringSSLBufferevents, BOOL,    "0"),
429
  VAR("__ReloadTorrcOnSIGHUP",   BOOL,  ReloadTorrcOnSIGHUP,      "1"),
430
431
432
  VAR("__AllDirActionsPrivate",  BOOL,  AllDirActionsPrivate,     "0"),
  VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits, "0"),
  VAR("__LeaveStreamsUnattached",BOOL,  LeaveStreamsUnattached,   "0"),
433
434
  VAR("__HashedControlSessionPassword", LINELIST, HashedControlSessionPassword,
      NULL),
435
  VAR("__OwningControllerProcess",STRING,OwningControllerProcess, NULL),
436
  V(MinUptimeHidServDirectoryV2, INTERVAL, "25 hours"),
437
  V(VoteOnHidServDirectoriesV2,  BOOL,     "1"),
438
  V(_UsingTestNetworkDefaults,   BOOL,     "0"),
439

440
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
441
};
442

443
444
/** Override default values with these if the user sets the TestingTorNetwork
 * option. */
445
static const config_var_t testing_tor_network_defaults[] = {
446
  V(ServerDNSAllowBrokenConfig,  BOOL,  "1"),
447
448
449
450
451
452
  V(DirAllowPrivateAddresses,    BOOL,     "1"),
  V(EnforceDistinctSubnets,      BOOL,     "0"),
  V(AssumeReachable,             BOOL,     "1"),
  V(AuthDirMaxServersPerAddr,    UINT,     "0"),
  V(AuthDirMaxServersPerAuthAddr,UINT,     "0"),
  V(ClientDNSRejectInternalAddresses, BOOL,"0"),
453
  V(ClientRejectInternalAddresses, BOOL,   "0"),
454
  V(CountPrivateBandwidth,       BOOL,     "1"),
455
456
457
458
  V(ExitPolicyRejectPrivate,     BOOL,     "0"),
  V(V3AuthVotingInterval,        INTERVAL, "5 minutes"),
  V(V3AuthVoteDelay,             INTERVAL, "20 seconds"),
  V(V3AuthDistDelay,             INTERVAL, "20 seconds"),
459
460
461
462
463
  V(TestingV3AuthInitialVotingInterval, INTERVAL, "5 minutes"),
  V(TestingV3AuthInitialVoteDelay, INTERVAL, "20 seconds"),
  V(TestingV3AuthInitialDistDelay, INTERVAL, "20 seconds"),
  V(TestingAuthDirTimeToLearnReachability, INTERVAL, "0 minutes"),
  V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "0 minutes"),
464
  V(MinUptimeHidServDirectoryV2, INTERVAL, "0 minutes"),
465
  V(_UsingTestNetworkDefaults,   BOOL,     "1"),
466

467
468
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
};
469
470
#undef VAR

471
472
#define VAR(name,conftype,member,initvalue)                             \
  { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member),  \
473
      initvalue }
474
475

/** Array of "state" variables saved to the ~/.tor/state file. */
476
static config_var_t _state_vars[] = {
477
478
479
480
481
  V(AccountingBytesReadInInterval,    MEMUNIT,  NULL),
  V(AccountingBytesWrittenInInterval, MEMUNIT,  NULL),
  V(AccountingExpectedUsage,          MEMUNIT,  NULL),
  V(AccountingIntervalStart,          ISOTIME,  NULL),
  V(AccountingSecondsActive,          INTERVAL, NULL),
482
483
484
  V(AccountingSecondsToReachSoftLimit,INTERVAL, NULL),
  V(AccountingSoftLimitHitAt,         ISOTIME,  NULL),
  V(AccountingBytesAtSoftLimit,       MEMUNIT,  NULL),
Roger Dingledine's avatar
Roger Dingledine committed
485

486
487
488
  VAR("EntryGuard",              LINELIST_S,  EntryGuards,             NULL),
  VAR("EntryGuardDownSince",     LINELIST_S,  EntryGuards,             NULL),
  VAR("EntryGuardUnlistedSince", LINELIST_S,  EntryGuards,             NULL),
489
  VAR("EntryGuardAddedBy",       LINELIST_S,  EntryGuards,             NULL),
490
  V(EntryGuards,                 LINELIST_V,  NULL),
Nick Mathewson's avatar
Nick Mathewson committed
491

492
493
494
  VAR("TransportProxy",               LINELIST_S, TransportProxies, NULL),
  V(TransportProxies,                 LINELIST_V, NULL),

495
496
497
  V(BWHistoryReadEnds,                ISOTIME,  NULL),
  V(BWHistoryReadInterval,            UINT,     "900"),
  V(BWHistoryReadValues,              CSV,      ""),
498
  V(BWHistoryReadMaxima,              CSV,      ""),
499
500
501
  V(BWHistoryWriteEnds,               ISOTIME,  NULL),
  V(BWHistoryWriteInterval,           UINT,     "900"),
  V(BWHistoryWriteValues,             CSV,      ""),
502
  V(BWHistoryWriteMaxima,             CSV,      ""),
503
504
505
  V(BWHistoryDirReadEnds,             ISOTIME,  NULL),
  V(BWHistoryDirReadInterval,         UINT,     "900"),
  V(BWHistoryDirReadValues,           CSV,      ""),
506
  V(BWHistoryDirReadMaxima,           CSV,      ""),
507
508
509
  V(BWHistoryDirWriteEnds,            ISOTIME,  NULL),
  V(BWHistoryDirWriteInterval,        UINT,     "900"),
  V(BWHistoryDirWriteValues,          CSV,      ""),
510
  V(BWHistoryDirWriteMaxima,          CSV,      ""),
511

512
  V(TorVersion,                       STRING,   NULL),
513

514
515
  V(LastRotatedOnionKey,              ISOTIME,  NULL),
  V(LastWritten,                      ISOTIME,  NULL),
516

517
  V(TotalBuildTimes,                  UINT,     NULL),
518
  V(CircuitBuildAbandonedCount,       UINT,     "0"),
519
520
  VAR("CircuitBuildTimeBin",          LINELIST_S, BuildtimeHistogram, NULL),
  VAR("BuildtimeHistogram",           LINELIST_V, BuildtimeHistogram, NULL),
521
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
522
523
};

524
#undef VAR
525
#undef V
526
527
#undef OBSOLETE

528
529
/** Represents an English description of a configuration variable; used when
 * generating configuration file comments. */
530
531
532
533
534
typedef struct config_var_description_t {
  const char *name;
  const char *description;
} config_var_description_t;

535
/** Type of a callback to validate whether a given configuration is
Roger Dingledine's avatar
Roger Dingledine committed
536
 * well-formed and consistent. See options_trial_assign() for documentation
537
 * of arguments. */
538
typedef int (*validate_fn_t)(void*,void*,int,char**);
539

540
541
542
/** Information on the keys, value types, key-to-struct-member mappings,
 * variable descriptions, validation functions, and abbreviations for a
 * configuration or storage format. */
543
typedef struct {
544
545
546
  size_t size; /**< Size of the struct that everything gets parsed into. */
  uint32_t magic; /**< Required 'magic value' to make sure we have a struct
                   * of the right type. */
Roger Dingledine's avatar
Roger Dingledine committed
547
  off_t magic_offset; /**< Offset of the magic value within the struct. */
548
  config_abbrev_t *abbrevs; /**< List of abbreviations that we expand when
Roger Dingledine's avatar
Roger Dingledine committed
549
                             * parsing this format. */
550
551
552
  config_var_t *vars; /**< List of variables we recognize, their default
                       * values, and where we stick them in the structure. */
  validate_fn_t validate_fn; /**< Function to validate config. */
Roger Dingledine's avatar
Roger Dingledine committed
553
554
555
  /** If present, extra is a LINELIST variable for unrecognized
   * lines.  Otherwise, unrecognized lines are an error. */
  config_var_t *extra;
556
557
} config_format_t;

558
559
/** Macro: assert that <b>cfg</b> has the right magic field for format
 * <b>fmt</b>. */
560
#define CHECK(fmt, cfg) STMT_BEGIN                                      \
561
    tor_assert(fmt && cfg);                                             \
562
    tor_assert((fmt)->magic ==                                          \
563
               *(uint32_t*)STRUCT_VAR_P(cfg,fmt->magic_offset));        \
564
  STMT_END
565

566
567
568
#ifdef MS_WINDOWS
static char *get_windows_conf_root(void);
#endif
569
static void config_line_append(config_line_t **lst,
570
                               const char *key, const char *val);
571
572
573
574
575
static void option_clear(const config_format_t *fmt, or_options_t *options,
                         const config_var_t *var);
static void option_reset(const config_format_t *fmt, or_options_t *options,
                         const config_var_t *var, int use_defaults);
static void config_free(const config_format_t *fmt, void *options);
576
static int config_lines_eq(config_line_t *a, config_line_t *b);
577
578
static int option_is_same(const config_format_t *fmt,
                          const or_options_t *o1, const or_options_t *o2,
579
                          const char *name);
580
581
582
583
static or_options_t *options_dup(const config_format_t *fmt,
                                 const or_options_t *old);
static int options_validate(or_options_t *old_options,
                            or_options_t *options,
584
                            int from_setconf, char **msg);
585
586
587
588
static int options_act_reversible(const or_options_t *old_options, char **msg);
static int options_act(const or_options_t *old_options);
static int options_transition_allowed(const or_options_t *old,
                                      const or_options_t *new,
589
                                      char **msg);
590
591
592
593
static int options_transition_affects_workers(
      const or_options_t *old_options, const or_options_t *new_options);
static int options_transition_affects_descriptor(
      const or_options_t *old_options, const or_options_t *new_options);
594
static int check_nickname_list(const char *lst, const char *name, char **msg);
595

596
static int parse_bridge_line(const char *line, int validate_only);
George Kadianakis's avatar
George Kadianakis committed
597
static int parse_client_transport_line(const char *line, int validate_only);
598
599

static int parse_server_transport_line(const char *line, int validate_only);
600
static int parse_dir_server_line(const char *line,
601
                                 dirinfo_type_t required_type,
602
                                 int validate_only);
603
static void port_cfg_free(port_cfg_t *port);
604
static int parse_ports(const or_options_t *options, int validate_only,
605
                              char **msg_out, int *n_ports_out);
606
607
608
static int check_server_ports(const smartlist_t *ports,
                              const or_options_t *options);

609
static int validate_data_directory(or_options_t *options);
610
611
612
613
614
615
static int write_configuration_file(const char *fname,
                                    const or_options_t *options);
static config_line_t *get_assigned_option(const config_format_t *fmt,
                                        const void *options, const char *key,
                                        int escape_val);
static void config_init(const config_format_t *fmt, void *options);
616
static int or_state_validate(or_state_t *old_options, or_state_t *options,
617
                             int from_setconf, char **msg);
618
619
static int or_state_load(void);
static int options_init_logs(or_options_t *options, int validate_only);
620

621
static uint64_t config_parse_memunit(const char *s, int *ok);
622
static int config_parse_msec_interval(const char *s, int *ok);
623
static int config_parse_interval(const char *s, int *ok);
624
static void init_libevent(const or_options_t *options);
625
static int opt_streq(const char *s1, const char *s2);
626

627
/** Magic value for or_options_t. */
628
629
#define OR_OPTIONS_MAGIC 9090909

630
/** Configuration format for or_options_t. */
631
static config_format_t options_format = {
632
633
634
  sizeof(or_options_t),
  OR_OPTIONS_MAGIC,
  STRUCT_OFFSET(or_options_t, _magic),
635
636
637
  _option_abbrevs,
  _option_vars,
  (validate_fn_t)options_validate,
638
  NULL
639
640
};

641
/** Magic value for or_state_t. */
642
643
#define OR_STATE_MAGIC 0x57A73f57

644
645
/** "Extra" variable in the state that receives lines we can't parse. This
 * lets us preserve options from versions of Tor newer than us. */
646
647
648
649
static config_var_t state_extra_var = {
  "__extra", CONFIG_TYPE_LINELIST, STRUCT_OFFSET(or_state_t, ExtraLines), NULL
};

650
/** Configuration format for or_state_t. */
651
static const config_format_t state_format = {
652
653
654
  sizeof(or_state_t),
  OR_STATE_MAGIC,
  STRUCT_OFFSET(or_state_t, _magic),
655
  _state_abbrevs,
656
657
  _state_vars,
  (validate_fn_t)or_state_validate,
658
  &state_extra_var,
659
660
};

661
662
663
664
665
/*
 * Functions to read and write the global options pointer.
 */

/** Command-line and config-file options. */
666
static or_options_t *global_options = NULL;
667
668
/** DOCDOC */
static or_options_t *global_default_options = NULL;
Roger Dingledine's avatar
Roger Dingledine committed
669
/** Name of most recently read torrc file. */
670
static char *torrc_fname = NULL;
671
672
/** DOCDOC */
static char *torrc_defaults_fname;
673
/** Persistent serialized state. */
674
static or_state_t *global_state = NULL;
675
676
/** Configuration Options set by command line. */
static config_line_t *global_cmdline_options = NULL;
Roger Dingledine's avatar
Roger Dingledine committed
677
/** Contents of most recently read DirPortFrontPage file. */
678
static char *global_dirfrontpagecontents = NULL;
679
680
/** List of port_cfg_t for all configured ports. */
static smartlist_t *configured_ports = NULL;
681
682
683
684
685
686
687

/** Return the contents of our frontpage string, or NULL if not configured. */
const char *
get_dirportfrontpage(void)
{
  return global_dirfrontpagecontents;
}
688

689
/** Allocate an empty configuration object of a given format type. */
690
static void *
691
config_alloc(const config_format_t *fmt)
692
{
693
  void *opts = tor_malloc_zero(fmt->size);
694
  *(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
695
696
697
698
  CHECK(fmt, opts);
  return opts;
}

699
700
/** Return the currently configured options. */
or_options_t *
701
get_options_mutable(void)
702
{
703
704
705
  tor_assert(global_options);
  return global_options;
}
706

707
708
709
710
711
712
713
/** Returns the currently configured options */
const or_options_t *
get_options(void)
{
  return get_options_mutable();
}

714
715
/** Change the current global options to contain <b>new_val</b> instead of
 * their current value; take action based on the new value; free the old value
716
 * as necessary.  Returns 0 on success, -1 on failure.
717
 */
718
int
719
set_options(or_options_t *new_val, char **msg)
720
{
721
722
723
  int i;
  smartlist_t *elements;
  config_line_t *line;
724
  or_options_t *old_options = global_options;
725
  global_options = new_val;
726
727
  /* Note that we pass the *old* options below, for comparison. It
   * pulls the new options directly out of global_options. */
728
729
  if (options_act_reversible(old_options, msg)<0) {
    tor_assert(*msg);
730
731
732
    global_options = old_options;
    return -1;
  }
733
  if (options_act(old_options) < 0) { /* acting on the options failed. die. */
734
    log_err(LD_BUG,
Roger Dingledine's avatar
Roger Dingledine committed
735
            "Acting on config options left us in a broken state. Dying.");
736
737
    exit(1);
  }
738
739
740
741
742
  /* Issues a CONF_CHANGED event to notify controller of the change. If Tor is
   * just starting up then the old_options will be undefined. */
  if (old_options) {
    elements = smartlist_create();
    for (i=0; options_format.vars[i].name; ++i) {
743
744
      const config_var_t *var = &options_format.vars[i];
      const char *var_name = var->name;
Kamran Riaz Khan's avatar