config.c 185 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

41
42
#include "procmon.h"

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

72
/** An abbreviation for a configuration option allowed on the command line. */
73
typedef struct config_abbrev_t {
74
75
  const char *abbreviated;
  const char *full;
76
  int commandline_only;
77
  int warn;
78
79
} config_abbrev_t;

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

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

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

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

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

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

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

420
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
421
};
422

423
424
/** Override default values with these if the user sets the TestingTorNetwork
 * option. */
425
static const config_var_t testing_tor_network_defaults[] = {
426
  V(ServerDNSAllowBrokenConfig,  BOOL,  "1"),
427
428
429
430
431
432
  V(DirAllowPrivateAddresses,    BOOL,     "1"),
  V(EnforceDistinctSubnets,      BOOL,     "0"),
  V(AssumeReachable,             BOOL,     "1"),
  V(AuthDirMaxServersPerAddr,    UINT,     "0"),
  V(AuthDirMaxServersPerAuthAddr,UINT,     "0"),
  V(ClientDNSRejectInternalAddresses, BOOL,"0"),
433
  V(ClientRejectInternalAddresses, BOOL,   "0"),
434
  V(CountPrivateBandwidth,       BOOL,     "1"),
435
436
437
438
  V(ExitPolicyRejectPrivate,     BOOL,     "0"),
  V(V3AuthVotingInterval,        INTERVAL, "5 minutes"),
  V(V3AuthVoteDelay,             INTERVAL, "20 seconds"),
  V(V3AuthDistDelay,             INTERVAL, "20 seconds"),
439
440
441
442
443
  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"),
444
  V(MinUptimeHidServDirectoryV2, INTERVAL, "0 minutes"),
445
  V(_UsingTestNetworkDefaults,   BOOL,     "1"),
446

447
448
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
};
449
450
#undef VAR

451
452
#define VAR(name,conftype,member,initvalue)                             \
  { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member),  \
453
      initvalue }
454
455

/** Array of "state" variables saved to the ~/.tor/state file. */
456
static config_var_t _state_vars[] = {
457
458
459
460
461
  V(AccountingBytesReadInInterval,    MEMUNIT,  NULL),
  V(AccountingBytesWrittenInInterval, MEMUNIT,  NULL),
  V(AccountingExpectedUsage,          MEMUNIT,  NULL),
  V(AccountingIntervalStart,          ISOTIME,  NULL),
  V(AccountingSecondsActive,          INTERVAL, NULL),
462
463
464
  V(AccountingSecondsToReachSoftLimit,INTERVAL, NULL),
  V(AccountingSoftLimitHitAt,         ISOTIME,  NULL),
  V(AccountingBytesAtSoftLimit,       MEMUNIT,  NULL),
Roger Dingledine's avatar
Roger Dingledine committed
465

466
467
468
  VAR("EntryGuard",              LINELIST_S,  EntryGuards,             NULL),
  VAR("EntryGuardDownSince",     LINELIST_S,  EntryGuards,             NULL),
  VAR("EntryGuardUnlistedSince", LINELIST_S,  EntryGuards,             NULL),
469
  VAR("EntryGuardAddedBy",       LINELIST_S,  EntryGuards,             NULL),
470
  V(EntryGuards,                 LINELIST_V,  NULL),
Nick Mathewson's avatar
Nick Mathewson committed
471

472
473
474
  V(BWHistoryReadEnds,                ISOTIME,  NULL),
  V(BWHistoryReadInterval,            UINT,     "900"),
  V(BWHistoryReadValues,              CSV,      ""),
475
  V(BWHistoryReadMaxima,              CSV,      ""),
476
477
478
  V(BWHistoryWriteEnds,               ISOTIME,  NULL),
  V(BWHistoryWriteInterval,           UINT,     "900"),
  V(BWHistoryWriteValues,             CSV,      ""),
479
  V(BWHistoryWriteMaxima,             CSV,      ""),
480
481
482
  V(BWHistoryDirReadEnds,             ISOTIME,  NULL),
  V(BWHistoryDirReadInterval,         UINT,     "900"),
  V(BWHistoryDirReadValues,           CSV,      ""),
483
  V(BWHistoryDirReadMaxima,           CSV,      ""),
484
485
486
  V(BWHistoryDirWriteEnds,            ISOTIME,  NULL),
  V(BWHistoryDirWriteInterval,        UINT,     "900"),
  V(BWHistoryDirWriteValues,          CSV,      ""),
487
  V(BWHistoryDirWriteMaxima,          CSV,      ""),
488

489
  V(TorVersion,                       STRING,   NULL),
490

491
492
  V(LastRotatedOnionKey,              ISOTIME,  NULL),
  V(LastWritten,                      ISOTIME,  NULL),
493

494
  V(TotalBuildTimes,                  UINT,     NULL),
495
  V(CircuitBuildAbandonedCount,       UINT,     "0"),
496
497
  VAR("CircuitBuildTimeBin",          LINELIST_S, BuildtimeHistogram, NULL),
  VAR("BuildtimeHistogram",           LINELIST_V, BuildtimeHistogram, NULL),
498

499
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
500
501
};

