config.c 182 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"
Sebastian Hahn's avatar
Sebastian Hahn committed
36
#include "routerlist.h"
37
38
39
#ifdef MS_WINDOWS
#include <shlobj.h>
#endif
Roger Dingledine's avatar
Roger Dingledine committed
40

Nick Mathewson's avatar
Nick Mathewson committed
41
42
/** Enumeration of types which option values can take */
typedef enum config_type_t {
43
  CONFIG_TYPE_STRING = 0,   /**< An arbitrary string. */
44
  CONFIG_TYPE_FILENAME,     /**< A filename: some prefixes get expanded. */
45
  CONFIG_TYPE_UINT,         /**< A non-negative integer less than MAX_INT */
46
  CONFIG_TYPE_INTERVAL,     /**< A number of seconds, with optional units*/
47
48
  CONFIG_TYPE_MSEC_INTERVAL,/**< A number of milliseconds, with optional
                              * units */
49
  CONFIG_TYPE_MEMUNIT,      /**< A number of bytes, with optional units*/
50
51
  CONFIG_TYPE_DOUBLE,       /**< A floating-point value */
  CONFIG_TYPE_BOOL,         /**< A boolean value, expressed as 0 or 1. */
52
53
  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
54
  CONFIG_TYPE_ISOTIME,      /**< An ISO-formatted time relative to GMT. */
55
56
  CONFIG_TYPE_CSV,          /**< A list of strings, separated by commas and
                              * optional whitespace. */
57
  CONFIG_TYPE_LINELIST,     /**< Uninterpreted config lines */
58
59
60
61
62
  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.
                             */
63
64
  CONFIG_TYPE_ROUTERSET,    /**< A list of router names, addrs, and fps,
                             * parsed into a routerset_t. */
65
  CONFIG_TYPE_OBSOLETE,     /**< Obsolete (ignored) option. */
Nick Mathewson's avatar
Nick Mathewson committed
66
} config_type_t;
67

68
/** An abbreviation for a configuration option allowed on the command line. */
69
typedef struct config_abbrev_t {
70
71
  const char *abbreviated;
  const char *full;
72
  int commandline_only;
73
  int warn;
74
75
} config_abbrev_t;

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

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

