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"
Sebastian Hahn's avatar
Sebastian Hahn committed
16
#include "router.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
17
#include "routerlist.h"
18
19
20
#ifdef MS_WINDOWS
#include <shlobj.h>
#endif
Roger Dingledine's avatar
Roger Dingledine committed
21

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

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

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

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

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

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

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

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

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

375
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
376
};
377

378
379
/** Override default values with these if the user sets the TestingTorNetwork
 * option. */
380
static config_var_t testing_tor_network_defaults[] = {
381
  V(ServerDNSAllowBrokenConfig,  BOOL,  "1"),
382
383
384
385
386
387
388
389
390
391
  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"),
392
393
394
395
396
  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"),
397
398
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
};
399
400
#undef VAR

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

/** Array of "state" variables saved to the ~/.tor/state file. */
406
static config_var_t _state_vars[] = {
407
408
409
410
411
  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
412

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

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

426
  V(TorVersion,                       STRING,   NULL),
427

428
429
  V(LastRotatedOnionKey,              ISOTIME,  NULL),
  V(LastWritten,                      ISOTIME,  NULL),
430

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

436
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
437
438
};

439
#undef VAR
440
#undef V
441
442
#undef OBSOLETE

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

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

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

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

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

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

524
525
526
static int is_listening_on_low_port(uint16_t port_option,
                                    const config_line_t *listen_options);

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

532
/** Magic value for or_options_t. */
533
534
#define OR_OPTIONS_MAGIC 9090909

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

546
/** Magic value for or_state_t. */
547
548
#define OR_STATE_MAGIC 0x57A73f57

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

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

566
567
568
569
570
/*
 * Functions to read and write the global options pointer.
 */

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

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

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

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

  config_free(&options_format, old_options);
629
630

  return 0;
631
632
}

633
extern const char tor_git_revision[]; /* from tor_main.c */
634

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

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

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

662
  routerset_free(options->_ExcludeExitNodesUnion);
663
664
665
  config_free(&options_format, options);
}

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

680
  tor_free(torrc_fname);
681
  tor_free(_version);
682
  tor_free(global_dirfrontpagecontents);
683
684
}

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

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

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

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

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

/** 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)
819
    if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
820
821
      return -1;
  for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
822
    if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
823
824
      return -1;
  for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
825
    if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
826
827
      return -1;
  for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
828
    if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
829
830
831
832
833
834
835
836
837
838
839
840
841
      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 =
842
    !smartlist_len(router_get_trusted_dir_servers()) || !old_options ||
843
844
845
846
847
848
849
85