config.c 169 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-2010, 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 "geoip.h"
16
17
18
#ifdef MS_WINDOWS
#include <shlobj.h>
#endif
Roger Dingledine's avatar
Roger Dingledine committed
19

Nick Mathewson's avatar
Nick Mathewson committed
20
21
/** Enumeration of types which option values can take */
typedef enum config_type_t {
22
  CONFIG_TYPE_STRING = 0,   /**< An arbitrary string. */
23
  CONFIG_TYPE_FILENAME,     /**< A filename: some prefixes get expanded. */
24
  CONFIG_TYPE_UINT,         /**< A non-negative integer less than MAX_INT */
25
26
  CONFIG_TYPE_INTERVAL,     /**< A number of seconds, with optional units*/
  CONFIG_TYPE_MEMUNIT,      /**< A number of bytes, with optional units*/
27
28
  CONFIG_TYPE_DOUBLE,       /**< A floating-point value */
  CONFIG_TYPE_BOOL,         /**< A boolean value, expressed as 0 or 1. */
Nick Mathewson's avatar
Nick Mathewson committed
29
  CONFIG_TYPE_ISOTIME,      /**< An ISO-formatted time relative to GMT. */
30
31
  CONFIG_TYPE_CSV,          /**< A list of strings, separated by commas and
                              * optional whitespace. */
32
  CONFIG_TYPE_LINELIST,     /**< Uninterpreted config lines */
33
34
35
36
37
  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.
                             */
38
39
  CONFIG_TYPE_ROUTERSET,    /**< A list of router names, addrs, and fps,
                             * parsed into a routerset_t. */
40
  CONFIG_TYPE_OBSOLETE,     /**< Obsolete (ignored) option. */
Nick Mathewson's avatar
Nick Mathewson committed
41
} config_type_t;
42

43
/** An abbreviation for a configuration option allowed on the command line. */
44
typedef struct config_abbrev_t {
45
46
  const char *abbreviated;
  const char *full;
47
  int commandline_only;
48
  int warn;
49
50
} config_abbrev_t;

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

55
56
/** A list of abbreviations and aliases to map command-line options, obsolete
 * option names, or alternative option names, to their current values. */
57
static config_abbrev_t _option_abbrevs[] = {
58
  PLURAL(ExitNode),
59
  PLURAL(EntryNode),
60
61
  PLURAL(ExcludeNode),
  PLURAL(FirewallPort),
62
  PLURAL(LongLivedPort),
63
64
  PLURAL(HiddenServiceNode),
  PLURAL(HiddenServiceExcludeNode),
65
  PLURAL(NumCpu),
66
67
  PLURAL(RendNode),
  PLURAL(RendExcludeNode),
68
69
  PLURAL(StrictEntryNode),
  PLURAL(StrictExitNode),
70
  PLURAL(StrictNode),
71
  { "l", "Log", 1, 0},
72
  { "AllowUnverifiedNodes", "AllowInvalidNodes", 0, 0},
73
74
  { "AutomapHostSuffixes", "AutomapHostsSuffixes", 0, 0},
  { "AutomapHostOnResolve", "AutomapHostsOnResolve", 0, 0},
75
76
77
78
  { "BandwidthRateBytes", "BandwidthRate", 0, 0},
  { "BandwidthBurstBytes", "BandwidthBurst", 0, 0},
  { "DirFetchPostPeriod", "StatusFetchPeriod", 0, 0},
  { "MaxConn", "ConnLimit", 0, 1},
79
80
81
  { "ORBindAddress", "ORListenAddress", 0, 0},
  { "DirBindAddress", "DirListenAddress", 0, 0},
  { "SocksBindAddress", "SocksListenAddress", 0, 0},
82
83
84
85
  { "UseHelperNodes", "UseEntryGuards", 0, 0},
  { "NumHelperNodes", "NumEntryGuards", 0, 0},
  { "UseEntryNodes", "UseEntryGuards", 0, 0},
  { "NumEntryNodes", "NumEntryGuards", 0, 0},
86
87
  { "ResolvConf", "ServerDNSResolvConfFile", 0, 1},
  { "SearchDomains", "ServerDNSSearchDomains", 0, 1},
88
  { "ServerDNSAllowBrokenResolvConf", "ServerDNSAllowBrokenConfig", 0, 0},
89
  { "PreferTunnelledDirConns", "PreferTunneledDirConns", 0, 0},
90
  { "BridgeAuthoritativeDirectory", "BridgeAuthoritativeDir", 0, 0},
91
  { "HashedControlPassword", "__HashedControlSessionPassword", 1, 0},
92
93
  { "StrictEntryNodes", "StrictNodes", 0, 1},
  { "StrictExitNodes", "StrictNodes", 0, 1},
94
95
  { NULL, NULL, 0, 0},
};
96
97

