config.c 200 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
  VAR("MapAddress",              LINELIST, AddressMap,           NULL),
  V(MaxAdvertisedBandwidth,      MEMUNIT,  "1 GB"),
  V(MaxCircuitDirtiness,         INTERVAL, "10 minutes"),
318
  V(MaxClientCircuitsPending,    UINT,     "32"),
319
  V(MaxOnionsPending,            UINT,     "100"),
320
  OBSOLETE("MonthlyAccountingStart"),
321
322
  V(MyFamily,                    STRING,   NULL),
  V(NewCircuitPeriod,            INTERVAL, "30 seconds"),
323
  VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "0"),
324
  V(NATDListenAddress,           LINELIST, NULL),
325
  V(NATDPort,                    LINELIST, NULL),
326
  V(Nickname,                    STRING,   NULL),
327
  V(WarnUnsafeSocks,              BOOL,     "1"),
Sebastian Hahn's avatar
Sebastian Hahn committed
328
  OBSOLETE("NoPublish"),
329
  VAR("NodeFamily",              LINELIST, NodeFamilies,         NULL),
330
  V(NumCPUs,                     UINT,     "0"),
331
332
  V(NumEntryGuards,              UINT,     "3"),
  V(ORListenAddress,             LINELIST, NULL),
333
  V(ORPort,                      PORT,     "0"),
334
  V(OutboundBindAddress,         STRING,   NULL),
335
  OBSOLETE("PathlenCoinWeight"),
336
337
  V(PerConnBWBurst,              MEMUNIT,  "0"),
  V(PerConnBWRate,               MEMUNIT,  "0"),
338
  V(PidFile,                     STRING,   NULL),
339
  V(TestingTorNetwork,           BOOL,     "0"),
340
  V(OptimisticData,              AUTOBOOL, "auto"),
341
342
  V(PortForwarding,              BOOL,     "0"),
  V(PortForwardingHelper,        FILENAME, "tor-fw-helper"),
Roger Dingledine's avatar
Roger Dingledine committed
343
  V(PreferTunneledDirConns,      BOOL,     "1"),
344
  V(ProtocolWarnings,            BOOL,     "0"),
345
  V(PublishServerDescriptor,     CSV,      "1"),
346
347
348
349
350
351
352
  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),
353
  OBSOLETE("RedirectExit"),
354
  V(RefuseUnknownExits,          AUTOBOOL, "auto"),
355
  V(RejectPlaintextPorts,        CSV,      ""),
356
357
  V(RelayBandwidthBurst,         MEMUNIT,  "0"),
  V(RelayBandwidthRate,          MEMUNIT,  "0"),
358
359
  OBSOLETE("RendExcludeNodes"),
  OBSOLETE("RendNodes"),
360
361
  V(RendPostPeriod,              INTERVAL, "1 hour"),
  V(RephistTrackTime,            INTERVAL, "24 hours"),
362
  OBSOLETE("RouterFile"),
363
  V(RunAsDaemon,                 BOOL,     "0"),
364
365
//  V(RunTesting,                  BOOL,     "0"),
  OBSOLETE("RunTesting"), // currently unused
366
  V(SafeLogging,                 STRING,   "1"),
367
  V(SafeSocks,                   BOOL,     "0"),
368
  V(ServerDNSAllowBrokenConfig,  BOOL,     "1"),
369
370
  V(ServerDNSAllowNonRFC953Hostnames, BOOL,"0"),
  V(ServerDNSDetectHijacking,    BOOL,     "1"),
371
  V(ServerDNSRandomizeCase,      BOOL,     "1"),
372
373
374
  V(ServerDNSResolvConfFile,     STRING,   NULL),
  V(ServerDNSSearchDomains,      BOOL,     "0"),
  V(ServerDNSTestAddresses,      CSV,
375
      "www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"),
376
377
378
  V(ShutdownWaitLength,          INTERVAL, "30 seconds"),
  V(SocksListenAddress,          LINELIST, NULL),
  V(SocksPolicy,                 LINELIST, NULL),
379
  V(SocksPort,                   LINELIST, NULL),
380
  V(SocksTimeout,                INTERVAL, "2 minutes"),
381
  OBSOLETE("StatusFetchPeriod"),