502
#undef VAR
503
#undef V
504
505
#undef OBSOLETE

506
507
/** Represents an English description of a configuration variable; used when
 * generating configuration file comments. */
508
509
510
511
512
typedef struct config_var_description_t {
  const char *name;
  const char *description;
} config_var_description_t;

513
/** Type of a callback to validate whether a given configuration is
Roger Dingledine's avatar
Roger Dingledine committed
514
 * well-formed and consistent. See options_trial_assign() for documentation
515
 * of arguments. */
516
typedef int (*validate_fn_t)(void*,void*,int,char**);
517

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

536
537
/** Macro: assert that <b>cfg</b> has the right magic field for format
 * <b>fmt</b>. */
538
#define CHECK(fmt, cfg) STMT_BEGIN                                      \
539
    tor_assert(fmt && cfg);                                             \
540
    tor_assert((fmt)->magic ==                                          \
541
               *(uint32_t*)STRUCT_VAR_P(cfg,fmt->magic_offset));        \
542
  STMT_END
543

544
545
546
#ifdef MS_WINDOWS
static char *get_windows_conf_root(void);
#endif
547
static void config_line_append(config_line_t **lst,
548
                               const char *key, const char *val);
549
550
551
552
553
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);
554
static int config_lines_eq(config_line_t *a, config_line_t *b);
555
556
static int option_is_same(const config_format_t *fmt,
                          const or_options_t *o1, const or_options_t *o2,
557
                          const char *name);
558
559
560
561
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,
562
                            int from_setconf, char **msg);
563
564
565
566
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,
567
                                      char **msg);
568
569
570
571
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);
572
static int check_nickname_list(const char *lst, const char *name, char **msg);
573
static void config_register_addressmaps(const or_options_t *options);
574

575
static int parse_bridge_line(const char *line, int validate_only);
576
static int parse_dir_server_line(const char *line,
577
                                 dirinfo_type_t required_type,
578
                                 int validate_only);
579
static int validate_data_directory(or_options_t *options);
580
581
582
583
584
585
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);
586
static int or_state_validate(or_state_t *old_options, or_state_t *options,
587
                             int from_setconf, char **msg);
588
589
static int or_state_load(void);
static int options_init_logs(or_options_t *options, int validate_only);
590

591
static int is_listening_on_low_port(int port_option,
592
593
                                    const config_line_t *listen_options);

594
static uint64_t config_parse_memunit(const char *s, int *ok);
595
static int config_parse_msec_interval(const char *s, int *ok);
596
static int config_parse_interval(const char *s, int *ok);
597
static void init_libevent(const or_options_t *options);
598
static int opt_streq(const char *s1, const char *s2);
599

600
/** Magic value for or_options_t. */
601
602
#define OR_OPTIONS_MAGIC 9090909

603
/** Configuration format for or_options_t. */
604
static config_format_t options_format = {
605
606
607
  sizeof(or_options_t),
  OR_OPTIONS_MAGIC,
  STRUCT_OFFSET(or_options_t, _magic),
608
609
610
  _option_abbrevs,
  _option_vars,
  (validate_fn_t)options_validate,
611
  NULL
612
613
};

614
/** Magic value for or_state_t. */
615
616
#define OR_STATE_MAGIC 0x57A73f57