/** A list of state-file "abbreviations," for compatibility. */
98
static config_abbrev_t _state_abbrevs[] = {
99
  { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
100
101
102
103
104
105
  { "HelperNode", "EntryGuard", 0, 0 },
  { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
  { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
  { "EntryNode", "EntryGuard", 0, 0 },
  { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
  { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
106
  { NULL, NULL, 0, 0},
107
};
108
#undef PLURAL
109

110
/** A variable allowed in the configuration file or on the command line. */
111
typedef struct config_var_t {
112
  const char *name; /**< The full keyword (case insensitive). */
113
114
  config_type_t type; /**< How to interpret the type and turn it into a
                       * value. */
115
116
  off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
  const char *initvalue; /**< String (or null) describing initial value. */
117
118
} config_var_t;

Nick Mathewson's avatar
Nick Mathewson committed
119
120
121
122
/** 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>"
 */
123
124
#define VAR(name,conftype,member,initvalue)                             \
  { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), \
125
      initvalue }
126
127
128
/** 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
129
/** An entry for config_vars: "The option <b>name</b> is obsolete." */
130
#define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
131

Nick Mathewson's avatar
Nick Mathewson committed
132
133
134
135
/** Array of configuration options.  Until we disallow nonstandard
 * abbreviations, order is significant, since the first matching option will
 * be chosen first.
 */
136
static config_var_t _option_vars[] = {
137
  OBSOLETE("AccountingMaxKB"),
138
139
140
  V(AccountingMax,               MEMUNIT,  "0 bytes"),
  V(AccountingStart,             STRING,   NULL),
  V(Address,                     STRING,   NULL),
141
  V(AllowDotExit,                BOOL,     "0"),
142
143
  V(AllowInvalidNodes,           CSV,      "middle,rendezvous"),
  V(AllowNonRFC953Hostnames,     BOOL,     "0"),
144
145
  V(AllowSingleHopCircuits,      BOOL,     "0"),
  V(AllowSingleHopExits,         BOOL,     "0"),
146
147
148
  V(AlternateBridgeAuthority,    LINELIST, NULL),
  V(AlternateDirAuthority,       LINELIST, NULL),
  V(AlternateHSAuthority,        LINELIST, NULL),
149
  V(AssumeReachable,             BOOL,     "0"),
150
  V(AuthDirBadDir,               LINELIST, NULL),
151
152
153
154
  V(AuthDirBadExit,              LINELIST, NULL),
  V(AuthDirInvalid,              LINELIST, NULL),
  V(AuthDirReject,               LINELIST, NULL),
  V(AuthDirRejectUnlisted,       BOOL,     "0"),
155
  V(AuthDirListBadDirs,          BOOL,     "0"),
156
  V(AuthDirListBadExits,         BOOL,     "0"),
157
158
  V(AuthDirMaxServersPerAddr,    UINT,     "2"),
  V(AuthDirMaxServersPerAuthAddr,UINT,     "5"),
159
160
161
162
  VAR("AuthoritativeDirectory",  BOOL, AuthoritativeDir,    "0"),
  V(AutomapHostsOnResolve,       BOOL,     "0"),
  V(AutomapHostsSuffixes,        CSV,      ".onion,.exit"),
  V(AvoidDiskWrites,             BOOL,     "0"),
163
164
  V(BandwidthBurst,              MEMUNIT,  "10 MB"),
  V(BandwidthRate,               MEMUNIT,  "5 MB"),
165
166
  V(BridgeAuthoritativeDir,      BOOL,     "0"),
  VAR("Bridge",                  LINELIST, Bridges,    NULL),
167
  V(BridgePassword,              STRING,   NULL),
168
  V(BridgeRecordUsageByCountry,  BOOL,     "1"),
169
  V(BridgeRelay,                 BOOL,     "0"),
170
  V(CellStatistics,              BOOL,     "0"),
171
  V(LearnCircuitBuildTimeout,    BOOL,     "1"),
172
  V(CircuitBuildTimeout,         INTERVAL, "0"),
173
  V(CircuitIdleTimeout,          INTERVAL, "1 hour"),
174
  V(CircuitStreamTimeout,        INTERVAL, "0"),
175
  V(CircuitPriorityHalflife,     DOUBLE,  "-100.0"), /*negative:'Use default'*/
176
177
  V(ClientDNSRejectInternalAddresses, BOOL,"1"),
  V(ClientOnly,                  BOOL,     "0"),
178
  V(ConsensusParams,             STRING,   NULL),
179
180
181
182
183
184
185
186
187
188
  V(ConnLimit,                   UINT,     "1000"),
  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),
189
  V(DataDirectory,               FILENAME, NULL),
190
  OBSOLETE("DebugLogFile"),
191
  V(DirAllowPrivateAddresses,    BOOL,     NULL),
192
  V(TestingAuthDirTimeToLearnReachability, INTERVAL, "30 minutes"),
193
  V(DirListenAddress,            LINELIST, NULL),
194
  OBSOLETE("DirFetchPeriod"),
195
196
  V(DirPolicy,                   LINELIST, NULL),
  V(DirPort,                     UINT,     "0"),
197
  V(DirPortFrontPage,            FILENAME, NULL),
198
  OBSOLETE("DirPostPeriod"),
199
200
201
202
  OBSOLETE("DirRecordUsageByCountry"),
  OBSOLETE("DirRecordUsageGranularity"),
  OBSOLETE("DirRecordUsageRetainIPs"),
  OBSOLETE("DirRecordUsageSaveInterval"),
Karsten Loesing's avatar
Karsten Loesing committed
203
  V(DirReqStatistics,            BOOL,     "0"),
204
  VAR("DirServer",               LINELIST, DirServers, NULL),
205
  V(DisableAllSwap,              BOOL,     "0"),
206
207
208
209
  V(DNSPort,                     UINT,     "0"),
  V(DNSListenAddress,            LINELIST, NULL),
  V(DownloadExtraInfo,           BOOL,     "0"),
  V(EnforceDistinctSubnets,      BOOL,     "1"),
210
  V(EntryNodes,                  ROUTERSET,   NULL),
211
  V(EntryStatistics,             BOOL,     "0"),
212
  V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "10 minutes"),
213
214
  V(ExcludeNodes,                ROUTERSET, NULL),
  V(ExcludeExitNodes,            ROUTERSET, NULL),
215
  V(ExcludeSingleHopRelays,      BOOL,     "1"),
216
  V(ExitNodes,                   ROUTERSET, NULL),
217
218
  V(ExitPolicy,                  LINELIST, NULL),
  V(ExitPolicyRejectPrivate,     BOOL,     "1"),
219
  V(ExitPortStatistics,          BOOL,     "0"),
220
  V(ExtraInfoStatistics,         BOOL,     "0"),
221

valerino's avatar
valerino committed
222
223
224
#if defined (WINCE)
  V(FallbackNetworkstatusFile,   FILENAME, "fallback-consensus"),
#else
225
  V(FallbackNetworkstatusFile,   FILENAME,
226
    SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "fallback-consensus"),
valerino's avatar
valerino committed
227
#endif
228
229
230
  V(FascistFirewall,             BOOL,     "0"),
  V(FirewallPorts,               CSV,      ""),
  V(FastFirstHopPK,              BOOL,     "1"),
231
  V(FetchDirInfoEarly,           BOOL,     "0"),
232
  V(FetchDirInfoExtraEarly,      BOOL,     "0"),
233
234
235
  V(FetchServerDescriptors,      BOOL,     "1"),
  V(FetchHidServDescriptors,     BOOL,     "1"),
  V(FetchUselessDescriptors,     BOOL,     "0"),
236
#ifdef WIN32
237
  V(GeoIPFile,                   FILENAME, "<default>"),
238
#else
239
240
  V(GeoIPFile,                   FILENAME,
    SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "geoip"),
241
#endif
242
  OBSOLETE("Group"),
243
  V(HardwareAccel,               BOOL,     "0"),
244
245
  V(AccelName,                   STRING,   NULL),
  V(AccelDir,                    FILENAME, NULL),
246
  V(HashedControlPassword,       LINELIST, NULL),
247
  V(HidServDirectoryV2,          BOOL,     "1"),
Nick Mathewson's avatar
Nick Mathewson committed
248
  VAR("HiddenServiceDir",    LINELIST_S, RendConfigLines,    NULL),
249
250
  OBSOLETE("HiddenServiceExcludeNodes"),
  OBSOLETE("HiddenServiceNodes"),
Nick Mathewson's avatar
Nick Mathewson committed
251
252
  VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines,    NULL),
  VAR("HiddenServicePort",   LINELIST_S, RendConfigLines,    NULL),
253
  VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines,    NULL),
254
  VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL),