382
  V(StrictNodes,                 BOOL,     "0"),
383
  OBSOLETE("SysLog"),
384
  V(TestSocks,                   BOOL,     "0"),
385
  OBSOLETE("TestVia"),
386
387
  V(TrackHostExits,              CSV,      NULL),
  V(TrackHostExitsExpire,        INTERVAL, "30 minutes"),
388
  OBSOLETE("TrafficShaping"),
389
  V(TransListenAddress,          LINELIST, NULL),
390
  V(TransPort,                   LINELIST, NULL),
Roger Dingledine's avatar
Roger Dingledine committed
391
  V(TunnelDirConns,              BOOL,     "1"),
392
  V(UpdateBridgesFromAuthority,  BOOL,     "0"),
393
  V(UseBridges,                  BOOL,     "0"),
394
  V(UseEntryGuards,              BOOL,     "1"),
395
  V(UseMicrodescriptors,         AUTOBOOL, "auto"),
396
  V(User,                        STRING,   NULL),
397
  VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir,   "0"),
398
  VAR("V2AuthoritativeDirectory",BOOL, V2AuthoritativeDir,   "0"),
399
  VAR("V3AuthoritativeDirectory",BOOL, V3AuthoritativeDir,   "0"),
400
401
402
  V(TestingV3AuthInitialVotingInterval, INTERVAL, "30 minutes"),
  V(TestingV3AuthInitialVoteDelay, INTERVAL, "5 minutes"),
  V(TestingV3AuthInitialDistDelay, INTERVAL, "5 minutes"),
403
404
405
406
  V(V3AuthVotingInterval,        INTERVAL, "1 hour"),
  V(V3AuthVoteDelay,             INTERVAL, "5 minutes"),
  V(V3AuthDistDelay,             INTERVAL, "5 minutes"),
  V(V3AuthNIntervalsValid,       UINT,     "3"),
407
  V(V3AuthUseLegacyKey,          BOOL,     "0"),
408
  V(V3BandwidthsFile,            FILENAME, NULL),
409
  VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
410
  V(VirtualAddrNetwork,          STRING,   "127.192.0.0/10"),
411
  V(WarnPlaintextPorts,          CSV,      "23,109,110,143"),
412
  V(_UseFilteringSSLBufferevents, BOOL,    "0"),
413
  VAR("__ReloadTorrcOnSIGHUP",   BOOL,  ReloadTorrcOnSIGHUP,      "1"),
414
415
416
  VAR("__AllDirActionsPrivate",  BOOL,  AllDirActionsPrivate,     "0"),
  VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits, "0"),
  VAR("__LeaveStreamsUnattached",BOOL,  LeaveStreamsUnattached,   "0"),
417
418
  VAR("__HashedControlSessionPassword", LINELIST, HashedControlSessionPassword,
      NULL),
419
  VAR("__OwningControllerProcess",STRING,OwningControllerProcess, NULL),
420
  V(MinUptimeHidServDirectoryV2, INTERVAL, "24 hours"),
421
  V(_UsingTestNetworkDefaults,   BOOL,     "0"),
422

423
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
424
};
425

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

450
451
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
};
452
453
#undef VAR

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

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

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

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

492
  V(TorVersion,                       STRING,   NULL),
493

494
495
  V(LastRotatedOnionKey,              ISOTIME,  NULL),
  V(LastWritten,                      ISOTIME,  NULL),
496

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

502
  { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
503
504
};

505
#undef VAR
506
#undef V
507
508
#undef OBSOLETE

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

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

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

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

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

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

597
static int is_listening_on_low_port(int port_option,
598
599
                                    const config_line_t *listen_options);

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

606
/** Magic value for or_options_t. */
607
608
#define OR_OPTIONS_MAGIC 9090909

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

620
/** Magic value for or_state_t. */
621
622
#define OR_STATE_MAGIC 0x57A73f57

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

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

640
641
642
643
644
/*
 * Functions to read and write the global options pointer.
 */

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

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

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

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

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

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

  config_free(&options_format, old_options);
712
713

  return 0;
714
715
}

716
extern const char tor_git_revision[]; /* from tor_main.c */
717

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

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

737
738
739
740
741
/** Release additional memory allocated in options
 */
static void
or_options_free(or_options_t *options)
{
742
743