617
618
/** "Extra" variable in the state that receives lines we can't parse. This
 * lets us preserve options from versions of Tor newer than us. */
619
620
621
622
static config_var_t state_extra_var = {
  "__extra", CONFIG_TYPE_LINELIST, STRUCT_OFFSET(or_state_t, ExtraLines), NULL
};

623
/** Configuration format for or_state_t. */
624
static const config_format_t state_format = {
625
626
627
  sizeof(or_state_t),
  OR_STATE_MAGIC,
  STRUCT_OFFSET(or_state_t, _magic),
628
  _state_abbrevs,
629
630
  _state_vars,
  (validate_fn_t)or_state_validate,
631
  &state_extra_var,
632
633
};

634
635
636
637
638
/*
 * Functions to read and write the global options pointer.
 */

/** Command-line and config-file options. */
639
static or_options_t *global_options = NULL;
Roger Dingledine's avatar
Roger Dingledine committed
640
/** Name of most recently read torrc file. */
641
static char *torrc_fname = NULL;
642
/** Persistent serialized state. */
643
static or_state_t *global_state = NULL;
644
645
/** Configuration Options set by command line. */
static config_line_t *global_cmdline_options = NULL;
Roger Dingledine's avatar
Roger Dingledine committed
646
/** Contents of most recently read DirPortFrontPage file. */
647
648
649
650
651
652
653
654
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;
}
655

656
/** Allocate an empty configuration object of a given format type. */
657
static void *
658
config_alloc(const config_format_t *fmt)
659
{
660
  void *opts = tor_malloc_zero(fmt->size);
661
  *(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
662
663
664
665
  CHECK(fmt, opts);
  return opts;
}

666
667
/** Return the currently configured options. */
or_options_t *
668
get_options_mutable(void)
669
{
670
671
672
  tor_assert(global_options);
  return global_options;
}
673

674
675
676
677
678
679
680
/** Returns the currently configured options */
const or_options_t *
get_options(void)
{
  return get_options_mutable();
}

681
682
/** 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
683
 * as necessary.  Returns 0 on success, -1 on failure.
684
 */
685
int
686
set_options(or_options_t *new_val, char **msg)
687
{
688
  or_options_t *old_options = global_options;
689
  global_options = new_val;
690
691
  /* Note that we pass the *old* options below, for comparison. It
   * pulls the new options directly out of global_options. */
692
693
  if (options_act_reversible(old_options, msg)<0) {
    tor_assert(*msg);
694
695
696
    global_options = old_options;
    return -1;
  }
697
  if (options_act(old_options) < 0) { /* acting on the options failed. die. */
698
    log_err(LD_BUG,
Roger Dingledine's avatar
Roger Dingledine committed
699
            "Acting on config options left us in a broken state. Dying.");
700
701
    exit(1);
  }
702
703

  config_free(&options_format, old_options);
704
705

  return 0;
706
707
}

708
extern const char tor_git_revision[]; /* from tor_main.c */
709

710
/** The version of this Tor process, as parsed. */
711
712
static char *_version = NULL;

713
/** Return the current Tor version. */
714
715
716
const char *
get_version(void)
{
717
  if (_version == NULL) {
718
719
    if (strlen(tor_git_revision)) {
      size_t len = strlen(VERSION)+strlen(tor_git_revision)+16;
720
      _version = tor_malloc(len);
721
      tor_snprintf(_version, len, "%s (git-%s)", VERSION, tor_git_revision);
722
    } else {
723
      _version = tor_strdup(VERSION);
724
725
    }
  }
726
  return _version;
727
728
}

729
730
731
732
733
/** Release additional memory allocated in options
 */
static void
or_options_free(or_options_t *options)
{
734
735
736
  if (!options)
    return;

737
  routerset_free(options->_ExcludeExitNodesUnion);
738
739
740
741
742
  if (options->NodeFamilySets) {
    SMARTLIST_FOREACH(options->NodeFamilySets, routerset_t *,
                      rs, routerset_free(rs));
    smartlist_free(options->NodeFamilySets);
  }
743
744
745
  config_free(&options_format, options);
}

746
747
/** Release all memory and resources held by global configuration structures.
 */
748
749
750
void
config_free_all(void)
{
751
752
753
754
755
756
757
758
759
  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;