255
  V(HidServAuth,                 LINELIST, NULL),
256
  V(HSAuthoritativeDir,          BOOL,     "0"),
257
  OBSOLETE("HSAuthorityRecordStats"),
258
259
260
261
  V(HttpProxy,                   STRING,   NULL),
  V(HttpProxyAuthenticator,      STRING,   NULL),
  V(HttpsProxy,                  STRING,   NULL),
  V(HttpsProxyAuthenticator,     STRING,   NULL),
262
263
264
265
  V(Socks4Proxy,                 STRING,   NULL),
  V(Socks5Proxy,                 STRING,   NULL),
  V(Socks5ProxyUsername,         STRING,   NULL),
  V(Socks5ProxyPassword,         STRING,   NULL),
266
  OBSOLETE("IgnoreVersion"),
267
268
  V(KeepalivePeriod,             INTERVAL, "5 minutes"),
  VAR("Log",                     LINELIST, Logs,             NULL),
269
  OBSOLETE("LinkPadding"),
270
271
  OBSOLETE("LogLevel"),
  OBSOLETE("LogFile"),
272
  V(LongLivedPorts,              CSV,
273
                         "21,22,706,1863,5050,5190,5222,5223,6667,6697,8300"),
274
275
276
277
  VAR("MapAddress",              LINELIST, AddressMap,           NULL),
  V(MaxAdvertisedBandwidth,      MEMUNIT,  "1 GB"),
  V(MaxCircuitDirtiness,         INTERVAL, "10 minutes"),
  V(MaxOnionsPending,            UINT,     "100"),