/** A list of state-file "abbreviations," for compatibility. */
123
static config_abbrev_t _state_abbrevs[] = {
124
  { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
125
126
127
128
129
130
  { "HelperNode", "EntryGuard", 0, 0 },
  { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
  { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
  { "EntryNode", "EntryGuard", 0, 0 },
  { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
  { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
131
  { NULL, NULL, 0, 0},
132
};
133
#undef PLURAL
134

135
/** A variable allowed in the configuration file or on the command line. */
136
typedef struct config_var_t {
137
  const char *name; /**< The full keyword (case insensitive). */
138
139
  config_type_t type; /**< How to interpret the type and turn it into a
                       * value. */
140
141
  off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
  const char *initvalue; /**< String (or null) describing initial value. */
142
143
} config_var_t;

Nick Mathewson's avatar
Nick Mathewson committed
144
145
146
147
/** 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>"
 */
148
149
#define VAR(name,conftype,member,initvalue)                             \
  { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), \
150
      initvalue }
151
152
153
/** 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
154
/** An entry for config_vars: "The option <b>name</b> is obsolete." */
155
#define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
156

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

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

410
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
411
};
412

413
414
/** Override default values with these if the user sets the TestingTorNetwork
 * option. */
415
static config_var_t testing_tor_network_defaults[] = {
416
  V(ServerDNSAllowBrokenConfig,  BOOL,  "1"),
417
418
419
420
421
422
  V(DirAllowPrivateAddresses,    BOOL,     "1"),
  V(EnforceDistinctSubnets,      BOOL,     "0"),
  V(AssumeReachable,             BOOL,     "1"),
  V(AuthDirMaxServersPerAddr,    UINT,     "0"),
  V(AuthDirMaxServersPerAuthAddr,UINT,     "0"),
  V(ClientDNSRejectInternalAddresses, BOOL,"0"),
423
  V(ClientRejectInternalAddresses, BOOL,   "0"),
424
  V(CountPrivateBandwidth,       BOOL,     "1"),
425
426
427
428
  V(ExitPolicyRejectPrivate,     BOOL,     "0"),
  V(V3AuthVotingInterval,        INTERVAL, "5 minutes"),
  V(V3AuthVoteDelay,             INTERVAL, "20 seconds"),
  V(V3AuthDistDelay,             INTERVAL, "20 seconds"),
429
430
431
432
433
  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"),
434
  V(MinUptimeHidServDirectoryV2, INTERVAL, "0 minutes"),
435
  V(_UsingTestNetworkDefaults,   BOOL,     "1"),
436

437
438
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
};
439
440
#undef VAR

441
442
#define VAR(name,conftype,member,initvalue)                             \
  { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member),  \
443
      initvalue }
444
445

/** Array of "state" variables saved to the ~/.tor/state file. */
446
static config_var_t _state_vars[] = {
447
448
449
450
451
  V(AccountingBytesReadInInterval,    MEMUNIT,  NULL),
  V(AccountingBytesWrittenInInterval, MEMUNIT,  NULL),
  V(AccountingExpectedUsage,          MEMUNIT,  NULL),
  V(AccountingIntervalStart,          ISOTIME,  NULL),
  V(AccountingSecondsActive,          INTERVAL, NULL),
452
453
454
  V(AccountingSecondsToReachSoftLimit,INTERVAL, NULL),
  V(AccountingSoftLimitHitAt,         ISOTIME,  NULL),
  V(AccountingBytesAtSoftLimit,       MEMUNIT,  NULL),
Roger Dingledine's avatar
Roger Dingledine committed
455

456
457
458
  VAR("EntryGuard",              LINELIST_S,  EntryGuards,             NULL),
  VAR("EntryGuardDownSince",     LINELIST_S,  EntryGuards,             NULL),
  VAR("EntryGuardUnlistedSince", LINELIST_S,  EntryGuards,             NULL),
459
  VAR("EntryGuardAddedBy",       LINELIST_S,  EntryGuards,             NULL),
460
  V(EntryGuards,                 LINELIST_V,  NULL),
Nick Mathewson's avatar
Nick Mathewson committed
461

462
463
464
  V(BWHistoryReadEnds,                ISOTIME,  NULL),
  V(BWHistoryReadInterval,            UINT,     "900"),
  V(BWHistoryReadValues,              CSV,      ""),
465
  V(BWHistoryReadMaxima,              CSV,      ""),
466
467
468
  V(BWHistoryWriteEnds,               ISOTIME,  NULL),
  V(BWHistoryWriteInterval,           UINT,     "900"),
  V(BWHistoryWriteValues,             CSV,      ""),
469
  V(BWHistoryWriteMaxima,             CSV,      ""),
470
471
472
  V(BWHistoryDirReadEnds,             ISOTIME,  NULL),
  V(BWHistoryDirReadInterval,         UINT,     "900"),
  V(BWHistoryDirReadValues,           CSV,      ""),
473
  V(BWHistoryDirReadMaxima,           CSV,      ""),
474
475
476
  V(BWHistoryDirWriteEnds,            ISOTIME,  NULL),
  V(BWHistoryDirWriteInterval,        UINT,     "900"),
  V(BWHistoryDirWriteValues,          CSV,      ""),
477
  V(BWHistoryDirWriteMaxima,          CSV,      ""),
478

479
  V(TorVersion,                       STRING,   NULL),
480

481
482
  V(LastRotatedOnionKey,              ISOTIME,  NULL),
  V(LastWritten,                      ISOTIME,  NULL),
483

484
  V(TotalBuildTimes,                  UINT,     NULL),
485
  V(CircuitBuildAbandonedCount,       UINT,     "0"),
486
487
  VAR("CircuitBuildTimeBin",          LINELIST_S, BuildtimeHistogram, NULL),
  VAR("BuildtimeHistogram",           LINELIST_V, BuildtimeHistogram, NULL),
488

489
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
490
491
};

492
#undef VAR
493
#undef V
494
495
#undef OBSOLETE

496
497
/** Represents an English description of a configuration variable; used when
 * generating configuration file comments. */
498
499
500
501
502
typedef struct config_var_description_t {
  const char *name;
  const char *description;
} config_var_description_t;

503
/** Type of a callback to validate whether a given configuration is
Roger Dingledine's avatar
Roger Dingledine committed
504
 * well-formed and consistent. See options_trial_assign() for documentation
505
 * of arguments. */
506
typedef int (*validate_fn_t)(void*,void*,int,char**);
507

508
509
510
/** Information on the keys, value types, key-to-struct-member mappings,
 * variable descriptions, validation functions, and abbreviations for a
 * configuration or storage format. */
511
typedef struct {
512
513
514
  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
515
  off_t magic_offset; /**< Offset of the magic value within the struct. */
516
  config_abbrev_t *abbrevs; /**< List of abbreviations that we expand when
Roger Dingledine's avatar
Roger Dingledine committed
517
                             * parsing this format. */
518
519
520
  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
521
522
523
  /** If present, extra is a LINELIST variable for unrecognized
   * lines.  Otherwise, unrecognized lines are an error. */
  config_var_t *extra;
524
525
} config_format_t;

526
527
/** Macro: assert that <b>cfg</b> has the right magic field for format
 * <b>fmt</b>. */
528
#define CHECK(fmt, cfg) STMT_BEGIN                                      \
529
    tor_assert(fmt && cfg);                                             \
530
    tor_assert((fmt)->magic ==                                          \
531
               *(uint32_t*)STRUCT_VAR_P(cfg,fmt->magic_offset));        \
532
  STMT_END
533

534
535
536
#ifdef MS_WINDOWS
static char *get_windows_conf_root(void);
#endif
537
static void config_line_append(config_line_t **lst,
538
                               const char *key, const char *val);
539
540
static void option_clear(config_format_t *fmt, or_options_t *options,
                         config_var_t *var);
541
static void option_reset(config_format_t *fmt, or_options_t *options,
542
                         config_var_t *var, int use_defaults);
543
static void config_free(config_format_t *fmt, void *options);
544
static int config_lines_eq(config_line_t *a, config_line_t *b);
545
static int option_is_same(config_format_t *fmt,
546
547
                          or_options_t *o1, or_options_t *o2,
                          const char *name);
548
static or_options_t *options_dup(config_format_t *fmt, or_options_t *old);
549
550
551
static int options_validate(or_options_t *old_options, or_options_t *options,
                            int from_setconf, char **msg);
static int options_act_reversible(or_options_t *old_options, char **msg);
552
static int options_act(or_options_t *old_options);
553
554
static int options_transition_allowed(or_options_t *old, or_options_t *new,
                                      char **msg);
555
556
557
558
static int options_transition_affects_workers(or_options_t *old_options,
                                              or_options_t *new_options);
static int options_transition_affects_descriptor(or_options_t *old_options,
                                                 or_options_t *new_options);
559
static int check_nickname_list(const char *lst, const char *name, char **msg);
560
static void config_register_addressmaps(or_options_t *options);
561

562
static int parse_bridge_line(const char *line, int validate_only);
563
564
565
static int parse_dir_server_line(const char *line,
                                 authority_type_t required_type,
                                 int validate_only);
566
static int validate_data_directory(or_options_t *options);
567
static int write_configuration_file(const char *fname, or_options_t *options);
568
static config_line_t *get_assigned_option(config_format_t *fmt,
569
570
                                          void *options, const char *key,
                                          int escape_val);
571
static void config_init(config_format_t *fmt, void *options);
572
static int or_state_validate(or_state_t *old_options, or_state_t *options,
573
                             int from_setconf, char **msg);
574
575
static int or_state_load(void);
static int options_init_logs(or_options_t *options, int validate_only);
576

577
578
579
static int is_listening_on_low_port(uint16_t port_option,
                                    const config_line_t *listen_options);

580
static uint64_t config_parse_memunit(const char *s, int *ok);
581
static int config_parse_msec_interval(const char *s, int *ok);
582
static int config_parse_interval(const char *s, int *ok);
583
static void init_libevent(const or_options_t *options);
584
static int opt_streq(const char *s1, const char *s2);
585

586
/** Magic value for or_options_t. */
587
588
#define OR_OPTIONS_MAGIC 9090909

589
/** Configuration format for or_options_t. */
590
static config_format_t options_format = {
591
592
593
  sizeof(or_options_t),
  OR_OPTIONS_MAGIC,
  STRUCT_OFFSET(or_options_t, _magic),
594
595
596
  _option_abbrevs,
  _option_vars,
  (validate_fn_t)options_validate,
597
  NULL
598
599
};

600
/** Magic value for or_state_t. */
601
602
#define OR_STATE_MAGIC 0x57A73f57

603
604
/** "Extra" variable in the state that receives lines we can't parse. This
 * lets us preserve options from versions of Tor newer than us. */
605
606
607
608
static config_var_t state_extra_var = {
  "__extra", CONFIG_TYPE_LINELIST, STRUCT_OFFSET(or_state_t, ExtraLines), NULL
};

609
/** Configuration format for or_state_t. */
610
611
612
613
static config_format_t state_format = {
  sizeof(or_state_t),
  OR_STATE_MAGIC,
  STRUCT_OFFSET(or_state_t, _magic),
614
  _state_abbrevs,
615
616
  _state_vars,
  (validate_fn_t)or_state_validate,
617
  &state_extra_var,
618
619
};

620
621
622
623
624
/*
 * Functions to read and write the global options pointer.
 */

/** Command-line and config-file options. */
625
static or_options_t *global_options = NULL;
Roger Dingledine's avatar
Roger Dingledine committed
626
/** Name of most recently read torrc file. */
627
static char *torrc_fname = NULL;
628
/** Persistent serialized state. */
629
static or_state_t *global_state = NULL;
630
631
/** Configuration Options set by command line. */
static config_line_t *global_cmdline_options = NULL;
Roger Dingledine's avatar
Roger Dingledine committed
632
/** Contents of most recently read DirPortFrontPage file. */
633
634
635
636
637
638
639
640
static char *global_dirfrontpagecontents = NULL;

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

642
/** Allocate an empty configuration object of a given format type. */
643
644
645
static void *
config_alloc(config_format_t *fmt)
{
646
  void *opts = tor_malloc_zero(fmt->size);
647
  *(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
648
649
650
651
  CHECK(fmt, opts);
  return opts;
}

652
653
/** Return the currently configured options. */
or_options_t *
654
655
get_options(void)
{
656
657
658
  tor_assert(global_options);
  return global_options;
}
659

660
661
/** 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
662
 * as necessary.  Returns 0 on success, -1 on failure.
663
 */
664
int
665
set_options(or_options_t *new_val, char **msg)
666
{
667
  or_options_t *old_options = global_options;
668
  global_options = new_val;
669
670
  /* Note that we pass the *old* options below, for comparison. It
   * pulls the new options directly out of global_options. */
671
672
  if (options_act_reversible(old_options, msg)<0) {
    tor_assert(*msg);
673
674
675
    global_options = old_options;
    return -1;
  }
676
  if (options_act(old_options) < 0) { /* acting on the options failed. die. */
677
    log_err(LD_BUG,
Roger Dingledine's avatar
Roger Dingledine committed
678
            "Acting on config options left us in a broken state. Dying.");
679
680
    exit(1);
  }
681
682

  config_free(&options_format, old_options);
683
684

  return 0;
685
686
}

687
extern const char tor_git_revision[]; /* from tor_main.c */
688

689
/** The version of this Tor process, as parsed. */
690
691
static char *_version = NULL;

692
/** Return the current Tor version. */
693
694
695
const char *
get_version(void)
{
696
  if (_version == NULL) {
697
698
    if (strlen(tor_git_revision)) {
      size_t len = strlen(VERSION)+strlen(tor_git_revision)+16;
699
      _version = tor_malloc(len);
700
      tor_snprintf(_version, len, "%s (git-%s)", VERSION, tor_git_revision);
701
    } else {
702
      _version = tor_strdup(VERSION);
703
704
    }
  }
705
  return _version;
706
707
}

708
709
710
711
712
/** Release additional memory allocated in options
 */
static void
or_options_free(or_options_t *options)
{
713
714
715
  if (!options)
    return;

716
  routerset_free(options->_ExcludeExitNodesUnion);
717
718
719
720
721
  if (options->NodeFamilySets) {
    SMARTLIST_FOREACH(options->NodeFamilySets, routerset_t *,
                      rs, routerset_free(rs));
    smartlist_free(options->NodeFamilySets);
  }
722
723
724
  config_free(&options_format, options);
}

725
726
/** Release all memory and resources held by global configuration structures.
 */
727
728
729
void
config_free_all(void)
{
730
731
732
733
734
735
736
737
738
  or_options_free(global_options);
  global_options = NULL;

  config_free(&state_format, global_state);
  global_state = NULL;

  config_free_lines(global_cmdline_options);
  global_cmdline_options = NULL;

739
  tor_free(torrc_fname);
740
  tor_free(_version);
741
  tor_free(global_dirfrontpagecontents);
742
743
}

744
745
746
747
748
/** Make <b>address</b> -- a piece of information related to our operation as
 * a client -- safe to log according to the settings in options->SafeLogging,
 * and return it.
 *
 * (We return "[scrubbed]" if SafeLogging is "1", and address otherwise.)
749
750
 */
const char *
751
safe_str_client(const char *address)
752
{
753
  tor_assert(address);
754
  if (get_options()->_SafeLogging == SAFELOG_SCRUB_ALL)
755
756
757
758
759
    return "[scrubbed]";
  else
    return address;
}

760
761
762
763
764
765
/** Make <b>address</b> -- a piece of information of unspecified sensitivity
 * -- safe to log according to the settings in options->SafeLogging, and
 * return it.
 *
 * (We return "[scrubbed]" if SafeLogging is anything besides "0", and address
 * otherwise.)
766
767
 */
const char *
768
769
safe_str(const char *address)
{
770
  tor_assert(address);
771
  if (get_options()->_SafeLogging != SAFELOG_SCRUB_NONE)
772
773
774
775
776
    return "[scrubbed]";
  else
    return address;
}

777
/** Equivalent to escaped(safe_str_client(address)).  See reentrancy note on
778
779