config.c 199 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
206
  V(ClientDNSRejectInternalAddresses, BOOL,"1"),
  V(ClientOnly,                  BOOL,     "0"),
207
  V(ClientRejectInternalAddresses, BOOL,   "1"),
208
  V(ClientTransportPlugin,       LINELIST, NULL),
209
  V(ConsensusParams,             STRING,   NULL),
210
  V(ConnLimit,                   UINT,     "1000"),
211
  V(ConnDirectionStatistics,     BOOL,     "0"),
212
213
214
215
  V(ConstrainedSockets,          BOOL,     "0"),
  V(ConstrainedSockSize,         MEMUNIT,  "8192"),
  V(ContactInfo,                 STRING,   NULL),
  V(ControlListenAddress,        LINELIST, NULL),
216
  V(ControlPort,                 PORT,     "0"),
217
  V(ControlPortFileGroupReadable,BOOL,     "0"),
218
  V(ControlPortWriteToFile,      FILENAME, NULL),
219
  V(ControlSocket,               LINELIST, NULL),
220
  V(ControlSocketsGroupWritable, BOOL,     "0"),
221
222
223
  V(CookieAuthentication,        BOOL,     "0"),
  V(CookieAuthFileGroupReadable, BOOL,     "0"),
  V(CookieAuthFile,              STRING,   NULL),
224
  V(CountPrivateBandwidth,       BOOL,     "0"),
225
  V(DataDirectory,               FILENAME, NULL),
226
  OBSOLETE("DebugLogFile"),
227
  V(DirAllowPrivateAddresses,    BOOL,     NULL),
228
  V(TestingAuthDirTimeToLearnReachability, INTERVAL, "30 minutes"),
229
  V(DirListenAddress,            LINELIST, NULL),
230
  OBSOLETE("DirFetchPeriod"),
231
  V(DirPolicy,                   LINELIST, NULL),
232
  V(DirPort,                     PORT,     "0"),
233
  V(DirPortFrontPage,            FILENAME, NULL),
234
  OBSOLETE("DirPostPeriod"),
235
236
237
238
  OBSOLETE("DirRecordUsageByCountry"),
  OBSOLETE("DirRecordUsageGranularity"),
  OBSOLETE("DirRecordUsageRetainIPs"),
  OBSOLETE("DirRecordUsageSaveInterval"),
239
  V(DirReqStatistics,            BOOL,     "1"),
240
  VAR("DirServer",               LINELIST, DirServers, NULL),
241
  V(DisableAllSwap,              BOOL,     "0"),
242
  V(DisableIOCP,                 BOOL,     "1"),
243
  V(DNSPort,                     LINELIST, NULL),
244
245
246
  V(DNSListenAddress,            LINELIST, NULL),
  V(DownloadExtraInfo,           BOOL,     "0"),
  V(EnforceDistinctSubnets,      BOOL,     "1"),
247
  V(EntryNodes,                  ROUTERSET,   NULL),
248
  V(EntryStatistics,             BOOL,     "0"),
249
  V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "10 minutes"),
250
251
  V(ExcludeNodes,                ROUTERSET, NULL),
  V(ExcludeExitNodes,            ROUTERSET, NULL),
252
  V(ExcludeSingleHopRelays,      BOOL,     "1"),
253
  V(ExitNodes,                   ROUTERSET, NULL),
254
255
  V(ExitPolicy,                  LINELIST, NULL),
  V(ExitPolicyRejectPrivate,     BOOL,     "1"),
256
  V(ExitPortStatistics,          BOOL,     "0"),
257
  V(ExtraInfoStatistics,         BOOL,     "1"),
258

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

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

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

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

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

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

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

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

490
  V(TorVersion,                       STRING,   NULL),
491

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

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

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

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

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

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

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

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

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

575
static int parse_bridge_line(const char *line, int validate_only);
George Kadianakis's avatar
George Kadianakis committed
576
static int parse_client_transport_line(const char *line, int validate_only);
577
static int parse_dir_server_line(const char *line,
578
                                 dirinfo_type_t required_type,
579
                                 int validate_only);
580
static void port_cfg_free(port_cfg_t *port);
581
582
static int parse_client_ports(const or_options_t *options, int validate_only,
                              char **msg_out, int *n_ports_out);
583
static int validate_data_directory(or_options_t *options);
584
585
586
587
588
589
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);
590
static int or_state_validate(or_state_t *old_options, or_state_t *options,
591
                             int from_setconf, char **msg);
592
593
static int or_state_load(void);
static int options_init_logs(or_options_t *options, int validate_only);
594

595
static int is_listening_on_low_port(int port_option,
596
597
                                    const config_line_t *listen_options);

598
static uint64_t config_parse_memunit(const char *s, int *ok);
599
static int config_parse_msec_interval(const char *s, int *ok);
600
static int config_parse_interval(const char *s, int *ok);
601
static void init_libevent(const or_options_t *options);
602
static int opt_streq(const char *s1, const char *s2);
603

604
/** Magic value for or_options_t. */
605
606
#define OR_OPTIONS_MAGIC 9090909

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

618
/** Magic value for or_state_t. */
619
620
#define OR_STATE_MAGIC 0x57A73f57

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

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

638
639
640
641
642
/*
 * Functions to read and write the global options pointer.
 */

/** Command-line and config-file options. */
643
static or_options_t *global_options = NULL;
Roger Dingledine's avatar
Roger Dingledine committed
644
/** Name of most recently read torrc file. */
645
static char *torrc_fname = NULL;
646
/** Persistent serialized state. */
647
static or_state_t *global_state = NULL;
648
649
/** Configuration Options set by command line. */
static config_line_t *global_cmdline_options = NULL;
Roger Dingledine's avatar
Roger Dingledine committed
650
/** Contents of most recently read DirPortFrontPage file. */
651
static char *global_dirfrontpagecontents = NULL;
652
653
/** List of port_cfg_t for client-level (SOCKS, DNS, Trans, NATD) ports. */
static smartlist_t *configured_client_ports = NULL;
654
655
656
657
658
659
660

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

662
/** Allocate an empty configuration object of a given format type. */
663
static void *
664
config_alloc(const config_format_t *fmt)
665
{
666
  void *opts = tor_malloc_zero(fmt->size);
667
  *(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
668
669
670
671
  CHECK(fmt, opts);
  return opts;
}

672
673
/** Return the currently configured options. */
or_options_t *
674
get_options_mutable(void)
675
{
676
677
678
  tor_assert(global_options);
  return global_options;
}
679

680
681
682
683
684
685
686
/** Returns the currently configured options */
const or_options_t *
get_options(void)
{
  return get_options_mutable();
}

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

  config_free(&options_format, old_options);
710
711

  return 0;
712
713
}

714
extern const char tor_git_revision[]; /* from tor_main.c */
715

716
/** The version of this Tor process, as parsed. */
717
718
static char *_version = NULL;

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

735
736
737
738
739
/** Release additional memory allocated in options
 */
static void
or_options_free(or_options_t *options)
{
740
741
742
  if (!options)
    return;

743
  routerset_free(options->_ExcludeExitNodesUnion);
744
745
746
747
748
  if (options->NodeFamilySets) {
    SMARTLIST_FOREACH(options->NodeFamilySets, routerset_t *,
                      rs, routerset_free(rs));
    smartlist_free(options->NodeFamilySets);
  }
749
750
751
  config_free(&options_format, options);
}