278
  OBSOLETE("MonthlyAccountingStart"),
279
280
  V(MyFamily,                    STRING,   NULL),
  V(NewCircuitPeriod,            INTERVAL, "30 seconds"),
281
  VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "0"),
282
283
284
  V(NatdListenAddress,           LINELIST, NULL),
  V(NatdPort,                    UINT,     "0"),
  V(Nickname,                    STRING,   NULL),
285
  V(WarnUnsafeSocks,              BOOL,     "1"),
286
287
288
289
290
291
292
  V(NoPublish,                   BOOL,     "0"),
  VAR("NodeFamily",              LINELIST, NodeFamilies,         NULL),
  V(NumCpus,                     UINT,     "1"),
  V(NumEntryGuards,              UINT,     "3"),
  V(ORListenAddress,             LINELIST, NULL),
  V(ORPort,                      UINT,     "0"),
  V(OutboundBindAddress,         STRING,   NULL),
293
  OBSOLETE("PathlenCoinWeight"),
294
295
  V(PerConnBWBurst,              MEMUNIT,  "0"),
  V(PerConnBWRate,               MEMUNIT,  "0"),
296
  V(PidFile,                     STRING,   NULL),
297
  V(TestingTorNetwork,           BOOL,     "0"),
Roger Dingledine's avatar
Roger Dingledine committed
298
  V(PreferTunneledDirConns,      BOOL,     "1"),
299
  V(ProtocolWarnings,            BOOL,     "0"),
300
  V(PublishServerDescriptor,     CSV,      "1"),
301
302
303
304
305
306
307
  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),
308
  OBSOLETE("RedirectExit"),
309
  V(RefuseUnknownExits,          BOOL,     "0"),
310
  V(RejectPlaintextPorts,        CSV,      ""),
311
312
  V(RelayBandwidthBurst,         MEMUNIT,  "0"),
  V(RelayBandwidthRate,          MEMUNIT,  "0"),
313
314
  OBSOLETE("RendExcludeNodes"),
  OBSOLETE("RendNodes"),
315
316
  V(RendPostPeriod,              INTERVAL, "1 hour"),
  V(RephistTrackTime,            INTERVAL, "24 hours"),
317
  OBSOLETE("RouterFile"),
318
319
  V(RunAsDaemon,                 BOOL,     "0"),
  V(RunTesting,                  BOOL,     "0"),
320
  V(SafeLogging,                 STRING,   "1"),
321
  V(SafeSocks,                   BOOL,     "0"),
322
  V(ServerDNSAllowBrokenConfig,  BOOL,     "1"),
323
324
  V(ServerDNSAllowNonRFC953Hostnames, BOOL,"0"),
  V(ServerDNSDetectHijacking,    BOOL,     "1"),
325
  V(ServerDNSRandomizeCase,      BOOL,     "1"),
326
327
328
  V(ServerDNSResolvConfFile,     STRING,   NULL),
  V(ServerDNSSearchDomains,      BOOL,     "0"),
  V(ServerDNSTestAddresses,      CSV,
329
      "www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"),
330
331
332
333
334
  V(ShutdownWaitLength,          INTERVAL, "30 seconds"),
  V(SocksListenAddress,          LINELIST, NULL),
  V(SocksPolicy,                 LINELIST, NULL),
  V(SocksPort,                   UINT,     "9050"),
  V(SocksTimeout,                INTERVAL, "2 minutes"),
335
  OBSOLETE("StatusFetchPeriod"),
336
  V(StrictNodes,                 BOOL,     "0"),
337
  OBSOLETE("SysLog"),
338
  V(TestSocks,                   BOOL,     "0"),
339
  OBSOLETE("TestVia"),
340
341
  V(TrackHostExits,              CSV,      NULL),
  V(TrackHostExitsExpire,        INTERVAL, "30 minutes"),
342
  OBSOLETE("TrafficShaping"),
343
344
  V(TransListenAddress,          LINELIST, NULL),
  V(TransPort,                   UINT,     "0"),
Roger Dingledine's avatar
Roger Dingledine committed
345
  V(TunnelDirConns,              BOOL,     "1"),
346
347
348
349
  V(UpdateBridgesFromAuthority,  BOOL,     "0"),
  V(UseBridges,                  BOOL,     "0"),
  V(UseEntryGuards,              BOOL,     "1"),
  V(User,                        STRING,   NULL),
350
  VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir,   "0"),
351
  VAR("V2AuthoritativeDirectory",BOOL, V2AuthoritativeDir,   "0"),
352
  VAR("V3AuthoritativeDirectory",BOOL, V3AuthoritativeDir,   "0"),
353
354
355
  V(TestingV3AuthInitialVotingInterval, INTERVAL, "30 minutes"),
  V(TestingV3AuthInitialVoteDelay, INTERVAL, "5 minutes"),
  V(TestingV3AuthInitialDistDelay, INTERVAL, "5 minutes"),
356
357
358
359
  V(V3AuthVotingInterval,        INTERVAL, "1 hour"),
  V(V3AuthVoteDelay,             INTERVAL, "5 minutes"),
  V(V3AuthDistDelay,             INTERVAL, "5 minutes"),
  V(V3AuthNIntervalsValid,       UINT,     "3"),
360
  V(V3AuthUseLegacyKey,          BOOL,     "0"),
361
  V(V3BandwidthsFile,            FILENAME, NULL),
362
  VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
363
  V(VirtualAddrNetwork,          STRING,   "127.192.0.0/10"),
364
  V(WarnPlaintextPorts,          CSV,      "23,109,110,143"),
365
  VAR("__ReloadTorrcOnSIGHUP",   BOOL,  ReloadTorrcOnSIGHUP,      "1"),
366
367
368
  VAR("__AllDirActionsPrivate",  BOOL,  AllDirActionsPrivate,     "0"),
  VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits, "0"),
  VAR("__LeaveStreamsUnattached",BOOL,  LeaveStreamsUnattached,   "0"),
369
370
  VAR("__HashedControlSessionPassword", LINELIST, HashedControlSessionPassword,
      NULL),
371
  V(MinUptimeHidServDirectoryV2, INTERVAL, "24 hours"),
372

373
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
374
};
375

376
377
/** Override default values with these if the user sets the TestingTorNetwork
 * option. */
378
static config_var_t testing_tor_network_defaults[] = {
379
  V(ServerDNSAllowBrokenConfig,  BOOL,  "1"),
380
381
382
383
384
385
386
387
388
389
  V(DirAllowPrivateAddresses,    BOOL,     "1"),
  V(EnforceDistinctSubnets,      BOOL,     "0"),
  V(AssumeReachable,             BOOL,     "1"),
  V(AuthDirMaxServersPerAddr,    UINT,     "0"),
  V(AuthDirMaxServersPerAuthAddr,UINT,     "0"),
  V(ClientDNSRejectInternalAddresses, BOOL,"0"),
  V(ExitPolicyRejectPrivate,     BOOL,     "0"),
  V(V3AuthVotingInterval,        INTERVAL, "5 minutes"),
  V(V3AuthVoteDelay,             INTERVAL, "20 seconds"),
  V(V3AuthDistDelay,             INTERVAL, "20 seconds"),
390
391
392
393
394
  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"),
395
396
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
};
397
398
#undef VAR

399
400
#define VAR(name,conftype,member,initvalue)                             \
  { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member),  \
401
      initvalue }
402
403

/** Array of "state" variables saved to the ~/.tor/state file. */
404
static config_var_t _state_vars[] = {
405
406
407
408
409
  V(AccountingBytesReadInInterval,    MEMUNIT,  NULL),
  V(AccountingBytesWrittenInInterval, MEMUNIT,  NULL),
  V(AccountingExpectedUsage,          MEMUNIT,  NULL),
  V(AccountingIntervalStart,          ISOTIME,  NULL),
  V(AccountingSecondsActive,          INTERVAL, NULL),
Roger Dingledine's avatar
Roger Dingledine committed
410

411
412
413
  VAR("EntryGuard",              LINELIST_S,  EntryGuards,             NULL),
  VAR("EntryGuardDownSince",     LINELIST_S,  EntryGuards,             NULL),
  VAR("EntryGuardUnlistedSince", LINELIST_S,  EntryGuards,             NULL),
414
  VAR("EntryGuardAddedBy",       LINELIST_S,  EntryGuards,             NULL),
415
  V(EntryGuards,                 LINELIST_V,  NULL),
Nick Mathewson's avatar
Nick Mathewson committed
416

417
418
419
420
421
422
  V(BWHistoryReadEnds,                ISOTIME,  NULL),
  V(BWHistoryReadInterval,            UINT,     "900"),
  V(BWHistoryReadValues,              CSV,      ""),
  V(BWHistoryWriteEnds,               ISOTIME,  NULL),
  V(BWHistoryWriteInterval,           UINT,     "900"),
  V(BWHistoryWriteValues,             CSV,      ""),
423

424
  V(TorVersion,                       STRING,   NULL),
425

426
427
  V(LastRotatedOnionKey,              ISOTIME,  NULL),
  V(LastWritten,                      ISOTIME,  NULL),
428

429
  V(TotalBuildTimes,                  UINT,     NULL),
430
  V(CircuitBuildAbandonedCount,         UINT,     "0"),
431
432
  VAR("CircuitBuildTimeBin",          LINELIST_S, BuildtimeHistogram, NULL),
  VAR("BuildtimeHistogram",           LINELIST_V, BuildtimeHistogram, NULL),
433

434
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
435
436
};

437
#undef VAR
438
#undef V
439
440
#undef OBSOLETE

441
442
/** Represents an English description of a configuration variable; used when
 * generating configuration file comments. */
443
444
445
446
447
typedef struct config_var_description_t {
  const char *name;
  const char *description;
} config_var_description_t;

448
/** Type of a callback to validate whether a given configuration is
Roger Dingledine's avatar
Roger Dingledine committed
449
 * well-formed and consistent. See options_trial_assign() for documentation
450
 * of arguments. */
451
typedef int (*validate_fn_t)(void*,void*,int,char**);
452

453
454
455
/** Information on the keys, value types, key-to-struct-member mappings,
 * variable descriptions, validation functions, and abbreviations for a
 * configuration or storage format. */
456
typedef struct {
457
458
459
  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
460
  off_t magic_offset; /**< Offset of the magic value within the struct. */
461
  config_abbrev_t *abbrevs; /**< List of abbreviations that we expand when
Roger Dingledine's avatar
Roger Dingledine committed
462
                             * parsing this format. */
463
464
465
  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
466
467
468
  /** If present, extra is a LINELIST variable for unrecognized
   * lines.  Otherwise, unrecognized lines are an error. */
  config_var_t *extra;
469
470
} config_format_t;

471
472
/** Macro: assert that <b>cfg</b> has the right magic field for format
 * <b>fmt</b>. */
473
#define CHECK(fmt, cfg) STMT_BEGIN                                      \
474
    tor_assert(fmt && cfg);                                             \
475
    tor_assert((fmt)->magic ==                                          \
476
               *(uint32_t*)STRUCT_VAR_P(cfg,fmt->magic_offset));        \
477
  STMT_END
478

479
480
481
#ifdef MS_WINDOWS
static char *get_windows_conf_root(void);
#endif
482
static void config_line_append(config_line_t **lst,
483
                               const char *key, const char *val);
484
485
static void option_clear(config_format_t *fmt, or_options_t *options,
                         config_var_t *var);
486
static void option_reset(config_format_t *fmt, or_options_t *options,
487
                         config_var_t *var, int use_defaults);
488
static void config_free(config_format_t *fmt, void *options);
489
static int config_lines_eq(config_line_t *a, config_line_t *b);
490
static int option_is_same(config_format_t *fmt,
491
492
                          or_options_t *o1, or_options_t *o2,
                          const char *name);
493
static or_options_t *options_dup(config_format_t *fmt, or_options_t *old);
494
495
496
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);
497
static int options_act(or_options_t *old_options);
498
499
static int options_transition_allowed(or_options_t *old, or_options_t *new,
                                      char **msg);
500
501
502
503
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);
504
static int check_nickname_list(const char *lst, const char *name, char **msg);
505
static void config_register_addressmaps(or_options_t *options);
506

507
static int parse_bridge_line(const char *line, int validate_only);
508
509
510
static int parse_dir_server_line(const char *line,
                                 authority_type_t required_type,
                                 int validate_only);
511
static int validate_data_directory(or_options_t *options);
512
static int write_configuration_file(const char *fname, or_options_t *options);
513
static config_line_t *get_assigned_option(config_format_t *fmt,
514
515
                                          void *options, const char *key,
                                          int escape_val);
516
static void config_init(config_format_t *fmt, void *options);
517
static int or_state_validate(or_state_t *old_options, or_state_t *options,
518
                             int from_setconf, char **msg);
519
520
static int or_state_load(void);
static int options_init_logs(or_options_t *options, int validate_only);
521

522
523
524
static int is_listening_on_low_port(uint16_t port_option,
                                    const config_line_t *listen_options);

525
526
static uint64_t config_parse_memunit(const char *s, int *ok);
static int config_parse_interval(const char *s, int *ok);
527
static void init_libevent(void);
528
static int opt_streq(const char *s1, const char *s2);
529

530
/** Magic value for or_options_t. */
531
532
#define OR_OPTIONS_MAGIC 9090909

533
/** Configuration format for or_options_t. */
534
static config_format_t options_format = {
535
536
537
  sizeof(or_options_t),
  OR_OPTIONS_MAGIC,
  STRUCT_OFFSET(or_options_t, _magic),
538
539
540
  _option_abbrevs,
  _option_vars,
  (validate_fn_t)options_validate,
541
  NULL
542
543
};

544
/** Magic value for or_state_t. */
545
546
#define OR_STATE_MAGIC 0x57A73f57

547
548
/** "Extra" variable in the state that receives lines we can't parse. This
 * lets us preserve options from versions of Tor newer than us. */
549
550
551
552
static config_var_t state_extra_var = {
  "__extra", CONFIG_TYPE_LINELIST, STRUCT_OFFSET(or_state_t, ExtraLines), NULL
};

553
/** Configuration format for or_state_t. */
554
555
556
557
static config_format_t state_format = {
  sizeof(or_state_t),
  OR_STATE_MAGIC,
  STRUCT_OFFSET(or_state_t, _magic),
558
  _state_abbrevs,
559
560
  _state_vars,
  (validate_fn_t)or_state_validate,
561
  &state_extra_var,
562
563
};

564
565
566
567
568
/*
 * Functions to read and write the global options pointer.
 */

/** Command-line and config-file options. */
569
static or_options_t *global_options = NULL;
Roger Dingledine's avatar
Roger Dingledine committed
570
/** Name of most recently read torrc file. */
571
static char *torrc_fname = NULL;
572
/** Persistent serialized state. */
573
static or_state_t *global_state = NULL;
574
575
/** Configuration Options set by command line. */
static config_line_t *global_cmdline_options = NULL;
Roger Dingledine's avatar
Roger Dingledine committed
576
/** Contents of most recently read DirPortFrontPage file. */
577
578
579
580
581
582
583
584
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;
}
585

586
/** Allocate an empty configuration object of a given format type. */
587
588
589
static void *
config_alloc(config_format_t *fmt)
{
590
  void *opts = tor_malloc_zero(fmt->size);
591
  *(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
592
593
594
595
  CHECK(fmt, opts);
  return opts;
}

596
597
/** Return the currently configured options. */
or_options_t *
598
599
get_options(void)
{
600
601
602
  tor_assert(global_options);
  return global_options;
}
603

604
605
/** 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
606
 * as necessary.  Returns 0 on success, -1 on failure.
607
 */
608
int
609
set_options(or_options_t *new_val, char **msg)
610
{
611
  or_options_t *old_options = global_options;
612
  global_options = new_val;
613
614
  /* Note that we pass the *old* options below, for comparison. It
   * pulls the new options directly out of global_options. */
615
616
  if (options_act_reversible(old_options, msg)<0) {
    tor_assert(*msg);
617
618
619
    global_options = old_options;
    return -1;
  }
620
  if (options_act(old_options) < 0) { /* acting on the options failed. die. */
621
    log_err(LD_BUG,
Roger Dingledine's avatar
Roger Dingledine committed
622
            "Acting on config options left us in a broken state. Dying.");
623
624
    exit(1);
  }
625
626

  config_free(&options_format, old_options);
627
628

  return 0;
629
630
}

631
extern const char tor_git_revision[]; /* from tor_main.c */
632

633
/** The version of this Tor process, as parsed. */
634
635
static char *_version = NULL;

636
/** Return the current Tor version. */
637
638
639
const char *
get_version(void)
{
640
  if (_version == NULL) {
641
642
    if (strlen(tor_git_revision)) {
      size_t len = strlen(VERSION)+strlen(tor_git_revision)+16;
643
      _version = tor_malloc(len);
644
      tor_snprintf(_version, len, "%s (git-%s)", VERSION, tor_git_revision);
645
    } else {
646
      _version = tor_strdup(VERSION);
647
648
    }
  }
649
  return _version;
650
651
}

652
653
654
655
656
/** Release additional memory allocated in options
 */
static void
or_options_free(or_options_t *options)
{
657
658
659
  if (!options)
    return;

660
  routerset_free(options->_ExcludeExitNodesUnion);
661
662
663
  config_free(&options_format, options);
}

664
665
/** Release all memory and resources held by global configuration structures.
 */
666
667
668
void
config_free_all(void)
{
669
670
671
672
673
674
675
676
677
  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;

678
  tor_free(torrc_fname);
679
  tor_free(_version);
680
  tor_free(global_dirfrontpagecontents);
681
682
}

683
684
685
686
687
/** 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.)
688
689
 */
const char *
690
safe_str_client(const char *address)
691
{
692
  tor_assert(address);
693
  if (get_options()->_SafeLogging == SAFELOG_SCRUB_ALL)
694
695
696
697
698
    return "[scrubbed]";
  else
    return address;
}

699
700
701
702
703
704
/** 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.)
705
706
 */
const char *
707
708
safe_str(const char *address)
{
709
  tor_assert(address);
710
  if (get_options()->_SafeLogging != SAFELOG_SCRUB_NONE)
711
712
713
714
715
    return "[scrubbed]";
  else
    return address;
}

716
/** Equivalent to escaped(safe_str_client(address)).  See reentrancy note on
717
718
 * escaped(): don't use this outside the main thread, or twice in the same
 * log statement. */
719
const char *
720
escaped_safe_str_client(const char *address)
721
{
722
  if (get_options()->_SafeLogging == SAFELOG_SCRUB_ALL)
723
724
725
726
727
    return "[scrubbed]";
  else
    return escaped(address);
}

728
/** Equivalent to escaped(safe_str(address)).  See reentrancy note on
729
730
 * escaped(): don't use this outside the main thread, or twice in the same
 * log statement. */
731
732
733
const char *
escaped_safe_str(const char *address)
{
734
  if (get_options()->_SafeLogging != SAFELOG_SCRUB_NONE)
735
736
737
738
739
    return "[scrubbed]";
  else
    return escaped(address);
}

740
741
/** Add the default directory authorities directly into the trusted dir list,
 * but only add them insofar as they share bits with <b>type</b>. */
742
static void
743
add_default_trusted_dir_authorities(authority_type_t type)
744
{
745
  int i;
746
  const char *dirservers[] = {
747
748
749
    "moria1 orport=9101 no-v2 "
      "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
      "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
750
    "tor26 v1 orport=443 v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
Peter Palfrader's avatar
Peter Palfrader committed
751
      "86.59.21.38:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
Roger Dingledine's avatar
Roger Dingledine committed
752
753
    "dizum orport=443 v3ident=E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58 "
      "194.109.206.212:80 7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
754
    "Tonga orport=443 bridge no-v2 82.94.251.203:80 "
755
      "4A0C CD2D DC79 9508 3D73 F5D6 6710 0C8A 5831 F16D",
756
757
    "ides orport=9090 no-v2 v3ident=27B6B5996C426270A5C95488AA5BCEB6BCC86956 "
      "216.224.124.114:9030 F397 038A DC51 3361 35E7 B80B D99C A384 4360 292B",
758
759
760
    "gabelmoo orport=8080 no-v2 "
      "v3ident=ED03BB616EB2F60BEC80151114BB25CEF515B226 "
      "80.190.246.100:8180 F204 4413 DAC2 E02E 3D6B CF47 35A1 9BCA 1DE9 7281",
761
762
    "dannenberg orport=443 no-v2 "
      "v3ident=585769C78764D58426B8B52B6651A5A71137189A "
763
      "193.23.244.244:80 7BE6 83E6 5D48 1413 21C5 ED92 F075 C553 64AC 7123",
764
765
    "urras orport=80 no-v2 v3ident=80550987E1D626E3EBA5E5E75A458DE0626D088C "
      "208.83.223.34:443 0AD3 FA88 4D18 F89E EA2D 89C0 1937 9E0E 7FD9 4417",
766
767
768
    "maatuska orport=80 no-v2 "
      "v3ident=49015F787433103580E3B66A1707A00E60F2D15B "
      "213.115.239.118:443 BD6A 8292 55CB 08E6 6FBE 7D37 4836 3586 E46B 3810",
769
    NULL
770
  };
771
772
773
774
775
776
  for (i=0; dirservers[i]; i++) {
    if (parse_dir_server_line(dirservers[i], type, 0)<0) {
      log_err(LD_BUG, "Couldn't parse internal dirserver line %s",
              dirservers[i]);
    }
  }
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
}

/** Look at all the config options for using alternate directory
 * authorities, and make sure none of them are broken. Also, warn the
 * user if we changed any dangerous ones.
 */
static int
validate_dir_authorities(or_options_t *options, or_options_t *old_options)
{
  config_line_t *cl;

  if (options->DirServers &&
      (options->AlternateDirAuthority || options->AlternateBridgeAuthority ||
       options->AlternateHSAuthority)) {
    log_warn(LD_CONFIG,
             "You cannot set both DirServers and Alternate*Authority.");
    return -1;
  }

  /* do we want to complain to the user about being partitionable? */
  if ((options->DirServers &&
       (!old_options ||
        !config_lines_eq(options->DirServers, old_options->DirServers))) ||
      (options->AlternateDirAuthority &&
       (!old_options ||
        !config_lines_eq(options->AlternateDirAuthority,
                         old_options->AlternateDirAuthority)))) {
    log_warn(LD_CONFIG,
             "You have used DirServer or AlternateDirAuthority to "
             "specify alternate directory authorities in "
             "your configuration. This is potentially dangerous: it can "
             "make you look different from all other Tor users, and hurt "
             "your anonymity. Even if you've specified the same "
             "authorities as Tor uses by default, the defaults could "
             "change in the future. Be sure you know what you're doing.");
  }

  /* Now go through the four ways you can configure an alternate
   * set of directory authorities, and make sure none are broken. */
  for (cl = options->DirServers; cl; cl = cl->next)
817
    if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
818
819
      return -1;
  for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
820
    if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
821
822
      return -1;
  for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
823
    if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
824
825
      return -1;
  for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
826
    if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
827
828
829
830
831
832
833
834
835
836
837
838
839
      return -1;
  return 0;
}

/** Look at all the config options and assign new dir authorities
 * as appropriate.
 */
static int
consider_adding_dir_authorities(or_options_t *options,
                                or_options_t *old_options)
{
  config_line_t *cl;
  int need_to_update =
840
    !smartlist_len(router_get_trusted_dir_servers()) || !old_options ||
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
    !config_lines_eq(options->DirServers, old_options->DirServers) ||
    !config_lines_eq(options->AlternateBridgeAuthority,
                     old_options->AlternateBridgeAuthority) ||
    !config_lines_eq(options->AlternateDirAuthority,
                     old_options->AlternateDirAuthority) ||