Create rephist.h
[tor/rransom.git] / src / or / config.c
bloba4e4f89c1af67e312355a92b5d0c5d3ce7f23c22
1 /* Copyright (c) 2001 Matej Pfajfar.
2 * 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 */
7 /**
8 * \file config.c
9 * \brief Code to parse and interpret configuration files.
10 **/
12 #define CONFIG_PRIVATE
14 #include "or.h"
15 #include "circuitbuild.h"
16 #include "circuitlist.h"
17 #include "config.h"
18 #include "connection.h"
19 #include "connection_edge.h"
20 #include "control.h"
21 #include "cpuworker.h"
22 #include "dirserv.h"
23 #include "dirvote.h"
24 #include "dns.h"
25 #include "geoip.h"
26 #include "hibernate.h"
27 #include "main.h"
28 #include "networkstatus.h"
29 #include "policies.h"
30 #include "relay.h"
31 #include "rendclient.h"
32 #include "rendservice.h"
33 #include "rephist.h"
34 #include "router.h"
35 #include "routerlist.h"
36 #ifdef MS_WINDOWS
37 #include <shlobj.h>
38 #endif
40 /** Enumeration of types which option values can take */
41 typedef enum config_type_t {
42 CONFIG_TYPE_STRING = 0, /**< An arbitrary string. */
43 CONFIG_TYPE_FILENAME, /**< A filename: some prefixes get expanded. */
44 CONFIG_TYPE_UINT, /**< A non-negative integer less than MAX_INT */
45 CONFIG_TYPE_INTERVAL, /**< A number of seconds, with optional units*/
46 CONFIG_TYPE_MEMUNIT, /**< A number of bytes, with optional units*/
47 CONFIG_TYPE_DOUBLE, /**< A floating-point value */
48 CONFIG_TYPE_BOOL, /**< A boolean value, expressed as 0 or 1. */
49 CONFIG_TYPE_ISOTIME, /**< An ISO-formatted time relative to GMT. */
50 CONFIG_TYPE_CSV, /**< A list of strings, separated by commas and
51 * optional whitespace. */
52 CONFIG_TYPE_LINELIST, /**< Uninterpreted config lines */
53 CONFIG_TYPE_LINELIST_S, /**< Uninterpreted, context-sensitive config lines,
54 * mixed with other keywords. */
55 CONFIG_TYPE_LINELIST_V, /**< Catch-all "virtual" option to summarize
56 * context-sensitive config lines when fetching.
58 CONFIG_TYPE_ROUTERSET, /**< A list of router names, addrs, and fps,
59 * parsed into a routerset_t. */
60 CONFIG_TYPE_OBSOLETE, /**< Obsolete (ignored) option. */
61 } config_type_t;
63 /** An abbreviation for a configuration option allowed on the command line. */
64 typedef struct config_abbrev_t {
65 const char *abbreviated;
66 const char *full;
67 int commandline_only;
68 int warn;
69 } config_abbrev_t;
71 /* Handy macro for declaring "In the config file or on the command line,
72 * you can abbreviate <b>tok</b>s as <b>tok</b>". */
73 #define PLURAL(tok) { #tok, #tok "s", 0, 0 }
75 /** A list of abbreviations and aliases to map command-line options, obsolete
76 * option names, or alternative option names, to their current values. */
77 static config_abbrev_t _option_abbrevs[] = {
78 PLURAL(ExitNode),
79 PLURAL(EntryNode),
80 PLURAL(ExcludeNode),
81 PLURAL(FirewallPort),
82 PLURAL(LongLivedPort),
83 PLURAL(HiddenServiceNode),
84 PLURAL(HiddenServiceExcludeNode),
85 PLURAL(NumCpu),
86 PLURAL(RendNode),
87 PLURAL(RendExcludeNode),
88 PLURAL(StrictEntryNode),
89 PLURAL(StrictExitNode),
90 PLURAL(StrictNode),
91 { "l", "Log", 1, 0},
92 { "AllowUnverifiedNodes", "AllowInvalidNodes", 0, 0},
93 { "AutomapHostSuffixes", "AutomapHostsSuffixes", 0, 0},
94 { "AutomapHostOnResolve", "AutomapHostsOnResolve", 0, 0},
95 { "BandwidthRateBytes", "BandwidthRate", 0, 0},
96 { "BandwidthBurstBytes", "BandwidthBurst", 0, 0},
97 { "DirFetchPostPeriod", "StatusFetchPeriod", 0, 0},
98 { "MaxConn", "ConnLimit", 0, 1},
99 { "ORBindAddress", "ORListenAddress", 0, 0},
100 { "DirBindAddress", "DirListenAddress", 0, 0},
101 { "SocksBindAddress", "SocksListenAddress", 0, 0},
102 { "UseHelperNodes", "UseEntryGuards", 0, 0},
103 { "NumHelperNodes", "NumEntryGuards", 0, 0},
104 { "UseEntryNodes", "UseEntryGuards", 0, 0},
105 { "NumEntryNodes", "NumEntryGuards", 0, 0},
106 { "ResolvConf", "ServerDNSResolvConfFile", 0, 1},
107 { "SearchDomains", "ServerDNSSearchDomains", 0, 1},
108 { "ServerDNSAllowBrokenResolvConf", "ServerDNSAllowBrokenConfig", 0, 0},
109 { "PreferTunnelledDirConns", "PreferTunneledDirConns", 0, 0},
110 { "BridgeAuthoritativeDirectory", "BridgeAuthoritativeDir", 0, 0},
111 { "HashedControlPassword", "__HashedControlSessionPassword", 1, 0},
112 { "StrictEntryNodes", "StrictNodes", 0, 1},
113 { "StrictExitNodes", "StrictNodes", 0, 1},
114 { NULL, NULL, 0, 0},
117 /** A list of state-file "abbreviations," for compatibility. */
118 static config_abbrev_t _state_abbrevs[] = {
119 { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
120 { "HelperNode", "EntryGuard", 0, 0 },
121 { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
122 { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
123 { "EntryNode", "EntryGuard", 0, 0 },
124 { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
125 { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
126 { NULL, NULL, 0, 0},
128 #undef PLURAL
130 /** A variable allowed in the configuration file or on the command line. */
131 typedef struct config_var_t {
132 const char *name; /**< The full keyword (case insensitive). */
133 config_type_t type; /**< How to interpret the type and turn it into a
134 * value. */
135 off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
136 const char *initvalue; /**< String (or null) describing initial value. */
137 } config_var_t;
139 /** An entry for config_vars: "The option <b>name</b> has type
140 * CONFIG_TYPE_<b>conftype</b>, and corresponds to
141 * or_options_t.<b>member</b>"
143 #define VAR(name,conftype,member,initvalue) \
144 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), \
145 initvalue }
146 /** As VAR, but the option name and member name are the same. */
147 #define V(member,conftype,initvalue) \
148 VAR(#member, conftype, member, initvalue)
149 /** An entry for config_vars: "The option <b>name</b> is obsolete." */
150 #define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
152 /** Array of configuration options. Until we disallow nonstandard
153 * abbreviations, order is significant, since the first matching option will
154 * be chosen first.
156 static config_var_t _option_vars[] = {
157 OBSOLETE("AccountingMaxKB"),
158 V(AccountingMax, MEMUNIT, "0 bytes"),
159 V(AccountingStart, STRING, NULL),
160 V(Address, STRING, NULL),
161 V(AllowDotExit, BOOL, "0"),
162 V(AllowInvalidNodes, CSV, "middle,rendezvous"),
163 V(AllowNonRFC953Hostnames, BOOL, "0"),
164 V(AllowSingleHopCircuits, BOOL, "0"),
165 V(AllowSingleHopExits, BOOL, "0"),
166 V(AlternateBridgeAuthority, LINELIST, NULL),
167 V(AlternateDirAuthority, LINELIST, NULL),
168 V(AlternateHSAuthority, LINELIST, NULL),
169 V(AssumeReachable, BOOL, "0"),
170 V(AuthDirBadDir, LINELIST, NULL),
171 V(AuthDirBadExit, LINELIST, NULL),
172 V(AuthDirInvalid, LINELIST, NULL),
173 V(AuthDirReject, LINELIST, NULL),
174 V(AuthDirRejectUnlisted, BOOL, "0"),
175 V(AuthDirListBadDirs, BOOL, "0"),
176 V(AuthDirListBadExits, BOOL, "0"),
177 V(AuthDirMaxServersPerAddr, UINT, "2"),
178 V(AuthDirMaxServersPerAuthAddr,UINT, "5"),
179 VAR("AuthoritativeDirectory", BOOL, AuthoritativeDir, "0"),
180 V(AutomapHostsOnResolve, BOOL, "0"),
181 V(AutomapHostsSuffixes, CSV, ".onion,.exit"),
182 V(AvoidDiskWrites, BOOL, "0"),
183 V(BandwidthBurst, MEMUNIT, "10 MB"),
184 V(BandwidthRate, MEMUNIT, "5 MB"),
185 V(BridgeAuthoritativeDir, BOOL, "0"),
186 VAR("Bridge", LINELIST, Bridges, NULL),
187 V(BridgePassword, STRING, NULL),
188 V(BridgeRecordUsageByCountry, BOOL, "1"),
189 V(BridgeRelay, BOOL, "0"),
190 V(CellStatistics, BOOL, "0"),
191 V(LearnCircuitBuildTimeout, BOOL, "1"),
192 V(CircuitBuildTimeout, INTERVAL, "0"),
193 V(CircuitIdleTimeout, INTERVAL, "1 hour"),
194 V(CircuitStreamTimeout, INTERVAL, "0"),
195 V(CircuitPriorityHalflife, DOUBLE, "-100.0"), /*negative:'Use default'*/
196 V(ClientDNSRejectInternalAddresses, BOOL,"1"),
197 V(ClientOnly, BOOL, "0"),
198 V(ConsensusParams, STRING, NULL),
199 V(ConnLimit, UINT, "1000"),
200 V(ConstrainedSockets, BOOL, "0"),
201 V(ConstrainedSockSize, MEMUNIT, "8192"),
202 V(ContactInfo, STRING, NULL),
203 V(ControlListenAddress, LINELIST, NULL),
204 V(ControlPort, UINT, "0"),
205 V(ControlSocket, LINELIST, NULL),
206 V(CookieAuthentication, BOOL, "0"),
207 V(CookieAuthFileGroupReadable, BOOL, "0"),
208 V(CookieAuthFile, STRING, NULL),
209 V(DataDirectory, FILENAME, NULL),
210 OBSOLETE("DebugLogFile"),
211 V(DirAllowPrivateAddresses, BOOL, NULL),
212 V(TestingAuthDirTimeToLearnReachability, INTERVAL, "30 minutes"),
213 V(DirListenAddress, LINELIST, NULL),
214 OBSOLETE("DirFetchPeriod"),
215 V(DirPolicy, LINELIST, NULL),
216 V(DirPort, UINT, "0"),
217 V(DirPortFrontPage, FILENAME, NULL),
218 OBSOLETE("DirPostPeriod"),
219 OBSOLETE("DirRecordUsageByCountry"),
220 OBSOLETE("DirRecordUsageGranularity"),
221 OBSOLETE("DirRecordUsageRetainIPs"),
222 OBSOLETE("DirRecordUsageSaveInterval"),
223 V(DirReqStatistics, BOOL, "0"),
224 VAR("DirServer", LINELIST, DirServers, NULL),
225 V(DisableAllSwap, BOOL, "0"),
226 V(DNSPort, UINT, "0"),
227 V(DNSListenAddress, LINELIST, NULL),
228 V(DownloadExtraInfo, BOOL, "0"),
229 V(EnforceDistinctSubnets, BOOL, "1"),
230 V(EntryNodes, ROUTERSET, NULL),
231 V(EntryStatistics, BOOL, "0"),
232 V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "10 minutes"),
233 V(ExcludeNodes, ROUTERSET, NULL),
234 V(ExcludeExitNodes, ROUTERSET, NULL),
235 V(ExcludeSingleHopRelays, BOOL, "1"),
236 V(ExitNodes, ROUTERSET, NULL),
237 V(ExitPolicy, LINELIST, NULL),
238 V(ExitPolicyRejectPrivate, BOOL, "1"),
239 V(ExitPortStatistics, BOOL, "0"),
240 V(ExtraInfoStatistics, BOOL, "0"),
242 #if defined (WINCE)
243 V(FallbackNetworkstatusFile, FILENAME, "fallback-consensus"),
244 #else
245 V(FallbackNetworkstatusFile, FILENAME,
246 SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "fallback-consensus"),
247 #endif
248 V(FascistFirewall, BOOL, "0"),
249 V(FirewallPorts, CSV, ""),
250 V(FastFirstHopPK, BOOL, "1"),
251 V(FetchDirInfoEarly, BOOL, "0"),
252 V(FetchDirInfoExtraEarly, BOOL, "0"),
253 V(FetchServerDescriptors, BOOL, "1"),
254 V(FetchHidServDescriptors, BOOL, "1"),
255 V(FetchUselessDescriptors, BOOL, "0"),
256 #ifdef WIN32
257 V(GeoIPFile, FILENAME, "<default>"),
258 #else
259 V(GeoIPFile, FILENAME,
260 SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "geoip"),
261 #endif
262 OBSOLETE("Group"),
263 V(HardwareAccel, BOOL, "0"),
264 V(AccelName, STRING, NULL),
265 V(AccelDir, FILENAME, NULL),
266 V(HashedControlPassword, LINELIST, NULL),
267 V(HidServDirectoryV2, BOOL, "1"),
268 VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
269 OBSOLETE("HiddenServiceExcludeNodes"),
270 OBSOLETE("HiddenServiceNodes"),
271 VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
272 VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
273 VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines, NULL),
274 VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL),
275 V(HidServAuth, LINELIST, NULL),
276 V(HSAuthoritativeDir, BOOL, "0"),
277 OBSOLETE("HSAuthorityRecordStats"),
278 V(HttpProxy, STRING, NULL),
279 V(HttpProxyAuthenticator, STRING, NULL),
280 V(HttpsProxy, STRING, NULL),
281 V(HttpsProxyAuthenticator, STRING, NULL),
282 V(Socks4Proxy, STRING, NULL),
283 V(Socks5Proxy, STRING, NULL),
284 V(Socks5ProxyUsername, STRING, NULL),
285 V(Socks5ProxyPassword, STRING, NULL),
286 OBSOLETE("IgnoreVersion"),
287 V(KeepalivePeriod, INTERVAL, "5 minutes"),
288 VAR("Log", LINELIST, Logs, NULL),
289 OBSOLETE("LinkPadding"),
290 OBSOLETE("LogLevel"),
291 OBSOLETE("LogFile"),
292 V(LongLivedPorts, CSV,
293 "21,22,706,1863,5050,5190,5222,5223,6667,6697,8300"),
294 VAR("MapAddress", LINELIST, AddressMap, NULL),
295 V(MaxAdvertisedBandwidth, MEMUNIT, "1 GB"),
296 V(MaxCircuitDirtiness, INTERVAL, "10 minutes"),
297 V(MaxOnionsPending, UINT, "100"),
298 OBSOLETE("MonthlyAccountingStart"),
299 V(MyFamily, STRING, NULL),
300 V(NewCircuitPeriod, INTERVAL, "30 seconds"),
301 VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "0"),
302 V(NatdListenAddress, LINELIST, NULL),
303 V(NatdPort, UINT, "0"),
304 V(Nickname, STRING, NULL),
305 V(WarnUnsafeSocks, BOOL, "1"),
306 V(NoPublish, BOOL, "0"),
307 VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
308 V(NumCpus, UINT, "1"),
309 V(NumEntryGuards, UINT, "3"),
310 V(ORListenAddress, LINELIST, NULL),
311 V(ORPort, UINT, "0"),
312 V(OutboundBindAddress, STRING, NULL),
313 OBSOLETE("PathlenCoinWeight"),
314 V(PerConnBWBurst, MEMUNIT, "0"),
315 V(PerConnBWRate, MEMUNIT, "0"),
316 V(PidFile, STRING, NULL),
317 V(TestingTorNetwork, BOOL, "0"),
318 V(PreferTunneledDirConns, BOOL, "1"),
319 V(ProtocolWarnings, BOOL, "0"),
320 V(PublishServerDescriptor, CSV, "1"),
321 V(PublishHidServDescriptors, BOOL, "1"),
322 V(ReachableAddresses, LINELIST, NULL),
323 V(ReachableDirAddresses, LINELIST, NULL),
324 V(ReachableORAddresses, LINELIST, NULL),
325 V(RecommendedVersions, LINELIST, NULL),
326 V(RecommendedClientVersions, LINELIST, NULL),
327 V(RecommendedServerVersions, LINELIST, NULL),
328 OBSOLETE("RedirectExit"),
329 V(RefuseUnknownExits, BOOL, "0"),
330 V(RejectPlaintextPorts, CSV, ""),
331 V(RelayBandwidthBurst, MEMUNIT, "0"),
332 V(RelayBandwidthRate, MEMUNIT, "0"),
333 OBSOLETE("RendExcludeNodes"),
334 OBSOLETE("RendNodes"),
335 V(RendPostPeriod, INTERVAL, "1 hour"),
336 V(RephistTrackTime, INTERVAL, "24 hours"),
337 OBSOLETE("RouterFile"),
338 V(RunAsDaemon, BOOL, "0"),
339 V(RunTesting, BOOL, "0"),
340 V(SafeLogging, STRING, "1"),
341 V(SafeSocks, BOOL, "0"),
342 V(ServerDNSAllowBrokenConfig, BOOL, "1"),
343 V(ServerDNSAllowNonRFC953Hostnames, BOOL,"0"),
344 V(ServerDNSDetectHijacking, BOOL, "1"),
345 V(ServerDNSRandomizeCase, BOOL, "1"),
346 V(ServerDNSResolvConfFile, STRING, NULL),
347 V(ServerDNSSearchDomains, BOOL, "0"),
348 V(ServerDNSTestAddresses, CSV,
349 "www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"),
350 V(ShutdownWaitLength, INTERVAL, "30 seconds"),
351 V(SocksListenAddress, LINELIST, NULL),
352 V(SocksPolicy, LINELIST, NULL),
353 V(SocksPort, UINT, "9050"),
354 V(SocksTimeout, INTERVAL, "2 minutes"),
355 OBSOLETE("StatusFetchPeriod"),
356 V(StrictNodes, BOOL, "0"),
357 OBSOLETE("SysLog"),
358 V(TestSocks, BOOL, "0"),
359 OBSOLETE("TestVia"),
360 V(TrackHostExits, CSV, NULL),
361 V(TrackHostExitsExpire, INTERVAL, "30 minutes"),
362 OBSOLETE("TrafficShaping"),
363 V(TransListenAddress, LINELIST, NULL),
364 V(TransPort, UINT, "0"),
365 V(TunnelDirConns, BOOL, "1"),
366 V(UpdateBridgesFromAuthority, BOOL, "0"),
367 V(UseBridges, BOOL, "0"),
368 V(UseEntryGuards, BOOL, "1"),
369 V(User, STRING, NULL),
370 VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
371 VAR("V2AuthoritativeDirectory",BOOL, V2AuthoritativeDir, "0"),
372 VAR("V3AuthoritativeDirectory",BOOL, V3AuthoritativeDir, "0"),
373 V(TestingV3AuthInitialVotingInterval, INTERVAL, "30 minutes"),
374 V(TestingV3AuthInitialVoteDelay, INTERVAL, "5 minutes"),
375 V(TestingV3AuthInitialDistDelay, INTERVAL, "5 minutes"),
376 V(V3AuthVotingInterval, INTERVAL, "1 hour"),
377 V(V3AuthVoteDelay, INTERVAL, "5 minutes"),
378 V(V3AuthDistDelay, INTERVAL, "5 minutes"),
379 V(V3AuthNIntervalsValid, UINT, "3"),
380 V(V3AuthUseLegacyKey, BOOL, "0"),
381 V(V3BandwidthsFile, FILENAME, NULL),
382 VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
383 V(VirtualAddrNetwork, STRING, "127.192.0.0/10"),
384 V(WarnPlaintextPorts, CSV, "23,109,110,143"),
385 VAR("__ReloadTorrcOnSIGHUP", BOOL, ReloadTorrcOnSIGHUP, "1"),
386 VAR("__AllDirActionsPrivate", BOOL, AllDirActionsPrivate, "0"),
387 VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits, "0"),
388 VAR("__LeaveStreamsUnattached",BOOL, LeaveStreamsUnattached, "0"),
389 VAR("__HashedControlSessionPassword", LINELIST, HashedControlSessionPassword,
390 NULL),
391 V(MinUptimeHidServDirectoryV2, INTERVAL, "24 hours"),
393 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
396 /** Override default values with these if the user sets the TestingTorNetwork
397 * option. */
398 static config_var_t testing_tor_network_defaults[] = {
399 V(ServerDNSAllowBrokenConfig, BOOL, "1"),
400 V(DirAllowPrivateAddresses, BOOL, "1"),
401 V(EnforceDistinctSubnets, BOOL, "0"),
402 V(AssumeReachable, BOOL, "1"),
403 V(AuthDirMaxServersPerAddr, UINT, "0"),
404 V(AuthDirMaxServersPerAuthAddr,UINT, "0"),
405 V(ClientDNSRejectInternalAddresses, BOOL,"0"),
406 V(ExitPolicyRejectPrivate, BOOL, "0"),
407 V(V3AuthVotingInterval, INTERVAL, "5 minutes"),
408 V(V3AuthVoteDelay, INTERVAL, "20 seconds"),
409 V(V3AuthDistDelay, INTERVAL, "20 seconds"),
410 V(TestingV3AuthInitialVotingInterval, INTERVAL, "5 minutes"),
411 V(TestingV3AuthInitialVoteDelay, INTERVAL, "20 seconds"),
412 V(TestingV3AuthInitialDistDelay, INTERVAL, "20 seconds"),
413 V(TestingAuthDirTimeToLearnReachability, INTERVAL, "0 minutes"),
414 V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "0 minutes"),
415 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
417 #undef VAR
419 #define VAR(name,conftype,member,initvalue) \
420 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member), \
421 initvalue }
423 /** Array of "state" variables saved to the ~/.tor/state file. */
424 static config_var_t _state_vars[] = {
425 V(AccountingBytesReadInInterval, MEMUNIT, NULL),
426 V(AccountingBytesWrittenInInterval, MEMUNIT, NULL),
427 V(AccountingExpectedUsage, MEMUNIT, NULL),
428 V(AccountingIntervalStart, ISOTIME, NULL),
429 V(AccountingSecondsActive, INTERVAL, NULL),
431 VAR("EntryGuard", LINELIST_S, EntryGuards, NULL),
432 VAR("EntryGuardDownSince", LINELIST_S, EntryGuards, NULL),
433 VAR("EntryGuardUnlistedSince", LINELIST_S, EntryGuards, NULL),
434 VAR("EntryGuardAddedBy", LINELIST_S, EntryGuards, NULL),
435 V(EntryGuards, LINELIST_V, NULL),
437 V(BWHistoryReadEnds, ISOTIME, NULL),
438 V(BWHistoryReadInterval, UINT, "900"),
439 V(BWHistoryReadValues, CSV, ""),
440 V(BWHistoryWriteEnds, ISOTIME, NULL),
441 V(BWHistoryWriteInterval, UINT, "900"),
442 V(BWHistoryWriteValues, CSV, ""),
444 V(TorVersion, STRING, NULL),
446 V(LastRotatedOnionKey, ISOTIME, NULL),
447 V(LastWritten, ISOTIME, NULL),
449 V(TotalBuildTimes, UINT, NULL),
450 V(CircuitBuildAbandonedCount, UINT, "0"),
451 VAR("CircuitBuildTimeBin", LINELIST_S, BuildtimeHistogram, NULL),
452 VAR("BuildtimeHistogram", LINELIST_V, BuildtimeHistogram, NULL),
454 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
457 #undef VAR
458 #undef V
459 #undef OBSOLETE
461 /** Represents an English description of a configuration variable; used when
462 * generating configuration file comments. */
463 typedef struct config_var_description_t {
464 const char *name;
465 const char *description;
466 } config_var_description_t;
468 /** Type of a callback to validate whether a given configuration is
469 * well-formed and consistent. See options_trial_assign() for documentation
470 * of arguments. */
471 typedef int (*validate_fn_t)(void*,void*,int,char**);
473 /** Information on the keys, value types, key-to-struct-member mappings,
474 * variable descriptions, validation functions, and abbreviations for a
475 * configuration or storage format. */
476 typedef struct {
477 size_t size; /**< Size of the struct that everything gets parsed into. */
478 uint32_t magic; /**< Required 'magic value' to make sure we have a struct
479 * of the right type. */
480 off_t magic_offset; /**< Offset of the magic value within the struct. */
481 config_abbrev_t *abbrevs; /**< List of abbreviations that we expand when
482 * parsing this format. */
483 config_var_t *vars; /**< List of variables we recognize, their default
484 * values, and where we stick them in the structure. */
485 validate_fn_t validate_fn; /**< Function to validate config. */
486 /** If present, extra is a LINELIST variable for unrecognized
487 * lines. Otherwise, unrecognized lines are an error. */
488 config_var_t *extra;
489 } config_format_t;
491 /** Macro: assert that <b>cfg</b> has the right magic field for format
492 * <b>fmt</b>. */
493 #define CHECK(fmt, cfg) STMT_BEGIN \
494 tor_assert(fmt && cfg); \
495 tor_assert((fmt)->magic == \
496 *(uint32_t*)STRUCT_VAR_P(cfg,fmt->magic_offset)); \
497 STMT_END
499 #ifdef MS_WINDOWS
500 static char *get_windows_conf_root(void);
501 #endif
502 static void config_line_append(config_line_t **lst,
503 const char *key, const char *val);
504 static void option_clear(config_format_t *fmt, or_options_t *options,
505 config_var_t *var);
506 static void option_reset(config_format_t *fmt, or_options_t *options,
507 config_var_t *var, int use_defaults);
508 static void config_free(config_format_t *fmt, void *options);
509 static int config_lines_eq(config_line_t *a, config_line_t *b);
510 static int option_is_same(config_format_t *fmt,
511 or_options_t *o1, or_options_t *o2,
512 const char *name);
513 static or_options_t *options_dup(config_format_t *fmt, or_options_t *old);
514 static int options_validate(or_options_t *old_options, or_options_t *options,
515 int from_setconf, char **msg);
516 static int options_act_reversible(or_options_t *old_options, char **msg);
517 static int options_act(or_options_t *old_options);
518 static int options_transition_allowed(or_options_t *old, or_options_t *new,
519 char **msg);
520 static int options_transition_affects_workers(or_options_t *old_options,
521 or_options_t *new_options);
522 static int options_transition_affects_descriptor(or_options_t *old_options,
523 or_options_t *new_options);
524 static int check_nickname_list(const char *lst, const char *name, char **msg);
525 static void config_register_addressmaps(or_options_t *options);
527 static int parse_bridge_line(const char *line, int validate_only);
528 static int parse_dir_server_line(const char *line,
529 authority_type_t required_type,
530 int validate_only);
531 static int validate_data_directory(or_options_t *options);
532 static int write_configuration_file(const char *fname, or_options_t *options);
533 static config_line_t *get_assigned_option(config_format_t *fmt,
534 void *options, const char *key,
535 int escape_val);
536 static void config_init(config_format_t *fmt, void *options);
537 static int or_state_validate(or_state_t *old_options, or_state_t *options,
538 int from_setconf, char **msg);
539 static int or_state_load(void);
540 static int options_init_logs(or_options_t *options, int validate_only);
542 static int is_listening_on_low_port(uint16_t port_option,
543 const config_line_t *listen_options);
545 static uint64_t config_parse_memunit(const char *s, int *ok);
546 static int config_parse_interval(const char *s, int *ok);
547 static void init_libevent(void);
548 static int opt_streq(const char *s1, const char *s2);
550 /** Magic value for or_options_t. */
551 #define OR_OPTIONS_MAGIC 9090909
553 /** Configuration format for or_options_t. */
554 static config_format_t options_format = {
555 sizeof(or_options_t),
556 OR_OPTIONS_MAGIC,
557 STRUCT_OFFSET(or_options_t, _magic),
558 _option_abbrevs,
559 _option_vars,
560 (validate_fn_t)options_validate,
561 NULL
564 /** Magic value for or_state_t. */
565 #define OR_STATE_MAGIC 0x57A73f57
567 /** "Extra" variable in the state that receives lines we can't parse. This
568 * lets us preserve options from versions of Tor newer than us. */
569 static config_var_t state_extra_var = {
570 "__extra", CONFIG_TYPE_LINELIST, STRUCT_OFFSET(or_state_t, ExtraLines), NULL
573 /** Configuration format for or_state_t. */
574 static config_format_t state_format = {
575 sizeof(or_state_t),
576 OR_STATE_MAGIC,
577 STRUCT_OFFSET(or_state_t, _magic),
578 _state_abbrevs,
579 _state_vars,
580 (validate_fn_t)or_state_validate,
581 &state_extra_var,
585 * Functions to read and write the global options pointer.
588 /** Command-line and config-file options. */
589 static or_options_t *global_options = NULL;
590 /** Name of most recently read torrc file. */
591 static char *torrc_fname = NULL;
592 /** Persistent serialized state. */
593 static or_state_t *global_state = NULL;
594 /** Configuration Options set by command line. */
595 static config_line_t *global_cmdline_options = NULL;
596 /** Contents of most recently read DirPortFrontPage file. */
597 static char *global_dirfrontpagecontents = NULL;
599 /** Return the contents of our frontpage string, or NULL if not configured. */
600 const char *
601 get_dirportfrontpage(void)
603 return global_dirfrontpagecontents;
606 /** Allocate an empty configuration object of a given format type. */
607 static void *
608 config_alloc(config_format_t *fmt)
610 void *opts = tor_malloc_zero(fmt->size);
611 *(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
612 CHECK(fmt, opts);
613 return opts;
616 /** Return the currently configured options. */
617 or_options_t *
618 get_options(void)
620 tor_assert(global_options);
621 return global_options;
624 /** Change the current global options to contain <b>new_val</b> instead of
625 * their current value; take action based on the new value; free the old value
626 * as necessary. Returns 0 on success, -1 on failure.
629 set_options(or_options_t *new_val, char **msg)
631 or_options_t *old_options = global_options;
632 global_options = new_val;
633 /* Note that we pass the *old* options below, for comparison. It
634 * pulls the new options directly out of global_options. */
635 if (options_act_reversible(old_options, msg)<0) {
636 tor_assert(*msg);
637 global_options = old_options;
638 return -1;
640 if (options_act(old_options) < 0) { /* acting on the options failed. die. */
641 log_err(LD_BUG,
642 "Acting on config options left us in a broken state. Dying.");
643 exit(1);
646 config_free(&options_format, old_options);
648 return 0;
651 extern const char tor_git_revision[]; /* from tor_main.c */
653 /** The version of this Tor process, as parsed. */
654 static char *_version = NULL;
656 /** Return the current Tor version. */
657 const char *
658 get_version(void)
660 if (_version == NULL) {
661 if (strlen(tor_git_revision)) {
662 size_t len = strlen(VERSION)+strlen(tor_git_revision)+16;
663 _version = tor_malloc(len);
664 tor_snprintf(_version, len, "%s (git-%s)", VERSION, tor_git_revision);
665 } else {
666 _version = tor_strdup(VERSION);
669 return _version;
672 /** Release additional memory allocated in options
674 static void
675 or_options_free(or_options_t *options)
677 if (!options)
678 return;
680 routerset_free(options->_ExcludeExitNodesUnion);
681 config_free(&options_format, options);
684 /** Release all memory and resources held by global configuration structures.
686 void
687 config_free_all(void)
689 or_options_free(global_options);
690 global_options = NULL;
692 config_free(&state_format, global_state);
693 global_state = NULL;
695 config_free_lines(global_cmdline_options);
696 global_cmdline_options = NULL;
698 tor_free(torrc_fname);
699 tor_free(_version);
700 tor_free(global_dirfrontpagecontents);
703 /** Make <b>address</b> -- a piece of information related to our operation as
704 * a client -- safe to log according to the settings in options->SafeLogging,
705 * and return it.
707 * (We return "[scrubbed]" if SafeLogging is "1", and address otherwise.)
709 const char *
710 safe_str_client(const char *address)
712 tor_assert(address);
713 if (get_options()->_SafeLogging == SAFELOG_SCRUB_ALL)
714 return "[scrubbed]";
715 else
716 return address;
719 /** Make <b>address</b> -- a piece of information of unspecified sensitivity
720 * -- safe to log according to the settings in options->SafeLogging, and
721 * return it.
723 * (We return "[scrubbed]" if SafeLogging is anything besides "0", and address
724 * otherwise.)
726 const char *
727 safe_str(const char *address)
729 tor_assert(address);
730 if (get_options()->_SafeLogging != SAFELOG_SCRUB_NONE)
731 return "[scrubbed]";
732 else
733 return address;
736 /** Equivalent to escaped(safe_str_client(address)). See reentrancy note on
737 * escaped(): don't use this outside the main thread, or twice in the same
738 * log statement. */
739 const char *
740 escaped_safe_str_client(const char *address)
742 if (get_options()->_SafeLogging == SAFELOG_SCRUB_ALL)
743 return "[scrubbed]";
744 else
745 return escaped(address);
748 /** Equivalent to escaped(safe_str(address)). See reentrancy note on
749 * escaped(): don't use this outside the main thread, or twice in the same
750 * log statement. */
751 const char *
752 escaped_safe_str(const char *address)
754 if (get_options()->_SafeLogging != SAFELOG_SCRUB_NONE)
755 return "[scrubbed]";
756 else
757 return escaped(address);
760 /** Add the default directory authorities directly into the trusted dir list,
761 * but only add them insofar as they share bits with <b>type</b>. */
762 static void
763 add_default_trusted_dir_authorities(authority_type_t type)
765 int i;
766 const char *dirservers[] = {
767 "moria1 orport=9101 no-v2 "
768 "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
769 "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
770 "tor26 v1 orport=443 v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
771 "86.59.21.38:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
772 "dizum orport=443 v3ident=E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58 "
773 "194.109.206.212:80 7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
774 "Tonga orport=443 bridge no-v2 82.94.251.203:80 "
775 "4A0C CD2D DC79 9508 3D73 F5D6 6710 0C8A 5831 F16D",
776 "ides orport=9090 no-v2 v3ident=27B6B5996C426270A5C95488AA5BCEB6BCC86956 "
777 "216.224.124.114:9030 F397 038A DC51 3361 35E7 B80B D99C A384 4360 292B",
778 "gabelmoo orport=8080 no-v2 "
779 "v3ident=ED03BB616EB2F60BEC80151114BB25CEF515B226 "
780 "80.190.246.100:8180 F204 4413 DAC2 E02E 3D6B CF47 35A1 9BCA 1DE9 7281",
781 "dannenberg orport=443 no-v2 "
782 "v3ident=585769C78764D58426B8B52B6651A5A71137189A "
783 "193.23.244.244:80 7BE6 83E6 5D48 1413 21C5 ED92 F075 C553 64AC 7123",
784 "urras orport=80 no-v2 v3ident=80550987E1D626E3EBA5E5E75A458DE0626D088C "
785 "208.83.223.34:443 0AD3 FA88 4D18 F89E EA2D 89C0 1937 9E0E 7FD9 4417",
786 "maatuska orport=80 no-v2 "
787 "v3ident=49015F787433103580E3B66A1707A00E60F2D15B "
788 "213.115.239.118:443 BD6A 8292 55CB 08E6 6FBE 7D37 4836 3586 E46B 3810",
789 NULL
791 for (i=0; dirservers[i]; i++) {
792 if (parse_dir_server_line(dirservers[i], type, 0)<0) {
793 log_err(LD_BUG, "Couldn't parse internal dirserver line %s",
794 dirservers[i]);
799 /** Look at all the config options for using alternate directory
800 * authorities, and make sure none of them are broken. Also, warn the
801 * user if we changed any dangerous ones.
803 static int
804 validate_dir_authorities(or_options_t *options, or_options_t *old_options)
806 config_line_t *cl;
808 if (options->DirServers &&
809 (options->AlternateDirAuthority || options->AlternateBridgeAuthority ||
810 options->AlternateHSAuthority)) {
811 log_warn(LD_CONFIG,
812 "You cannot set both DirServers and Alternate*Authority.");
813 return -1;
816 /* do we want to complain to the user about being partitionable? */
817 if ((options->DirServers &&
818 (!old_options ||
819 !config_lines_eq(options->DirServers, old_options->DirServers))) ||
820 (options->AlternateDirAuthority &&
821 (!old_options ||
822 !config_lines_eq(options->AlternateDirAuthority,
823 old_options->AlternateDirAuthority)))) {
824 log_warn(LD_CONFIG,
825 "You have used DirServer or AlternateDirAuthority to "
826 "specify alternate directory authorities in "
827 "your configuration. This is potentially dangerous: it can "
828 "make you look different from all other Tor users, and hurt "
829 "your anonymity. Even if you've specified the same "
830 "authorities as Tor uses by default, the defaults could "
831 "change in the future. Be sure you know what you're doing.");
834 /* Now go through the four ways you can configure an alternate
835 * set of directory authorities, and make sure none are broken. */
836 for (cl = options->DirServers; cl; cl = cl->next)
837 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
838 return -1;
839 for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
840 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
841 return -1;
842 for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
843 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
844 return -1;
845 for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
846 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
847 return -1;
848 return 0;
851 /** Look at all the config options and assign new dir authorities
852 * as appropriate.
854 static int
855 consider_adding_dir_authorities(or_options_t *options,
856 or_options_t *old_options)
858 config_line_t *cl;
859 int need_to_update =
860 !smartlist_len(router_get_trusted_dir_servers()) || !old_options ||
861 !config_lines_eq(options->DirServers, old_options->DirServers) ||
862 !config_lines_eq(options->AlternateBridgeAuthority,
863 old_options->AlternateBridgeAuthority) ||
864 !config_lines_eq(options->AlternateDirAuthority,
865 old_options->AlternateDirAuthority) ||
866 !config_lines_eq(options->AlternateHSAuthority,
867 old_options->AlternateHSAuthority);
869 if (!need_to_update)
870 return 0; /* all done */
872 /* Start from a clean slate. */
873 clear_trusted_dir_servers();
875 if (!options->DirServers) {
876 /* then we may want some of the defaults */
877 authority_type_t type = NO_AUTHORITY;
878 if (!options->AlternateBridgeAuthority)
879 type |= BRIDGE_AUTHORITY;
880 if (!options->AlternateDirAuthority)
881 type |= V1_AUTHORITY | V2_AUTHORITY | V3_AUTHORITY;
882 if (!options->AlternateHSAuthority)
883 type |= HIDSERV_AUTHORITY;
884 add_default_trusted_dir_authorities(type);
887 for (cl = options->DirServers; cl; cl = cl->next)
888 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
889 return -1;
890 for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
891 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
892 return -1;
893 for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
894 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
895 return -1;
896 for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
897 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
898 return -1;
899 return 0;
902 /** Fetch the active option list, and take actions based on it. All of the
903 * things we do should survive being done repeatedly. If present,
904 * <b>old_options</b> contains the previous value of the options.
906 * Return 0 if all goes well, return -1 if things went badly.
908 static int
909 options_act_reversible(or_options_t *old_options, char **msg)
911 smartlist_t *new_listeners = smartlist_create();
912 smartlist_t *replaced_listeners = smartlist_create();
913 static int libevent_initialized = 0;
914 or_options_t *options = get_options();
915 int running_tor = options->command == CMD_RUN_TOR;
916 int set_conn_limit = 0;
917 int r = -1;
918 int logs_marked = 0;
920 /* Daemonize _first_, since we only want to open most of this stuff in
921 * the subprocess. Libevent bases can't be reliably inherited across
922 * processes. */
923 if (running_tor && options->RunAsDaemon) {
924 /* No need to roll back, since you can't change the value. */
925 start_daemon();
928 #ifndef HAVE_SYS_UN_H
929 if (options->ControlSocket) {
930 *msg = tor_strdup("Unix domain sockets (ControlSocket) not supported"
931 " on this OS/with this build.");
932 goto rollback;
934 #endif
936 if (running_tor) {
937 /* We need to set the connection limit before we can open the listeners. */
938 if (set_max_file_descriptors((unsigned)options->ConnLimit,
939 &options->_ConnLimit) < 0) {
940 *msg = tor_strdup("Problem with ConnLimit value. See logs for details.");
941 goto rollback;
943 set_conn_limit = 1;
945 /* Set up libevent. (We need to do this before we can register the
946 * listeners as listeners.) */
947 if (running_tor && !libevent_initialized) {
948 init_libevent();
949 libevent_initialized = 1;
952 /* Launch the listeners. (We do this before we setuid, so we can bind to
953 * ports under 1024.) */
954 if (retry_all_listeners(replaced_listeners, new_listeners) < 0) {
955 *msg = tor_strdup("Failed to bind one of the listener ports.");
956 goto rollback;
960 #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
961 /* Open /dev/pf before dropping privileges. */
962 if (options->TransPort) {
963 if (get_pf_socket() < 0) {
964 *msg = tor_strdup("Unable to open /dev/pf for transparent proxy.");
965 goto rollback;
968 #endif
970 /* Attempt to lock all current and future memory with mlockall() only once */
971 if (options->DisableAllSwap) {
972 if (tor_mlockall() == -1) {
973 *msg = tor_strdup("DisableAllSwap failure. Do you have proper "
974 "permissions?");
975 goto done;
979 /* Setuid/setgid as appropriate */
980 if (options->User) {
981 if (switch_id(options->User) != 0) {
982 /* No need to roll back, since you can't change the value. */
983 *msg = tor_strdup("Problem with User value. See logs for details.");
984 goto done;
988 /* Ensure data directory is private; create if possible. */
989 if (check_private_dir(options->DataDirectory,
990 running_tor ? CPD_CREATE : CPD_CHECK)<0) {
991 tor_asprintf(msg,
992 "Couldn't access/create private data directory \"%s\"",
993 options->DataDirectory);
994 goto done;
995 /* No need to roll back, since you can't change the value. */
998 if (directory_caches_v2_dir_info(options)) {
999 size_t len = strlen(options->DataDirectory)+32;
1000 char *fn = tor_malloc(len);
1001 tor_snprintf(fn, len, "%s"PATH_SEPARATOR"cached-status",
1002 options->DataDirectory);
1003 if (check_private_dir(fn, running_tor ? CPD_CREATE : CPD_CHECK) < 0) {
1004 tor_asprintf(msg,
1005 "Couldn't access/create private data directory \"%s\"", fn);
1006 tor_free(fn);
1007 goto done;
1009 tor_free(fn);
1012 /* Bail out at this point if we're not going to be a client or server:
1013 * we don't run Tor itself. */
1014 if (!running_tor)
1015 goto commit;
1017 mark_logs_temp(); /* Close current logs once new logs are open. */
1018 logs_marked = 1;
1019 if (options_init_logs(options, 0)<0) { /* Configure the log(s) */
1020 *msg = tor_strdup("Failed to init Log options. See logs for details.");
1021 goto rollback;
1024 commit:
1025 r = 0;
1026 if (logs_marked) {
1027 log_severity_list_t *severity =
1028 tor_malloc_zero(sizeof(log_severity_list_t));
1029 close_temp_logs();
1030 add_callback_log(severity, control_event_logmsg);
1031 control_adjust_event_log_severity();
1032 tor_free(severity);
1034 SMARTLIST_FOREACH(replaced_listeners, connection_t *, conn,
1036 log_notice(LD_NET, "Closing old %s on %s:%d",
1037 conn_type_to_string(conn->type), conn->address, conn->port);
1038 connection_close_immediate(conn);
1039 connection_mark_for_close(conn);
1041 goto done;
1043 rollback:
1044 r = -1;
1045 tor_assert(*msg);
1047 if (logs_marked) {
1048 rollback_log_changes();
1049 control_adjust_event_log_severity();
1052 if (set_conn_limit && old_options)
1053 set_max_file_descriptors((unsigned)old_options->ConnLimit,
1054 &options->_ConnLimit);
1056 SMARTLIST_FOREACH(new_listeners, connection_t *, conn,
1058 log_notice(LD_NET, "Closing partially-constructed listener %s on %s:%d",
1059 conn_type_to_string(conn->type), conn->address, conn->port);
1060 connection_close_immediate(conn);
1061 connection_mark_for_close(conn);
1064 done:
1065 smartlist_free(new_listeners);
1066 smartlist_free(replaced_listeners);
1067 return r;
1070 /** If we need to have a GEOIP ip-to-country map to run with our configured
1071 * options, return 1 and set *<b>reason_out</b> to a description of why. */
1073 options_need_geoip_info(or_options_t *options, const char **reason_out)
1075 int bridge_usage =
1076 options->BridgeRelay && options->BridgeRecordUsageByCountry;
1077 int routerset_usage =
1078 routerset_needs_geoip(options->EntryNodes) ||
1079 routerset_needs_geoip(options->ExitNodes) ||
1080 routerset_needs_geoip(options->ExcludeExitNodes) ||
1081 routerset_needs_geoip(options->ExcludeNodes);
1083 if (routerset_usage && reason_out) {
1084 *reason_out = "We've been configured to use (or avoid) nodes in certain "
1085 "countries, and we need GEOIP information to figure out which ones they "
1086 "are.";
1087 } else if (bridge_usage && reason_out) {
1088 *reason_out = "We've been configured to see which countries can access "
1089 "us as a bridge, and we need GEOIP information to tell which countries "
1090 "clients are in.";
1092 return bridge_usage || routerset_usage;
1095 /** Return the bandwidthrate that we are going to report to the authorities
1096 * based on the config options. */
1097 uint32_t
1098 get_effective_bwrate(or_options_t *options)
1100 uint64_t bw = options->BandwidthRate;
1101 if (bw > options->MaxAdvertisedBandwidth)
1102 bw = options->MaxAdvertisedBandwidth;
1103 if (options->RelayBandwidthRate > 0 && bw > options->RelayBandwidthRate)
1104 bw = options->RelayBandwidthRate;
1105 /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
1106 return (uint32_t)bw;
1109 /** Return the bandwidthburst that we are going to report to the authorities
1110 * based on the config options. */
1111 uint32_t
1112 get_effective_bwburst(or_options_t *options)
1114 uint64_t bw = options->BandwidthBurst;
1115 if (options->RelayBandwidthBurst > 0 && bw > options->RelayBandwidthBurst)
1116 bw = options->RelayBandwidthBurst;
1117 /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
1118 return (uint32_t)bw;
1121 /** Fetch the active option list, and take actions based on it. All of the
1122 * things we do should survive being done repeatedly. If present,
1123 * <b>old_options</b> contains the previous value of the options.
1125 * Return 0 if all goes well, return -1 if it's time to die.
1127 * Note: We haven't moved all the "act on new configuration" logic
1128 * here yet. Some is still in do_hup() and other places.
1130 static int
1131 options_act(or_options_t *old_options)
1133 config_line_t *cl;
1134 or_options_t *options = get_options();
1135 int running_tor = options->command == CMD_RUN_TOR;
1136 char *msg;
1138 if (running_tor && !have_lockfile()) {
1139 if (try_locking(options, 1) < 0)
1140 return -1;
1143 if (consider_adding_dir_authorities(options, old_options) < 0)
1144 return -1;
1146 if (options->Bridges) {
1147 clear_bridge_list();
1148 for (cl = options->Bridges; cl; cl = cl->next) {
1149 if (parse_bridge_line(cl->value, 0)<0) {
1150 log_warn(LD_BUG,
1151 "Previously validated Bridge line could not be added!");
1152 return -1;
1157 if (running_tor && rend_config_services(options, 0)<0) {
1158 log_warn(LD_BUG,
1159 "Previously validated hidden services line could not be added!");
1160 return -1;
1163 if (running_tor && rend_parse_service_authorization(options, 0) < 0) {
1164 log_warn(LD_BUG, "Previously validated client authorization for "
1165 "hidden services could not be added!");
1166 return -1;
1169 /* Load state */
1170 if (! global_state && running_tor) {
1171 if (or_state_load())
1172 return -1;
1173 rep_hist_load_mtbf_data(time(NULL));
1176 /* Bail out at this point if we're not going to be a client or server:
1177 * we want to not fork, and to log stuff to stderr. */
1178 if (!running_tor)
1179 return 0;
1181 /* Finish backgrounding the process */
1182 if (options->RunAsDaemon) {
1183 /* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
1184 finish_daemon(options->DataDirectory);
1187 /* Write our PID to the PID file. If we do not have write permissions we
1188 * will log a warning */
1189 if (options->PidFile)
1190 write_pidfile(options->PidFile);
1192 /* Register addressmap directives */
1193 config_register_addressmaps(options);
1194 parse_virtual_addr_network(options->VirtualAddrNetwork, 0, &msg);
1196 /* Update address policies. */
1197 if (policies_parse_from_options(options) < 0) {
1198 /* This should be impossible, but let's be sure. */
1199 log_warn(LD_BUG,"Error parsing already-validated policy options.");
1200 return -1;
1203 if (init_cookie_authentication(options->CookieAuthentication) < 0) {
1204 log_warn(LD_CONFIG,"Error creating cookie authentication file.");
1205 return -1;
1208 /* reload keys as needed for rendezvous services. */
1209 if (rend_service_load_keys()<0) {
1210 log_warn(LD_GENERAL,"Error loading rendezvous service keys");
1211 return -1;
1214 /* Set up accounting */
1215 if (accounting_parse_options(options, 0)<0) {
1216 log_warn(LD_CONFIG,"Error in accounting options");
1217 return -1;
1219 if (accounting_is_enabled(options))
1220 configure_accounting(time(NULL));
1222 /* Change the cell EWMA settings */
1223 cell_ewma_set_scale_factor(options, networkstatus_get_latest_consensus());
1225 /* Check for transitions that need action. */
1226 if (old_options) {
1228 if ((options->UseEntryGuards && !old_options->UseEntryGuards) ||
1229 (options->ExcludeNodes &&
1230 !routerset_equal(old_options->ExcludeNodes,options->ExcludeNodes)) ||
1231 (options->ExcludeExitNodes &&
1232 !routerset_equal(old_options->ExcludeExitNodes,
1233 options->ExcludeExitNodes)) ||
1234 (options->EntryNodes &&
1235 !routerset_equal(old_options->EntryNodes, options->EntryNodes)) ||
1236 (options->ExitNodes &&
1237 !routerset_equal(old_options->ExitNodes, options->ExitNodes)) ||
1238 options->StrictNodes != old_options->StrictNodes) {
1239 log_info(LD_CIRC,
1240 "Changed to using entry guards, or changed preferred or "
1241 "excluded node lists. Abandoning previous circuits.");
1242 circuit_mark_all_unused_circs();
1243 circuit_expire_all_dirty_circs();
1246 if (! bool_eq(options->BridgeRelay, old_options->BridgeRelay)) {
1247 log_info(LD_GENERAL, "Bridge status changed. Forgetting GeoIP stats.");
1248 geoip_remove_old_clients(time(NULL)+(2*60*60));
1251 if (options_transition_affects_workers(old_options, options)) {
1252 log_info(LD_GENERAL,
1253 "Worker-related options changed. Rotating workers.");
1254 if (server_mode(options) && !server_mode(old_options)) {
1255 if (init_keys() < 0) {
1256 log_warn(LD_BUG,"Error initializing keys; exiting");
1257 return -1;
1259 ip_address_changed(0);
1260 if (has_completed_circuit || !any_predicted_circuits(time(NULL)))
1261 inform_testing_reachability();
1263 cpuworkers_rotate();
1264 if (dns_reset())
1265 return -1;
1266 } else {
1267 if (dns_reset())
1268 return -1;
1271 if (options->V3AuthoritativeDir && !old_options->V3AuthoritativeDir)
1272 init_keys();
1275 /* Maybe load geoip file */
1276 if (options->GeoIPFile &&
1277 ((!old_options || !opt_streq(old_options->GeoIPFile, options->GeoIPFile))
1278 || !geoip_is_loaded())) {
1279 /* XXXX Don't use this "<default>" junk; make our filename options
1280 * understand prefixes somehow. -NM */
1281 /* XXXX021 Reload GeoIPFile on SIGHUP. -NM */
1282 char *actual_fname = tor_strdup(options->GeoIPFile);
1283 #ifdef WIN32
1284 if (!strcmp(actual_fname, "<default>")) {
1285 const char *conf_root = get_windows_conf_root();
1286 size_t len = strlen(conf_root)+16;
1287 tor_free(actual_fname);
1288 actual_fname = tor_malloc(len+1);
1289 tor_snprintf(actual_fname, len, "%s\\geoip", conf_root);
1291 #endif
1292 geoip_load_file(actual_fname, options);
1293 tor_free(actual_fname);
1296 if (options->DirReqStatistics && !geoip_is_loaded()) {
1297 /* Check if GeoIP database could be loaded. */
1298 log_warn(LD_CONFIG, "Configured to measure directory request "
1299 "statistics, but no GeoIP database found!");
1300 return -1;
1303 if (options->EntryStatistics) {
1304 if (should_record_bridge_info(options)) {
1305 /* Don't allow measuring statistics on entry guards when configured
1306 * as bridge. */
1307 log_warn(LD_CONFIG, "Bridges cannot be configured to measure "
1308 "additional GeoIP statistics as entry guards.");
1309 return -1;
1310 } else if (!geoip_is_loaded()) {
1311 /* Check if GeoIP database could be loaded. */
1312 log_warn(LD_CONFIG, "Configured to measure entry node statistics, "
1313 "but no GeoIP database found!");
1314 return -1;
1318 /* Check if we need to parse and add the EntryNodes config option. */
1319 if (options->EntryNodes &&
1320 (!old_options ||
1321 (!routerset_equal(old_options->EntryNodes,options->EntryNodes))))
1322 entry_nodes_should_be_added();
1324 /* Since our options changed, we might need to regenerate and upload our
1325 * server descriptor.
1327 if (!old_options ||
1328 options_transition_affects_descriptor(old_options, options))
1329 mark_my_descriptor_dirty();
1331 /* We may need to reschedule some directory stuff if our status changed. */
1332 if (old_options) {
1333 if (authdir_mode_v3(options) && !authdir_mode_v3(old_options))
1334 dirvote_recalculate_timing(options, time(NULL));
1335 if (!bool_eq(directory_fetches_dir_info_early(options),
1336 directory_fetches_dir_info_early(old_options)) ||
1337 !bool_eq(directory_fetches_dir_info_later(options),
1338 directory_fetches_dir_info_later(old_options))) {
1339 /* Make sure update_router_have_min_dir_info gets called. */
1340 router_dir_info_changed();
1341 /* We might need to download a new consensus status later or sooner than
1342 * we had expected. */
1343 update_consensus_networkstatus_fetch_time(time(NULL));
1347 /* Load the webpage we're going to serve every time someone asks for '/' on
1348 our DirPort. */
1349 tor_free(global_dirfrontpagecontents);
1350 if (options->DirPortFrontPage) {
1351 global_dirfrontpagecontents =
1352 read_file_to_str(options->DirPortFrontPage, 0, NULL);
1353 if (!global_dirfrontpagecontents) {
1354 log_warn(LD_CONFIG,
1355 "DirPortFrontPage file '%s' not found. Continuing anyway.",
1356 options->DirPortFrontPage);
1360 return 0;
1364 * Functions to parse config options
1367 /** If <b>option</b> is an official abbreviation for a longer option,
1368 * return the longer option. Otherwise return <b>option</b>.
1369 * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
1370 * apply abbreviations that work for the config file and the command line.
1371 * If <b>warn_obsolete</b> is set, warn about deprecated names. */
1372 static const char *
1373 expand_abbrev(config_format_t *fmt, const char *option, int command_line,
1374 int warn_obsolete)
1376 int i;
1377 if (! fmt->abbrevs)
1378 return option;
1379 for (i=0; fmt->abbrevs[i].abbreviated; ++i) {
1380 /* Abbreviations are case insensitive. */
1381 if (!strcasecmp(option,fmt->abbrevs[i].abbreviated) &&
1382 (command_line || !fmt->abbrevs[i].commandline_only)) {
1383 if (warn_obsolete && fmt->abbrevs[i].warn) {
1384 log_warn(LD_CONFIG,
1385 "The configuration option '%s' is deprecated; "
1386 "use '%s' instead.",
1387 fmt->abbrevs[i].abbreviated,
1388 fmt->abbrevs[i].full);
1390 /* Keep going through the list in case we want to rewrite it more.
1391 * (We could imagine recursing here, but I don't want to get the
1392 * user into an infinite loop if we craft our list wrong.) */
1393 option = fmt->abbrevs[i].full;
1396 return option;
1399 /** Helper: Read a list of configuration options from the command line.
1400 * If successful, put them in *<b>result</b> and return 0, and return
1401 * -1 and leave *<b>result</b> alone. */
1402 static int
1403 config_get_commandlines(int argc, char **argv, config_line_t **result)
1405 config_line_t *front = NULL;
1406 config_line_t **new = &front;
1407 char *s;
1408 int i = 1;
1410 while (i < argc) {
1411 if (!strcmp(argv[i],"-f") ||
1412 !strcmp(argv[i],"--hash-password")) {
1413 i += 2; /* command-line option with argument. ignore them. */
1414 continue;
1415 } else if (!strcmp(argv[i],"--list-fingerprint") ||
1416 !strcmp(argv[i],"--verify-config") ||
1417 !strcmp(argv[i],"--ignore-missing-torrc") ||
1418 !strcmp(argv[i],"--quiet") ||
1419 !strcmp(argv[i],"--hush")) {
1420 i += 1; /* command-line option. ignore it. */
1421 continue;
1422 } else if (!strcmp(argv[i],"--nt-service") ||
1423 !strcmp(argv[i],"-nt-service")) {
1424 i += 1;
1425 continue;
1428 if (i == argc-1) {
1429 log_warn(LD_CONFIG,"Command-line option '%s' with no value. Failing.",
1430 argv[i]);
1431 config_free_lines(front);
1432 return -1;
1435 *new = tor_malloc_zero(sizeof(config_line_t));
1436 s = argv[i];
1438 /* Each keyword may be prefixed with one or two dashes. */
1439 if (*s == '-')
1440 s++;
1441 if (*s == '-')
1442 s++;
1444 (*new)->key = tor_strdup(expand_abbrev(&options_format, s, 1, 1));
1445 (*new)->value = tor_strdup(argv[i+1]);
1446 (*new)->next = NULL;
1447 log(LOG_DEBUG, LD_CONFIG, "command line: parsed keyword '%s', value '%s'",
1448 (*new)->key, (*new)->value);
1450 new = &((*new)->next);
1451 i += 2;
1453 *result = front;
1454 return 0;
1457 /** Helper: allocate a new configuration option mapping 'key' to 'val',
1458 * append it to *<b>lst</b>. */
1459 static void
1460 config_line_append(config_line_t **lst,
1461 const char *key,
1462 const char *val)
1464 config_line_t *newline;
1466 newline = tor_malloc(sizeof(config_line_t));
1467 newline->key = tor_strdup(key);
1468 newline->value = tor_strdup(val);
1469 newline->next = NULL;
1470 while (*lst)
1471 lst = &((*lst)->next);
1473 (*lst) = newline;
1476 /** Helper: parse the config string and strdup into key/value
1477 * strings. Set *result to the list, or NULL if parsing the string
1478 * failed. Return 0 on success, -1 on failure. Warn and ignore any
1479 * misformatted lines. */
1481 config_get_lines(const char *string, config_line_t **result)
1483 config_line_t *list = NULL, **next;
1484 char *k, *v;
1486 next = &list;
1487 do {
1488 k = v = NULL;
1489 string = parse_config_line_from_str(string, &k, &v);
1490 if (!string) {
1491 config_free_lines(list);
1492 tor_free(k);
1493 tor_free(v);
1494 return -1;
1496 if (k && v) {
1497 /* This list can get long, so we keep a pointer to the end of it
1498 * rather than using config_line_append over and over and getting
1499 * n^2 performance. */
1500 *next = tor_malloc(sizeof(config_line_t));
1501 (*next)->key = k;
1502 (*next)->value = v;
1503 (*next)->next = NULL;
1504 next = &((*next)->next);
1505 } else {
1506 tor_free(k);
1507 tor_free(v);
1509 } while (*string);
1511 *result = list;
1512 return 0;
1516 * Free all the configuration lines on the linked list <b>front</b>.
1518 void
1519 config_free_lines(config_line_t *front)
1521 config_line_t *tmp;
1523 while (front) {
1524 tmp = front;
1525 front = tmp->next;
1527 tor_free(tmp->key);
1528 tor_free(tmp->value);
1529 tor_free(tmp);
1533 /** If <b>key</b> is a configuration option, return the corresponding
1534 * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
1535 * warn, and return the corresponding config_var_t. Otherwise return NULL.
1537 static config_var_t *
1538 config_find_option(config_format_t *fmt, const char *key)
1540 int i;
1541 size_t keylen = strlen(key);
1542 if (!keylen)
1543 return NULL; /* if they say "--" on the command line, it's not an option */
1544 /* First, check for an exact (case-insensitive) match */
1545 for (i=0; fmt->vars[i].name; ++i) {
1546 if (!strcasecmp(key, fmt->vars[i].name)) {
1547 return &fmt->vars[i];
1550 /* If none, check for an abbreviated match */
1551 for (i=0; fmt->vars[i].name; ++i) {
1552 if (!strncasecmp(key, fmt->vars[i].name, keylen)) {
1553 log_warn(LD_CONFIG, "The abbreviation '%s' is deprecated. "
1554 "Please use '%s' instead",
1555 key, fmt->vars[i].name);
1556 return &fmt->vars[i];
1559 /* Okay, unrecognized option */
1560 return NULL;
1564 * Functions to assign config options.
1567 /** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
1568 * with <b>c</b>-\>value and return 0, or return -1 if bad value.
1570 * Called from config_assign_line() and option_reset().
1572 static int
1573 config_assign_value(config_format_t *fmt, or_options_t *options,
1574 config_line_t *c, char **msg)
1576 int i, ok;
1577 config_var_t *var;
1578 void *lvalue;
1580 CHECK(fmt, options);
1582 var = config_find_option(fmt, c->key);
1583 tor_assert(var);
1585 lvalue = STRUCT_VAR_P(options, var->var_offset);
1587 switch (var->type) {
1589 case CONFIG_TYPE_UINT:
1590 i = (int)tor_parse_long(c->value, 10, 0, INT_MAX, &ok, NULL);
1591 if (!ok) {
1592 tor_asprintf(msg,
1593 "Int keyword '%s %s' is malformed or out of bounds.",
1594 c->key, c->value);
1595 return -1;
1597 *(int *)lvalue = i;
1598 break;
1600 case CONFIG_TYPE_INTERVAL: {
1601 i = config_parse_interval(c->value, &ok);
1602 if (!ok) {
1603 tor_asprintf(msg,
1604 "Interval '%s %s' is malformed or out of bounds.",
1605 c->key, c->value);
1606 return -1;
1608 *(int *)lvalue = i;
1609 break;
1612 case CONFIG_TYPE_MEMUNIT: {
1613 uint64_t u64 = config_parse_memunit(c->value, &ok);
1614 if (!ok) {
1615 tor_asprintf(msg,
1616 "Value '%s %s' is malformed or out of bounds.",
1617 c->key, c->value);
1618 return -1;
1620 *(uint64_t *)lvalue = u64;
1621 break;
1624 case CONFIG_TYPE_BOOL:
1625 i = (int)tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
1626 if (!ok) {
1627 tor_asprintf(msg,
1628 "Boolean '%s %s' expects 0 or 1.",
1629 c->key, c->value);
1630 return -1;
1632 *(int *)lvalue = i;
1633 break;
1635 case CONFIG_TYPE_STRING:
1636 case CONFIG_TYPE_FILENAME:
1637 tor_free(*(char **)lvalue);
1638 *(char **)lvalue = tor_strdup(c->value);
1639 break;
1641 case CONFIG_TYPE_DOUBLE:
1642 *(double *)lvalue = atof(c->value);
1643 break;
1645 case CONFIG_TYPE_ISOTIME:
1646 if (parse_iso_time(c->value, (time_t *)lvalue)) {
1647 tor_asprintf(msg,
1648 "Invalid time '%s' for keyword '%s'", c->value, c->key);
1649 return -1;
1651 break;
1653 case CONFIG_TYPE_ROUTERSET:
1654 if (*(routerset_t**)lvalue) {
1655 routerset_free(*(routerset_t**)lvalue);
1657 *(routerset_t**)lvalue = routerset_new();
1658 if (routerset_parse(*(routerset_t**)lvalue, c->value, c->key)<0) {
1659 tor_asprintf(msg, "Invalid exit list '%s' for option '%s'",
1660 c->value, c->key);
1661 return -1;
1663 break;
1665 case CONFIG_TYPE_CSV:
1666 if (*(smartlist_t**)lvalue) {
1667 SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
1668 smartlist_clear(*(smartlist_t**)lvalue);
1669 } else {
1670 *(smartlist_t**)lvalue = smartlist_create();
1673 smartlist_split_string(*(smartlist_t**)lvalue, c->value, ",",
1674 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1675 break;
1677 case CONFIG_TYPE_LINELIST:
1678 case CONFIG_TYPE_LINELIST_S:
1679 config_line_append((config_line_t**)lvalue, c->key, c->value);
1680 break;
1681 case CONFIG_TYPE_OBSOLETE:
1682 log_warn(LD_CONFIG, "Skipping obsolete configuration option '%s'", c->key);
1683 break;
1684 case CONFIG_TYPE_LINELIST_V:
1685 tor_asprintf(msg,
1686 "You may not provide a value for virtual option '%s'", c->key);
1687 return -1;
1688 default:
1689 tor_assert(0);
1690 break;
1692 return 0;
1695 /** If <b>c</b> is a syntactically valid configuration line, update
1696 * <b>options</b> with its value and return 0. Otherwise return -1 for bad
1697 * key, -2 for bad value.
1699 * If <b>clear_first</b> is set, clear the value first. Then if
1700 * <b>use_defaults</b> is set, set the value to the default.
1702 * Called from config_assign().
1704 static int
1705 config_assign_line(config_format_t *fmt, or_options_t *options,
1706 config_line_t *c, int use_defaults,
1707 int clear_first, char **msg)
1709 config_var_t *var;
1711 CHECK(fmt, options);
1713 var = config_find_option(fmt, c->key);
1714 if (!var) {
1715 if (fmt->extra) {
1716 void *lvalue = STRUCT_VAR_P(options, fmt->extra->var_offset);
1717 log_info(LD_CONFIG,
1718 "Found unrecognized option '%s'; saving it.", c->key);
1719 config_line_append((config_line_t**)lvalue, c->key, c->value);
1720 return 0;
1721 } else {
1722 tor_asprintf(msg,
1723 "Unknown option '%s'. Failing.", c->key);
1724 return -1;
1727 /* Put keyword into canonical case. */
1728 if (strcmp(var->name, c->key)) {
1729 tor_free(c->key);
1730 c->key = tor_strdup(var->name);
1733 if (!strlen(c->value)) {
1734 /* reset or clear it, then return */
1735 if (!clear_first) {
1736 if (var->type == CONFIG_TYPE_LINELIST ||
1737 var->type == CONFIG_TYPE_LINELIST_S) {
1738 /* We got an empty linelist from the torrc or command line.
1739 As a special case, call this an error. Warn and ignore. */
1740 log_warn(LD_CONFIG,
1741 "Linelist option '%s' has no value. Skipping.", c->key);
1742 } else { /* not already cleared */
1743 option_reset(fmt, options, var, use_defaults);
1746 return 0;
1749 if (config_assign_value(fmt, options, c, msg) < 0)
1750 return -2;
1751 return 0;
1754 /** Restore the option named <b>key</b> in options to its default value.
1755 * Called from config_assign(). */
1756 static void
1757 config_reset_line(config_format_t *fmt, or_options_t *options,
1758 const char *key, int use_defaults)
1760 config_var_t *var;
1762 CHECK(fmt, options);
1764 var = config_find_option(fmt, key);
1765 if (!var)
1766 return; /* give error on next pass. */
1768 option_reset(fmt, options, var, use_defaults);
1771 /** Return true iff key is a valid configuration option. */
1773 option_is_recognized(const char *key)
1775 config_var_t *var = config_find_option(&options_format, key);
1776 return (var != NULL);
1779 /** Return the canonical name of a configuration option, or NULL
1780 * if no such option exists. */
1781 const char *
1782 option_get_canonical_name(const char *key)
1784 config_var_t *var = config_find_option(&options_format, key);
1785 return var ? var->name : NULL;
1788 /** Return a canonical list of the options assigned for key.
1790 config_line_t *
1791 option_get_assignment(or_options_t *options, const char *key)
1793 return get_assigned_option(&options_format, options, key, 1);
1796 /** Return true iff value needs to be quoted and escaped to be used in
1797 * a configuration file. */
1798 static int
1799 config_value_needs_escape(const char *value)
1801 if (*value == '\"')
1802 return 1;
1803 while (*value) {
1804 switch (*value)
1806 case '\r':
1807 case '\n':
1808 case '#':
1809 /* Note: quotes and backspaces need special handling when we are using
1810 * quotes, not otherwise, so they don't trigger escaping on their
1811 * own. */
1812 return 1;
1813 default:
1814 if (!TOR_ISPRINT(*value))
1815 return 1;
1817 ++value;
1819 return 0;
1822 /** Return a newly allocated deep copy of the lines in <b>inp</b>. */
1823 static config_line_t *
1824 config_lines_dup(const config_line_t *inp)
1826 config_line_t *result = NULL;
1827 config_line_t **next_out = &result;
1828 while (inp) {
1829 *next_out = tor_malloc(sizeof(config_line_t));
1830 (*next_out)->key = tor_strdup(inp->key);
1831 (*next_out)->value = tor_strdup(inp->value);
1832 inp = inp->next;
1833 next_out = &((*next_out)->next);
1835 (*next_out) = NULL;
1836 return result;
1839 /** Return newly allocated line or lines corresponding to <b>key</b> in the
1840 * configuration <b>options</b>. If <b>escape_val</b> is true and a
1841 * value needs to be quoted before it's put in a config file, quote and
1842 * escape that value. Return NULL if no such key exists. */
1843 static config_line_t *
1844 get_assigned_option(config_format_t *fmt, void *options,
1845 const char *key, int escape_val)
1847 config_var_t *var;
1848 const void *value;
1849 config_line_t *result;
1850 tor_assert(options && key);
1852 CHECK(fmt, options);
1854 var = config_find_option(fmt, key);
1855 if (!var) {
1856 log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key);
1857 return NULL;
1859 value = STRUCT_VAR_P(options, var->var_offset);
1861 result = tor_malloc_zero(sizeof(config_line_t));
1862 result->key = tor_strdup(var->name);
1863 switch (var->type)
1865 case CONFIG_TYPE_STRING:
1866 case CONFIG_TYPE_FILENAME:
1867 if (*(char**)value) {
1868 result->value = tor_strdup(*(char**)value);
1869 } else {
1870 tor_free(result->key);
1871 tor_free(result);
1872 return NULL;
1874 break;
1875 case CONFIG_TYPE_ISOTIME:
1876 if (*(time_t*)value) {
1877 result->value = tor_malloc(ISO_TIME_LEN+1);
1878 format_iso_time(result->value, *(time_t*)value);
1879 } else {
1880 tor_free(result->key);
1881 tor_free(result);
1883 escape_val = 0; /* Can't need escape. */
1884 break;
1885 case CONFIG_TYPE_INTERVAL:
1886 case CONFIG_TYPE_UINT:
1887 /* This means every or_options_t uint or bool element
1888 * needs to be an int. Not, say, a uint16_t or char. */
1889 tor_asprintf(&result->value, "%d", *(int*)value);
1890 escape_val = 0; /* Can't need escape. */
1891 break;
1892 case CONFIG_TYPE_MEMUNIT:
1893 tor_asprintf(&result->value, U64_FORMAT,
1894 U64_PRINTF_ARG(*(uint64_t*)value));
1895 escape_val = 0; /* Can't need escape. */
1896 break;
1897 case CONFIG_TYPE_DOUBLE:
1898 tor_asprintf(&result->value, "%f", *(double*)value);
1899 escape_val = 0; /* Can't need escape. */
1900 break;
1901 case CONFIG_TYPE_BOOL:
1902 result->value = tor_strdup(*(int*)value ? "1" : "0");
1903 escape_val = 0; /* Can't need escape. */
1904 break;
1905 case CONFIG_TYPE_ROUTERSET:
1906 result->value = routerset_to_string(*(routerset_t**)value);
1907 break;
1908 case CONFIG_TYPE_CSV:
1909 if (*(smartlist_t**)value)
1910 result->value =
1911 smartlist_join_strings(*(smartlist_t**)value, ",", 0, NULL);
1912 else
1913 result->value = tor_strdup("");
1914 break;
1915 case CONFIG_TYPE_OBSOLETE:
1916 log_fn(LOG_PROTOCOL_WARN, LD_CONFIG,
1917 "You asked me for the value of an obsolete config option '%s'.",
1918 key);
1919 tor_free(result->key);
1920 tor_free(result);
1921 return NULL;
1922 case CONFIG_TYPE_LINELIST_S:
1923 log_warn(LD_CONFIG,
1924 "Can't return context-sensitive '%s' on its own", key);
1925 tor_free(result->key);
1926 tor_free(result);
1927 return NULL;
1928 case CONFIG_TYPE_LINELIST:
1929 case CONFIG_TYPE_LINELIST_V:
1930 tor_free(result->key);
1931 tor_free(result);
1932 result = config_lines_dup(*(const config_line_t**)value);
1933 break;
1934 default:
1935 tor_free(result->key);
1936 tor_free(result);
1937 log_warn(LD_BUG,"Unknown type %d for known key '%s'",
1938 var->type, key);
1939 return NULL;
1942 if (escape_val) {
1943 config_line_t *line;
1944 for (line = result; line; line = line->next) {
1945 if (line->value && config_value_needs_escape(line->value)) {
1946 char *newval = esc_for_log(line->value);
1947 tor_free(line->value);
1948 line->value = newval;
1953 return result;
1956 /** Iterate through the linked list of requested options <b>list</b>.
1957 * For each item, convert as appropriate and assign to <b>options</b>.
1958 * If an item is unrecognized, set *msg and return -1 immediately,
1959 * else return 0 for success.
1961 * If <b>clear_first</b>, interpret config options as replacing (not
1962 * extending) their previous values. If <b>clear_first</b> is set,
1963 * then <b>use_defaults</b> to decide if you set to defaults after
1964 * clearing, or make the value 0 or NULL.
1966 * Here are the use cases:
1967 * 1. A non-empty AllowInvalid line in your torrc. Appends to current
1968 * if linelist, replaces current if csv.
1969 * 2. An empty AllowInvalid line in your torrc. Should clear it.
1970 * 3. "RESETCONF AllowInvalid" sets it to default.
1971 * 4. "SETCONF AllowInvalid" makes it NULL.
1972 * 5. "SETCONF AllowInvalid=foo" clears it and sets it to "foo".
1974 * Use_defaults Clear_first
1975 * 0 0 "append"
1976 * 1 0 undefined, don't use
1977 * 0 1 "set to null first"
1978 * 1 1 "set to defaults first"
1979 * Return 0 on success, -1 on bad key, -2 on bad value.
1981 * As an additional special case, if a LINELIST config option has
1982 * no value and clear_first is 0, then warn and ignore it.
1986 There are three call cases for config_assign() currently.
1988 Case one: Torrc entry
1989 options_init_from_torrc() calls config_assign(0, 0)
1990 calls config_assign_line(0, 0).
1991 if value is empty, calls option_reset(0) and returns.
1992 calls config_assign_value(), appends.
1994 Case two: setconf
1995 options_trial_assign() calls config_assign(0, 1)
1996 calls config_reset_line(0)
1997 calls option_reset(0)
1998 calls option_clear().
1999 calls config_assign_line(0, 1).
2000 if value is empty, returns.
2001 calls config_assign_value(), appends.
2003 Case three: resetconf
2004 options_trial_assign() calls config_assign(1, 1)
2005 calls config_reset_line(1)
2006 calls option_reset(1)
2007 calls option_clear().
2008 calls config_assign_value(default)
2009 calls config_assign_line(1, 1).
2010 returns.
2012 static int
2013 config_assign(config_format_t *fmt, void *options, config_line_t *list,
2014 int use_defaults, int clear_first, char **msg)
2016 config_line_t *p;
2018 CHECK(fmt, options);
2020 /* pass 1: normalize keys */
2021 for (p = list; p; p = p->next) {
2022 const char *full = expand_abbrev(fmt, p->key, 0, 1);
2023 if (strcmp(full,p->key)) {
2024 tor_free(p->key);
2025 p->key = tor_strdup(full);
2029 /* pass 2: if we're reading from a resetting source, clear all
2030 * mentioned config options, and maybe set to their defaults. */
2031 if (clear_first) {
2032 for (p = list; p; p = p->next)
2033 config_reset_line(fmt, options, p->key, use_defaults);
2036 /* pass 3: assign. */
2037 while (list) {
2038 int r;
2039 if ((r=config_assign_line(fmt, options, list, use_defaults,
2040 clear_first, msg)))
2041 return r;
2042 list = list->next;
2044 return 0;
2047 /** Try assigning <b>list</b> to the global options. You do this by duping
2048 * options, assigning list to the new one, then validating it. If it's
2049 * ok, then throw out the old one and stick with the new one. Else,
2050 * revert to old and return failure. Return SETOPT_OK on success, or
2051 * a setopt_err_t on failure.
2053 * If not success, point *<b>msg</b> to a newly allocated string describing
2054 * what went wrong.
2056 setopt_err_t
2057 options_trial_assign(config_line_t *list, int use_defaults,
2058 int clear_first, char **msg)
2060 int r;
2061 or_options_t *trial_options = options_dup(&options_format, get_options());
2063 if ((r=config_assign(&options_format, trial_options,
2064 list, use_defaults, clear_first, msg)) < 0) {
2065 config_free(&options_format, trial_options);
2066 return r;
2069 if (options_validate(get_options(), trial_options, 1, msg) < 0) {
2070 config_free(&options_format, trial_options);
2071 return SETOPT_ERR_PARSE; /*XXX make this a separate return value. */
2074 if (options_transition_allowed(get_options(), trial_options, msg) < 0) {
2075 config_free(&options_format, trial_options);
2076 return SETOPT_ERR_TRANSITION;
2079 if (set_options(trial_options, msg)<0) {
2080 config_free(&options_format, trial_options);
2081 return SETOPT_ERR_SETTING;
2084 /* we liked it. put it in place. */
2085 return SETOPT_OK;
2088 /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
2089 * Called from option_reset() and config_free(). */
2090 static void
2091 option_clear(config_format_t *fmt, or_options_t *options, config_var_t *var)
2093 void *lvalue = STRUCT_VAR_P(options, var->var_offset);
2094 (void)fmt; /* unused */
2095 switch (var->type) {
2096 case CONFIG_TYPE_STRING:
2097 case CONFIG_TYPE_FILENAME:
2098 tor_free(*(char**)lvalue);
2099 break;
2100 case CONFIG_TYPE_DOUBLE:
2101 *(double*)lvalue = 0.0;
2102 break;
2103 case CONFIG_TYPE_ISOTIME:
2104 *(time_t*)lvalue = 0;
2105 break;
2106 case CONFIG_TYPE_INTERVAL:
2107 case CONFIG_TYPE_UINT:
2108 case CONFIG_TYPE_BOOL:
2109 *(int*)lvalue = 0;
2110 break;
2111 case CONFIG_TYPE_MEMUNIT:
2112 *(uint64_t*)lvalue = 0;
2113 break;
2114 case CONFIG_TYPE_ROUTERSET:
2115 if (*(routerset_t**)lvalue) {
2116 routerset_free(*(routerset_t**)lvalue);
2117 *(routerset_t**)lvalue = NULL;
2119 break;
2120 case CONFIG_TYPE_CSV:
2121 if (*(smartlist_t**)lvalue) {
2122 SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
2123 smartlist_free(*(smartlist_t **)lvalue);
2124 *(smartlist_t **)lvalue = NULL;
2126 break;
2127 case CONFIG_TYPE_LINELIST:
2128 case CONFIG_TYPE_LINELIST_S:
2129 config_free_lines(*(config_line_t **)lvalue);
2130 *(config_line_t **)lvalue = NULL;
2131 break;
2132 case CONFIG_TYPE_LINELIST_V:
2133 /* handled by linelist_s. */
2134 break;
2135 case CONFIG_TYPE_OBSOLETE:
2136 break;
2140 /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
2141 * <b>use_defaults</b>, set it to its default value.
2142 * Called by config_init() and option_reset_line() and option_assign_line(). */
2143 static void
2144 option_reset(config_format_t *fmt, or_options_t *options,
2145 config_var_t *var, int use_defaults)
2147 config_line_t *c;
2148 char *msg = NULL;
2149 CHECK(fmt, options);
2150 option_clear(fmt, options, var); /* clear it first */
2151 if (!use_defaults)
2152 return; /* all done */
2153 if (var->initvalue) {
2154 c = tor_malloc_zero(sizeof(config_line_t));
2155 c->key = tor_strdup(var->name);
2156 c->value = tor_strdup(var->initvalue);
2157 if (config_assign_value(fmt, options, c, &msg) < 0) {
2158 log_warn(LD_BUG, "Failed to assign default: %s", msg);
2159 tor_free(msg); /* if this happens it's a bug */
2161 config_free_lines(c);
2165 /** Print a usage message for tor. */
2166 static void
2167 print_usage(void)
2169 printf(
2170 "Copyright (c) 2001-2004, Roger Dingledine\n"
2171 "Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson\n"
2172 "Copyright (c) 2007-2010, The Tor Project, Inc.\n\n"
2173 "tor -f <torrc> [args]\n"
2174 "See man page for options, or https://www.torproject.org/ for "
2175 "documentation.\n");
2178 /** Print all non-obsolete torrc options. */
2179 static void
2180 list_torrc_options(void)
2182 int i;
2183 smartlist_t *lines = smartlist_create();
2184 for (i = 0; _option_vars[i].name; ++i) {
2185 config_var_t *var = &_option_vars[i];
2186 if (var->type == CONFIG_TYPE_OBSOLETE ||
2187 var->type == CONFIG_TYPE_LINELIST_V)
2188 continue;
2189 printf("%s\n", var->name);
2191 smartlist_free(lines);
2194 /** Last value actually set by resolve_my_address. */
2195 static uint32_t last_resolved_addr = 0;
2197 * Based on <b>options-\>Address</b>, guess our public IP address and put it
2198 * (in host order) into *<b>addr_out</b>. If <b>hostname_out</b> is provided,
2199 * set *<b>hostname_out</b> to a new string holding the hostname we used to
2200 * get the address. Return 0 if all is well, or -1 if we can't find a suitable
2201 * public IP address.
2204 resolve_my_address(int warn_severity, or_options_t *options,
2205 uint32_t *addr_out, char **hostname_out)
2207 struct in_addr in;
2208 uint32_t addr; /* host order */
2209 char hostname[256];
2210 int explicit_ip=1;
2211 int explicit_hostname=1;
2212 int from_interface=0;
2213 char tmpbuf[INET_NTOA_BUF_LEN];
2214 const char *address = options->Address;
2215 int notice_severity = warn_severity <= LOG_NOTICE ?
2216 LOG_NOTICE : warn_severity;
2218 tor_assert(addr_out);
2220 if (address && *address) {
2221 strlcpy(hostname, address, sizeof(hostname));
2222 } else { /* then we need to guess our address */
2223 explicit_ip = 0; /* it's implicit */
2224 explicit_hostname = 0; /* it's implicit */
2226 if (gethostname(hostname, sizeof(hostname)) < 0) {
2227 log_fn(warn_severity, LD_NET,"Error obtaining local hostname");
2228 return -1;
2230 log_debug(LD_CONFIG,"Guessed local host name as '%s'",hostname);
2233 /* now we know hostname. resolve it and keep only the IP address */
2235 if (tor_inet_aton(hostname, &in) == 0) {
2236 /* then we have to resolve it */
2237 explicit_ip = 0;
2238 if (tor_lookup_hostname(hostname, &addr)) { /* failed to resolve */
2239 uint32_t interface_ip; /* host order */
2241 if (explicit_hostname) {
2242 log_fn(warn_severity, LD_CONFIG,
2243 "Could not resolve local Address '%s'. Failing.", hostname);
2244 return -1;
2246 log_fn(notice_severity, LD_CONFIG,
2247 "Could not resolve guessed local hostname '%s'. "
2248 "Trying something else.", hostname);
2249 if (get_interface_address(warn_severity, &interface_ip)) {
2250 log_fn(warn_severity, LD_CONFIG,
2251 "Could not get local interface IP address. Failing.");
2252 return -1;
2254 from_interface = 1;
2255 in.s_addr = htonl(interface_ip);
2256 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2257 log_fn(notice_severity, LD_CONFIG, "Learned IP address '%s' for "
2258 "local interface. Using that.", tmpbuf);
2259 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
2260 } else { /* resolved hostname into addr */
2261 in.s_addr = htonl(addr);
2263 if (!explicit_hostname &&
2264 is_internal_IP(ntohl(in.s_addr), 0)) {
2265 uint32_t interface_ip;
2267 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2268 log_fn(notice_severity, LD_CONFIG, "Guessed local hostname '%s' "
2269 "resolves to a private IP address (%s). Trying something "
2270 "else.", hostname, tmpbuf);
2272 if (get_interface_address(warn_severity, &interface_ip)) {
2273 log_fn(warn_severity, LD_CONFIG,
2274 "Could not get local interface IP address. Too bad.");
2275 } else if (is_internal_IP(interface_ip, 0)) {
2276 struct in_addr in2;
2277 in2.s_addr = htonl(interface_ip);
2278 tor_inet_ntoa(&in2,tmpbuf,sizeof(tmpbuf));
2279 log_fn(notice_severity, LD_CONFIG,
2280 "Interface IP address '%s' is a private address too. "
2281 "Ignoring.", tmpbuf);
2282 } else {
2283 from_interface = 1;
2284 in.s_addr = htonl(interface_ip);
2285 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2286 log_fn(notice_severity, LD_CONFIG,
2287 "Learned IP address '%s' for local interface."
2288 " Using that.", tmpbuf);
2289 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
2295 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2296 if (is_internal_IP(ntohl(in.s_addr), 0) &&
2297 options->_PublishServerDescriptor) {
2298 /* make sure we're ok with publishing an internal IP */
2299 if (!options->DirServers && !options->AlternateDirAuthority) {
2300 /* if they are using the default dirservers, disallow internal IPs
2301 * always. */
2302 log_fn(warn_severity, LD_CONFIG,
2303 "Address '%s' resolves to private IP address '%s'. "
2304 "Tor servers that use the default DirServers must have public "
2305 "IP addresses.", hostname, tmpbuf);
2306 return -1;
2308 if (!explicit_ip) {
2309 /* even if they've set their own dirservers, require an explicit IP if
2310 * they're using an internal address. */
2311 log_fn(warn_severity, LD_CONFIG, "Address '%s' resolves to private "
2312 "IP address '%s'. Please set the Address config option to be "
2313 "the IP address you want to use.", hostname, tmpbuf);
2314 return -1;
2318 log_debug(LD_CONFIG, "Resolved Address to '%s'.", tmpbuf);
2319 *addr_out = ntohl(in.s_addr);
2320 if (last_resolved_addr && last_resolved_addr != *addr_out) {
2321 /* Leave this as a notice, regardless of the requested severity,
2322 * at least until dynamic IP address support becomes bulletproof. */
2323 log_notice(LD_NET,
2324 "Your IP address seems to have changed to %s. Updating.",
2325 tmpbuf);
2326 ip_address_changed(0);
2328 if (last_resolved_addr != *addr_out) {
2329 const char *method;
2330 const char *h = hostname;
2331 if (explicit_ip) {
2332 method = "CONFIGURED";
2333 h = NULL;
2334 } else if (explicit_hostname) {
2335 method = "RESOLVED";
2336 } else if (from_interface) {
2337 method = "INTERFACE";
2338 h = NULL;
2339 } else {
2340 method = "GETHOSTNAME";
2342 control_event_server_status(LOG_NOTICE,
2343 "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s %s%s",
2344 tmpbuf, method, h?"HOSTNAME=":"", h);
2346 last_resolved_addr = *addr_out;
2347 if (hostname_out)
2348 *hostname_out = tor_strdup(hostname);
2349 return 0;
2352 /** Return true iff <b>addr</b> is judged to be on the same network as us, or
2353 * on a private network.
2356 is_local_addr(const tor_addr_t *addr)
2358 if (tor_addr_is_internal(addr, 0))
2359 return 1;
2360 /* Check whether ip is on the same /24 as we are. */
2361 if (get_options()->EnforceDistinctSubnets == 0)
2362 return 0;
2363 if (tor_addr_family(addr) == AF_INET) {
2364 /*XXXX022 IP6 what corresponds to an /24? */
2365 uint32_t ip = tor_addr_to_ipv4h(addr);
2367 /* It's possible that this next check will hit before the first time
2368 * resolve_my_address actually succeeds. (For clients, it is likely that
2369 * resolve_my_address will never be called at all). In those cases,
2370 * last_resolved_addr will be 0, and so checking to see whether ip is on
2371 * the same /24 as last_resolved_addr will be the same as checking whether
2372 * it was on net 0, which is already done by is_internal_IP.
2374 if ((last_resolved_addr & (uint32_t)0xffffff00ul)
2375 == (ip & (uint32_t)0xffffff00ul))
2376 return 1;
2378 return 0;
2381 /** Called when we don't have a nickname set. Try to guess a good nickname
2382 * based on the hostname, and return it in a newly allocated string. If we
2383 * can't, return NULL and let the caller warn if it wants to. */
2384 static char *
2385 get_default_nickname(void)
2387 static const char * const bad_default_nicknames[] = {
2388 "localhost",
2389 NULL,
2391 char localhostname[256];
2392 char *cp, *out, *outp;
2393 int i;
2395 if (gethostname(localhostname, sizeof(localhostname)) < 0)
2396 return NULL;
2398 /* Put it in lowercase; stop at the first dot. */
2399 if ((cp = strchr(localhostname, '.')))
2400 *cp = '\0';
2401 tor_strlower(localhostname);
2403 /* Strip invalid characters. */
2404 cp = localhostname;
2405 out = outp = tor_malloc(strlen(localhostname) + 1);
2406 while (*cp) {
2407 if (strchr(LEGAL_NICKNAME_CHARACTERS, *cp))
2408 *outp++ = *cp++;
2409 else
2410 cp++;
2412 *outp = '\0';
2414 /* Enforce length. */
2415 if (strlen(out) > MAX_NICKNAME_LEN)
2416 out[MAX_NICKNAME_LEN]='\0';
2418 /* Check for dumb names. */
2419 for (i = 0; bad_default_nicknames[i]; ++i) {
2420 if (!strcmp(out, bad_default_nicknames[i])) {
2421 tor_free(out);
2422 return NULL;
2426 return out;
2429 /** Release storage held by <b>options</b>. */
2430 static void
2431 config_free(config_format_t *fmt, void *options)
2433 int i;
2435 if (!options)
2436 return;
2438 tor_assert(fmt);
2440 for (i=0; fmt->vars[i].name; ++i)
2441 option_clear(fmt, options, &(fmt->vars[i]));
2442 if (fmt->extra) {
2443 config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->var_offset);
2444 config_free_lines(*linep);
2445 *linep = NULL;
2447 tor_free(options);
2450 /** Return true iff a and b contain identical keys and values in identical
2451 * order. */
2452 static int
2453 config_lines_eq(config_line_t *a, config_line_t *b)
2455 while (a && b) {
2456 if (strcasecmp(a->key, b->key) || strcmp(a->value, b->value))
2457 return 0;
2458 a = a->next;
2459 b = b->next;
2461 if (a || b)
2462 return 0;
2463 return 1;
2466 /** Return true iff the option <b>name</b> has the same value in <b>o1</b>
2467 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
2469 static int
2470 option_is_same(config_format_t *fmt,
2471 or_options_t *o1, or_options_t *o2, const char *name)
2473 config_line_t *c1, *c2;
2474 int r = 1;
2475 CHECK(fmt, o1);
2476 CHECK(fmt, o2);
2478 c1 = get_assigned_option(fmt, o1, name, 0);
2479 c2 = get_assigned_option(fmt, o2, name, 0);
2480 r = config_lines_eq(c1, c2);
2481 config_free_lines(c1);
2482 config_free_lines(c2);
2483 return r;
2486 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
2487 static or_options_t *
2488 options_dup(config_format_t *fmt, or_options_t *old)
2490 or_options_t *newopts;
2491 int i;
2492 config_line_t *line;
2494 newopts = config_alloc(fmt);
2495 for (i=0; fmt->vars[i].name; ++i) {
2496 if (fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2497 continue;
2498 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE)
2499 continue;
2500 line = get_assigned_option(fmt, old, fmt->vars[i].name, 0);
2501 if (line) {
2502 char *msg = NULL;
2503 if (config_assign(fmt, newopts, line, 0, 0, &msg) < 0) {
2504 log_err(LD_BUG, "Config_get_assigned_option() generated "
2505 "something we couldn't config_assign(): %s", msg);
2506 tor_free(msg);
2507 tor_assert(0);
2510 config_free_lines(line);
2512 return newopts;
2515 /** Return a new empty or_options_t. Used for testing. */
2516 or_options_t *
2517 options_new(void)
2519 return config_alloc(&options_format);
2522 /** Set <b>options</b> to hold reasonable defaults for most options.
2523 * Each option defaults to zero. */
2524 void
2525 options_init(or_options_t *options)
2527 config_init(&options_format, options);
2530 /* Check if the port number given in <b>port_option</b> in combination with
2531 * the specified port in <b>listen_options</b> will result in Tor actually
2532 * opening a low port (meaning a port lower than 1024). Return 1 if
2533 * it is, or 0 if it isn't or the concept of a low port isn't applicable for
2534 * the platform we're on. */
2535 static int
2536 is_listening_on_low_port(uint16_t port_option,
2537 const config_line_t *listen_options)
2539 #ifdef MS_WINDOWS
2540 (void) port_option;
2541 (void) listen_options;
2542 return 0; /* No port is too low for windows. */
2543 #else
2544 const config_line_t *l;
2545 uint16_t p;
2546 if (port_option == 0)
2547 return 0; /* We're not listening */
2548 if (listen_options == NULL)
2549 return (port_option < 1024);
2551 for (l = listen_options; l; l = l->next) {
2552 parse_addr_port(LOG_WARN, l->value, NULL, NULL, &p);
2553 if (p<1024) {
2554 return 1;
2557 return 0;
2558 #endif
2561 /** Set all vars in the configuration object <b>options</b> to their default
2562 * values. */
2563 static void
2564 config_init(config_format_t *fmt, void *options)
2566 int i;
2567 config_var_t *var;
2568 CHECK(fmt, options);
2570 for (i=0; fmt->vars[i].name; ++i) {
2571 var = &fmt->vars[i];
2572 if (!var->initvalue)
2573 continue; /* defaults to NULL or 0 */
2574 option_reset(fmt, options, var, 1);
2578 /** Allocate and return a new string holding the written-out values of the vars
2579 * in 'options'. If 'minimal', do not write out any default-valued vars.
2580 * Else, if comment_defaults, write default values as comments.
2582 static char *
2583 config_dump(config_format_t *fmt, void *options, int minimal,
2584 int comment_defaults)
2586 smartlist_t *elements;
2587 or_options_t *defaults;
2588 config_line_t *line, *assigned;
2589 char *result;
2590 int i;
2591 char *msg = NULL;
2593 defaults = config_alloc(fmt);
2594 config_init(fmt, defaults);
2596 /* XXX use a 1 here so we don't add a new log line while dumping */
2597 if (fmt->validate_fn(NULL,defaults, 1, &msg) < 0) {
2598 log_err(LD_BUG, "Failed to validate default config.");
2599 tor_free(msg);
2600 tor_assert(0);
2603 elements = smartlist_create();
2604 for (i=0; fmt->vars[i].name; ++i) {
2605 int comment_option = 0;
2606 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE ||
2607 fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2608 continue;
2609 /* Don't save 'hidden' control variables. */
2610 if (!strcmpstart(fmt->vars[i].name, "__"))
2611 continue;
2612 if (minimal && option_is_same(fmt, options, defaults, fmt->vars[i].name))
2613 continue;
2614 else if (comment_defaults &&
2615 option_is_same(fmt, options, defaults, fmt->vars[i].name))
2616 comment_option = 1;
2618 line = assigned = get_assigned_option(fmt, options, fmt->vars[i].name, 1);
2620 for (; line; line = line->next) {
2621 char *tmp;
2622 tor_asprintf(&tmp, "%s%s %s\n",
2623 comment_option ? "# " : "",
2624 line->key, line->value);
2625 smartlist_add(elements, tmp);
2627 config_free_lines(assigned);
2630 if (fmt->extra) {
2631 line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->var_offset);
2632 for (; line; line = line->next) {
2633 char *tmp;
2634 tor_asprintf(&tmp, "%s %s\n", line->key, line->value);
2635 smartlist_add(elements, tmp);
2639 result = smartlist_join_strings(elements, "", 0, NULL);
2640 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2641 smartlist_free(elements);
2642 config_free(fmt, defaults);
2643 return result;
2646 /** Return a string containing a possible configuration file that would give
2647 * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
2648 * include options that are the same as Tor's defaults.
2650 char *
2651 options_dump(or_options_t *options, int minimal)
2653 return config_dump(&options_format, options, minimal, 0);
2656 /** Return 0 if every element of sl is a string holding a decimal
2657 * representation of a port number, or if sl is NULL.
2658 * Otherwise set *msg and return -1. */
2659 static int
2660 validate_ports_csv(smartlist_t *sl, const char *name, char **msg)
2662 int i;
2663 tor_assert(name);
2665 if (!sl)
2666 return 0;
2668 SMARTLIST_FOREACH(sl, const char *, cp,
2670 i = atoi(cp);
2671 if (i < 1 || i > 65535) {
2672 tor_asprintf(msg, "Port '%s' out of range in %s", cp, name);
2673 return -1;
2676 return 0;
2679 /** If <b>value</b> exceeds ROUTER_MAX_DECLARED_BANDWIDTH, write
2680 * a complaint into *<b>msg</b> using string <b>desc</b>, and return -1.
2681 * Else return 0.
2683 static int
2684 ensure_bandwidth_cap(uint64_t *value, const char *desc, char **msg)
2686 if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
2687 /* This handles an understandable special case where somebody says "2gb"
2688 * whereas our actual maximum is 2gb-1 (INT_MAX) */
2689 --*value;
2691 if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
2692 tor_asprintf(msg, "%s ("U64_FORMAT") must be at most %d",
2693 desc, U64_PRINTF_ARG(*value),
2694 ROUTER_MAX_DECLARED_BANDWIDTH);
2695 return -1;
2697 return 0;
2700 /** Parse an authority type from <b>options</b>-\>PublishServerDescriptor
2701 * and write it to <b>options</b>-\>_PublishServerDescriptor. Treat "1"
2702 * as "v2,v3" unless BridgeRelay is 1, in which case treat it as "bridge".
2703 * Treat "0" as "".
2704 * Return 0 on success or -1 if not a recognized authority type (in which
2705 * case the value of _PublishServerDescriptor is undefined). */
2706 static int
2707 compute_publishserverdescriptor(or_options_t *options)
2709 smartlist_t *list = options->PublishServerDescriptor;
2710 authority_type_t *auth = &options->_PublishServerDescriptor;
2711 *auth = NO_AUTHORITY;
2712 if (!list) /* empty list, answer is none */
2713 return 0;
2714 SMARTLIST_FOREACH(list, const char *, string, {
2715 if (!strcasecmp(string, "v1"))
2716 *auth |= V1_AUTHORITY;
2717 else if (!strcmp(string, "1"))
2718 if (options->BridgeRelay)
2719 *auth |= BRIDGE_AUTHORITY;
2720 else
2721 *auth |= V2_AUTHORITY | V3_AUTHORITY;
2722 else if (!strcasecmp(string, "v2"))
2723 *auth |= V2_AUTHORITY;
2724 else if (!strcasecmp(string, "v3"))
2725 *auth |= V3_AUTHORITY;
2726 else if (!strcasecmp(string, "bridge"))
2727 *auth |= BRIDGE_AUTHORITY;
2728 else if (!strcasecmp(string, "hidserv"))
2729 *auth |= HIDSERV_AUTHORITY;
2730 else if (!strcasecmp(string, "") || !strcmp(string, "0"))
2731 /* no authority */;
2732 else
2733 return -1;
2735 return 0;
2738 /** Lowest allowable value for RendPostPeriod; if this is too low, hidden
2739 * services can overload the directory system. */
2740 #define MIN_REND_POST_PERIOD (10*60)
2742 /** Highest allowable value for RendPostPeriod. */
2743 #define MAX_DIR_PERIOD (MIN_ONION_KEY_LIFETIME/2)
2745 /** Lowest allowable value for MaxCircuitDirtiness; if this is too low, Tor
2746 * will generate too many circuits and potentially overload the network. */
2747 #define MIN_MAX_CIRCUIT_DIRTINESS 10
2749 /** Lowest allowable value for CircuitStreamTimeout; if this is too low, Tor
2750 * will generate too many circuits and potentially overload the network. */
2751 #define MIN_CIRCUIT_STREAM_TIMEOUT 10
2753 /** Return 0 if every setting in <b>options</b> is reasonable, and a
2754 * permissible transition from <b>old_options</b>. Else return -1.
2755 * Should have no side effects, except for normalizing the contents of
2756 * <b>options</b>.
2758 * On error, tor_strdup an error explanation into *<b>msg</b>.
2760 * XXX
2761 * If <b>from_setconf</b>, we were called by the controller, and our
2762 * Log line should stay empty. If it's 0, then give us a default log
2763 * if there are no logs defined.
2765 static int
2766 options_validate(or_options_t *old_options, or_options_t *options,
2767 int from_setconf, char **msg)
2769 int i;
2770 config_line_t *cl;
2771 const char *uname = get_uname();
2772 #define REJECT(arg) \
2773 STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
2774 #define COMPLAIN(arg) STMT_BEGIN log(LOG_WARN, LD_CONFIG, arg); STMT_END
2776 tor_assert(msg);
2777 *msg = NULL;
2779 if (options->ORPort < 0 || options->ORPort > 65535)
2780 REJECT("ORPort option out of bounds.");
2782 if (server_mode(options) &&
2783 (!strcmpstart(uname, "Windows 95") ||
2784 !strcmpstart(uname, "Windows 98") ||
2785 !strcmpstart(uname, "Windows Me"))) {
2786 log(LOG_WARN, LD_CONFIG, "Tor is running as a server, but you are "
2787 "running %s; this probably won't work. See "
2788 "https://wiki.torproject.org/TheOnionRouter/TorFAQ#ServerOS "
2789 "for details.", uname);
2792 if (options->ORPort == 0 && options->ORListenAddress != NULL)
2793 REJECT("ORPort must be defined if ORListenAddress is defined.");
2795 if (options->DirPort == 0 && options->DirListenAddress != NULL)
2796 REJECT("DirPort must be defined if DirListenAddress is defined.");
2798 if (options->DNSPort == 0 && options->DNSListenAddress != NULL)
2799 REJECT("DNSPort must be defined if DNSListenAddress is defined.");
2801 if (options->ControlPort == 0 && options->ControlListenAddress != NULL)
2802 REJECT("ControlPort must be defined if ControlListenAddress is defined.");
2804 if (options->TransPort == 0 && options->TransListenAddress != NULL)
2805 REJECT("TransPort must be defined if TransListenAddress is defined.");
2807 if (options->NatdPort == 0 && options->NatdListenAddress != NULL)
2808 REJECT("NatdPort must be defined if NatdListenAddress is defined.");
2810 /* Don't gripe about SocksPort 0 with SocksListenAddress set; a standard
2811 * configuration does this. */
2813 for (i = 0; i < 3; ++i) {
2814 int is_socks = i==0;
2815 int is_trans = i==1;
2816 config_line_t *line, *opt, *old;
2817 const char *tp;
2818 if (is_socks) {
2819 opt = options->SocksListenAddress;
2820 old = old_options ? old_options->SocksListenAddress : NULL;
2821 tp = "SOCKS proxy";
2822 } else if (is_trans) {
2823 opt = options->TransListenAddress;
2824 old = old_options ? old_options->TransListenAddress : NULL;
2825 tp = "transparent proxy";
2826 } else {
2827 opt = options->NatdListenAddress;
2828 old = old_options ? old_options->NatdListenAddress : NULL;
2829 tp = "natd proxy";
2832 for (line = opt; line; line = line->next) {
2833 char *address = NULL;
2834 uint16_t port;
2835 uint32_t addr;
2836 if (parse_addr_port(LOG_WARN, line->value, &address, &addr, &port)<0)
2837 continue; /* We'll warn about this later. */
2838 if (!is_internal_IP(addr, 1) &&
2839 (!old_options || !config_lines_eq(old, opt))) {
2840 log_warn(LD_CONFIG,
2841 "You specified a public address '%s' for a %s. Other "
2842 "people on the Internet might find your computer and use it as "
2843 "an open %s. Please don't allow this unless you have "
2844 "a good reason.", address, tp, tp);
2846 tor_free(address);
2850 if (validate_data_directory(options)<0)
2851 REJECT("Invalid DataDirectory");
2853 if (options->Nickname == NULL) {
2854 if (server_mode(options)) {
2855 if (!(options->Nickname = get_default_nickname())) {
2856 log_notice(LD_CONFIG, "Couldn't pick a nickname based on "
2857 "our hostname; using %s instead.", UNNAMED_ROUTER_NICKNAME);
2858 options->Nickname = tor_strdup(UNNAMED_ROUTER_NICKNAME);
2859 } else {
2860 log_notice(LD_CONFIG, "Choosing default nickname '%s'",
2861 options->Nickname);
2864 } else {
2865 if (!is_legal_nickname(options->Nickname)) {
2866 tor_asprintf(msg,
2867 "Nickname '%s' is wrong length or contains illegal characters.",
2868 options->Nickname);
2869 return -1;
2873 if (server_mode(options) && !options->ContactInfo)
2874 log(LOG_NOTICE, LD_CONFIG, "Your ContactInfo config option is not set. "
2875 "Please consider setting it, so we can contact you if your server is "
2876 "misconfigured or something else goes wrong.");
2878 /* Special case on first boot if no Log options are given. */
2879 if (!options->Logs && !options->RunAsDaemon && !from_setconf)
2880 config_line_append(&options->Logs, "Log", "notice stdout");
2882 if (options_init_logs(options, 1)<0) /* Validate the log(s) */
2883 REJECT("Failed to validate Log options. See logs for details.");
2885 if (options->NoPublish) {
2886 log(LOG_WARN, LD_CONFIG,
2887 "NoPublish is obsolete. Use PublishServerDescriptor instead.");
2888 SMARTLIST_FOREACH(options->PublishServerDescriptor, char *, s,
2889 tor_free(s));
2890 smartlist_clear(options->PublishServerDescriptor);
2893 if (authdir_mode(options)) {
2894 /* confirm that our address isn't broken, so we can complain now */
2895 uint32_t tmp;
2896 if (resolve_my_address(LOG_WARN, options, &tmp, NULL) < 0)
2897 REJECT("Failed to resolve/guess local address. See logs for details.");
2900 #ifndef MS_WINDOWS
2901 if (options->RunAsDaemon && torrc_fname && path_is_relative(torrc_fname))
2902 REJECT("Can't use a relative path to torrc when RunAsDaemon is set.");
2903 #endif
2905 if (options->SocksPort < 0 || options->SocksPort > 65535)
2906 REJECT("SocksPort option out of bounds.");
2908 if (options->DNSPort < 0 || options->DNSPort > 65535)
2909 REJECT("DNSPort option out of bounds.");
2911 if (options->TransPort < 0 || options->TransPort > 65535)
2912 REJECT("TransPort option out of bounds.");
2914 if (options->NatdPort < 0 || options->NatdPort > 65535)
2915 REJECT("NatdPort option out of bounds.");
2917 if (options->SocksPort == 0 && options->TransPort == 0 &&
2918 options->NatdPort == 0 && options->ORPort == 0 &&
2919 options->DNSPort == 0 && !options->RendConfigLines)
2920 log(LOG_WARN, LD_CONFIG,
2921 "SocksPort, TransPort, NatdPort, DNSPort, and ORPort are all "
2922 "undefined, and there aren't any hidden services configured. "
2923 "Tor will still run, but probably won't do anything.");
2925 if (options->ControlPort < 0 || options->ControlPort > 65535)
2926 REJECT("ControlPort option out of bounds.");
2928 if (options->DirPort < 0 || options->DirPort > 65535)
2929 REJECT("DirPort option out of bounds.");
2931 #ifndef USE_TRANSPARENT
2932 if (options->TransPort || options->TransListenAddress)
2933 REJECT("TransPort and TransListenAddress are disabled in this build.");
2934 #endif
2936 if (options->AccountingMax &&
2937 (is_listening_on_low_port(options->ORPort, options->ORListenAddress) ||
2938 is_listening_on_low_port(options->DirPort, options->DirListenAddress)))
2940 log(LOG_WARN, LD_CONFIG,
2941 "You have set AccountingMax to use hibernation. You have also "
2942 "chosen a low DirPort or OrPort. This combination can make Tor stop "
2943 "working when it tries to re-attach the port after a period of "
2944 "hibernation. Please choose a different port or turn off "
2945 "hibernation unless you know this combination will work on your "
2946 "platform.");
2949 if (options->ExcludeExitNodes || options->ExcludeNodes) {
2950 options->_ExcludeExitNodesUnion = routerset_new();
2951 routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeExitNodes);
2952 routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeNodes);
2955 if (options->ExcludeNodes && options->StrictNodes) {
2956 COMPLAIN("You have asked to exclude certain relays from all positions "
2957 "in your circuits. Expect hidden services and other Tor "
2958 "features to be broken in unpredictable ways.");
2961 if (options->EntryNodes && !routerset_is_list(options->EntryNodes)) {
2962 /* XXXX fix this; see entry_guards_prepend_from_config(). */
2963 REJECT("IPs or countries are not yet supported in EntryNodes.");
2966 if (options->AuthoritativeDir) {
2967 if (!options->ContactInfo && !options->TestingTorNetwork)
2968 REJECT("Authoritative directory servers must set ContactInfo");
2969 if (options->V1AuthoritativeDir && !options->RecommendedVersions)
2970 REJECT("V1 authoritative dir servers must set RecommendedVersions.");
2971 if (!options->RecommendedClientVersions)
2972 options->RecommendedClientVersions =
2973 config_lines_dup(options->RecommendedVersions);
2974 if (!options->RecommendedServerVersions)
2975 options->RecommendedServerVersions =
2976 config_lines_dup(options->RecommendedVersions);
2977 if (options->VersioningAuthoritativeDir &&
2978 (!options->RecommendedClientVersions ||
2979 !options->RecommendedServerVersions))
2980 REJECT("Versioning authoritative dir servers must set "
2981 "Recommended*Versions.");
2982 if (options->UseEntryGuards) {
2983 log_info(LD_CONFIG, "Authoritative directory servers can't set "
2984 "UseEntryGuards. Disabling.");
2985 options->UseEntryGuards = 0;
2987 if (!options->DownloadExtraInfo && authdir_mode_any_main(options)) {
2988 log_info(LD_CONFIG, "Authoritative directories always try to download "
2989 "extra-info documents. Setting DownloadExtraInfo.");
2990 options->DownloadExtraInfo = 1;
2992 if (!(options->BridgeAuthoritativeDir || options->HSAuthoritativeDir ||
2993 options->V1AuthoritativeDir || options->V2AuthoritativeDir ||
2994 options->V3AuthoritativeDir))
2995 REJECT("AuthoritativeDir is set, but none of "
2996 "(Bridge/HS/V1/V2/V3)AuthoritativeDir is set.");
2997 /* If we have a v3bandwidthsfile and it's broken, complain on startup */
2998 if (options->V3BandwidthsFile && !old_options) {
2999 dirserv_read_measured_bandwidths(options->V3BandwidthsFile, NULL);
3003 if (options->AuthoritativeDir && !options->DirPort)
3004 REJECT("Running as authoritative directory, but no DirPort set.");
3006 if (options->AuthoritativeDir && !options->ORPort)
3007 REJECT("Running as authoritative directory, but no ORPort set.");
3009 if (options->AuthoritativeDir && options->ClientOnly)
3010 REJECT("Running as authoritative directory, but ClientOnly also set.");
3012 if (options->FetchDirInfoExtraEarly && !options->FetchDirInfoEarly)
3013 REJECT("FetchDirInfoExtraEarly requires that you also set "
3014 "FetchDirInfoEarly");
3016 if (options->ConnLimit <= 0) {
3017 tor_asprintf(msg,
3018 "ConnLimit must be greater than 0, but was set to %d",
3019 options->ConnLimit);
3020 return -1;
3023 if (validate_ports_csv(options->FirewallPorts, "FirewallPorts", msg) < 0)
3024 return -1;
3026 if (validate_ports_csv(options->LongLivedPorts, "LongLivedPorts", msg) < 0)
3027 return -1;
3029 if (validate_ports_csv(options->RejectPlaintextPorts,
3030 "RejectPlaintextPorts", msg) < 0)
3031 return -1;
3033 if (validate_ports_csv(options->WarnPlaintextPorts,
3034 "WarnPlaintextPorts", msg) < 0)
3035 return -1;
3037 if (options->FascistFirewall && !options->ReachableAddresses) {
3038 if (options->FirewallPorts && smartlist_len(options->FirewallPorts)) {
3039 /* We already have firewall ports set, so migrate them to
3040 * ReachableAddresses, which will set ReachableORAddresses and
3041 * ReachableDirAddresses if they aren't set explicitly. */
3042 smartlist_t *instead = smartlist_create();
3043 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3044 new_line->key = tor_strdup("ReachableAddresses");
3045 /* If we're configured with the old format, we need to prepend some
3046 * open ports. */
3047 SMARTLIST_FOREACH(options->FirewallPorts, const char *, portno,
3049 int p = atoi(portno);
3050 char *s;
3051 if (p<0) continue;
3052 s = tor_malloc(16);
3053 tor_snprintf(s, 16, "*:%d", p);
3054 smartlist_add(instead, s);
3056 new_line->value = smartlist_join_strings(instead,",",0,NULL);
3057 /* These have been deprecated since 0.1.1.5-alpha-cvs */
3058 log(LOG_NOTICE, LD_CONFIG,
3059 "Converting FascistFirewall and FirewallPorts "
3060 "config options to new format: \"ReachableAddresses %s\"",
3061 new_line->value);
3062 options->ReachableAddresses = new_line;
3063 SMARTLIST_FOREACH(instead, char *, cp, tor_free(cp));
3064 smartlist_free(instead);
3065 } else {
3066 /* We do not have FirewallPorts set, so add 80 to
3067 * ReachableDirAddresses, and 443 to ReachableORAddresses. */
3068 if (!options->ReachableDirAddresses) {
3069 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3070 new_line->key = tor_strdup("ReachableDirAddresses");
3071 new_line->value = tor_strdup("*:80");
3072 options->ReachableDirAddresses = new_line;
3073 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
3074 "to new format: \"ReachableDirAddresses *:80\"");
3076 if (!options->ReachableORAddresses) {
3077 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3078 new_line->key = tor_strdup("ReachableORAddresses");
3079 new_line->value = tor_strdup("*:443");
3080 options->ReachableORAddresses = new_line;
3081 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
3082 "to new format: \"ReachableORAddresses *:443\"");
3087 for (i=0; i<3; i++) {
3088 config_line_t **linep =
3089 (i==0) ? &options->ReachableAddresses :
3090 (i==1) ? &options->ReachableORAddresses :
3091 &options->ReachableDirAddresses;
3092 if (!*linep)
3093 continue;
3094 /* We need to end with a reject *:*, not an implicit accept *:* */
3095 for (;;) {
3096 if (!strcmp((*linep)->value, "reject *:*")) /* already there */
3097 break;
3098 linep = &((*linep)->next);
3099 if (!*linep) {
3100 *linep = tor_malloc_zero(sizeof(config_line_t));
3101 (*linep)->key = tor_strdup(
3102 (i==0) ? "ReachableAddresses" :
3103 (i==1) ? "ReachableORAddresses" :
3104 "ReachableDirAddresses");
3105 (*linep)->value = tor_strdup("reject *:*");
3106 break;
3111 if ((options->ReachableAddresses ||
3112 options->ReachableORAddresses ||
3113 options->ReachableDirAddresses) &&
3114 server_mode(options))
3115 REJECT("Servers must be able to freely connect to the rest "
3116 "of the Internet, so they must not set Reachable*Addresses "
3117 "or FascistFirewall.");
3119 if (options->UseBridges &&
3120 server_mode(options))
3121 REJECT("Servers must be able to freely connect to the rest "
3122 "of the Internet, so they must not set UseBridges.");
3124 options->_AllowInvalid = 0;
3125 if (options->AllowInvalidNodes) {
3126 SMARTLIST_FOREACH(options->AllowInvalidNodes, const char *, cp, {
3127 if (!strcasecmp(cp, "entry"))
3128 options->_AllowInvalid |= ALLOW_INVALID_ENTRY;
3129 else if (!strcasecmp(cp, "exit"))
3130 options->_AllowInvalid |= ALLOW_INVALID_EXIT;
3131 else if (!strcasecmp(cp, "middle"))
3132 options->_AllowInvalid |= ALLOW_INVALID_MIDDLE;
3133 else if (!strcasecmp(cp, "introduction"))
3134 options->_AllowInvalid |= ALLOW_INVALID_INTRODUCTION;
3135 else if (!strcasecmp(cp, "rendezvous"))
3136 options->_AllowInvalid |= ALLOW_INVALID_RENDEZVOUS;
3137 else {
3138 tor_asprintf(msg,
3139 "Unrecognized value '%s' in AllowInvalidNodes", cp);
3140 return -1;
3145 if (!options->SafeLogging ||
3146 !strcasecmp(options->SafeLogging, "0")) {
3147 options->_SafeLogging = SAFELOG_SCRUB_NONE;
3148 } else if (!strcasecmp(options->SafeLogging, "relay")) {
3149 options->_SafeLogging = SAFELOG_SCRUB_RELAY;
3150 } else if (!strcasecmp(options->SafeLogging, "1")) {
3151 options->_SafeLogging = SAFELOG_SCRUB_ALL;
3152 } else {
3153 tor_asprintf(msg,
3154 "Unrecognized value '%s' in SafeLogging",
3155 escaped(options->SafeLogging));
3156 return -1;
3159 if (compute_publishserverdescriptor(options) < 0) {
3160 tor_asprintf(msg, "Unrecognized value in PublishServerDescriptor");
3161 return -1;
3164 if ((options->BridgeRelay
3165 || options->_PublishServerDescriptor & BRIDGE_AUTHORITY)
3166 && (options->_PublishServerDescriptor
3167 & (V1_AUTHORITY|V2_AUTHORITY|V3_AUTHORITY))) {
3168 REJECT("Bridges are not supposed to publish router descriptors to the "
3169 "directory authorities. Please correct your "
3170 "PublishServerDescriptor line.");
3173 if (options->MinUptimeHidServDirectoryV2 < 0) {
3174 log_warn(LD_CONFIG, "MinUptimeHidServDirectoryV2 option must be at "
3175 "least 0 seconds. Changing to 0.");
3176 options->MinUptimeHidServDirectoryV2 = 0;
3179 if (options->RendPostPeriod < MIN_REND_POST_PERIOD) {
3180 log_warn(LD_CONFIG, "RendPostPeriod option is too short; "
3181 "raising to %d seconds.", MIN_REND_POST_PERIOD);
3182 options->RendPostPeriod = MIN_REND_POST_PERIOD;
3185 if (options->RendPostPeriod > MAX_DIR_PERIOD) {
3186 log_warn(LD_CONFIG, "RendPostPeriod is too large; clipping to %ds.",
3187 MAX_DIR_PERIOD);
3188 options->RendPostPeriod = MAX_DIR_PERIOD;
3191 if (options->MaxCircuitDirtiness < MIN_MAX_CIRCUIT_DIRTINESS) {
3192 log_warn(LD_CONFIG, "MaxCircuitDirtiness option is too short; "
3193 "raising to %d seconds.", MIN_MAX_CIRCUIT_DIRTINESS);
3194 options->MaxCircuitDirtiness = MIN_MAX_CIRCUIT_DIRTINESS;
3197 if (options->CircuitStreamTimeout &&
3198 options->CircuitStreamTimeout < MIN_CIRCUIT_STREAM_TIMEOUT) {
3199 log_warn(LD_CONFIG, "CircuitStreamTimeout option is too short; "
3200 "raising to %d seconds.", MIN_CIRCUIT_STREAM_TIMEOUT);
3201 options->CircuitStreamTimeout = MIN_CIRCUIT_STREAM_TIMEOUT;
3204 if (options->KeepalivePeriod < 1)
3205 REJECT("KeepalivePeriod option must be positive.");
3207 if (ensure_bandwidth_cap(&options->BandwidthRate,
3208 "BandwidthRate", msg) < 0)
3209 return -1;
3210 if (ensure_bandwidth_cap(&options->BandwidthBurst,
3211 "BandwidthBurst", msg) < 0)
3212 return -1;
3213 if (ensure_bandwidth_cap(&options->MaxAdvertisedBandwidth,
3214 "MaxAdvertisedBandwidth", msg) < 0)
3215 return -1;
3216 if (ensure_bandwidth_cap(&options->RelayBandwidthRate,
3217 "RelayBandwidthRate", msg) < 0)
3218 return -1;
3219 if (ensure_bandwidth_cap(&options->RelayBandwidthBurst,
3220 "RelayBandwidthBurst", msg) < 0)
3221 return -1;
3222 if (ensure_bandwidth_cap(&options->PerConnBWRate,
3223 "PerConnBWRate", msg) < 0)
3224 return -1;
3225 if (ensure_bandwidth_cap(&options->PerConnBWBurst,
3226 "PerConnBWBurst", msg) < 0)
3227 return -1;
3229 if (server_mode(options)) {
3230 if (options->BandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
3231 tor_asprintf(msg,
3232 "BandwidthRate is set to %d bytes/second. "
3233 "For servers, it must be at least %d.",
3234 (int)options->BandwidthRate,
3235 ROUTER_REQUIRED_MIN_BANDWIDTH);
3236 return -1;
3237 } else if (options->MaxAdvertisedBandwidth <
3238 ROUTER_REQUIRED_MIN_BANDWIDTH/2) {
3239 tor_asprintf(msg,
3240 "MaxAdvertisedBandwidth is set to %d bytes/second. "
3241 "For servers, it must be at least %d.",
3242 (int)options->MaxAdvertisedBandwidth,
3243 ROUTER_REQUIRED_MIN_BANDWIDTH/2);
3244 return -1;
3246 if (options->RelayBandwidthRate &&
3247 options->RelayBandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
3248 tor_asprintf(msg,
3249 "RelayBandwidthRate is set to %d bytes/second. "
3250 "For servers, it must be at least %d.",
3251 (int)options->RelayBandwidthRate,
3252 ROUTER_REQUIRED_MIN_BANDWIDTH);
3253 return -1;
3257 if (options->RelayBandwidthRate && !options->RelayBandwidthBurst)
3258 options->RelayBandwidthBurst = options->RelayBandwidthRate;
3260 if (options->RelayBandwidthRate > options->RelayBandwidthBurst)
3261 REJECT("RelayBandwidthBurst must be at least equal "
3262 "to RelayBandwidthRate.");
3264 if (options->BandwidthRate > options->BandwidthBurst)
3265 REJECT("BandwidthBurst must be at least equal to BandwidthRate.");
3267 /* if they set relaybandwidth* really high but left bandwidth*
3268 * at the default, raise the defaults. */
3269 if (options->RelayBandwidthRate > options->BandwidthRate)
3270 options->BandwidthRate = options->RelayBandwidthRate;
3271 if (options->RelayBandwidthBurst > options->BandwidthBurst)
3272 options->BandwidthBurst = options->RelayBandwidthBurst;
3274 if (accounting_parse_options(options, 1)<0)
3275 REJECT("Failed to parse accounting options. See logs for details.");
3277 if (options->HttpProxy) { /* parse it now */
3278 if (tor_addr_port_parse(options->HttpProxy,
3279 &options->HttpProxyAddr, &options->HttpProxyPort) < 0)
3280 REJECT("HttpProxy failed to parse or resolve. Please fix.");
3281 if (options->HttpProxyPort == 0) { /* give it a default */
3282 options->HttpProxyPort = 80;
3286 if (options->HttpProxyAuthenticator) {
3287 if (strlen(options->HttpProxyAuthenticator) >= 48)
3288 REJECT("HttpProxyAuthenticator is too long (>= 48 chars).");
3291 if (options->HttpsProxy) { /* parse it now */
3292 if (tor_addr_port_parse(options->HttpsProxy,
3293 &options->HttpsProxyAddr, &options->HttpsProxyPort) <0)
3294 REJECT("HttpsProxy failed to parse or resolve. Please fix.");
3295 if (options->HttpsProxyPort == 0) { /* give it a default */
3296 options->HttpsProxyPort = 443;
3300 if (options->HttpsProxyAuthenticator) {
3301 if (strlen(options->HttpsProxyAuthenticator) >= 48)
3302 REJECT("HttpsProxyAuthenticator is too long (>= 48 chars).");
3305 if (options->Socks4Proxy) { /* parse it now */
3306 if (tor_addr_port_parse(options->Socks4Proxy,
3307 &options->Socks4ProxyAddr,
3308 &options->Socks4ProxyPort) <0)
3309 REJECT("Socks4Proxy failed to parse or resolve. Please fix.");
3310 if (options->Socks4ProxyPort == 0) { /* give it a default */
3311 options->Socks4ProxyPort = 1080;
3315 if (options->Socks5Proxy) { /* parse it now */
3316 if (tor_addr_port_parse(options->Socks5Proxy,
3317 &options->Socks5ProxyAddr,
3318 &options->Socks5ProxyPort) <0)
3319 REJECT("Socks5Proxy failed to parse or resolve. Please fix.");
3320 if (options->Socks5ProxyPort == 0) { /* give it a default */
3321 options->Socks5ProxyPort = 1080;
3325 if (options->Socks4Proxy && options->Socks5Proxy)
3326 REJECT("You cannot specify both Socks4Proxy and SOCKS5Proxy");
3328 if (options->Socks5ProxyUsername) {
3329 size_t len;
3331 len = strlen(options->Socks5ProxyUsername);
3332 if (len < 1 || len > 255)
3333 REJECT("Socks5ProxyUsername must be between 1 and 255 characters.");
3335 if (!options->Socks5ProxyPassword)
3336 REJECT("Socks5ProxyPassword must be included with Socks5ProxyUsername.");
3338 len = strlen(options->Socks5ProxyPassword);
3339 if (len < 1 || len > 255)
3340 REJECT("Socks5ProxyPassword must be between 1 and 255 characters.");
3341 } else if (options->Socks5ProxyPassword)
3342 REJECT("Socks5ProxyPassword must be included with Socks5ProxyUsername.");
3344 if (options->HashedControlPassword) {
3345 smartlist_t *sl = decode_hashed_passwords(options->HashedControlPassword);
3346 if (!sl) {
3347 REJECT("Bad HashedControlPassword: wrong length or bad encoding");
3348 } else {
3349 SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
3350 smartlist_free(sl);
3354 if (options->HashedControlSessionPassword) {
3355 smartlist_t *sl = decode_hashed_passwords(
3356 options->HashedControlSessionPassword);
3357 if (!sl) {
3358 REJECT("Bad HashedControlSessionPassword: wrong length or bad encoding");
3359 } else {
3360 SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
3361 smartlist_free(sl);
3365 if (options->ControlListenAddress) {
3366 int all_are_local = 1;
3367 config_line_t *ln;
3368 for (ln = options->ControlListenAddress; ln; ln = ln->next) {
3369 if (strcmpstart(ln->value, "127."))
3370 all_are_local = 0;
3372 if (!all_are_local) {
3373 if (!options->HashedControlPassword &&
3374 !options->HashedControlSessionPassword &&
3375 !options->CookieAuthentication) {
3376 log_warn(LD_CONFIG,
3377 "You have a ControlListenAddress set to accept "
3378 "unauthenticated connections from a non-local address. "
3379 "This means that programs not running on your computer "
3380 "can reconfigure your Tor, without even having to guess a "
3381 "password. That's so bad that I'm closing your ControlPort "
3382 "for you. If you need to control your Tor remotely, try "
3383 "enabling authentication and using a tool like stunnel or "
3384 "ssh to encrypt remote access.");
3385 options->ControlPort = 0;
3386 } else {
3387 log_warn(LD_CONFIG, "You have a ControlListenAddress set to accept "
3388 "connections from a non-local address. This means that "
3389 "programs not running on your computer can reconfigure your "
3390 "Tor. That's pretty bad, since the controller "
3391 "protocol isn't encrypted! Maybe you should just listen on "
3392 "127.0.0.1 and use a tool like stunnel or ssh to encrypt "
3393 "remote connections to your control port.");
3398 if (options->ControlPort && !options->HashedControlPassword &&
3399 !options->HashedControlSessionPassword &&
3400 !options->CookieAuthentication) {
3401 log_warn(LD_CONFIG, "ControlPort is open, but no authentication method "
3402 "has been configured. This means that any program on your "
3403 "computer can reconfigure your Tor. That's bad! You should "
3404 "upgrade your Tor controller as soon as possible.");
3407 if (options->UseEntryGuards && ! options->NumEntryGuards)
3408 REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0");
3410 if (check_nickname_list(options->MyFamily, "MyFamily", msg))
3411 return -1;
3412 for (cl = options->NodeFamilies; cl; cl = cl->next) {
3413 if (check_nickname_list(cl->value, "NodeFamily", msg))
3414 return -1;
3417 if (validate_addr_policies(options, msg) < 0)
3418 return -1;
3420 if (validate_dir_authorities(options, old_options) < 0)
3421 REJECT("Directory authority line did not parse. See logs for details.");
3423 if (options->UseBridges && !options->Bridges)
3424 REJECT("If you set UseBridges, you must specify at least one bridge.");
3425 if (options->UseBridges && !options->TunnelDirConns)
3426 REJECT("If you set UseBridges, you must set TunnelDirConns.");
3427 if (options->Bridges) {
3428 for (cl = options->Bridges; cl; cl = cl->next) {
3429 if (parse_bridge_line(cl->value, 1)<0)
3430 REJECT("Bridge line did not parse. See logs for details.");
3434 if (options->ConstrainedSockets) {
3435 /* If the user wants to constrain socket buffer use, make sure the desired
3436 * limit is between MIN|MAX_TCPSOCK_BUFFER in k increments. */
3437 if (options->ConstrainedSockSize < MIN_CONSTRAINED_TCP_BUFFER ||
3438 options->ConstrainedSockSize > MAX_CONSTRAINED_TCP_BUFFER ||
3439 options->ConstrainedSockSize % 1024) {
3440 tor_asprintf(msg,
3441 "ConstrainedSockSize is invalid. Must be a value between %d and %d "
3442 "in 1024 byte increments.",
3443 MIN_CONSTRAINED_TCP_BUFFER, MAX_CONSTRAINED_TCP_BUFFER);
3444 return -1;
3446 if (options->DirPort) {
3447 /* Providing cached directory entries while system TCP buffers are scarce
3448 * will exacerbate the socket errors. Suggest that this be disabled. */
3449 COMPLAIN("You have requested constrained socket buffers while also "
3450 "serving directory entries via DirPort. It is strongly "
3451 "suggested that you disable serving directory requests when "
3452 "system TCP buffer resources are scarce.");
3456 if (options->V3AuthVoteDelay + options->V3AuthDistDelay >=
3457 options->V3AuthVotingInterval/2) {
3458 REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than half "
3459 "V3AuthVotingInterval");
3461 if (options->V3AuthVoteDelay < MIN_VOTE_SECONDS)
3462 REJECT("V3AuthVoteDelay is way too low.");
3463 if (options->V3AuthDistDelay < MIN_DIST_SECONDS)
3464 REJECT("V3AuthDistDelay is way too low.");
3466 if (options->V3AuthNIntervalsValid < 2)
3467 REJECT("V3AuthNIntervalsValid must be at least 2.");
3469 if (options->V3AuthVotingInterval < MIN_VOTE_INTERVAL) {
3470 REJECT("V3AuthVotingInterval is insanely low.");
3471 } else if (options->V3AuthVotingInterval > 24*60*60) {
3472 REJECT("V3AuthVotingInterval is insanely high.");
3473 } else if (((24*60*60) % options->V3AuthVotingInterval) != 0) {
3474 COMPLAIN("V3AuthVotingInterval does not divide evenly into 24 hours.");
3477 if (rend_config_services(options, 1) < 0)
3478 REJECT("Failed to configure rendezvous options. See logs for details.");
3480 /* Parse client-side authorization for hidden services. */
3481 if (rend_parse_service_authorization(options, 1) < 0)
3482 REJECT("Failed to configure client authorization for hidden services. "
3483 "See logs for details.");
3485 if (parse_virtual_addr_network(options->VirtualAddrNetwork, 1, NULL)<0)
3486 return -1;
3488 if (options->PreferTunneledDirConns && !options->TunnelDirConns)
3489 REJECT("Must set TunnelDirConns if PreferTunneledDirConns is set.");
3491 if ((options->Socks4Proxy || options->Socks5Proxy) &&
3492 !options->HttpProxy && !options->PreferTunneledDirConns)
3493 REJECT("When Socks4Proxy or Socks5Proxy is configured, "
3494 "PreferTunneledDirConns and TunnelDirConns must both be "
3495 "set to 1, or HttpProxy must be configured.");
3497 if (options->AutomapHostsSuffixes) {
3498 SMARTLIST_FOREACH(options->AutomapHostsSuffixes, char *, suf,
3500 size_t len = strlen(suf);
3501 if (len && suf[len-1] == '.')
3502 suf[len-1] = '\0';
3506 if (options->TestingTorNetwork && !options->DirServers) {
3507 REJECT("TestingTorNetwork may only be configured in combination with "
3508 "a non-default set of DirServers.");
3511 /*XXXX022 checking for defaults manually like this is a bit fragile.*/
3513 /* Keep changes to hard-coded values synchronous to man page and default
3514 * values table. */
3515 if (options->TestingV3AuthInitialVotingInterval != 30*60 &&
3516 !options->TestingTorNetwork) {
3517 REJECT("TestingV3AuthInitialVotingInterval may only be changed in testing "
3518 "Tor networks!");
3519 } else if (options->TestingV3AuthInitialVotingInterval < MIN_VOTE_INTERVAL) {
3520 REJECT("TestingV3AuthInitialVotingInterval is insanely low.");
3521 } else if (((30*60) % options->TestingV3AuthInitialVotingInterval) != 0) {
3522 REJECT("TestingV3AuthInitialVotingInterval does not divide evenly into "
3523 "30 minutes.");
3526 if (options->TestingV3AuthInitialVoteDelay != 5*60 &&
3527 !options->TestingTorNetwork) {
3528 REJECT("TestingV3AuthInitialVoteDelay may only be changed in testing "
3529 "Tor networks!");
3530 } else if (options->TestingV3AuthInitialVoteDelay < MIN_VOTE_SECONDS) {
3531 REJECT("TestingV3AuthInitialVoteDelay is way too low.");
3534 if (options->TestingV3AuthInitialDistDelay != 5*60 &&
3535 !options->TestingTorNetwork) {
3536 REJECT("TestingV3AuthInitialDistDelay may only be changed in testing "
3537 "Tor networks!");
3538 } else if (options->TestingV3AuthInitialDistDelay < MIN_DIST_SECONDS) {
3539 REJECT("TestingV3AuthInitialDistDelay is way too low.");
3542 if (options->TestingV3AuthInitialVoteDelay +
3543 options->TestingV3AuthInitialDistDelay >=
3544 options->TestingV3AuthInitialVotingInterval/2) {
3545 REJECT("TestingV3AuthInitialVoteDelay plus TestingV3AuthInitialDistDelay "
3546 "must be less than half TestingV3AuthInitialVotingInterval");
3549 if (options->TestingAuthDirTimeToLearnReachability != 30*60 &&
3550 !options->TestingTorNetwork) {
3551 REJECT("TestingAuthDirTimeToLearnReachability may only be changed in "
3552 "testing Tor networks!");
3553 } else if (options->TestingAuthDirTimeToLearnReachability < 0) {
3554 REJECT("TestingAuthDirTimeToLearnReachability must be non-negative.");
3555 } else if (options->TestingAuthDirTimeToLearnReachability > 2*60*60) {
3556 COMPLAIN("TestingAuthDirTimeToLearnReachability is insanely high.");
3559 if (options->TestingEstimatedDescriptorPropagationTime != 10*60 &&
3560 !options->TestingTorNetwork) {
3561 REJECT("TestingEstimatedDescriptorPropagationTime may only be changed in "
3562 "testing Tor networks!");
3563 } else if (options->TestingEstimatedDescriptorPropagationTime < 0) {
3564 REJECT("TestingEstimatedDescriptorPropagationTime must be non-negative.");
3565 } else if (options->TestingEstimatedDescriptorPropagationTime > 60*60) {
3566 COMPLAIN("TestingEstimatedDescriptorPropagationTime is insanely high.");
3569 if (options->TestingTorNetwork) {
3570 log_warn(LD_CONFIG, "TestingTorNetwork is set. This will make your node "
3571 "almost unusable in the public Tor network, and is "
3572 "therefore only advised if you are building a "
3573 "testing Tor network!");
3576 if (options->AccelName && !options->HardwareAccel)
3577 options->HardwareAccel = 1;
3578 if (options->AccelDir && !options->AccelName)
3579 REJECT("Can't use hardware crypto accelerator dir without engine name.");
3581 return 0;
3582 #undef REJECT
3583 #undef COMPLAIN
3586 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
3587 * equal strings. */
3588 static int
3589 opt_streq(const char *s1, const char *s2)
3591 if (!s1 && !s2)
3592 return 1;
3593 else if (s1 && s2 && !strcmp(s1,s2))
3594 return 1;
3595 else
3596 return 0;
3599 /** Check if any of the previous options have changed but aren't allowed to. */
3600 static int
3601 options_transition_allowed(or_options_t *old, or_options_t *new_val,
3602 char **msg)
3604 if (!old)
3605 return 0;
3607 if (!opt_streq(old->PidFile, new_val->PidFile)) {
3608 *msg = tor_strdup("PidFile is not allowed to change.");
3609 return -1;
3612 if (old->RunAsDaemon != new_val->RunAsDaemon) {
3613 *msg = tor_strdup("While Tor is running, changing RunAsDaemon "
3614 "is not allowed.");
3615 return -1;
3618 if (strcmp(old->DataDirectory,new_val->DataDirectory)!=0) {
3619 tor_asprintf(msg,
3620 "While Tor is running, changing DataDirectory "
3621 "(\"%s\"->\"%s\") is not allowed.",
3622 old->DataDirectory, new_val->DataDirectory);
3623 return -1;
3626 if (!opt_streq(old->User, new_val->User)) {
3627 *msg = tor_strdup("While Tor is running, changing User is not allowed.");
3628 return -1;
3631 if ((old->HardwareAccel != new_val->HardwareAccel)
3632 || !opt_streq(old->AccelName, new_val->AccelName)
3633 || !opt_streq(old->AccelDir, new_val->AccelDir)) {
3634 *msg = tor_strdup("While Tor is running, changing OpenSSL hardware "
3635 "acceleration engine is not allowed.");
3636 return -1;
3639 if (old->TestingTorNetwork != new_val->TestingTorNetwork) {
3640 *msg = tor_strdup("While Tor is running, changing TestingTorNetwork "
3641 "is not allowed.");
3642 return -1;
3645 if (old->CellStatistics != new_val->CellStatistics ||
3646 old->DirReqStatistics != new_val->DirReqStatistics ||
3647 old->EntryStatistics != new_val->EntryStatistics ||
3648 old->ExitPortStatistics != new_val->ExitPortStatistics) {
3649 *msg = tor_strdup("While Tor is running, changing either "
3650 "CellStatistics, DirReqStatistics, EntryStatistics, "
3651 "or ExitPortStatistics is not allowed.");
3652 return -1;
3655 if (old->DisableAllSwap != new_val->DisableAllSwap) {
3656 *msg = tor_strdup("While Tor is running, changing DisableAllSwap "
3657 "is not allowed.");
3658 return -1;
3661 return 0;
3664 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
3665 * will require us to rotate the CPU and DNS workers; else return 0. */
3666 static int
3667 options_transition_affects_workers(or_options_t *old_options,
3668 or_options_t *new_options)
3670 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
3671 old_options->NumCpus != new_options->NumCpus ||
3672 old_options->ORPort != new_options->ORPort ||
3673 old_options->ServerDNSSearchDomains !=
3674 new_options->ServerDNSSearchDomains ||
3675 old_options->SafeLogging != new_options->SafeLogging ||
3676 old_options->ClientOnly != new_options->ClientOnly ||
3677 !config_lines_eq(old_options->Logs, new_options->Logs))
3678 return 1;
3680 /* Check whether log options match. */
3682 /* Nothing that changed matters. */
3683 return 0;
3686 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
3687 * will require us to generate a new descriptor; else return 0. */
3688 static int
3689 options_transition_affects_descriptor(or_options_t *old_options,
3690 or_options_t *new_options)
3692 /* XXX We can be smarter here. If your DirPort isn't being
3693 * published and you just turned it off, no need to republish. Etc. */
3694 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
3695 !opt_streq(old_options->Nickname,new_options->Nickname) ||
3696 !opt_streq(old_options->Address,new_options->Address) ||
3697 !config_lines_eq(old_options->ExitPolicy,new_options->ExitPolicy) ||
3698 old_options->ExitPolicyRejectPrivate !=
3699 new_options->ExitPolicyRejectPrivate ||
3700 old_options->ORPort != new_options->ORPort ||
3701 old_options->DirPort != new_options->DirPort ||
3702 old_options->ClientOnly != new_options->ClientOnly ||
3703 old_options->NoPublish != new_options->NoPublish ||
3704 old_options->_PublishServerDescriptor !=
3705 new_options->_PublishServerDescriptor ||
3706 get_effective_bwrate(old_options) != get_effective_bwrate(new_options) ||
3707 get_effective_bwburst(old_options) !=
3708 get_effective_bwburst(new_options) ||
3709 !opt_streq(old_options->ContactInfo, new_options->ContactInfo) ||
3710 !opt_streq(old_options->MyFamily, new_options->MyFamily) ||
3711 !opt_streq(old_options->AccountingStart, new_options->AccountingStart) ||
3712 old_options->AccountingMax != new_options->AccountingMax)
3713 return 1;
3715 return 0;
3718 #ifdef MS_WINDOWS
3719 /** Return the directory on windows where we expect to find our application
3720 * data. */
3721 static char *
3722 get_windows_conf_root(void)
3724 static int is_set = 0;
3725 static char path[MAX_PATH+1];
3726 WCHAR wpath[MAX_PATH] = {0};
3728 LPITEMIDLIST idl;
3729 IMalloc *m;
3730 HRESULT result;
3732 if (is_set)
3733 return path;
3735 /* Find X:\documents and settings\username\application data\ .
3736 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
3738 #ifdef ENABLE_LOCAL_APPDATA
3739 #define APPDATA_PATH CSIDL_LOCAL_APPDATA
3740 #else
3741 #define APPDATA_PATH CSIDL_APPDATA
3742 #endif
3743 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, APPDATA_PATH, &idl))) {
3744 getcwd(path,MAX_PATH);
3745 is_set = 1;
3746 log_warn(LD_CONFIG,
3747 "I couldn't find your application data folder: are you "
3748 "running an ancient version of Windows 95? Defaulting to \"%s\"",
3749 path);
3750 return path;
3752 /* Convert the path from an "ID List" (whatever that is!) to a path. */
3753 result = SHGetPathFromIDListW(idl, wpath);
3754 wcstombs(path,wpath,MAX_PATH);
3756 /* Now we need to free the memory that the path-idl was stored in. In
3757 * typical Windows fashion, we can't just call 'free()' on it. */
3758 SHGetMalloc(&m);
3759 if (m) {
3760 m->lpVtbl->Free(m, idl);
3761 m->lpVtbl->Release(m);
3763 if (!SUCCEEDED(result)) {
3764 return NULL;
3766 strlcat(path,"\\tor",MAX_PATH);
3767 is_set = 1;
3768 return path;
3770 #endif
3772 /** Return the default location for our torrc file. */
3773 static const char *
3774 get_default_conf_file(void)
3776 #ifdef MS_WINDOWS
3777 static char path[MAX_PATH+1];
3778 strlcpy(path, get_windows_conf_root(), MAX_PATH);
3779 strlcat(path,"\\torrc",MAX_PATH);
3780 return path;
3781 #else
3782 return (CONFDIR "/torrc");
3783 #endif
3786 /** Verify whether lst is a string containing valid-looking comma-separated
3787 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
3789 static int
3790 check_nickname_list(const char *lst, const char *name, char **msg)
3792 int r = 0;
3793 smartlist_t *sl;
3795 if (!lst)
3796 return 0;
3797 sl = smartlist_create();
3799 smartlist_split_string(sl, lst, ",",
3800 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0);
3802 SMARTLIST_FOREACH(sl, const char *, s,
3804 if (!is_legal_nickname_or_hexdigest(s)) {
3805 tor_asprintf(msg, "Invalid nickname '%s' in %s line", s, name);
3806 r = -1;
3807 break;
3810 SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
3811 smartlist_free(sl);
3812 return r;
3815 /** Learn config file name from command line arguments, or use the default */
3816 static char *
3817 find_torrc_filename(int argc, char **argv,
3818 int *using_default_torrc, int *ignore_missing_torrc)
3820 char *fname=NULL;
3821 int i;
3823 for (i = 1; i < argc; ++i) {
3824 if (i < argc-1 && !strcmp(argv[i],"-f")) {
3825 if (fname) {
3826 log(LOG_WARN, LD_CONFIG, "Duplicate -f options on command line.");
3827 tor_free(fname);
3829 fname = expand_filename(argv[i+1]);
3830 *using_default_torrc = 0;
3831 ++i;
3832 } else if (!strcmp(argv[i],"--ignore-missing-torrc")) {
3833 *ignore_missing_torrc = 1;
3837 if (*using_default_torrc) {
3838 /* didn't find one, try CONFDIR */
3839 const char *dflt = get_default_conf_file();
3840 if (dflt && file_status(dflt) == FN_FILE) {
3841 fname = tor_strdup(dflt);
3842 } else {
3843 #ifndef MS_WINDOWS
3844 char *fn;
3845 fn = expand_filename("~/.torrc");
3846 if (fn && file_status(fn) == FN_FILE) {
3847 fname = fn;
3848 } else {
3849 tor_free(fn);
3850 fname = tor_strdup(dflt);
3852 #else
3853 fname = tor_strdup(dflt);
3854 #endif
3857 return fname;
3860 /** Load torrc from disk, setting torrc_fname if successful */
3861 static char *
3862 load_torrc_from_disk(int argc, char **argv)
3864 char *fname=NULL;
3865 char *cf = NULL;
3866 int using_default_torrc = 1;
3867 int ignore_missing_torrc = 0;
3869 fname = find_torrc_filename(argc, argv,
3870 &using_default_torrc, &ignore_missing_torrc);
3871 tor_assert(fname);
3872 log(LOG_DEBUG, LD_CONFIG, "Opening config file \"%s\"", fname);
3874 tor_free(torrc_fname);
3875 torrc_fname = fname;
3877 /* Open config file */
3878 if (file_status(fname) != FN_FILE ||
3879 !(cf = read_file_to_str(fname,0,NULL))) {
3880 if (using_default_torrc == 1 || ignore_missing_torrc ) {
3881 log(LOG_NOTICE, LD_CONFIG, "Configuration file \"%s\" not present, "
3882 "using reasonable defaults.", fname);
3883 tor_free(fname); /* sets fname to NULL */
3884 torrc_fname = NULL;
3885 cf = tor_strdup("");
3886 } else {
3887 log(LOG_WARN, LD_CONFIG,
3888 "Unable to open configuration file \"%s\".", fname);
3889 goto err;
3893 return cf;
3894 err:
3895 tor_free(fname);
3896 torrc_fname = NULL;
3897 return NULL;
3900 /** Read a configuration file into <b>options</b>, finding the configuration
3901 * file location based on the command line. After loading the file
3902 * call options_init_from_string() to load the config.
3903 * Return 0 if success, -1 if failure. */
3905 options_init_from_torrc(int argc, char **argv)
3907 char *cf=NULL;
3908 int i, retval, command;
3909 static char **backup_argv;
3910 static int backup_argc;
3911 char *command_arg = NULL;
3912 char *errmsg=NULL;
3914 if (argv) { /* first time we're called. save command line args */
3915 backup_argv = argv;
3916 backup_argc = argc;
3917 } else { /* we're reloading. need to clean up old options first. */
3918 argv = backup_argv;
3919 argc = backup_argc;
3921 if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
3922 print_usage();
3923 exit(0);
3925 if (argc > 1 && !strcmp(argv[1], "--list-torrc-options")) {
3926 /* For documenting validating whether we've documented everything. */
3927 list_torrc_options();
3928 exit(0);
3931 if (argc > 1 && (!strcmp(argv[1],"--version"))) {
3932 printf("Tor version %s.\n",get_version());
3933 exit(0);
3935 if (argc > 1 && (!strcmp(argv[1],"--digests"))) {
3936 printf("Tor version %s.\n",get_version());
3937 printf("%s", libor_get_digests());
3938 printf("%s", tor_get_digests());
3939 exit(0);
3942 /* Go through command-line variables */
3943 if (!global_cmdline_options) {
3944 /* Or we could redo the list every time we pass this place.
3945 * It does not really matter */
3946 if (config_get_commandlines(argc, argv, &global_cmdline_options) < 0) {
3947 goto err;
3951 command = CMD_RUN_TOR;
3952 for (i = 1; i < argc; ++i) {
3953 if (!strcmp(argv[i],"--list-fingerprint")) {
3954 command = CMD_LIST_FINGERPRINT;
3955 } else if (!strcmp(argv[i],"--hash-password")) {
3956 command = CMD_HASH_PASSWORD;
3957 command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : "");
3958 ++i;
3959 } else if (!strcmp(argv[i],"--verify-config")) {
3960 command = CMD_VERIFY_CONFIG;
3964 if (command == CMD_HASH_PASSWORD) {
3965 cf = tor_strdup("");
3966 } else {
3967 cf = load_torrc_from_disk(argc, argv);
3968 if (!cf)
3969 goto err;
3972 retval = options_init_from_string(cf, command, command_arg, &errmsg);
3973 tor_free(cf);
3974 if (retval < 0)
3975 goto err;
3977 return 0;
3979 err:
3980 if (errmsg) {
3981 log(LOG_WARN,LD_CONFIG,"%s", errmsg);
3982 tor_free(errmsg);
3984 return -1;
3987 /** Load the options from the configuration in <b>cf</b>, validate
3988 * them for consistency and take actions based on them.
3990 * Return 0 if success, negative on error:
3991 * * -1 for general errors.
3992 * * -2 for failure to parse/validate,
3993 * * -3 for transition not allowed
3994 * * -4 for error while setting the new options
3996 setopt_err_t
3997 options_init_from_string(const char *cf,
3998 int command, const char *command_arg,
3999 char **msg)
4001 or_options_t *oldoptions, *newoptions;
4002 config_line_t *cl;
4003 int retval;
4004 setopt_err_t err = SETOPT_ERR_MISC;
4005 tor_assert(msg);
4007 oldoptions = global_options; /* get_options unfortunately asserts if
4008 this is the first time we run*/
4010 newoptions = tor_malloc_zero(sizeof(or_options_t));
4011 newoptions->_magic = OR_OPTIONS_MAGIC;
4012 options_init(newoptions);
4013 newoptions->command = command;
4014 newoptions->command_arg = command_arg;
4016 /* get config lines, assign them */
4017 retval = config_get_lines(cf, &cl);
4018 if (retval < 0) {
4019 err = SETOPT_ERR_PARSE;
4020 goto err;
4022 retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
4023 config_free_lines(cl);
4024 if (retval < 0) {
4025 err = SETOPT_ERR_PARSE;
4026 goto err;
4029 /* Go through command-line variables too */
4030 retval = config_assign(&options_format, newoptions,
4031 global_cmdline_options, 0, 0, msg);
4032 if (retval < 0) {
4033 err = SETOPT_ERR_PARSE;
4034 goto err;
4037 /* If this is a testing network configuration, change defaults
4038 * for a list of dependent config options, re-initialize newoptions
4039 * with the new defaults, and assign all options to it second time. */
4040 if (newoptions->TestingTorNetwork) {
4041 /* XXXX this is a bit of a kludge. perhaps there's a better way to do
4042 * this? We could, for example, make the parsing algorithm do two passes
4043 * over the configuration. If it finds any "suite" options like
4044 * TestingTorNetwork, it could change the defaults before its second pass.
4045 * Not urgent so long as this seems to work, but at any sign of trouble,
4046 * let's clean it up. -NM */
4048 /* Change defaults. */
4049 int i;
4050 for (i = 0; testing_tor_network_defaults[i].name; ++i) {
4051 config_var_t *new_var = &testing_tor_network_defaults[i];
4052 config_var_t *old_var =
4053 config_find_option(&options_format, new_var->name);
4054 tor_assert(new_var);
4055 tor_assert(old_var);
4056 old_var->initvalue = new_var->initvalue;
4059 /* Clear newoptions and re-initialize them with new defaults. */
4060 config_free(&options_format, newoptions);
4061 newoptions = tor_malloc_zero(sizeof(or_options_t));
4062 newoptions->_magic = OR_OPTIONS_MAGIC;
4063 options_init(newoptions);
4064 newoptions->command = command;
4065 newoptions->command_arg = command_arg;
4067 /* Assign all options a second time. */
4068 retval = config_get_lines(cf, &cl);
4069 if (retval < 0) {
4070 err = SETOPT_ERR_PARSE;
4071 goto err;
4073 retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
4074 config_free_lines(cl);
4075 if (retval < 0) {
4076 err = SETOPT_ERR_PARSE;
4077 goto err;
4079 retval = config_assign(&options_format, newoptions,
4080 global_cmdline_options, 0, 0, msg);
4081 if (retval < 0) {
4082 err = SETOPT_ERR_PARSE;
4083 goto err;
4087 /* Validate newoptions */
4088 if (options_validate(oldoptions, newoptions, 0, msg) < 0) {
4089 err = SETOPT_ERR_PARSE; /*XXX make this a separate return value.*/
4090 goto err;
4093 if (options_transition_allowed(oldoptions, newoptions, msg) < 0) {
4094 err = SETOPT_ERR_TRANSITION;
4095 goto err;
4098 if (set_options(newoptions, msg)) {
4099 err = SETOPT_ERR_SETTING;
4100 goto err; /* frees and replaces old options */
4103 return SETOPT_OK;
4105 err:
4106 config_free(&options_format, newoptions);
4107 if (*msg) {
4108 char *old_msg = *msg;
4109 tor_asprintf(msg, "Failed to parse/validate config: %s", old_msg);
4110 tor_free(old_msg);
4112 return err;
4115 /** Return the location for our configuration file.
4117 const char *
4118 get_torrc_fname(void)
4120 if (torrc_fname)
4121 return torrc_fname;
4122 else
4123 return get_default_conf_file();
4126 /** Adjust the address map based on the MapAddress elements in the
4127 * configuration <b>options</b>
4129 static void
4130 config_register_addressmaps(or_options_t *options)
4132 smartlist_t *elts;
4133 config_line_t *opt;
4134 char *from, *to;
4136 addressmap_clear_configured();
4137 elts = smartlist_create();
4138 for (opt = options->AddressMap; opt; opt = opt->next) {
4139 smartlist_split_string(elts, opt->value, NULL,
4140 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
4141 if (smartlist_len(elts) >= 2) {
4142 from = smartlist_get(elts,0);
4143 to = smartlist_get(elts,1);
4144 if (address_is_invalid_destination(to, 1)) {
4145 log_warn(LD_CONFIG,
4146 "Skipping invalid argument '%s' to MapAddress", to);
4147 } else {
4148 addressmap_register(from, tor_strdup(to), 0, ADDRMAPSRC_TORRC);
4149 if (smartlist_len(elts)>2) {
4150 log_warn(LD_CONFIG,"Ignoring extra arguments to MapAddress.");
4153 } else {
4154 log_warn(LD_CONFIG,"MapAddress '%s' has too few arguments. Ignoring.",
4155 opt->value);
4157 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
4158 smartlist_clear(elts);
4160 smartlist_free(elts);
4164 * Initialize the logs based on the configuration file.
4166 static int
4167 options_init_logs(or_options_t *options, int validate_only)
4169 config_line_t *opt;
4170 int ok;
4171 smartlist_t *elts;
4172 int daemon =
4173 #ifdef MS_WINDOWS
4175 #else
4176 options->RunAsDaemon;
4177 #endif
4179 ok = 1;
4180 elts = smartlist_create();
4182 for (opt = options->Logs; opt; opt = opt->next) {
4183 log_severity_list_t *severity;
4184 const char *cfg = opt->value;
4185 severity = tor_malloc_zero(sizeof(log_severity_list_t));
4186 if (parse_log_severity_config(&cfg, severity) < 0) {
4187 log_warn(LD_CONFIG, "Couldn't parse log levels in Log option 'Log %s'",
4188 opt->value);
4189 ok = 0; goto cleanup;
4192 smartlist_split_string(elts, cfg, NULL,
4193 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
4195 if (smartlist_len(elts) == 0)
4196 smartlist_add(elts, tor_strdup("stdout"));
4198 if (smartlist_len(elts) == 1 &&
4199 (!strcasecmp(smartlist_get(elts,0), "stdout") ||
4200 !strcasecmp(smartlist_get(elts,0), "stderr"))) {
4201 int err = smartlist_len(elts) &&
4202 !strcasecmp(smartlist_get(elts,0), "stderr");
4203 if (!validate_only) {
4204 if (daemon) {
4205 log_warn(LD_CONFIG,
4206 "Can't log to %s with RunAsDaemon set; skipping stdout",
4207 err?"stderr":"stdout");
4208 } else {
4209 add_stream_log(severity, err?"<stderr>":"<stdout>",
4210 fileno(err?stderr:stdout));
4213 goto cleanup;
4215 if (smartlist_len(elts) == 1 &&
4216 !strcasecmp(smartlist_get(elts,0), "syslog")) {
4217 #ifdef HAVE_SYSLOG_H
4218 if (!validate_only) {
4219 add_syslog_log(severity);
4221 #else
4222 log_warn(LD_CONFIG, "Syslog is not supported on this system. Sorry.");
4223 #endif
4224 goto cleanup;
4227 if (smartlist_len(elts) == 2 &&
4228 !strcasecmp(smartlist_get(elts,0), "file")) {
4229 if (!validate_only) {
4230 if (add_file_log(severity, smartlist_get(elts, 1)) < 0) {
4231 log_warn(LD_CONFIG, "Couldn't open file for 'Log %s': %s",
4232 opt->value, strerror(errno));
4233 ok = 0;
4236 goto cleanup;
4239 log_warn(LD_CONFIG, "Bad syntax on file Log option 'Log %s'",
4240 opt->value);
4241 ok = 0; goto cleanup;
4243 cleanup:
4244 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
4245 smartlist_clear(elts);
4246 tor_free(severity);
4248 smartlist_free(elts);
4250 return ok?0:-1;
4253 /** Read the contents of a Bridge line from <b>line</b>. Return 0
4254 * if the line is well-formed, and -1 if it isn't. If
4255 * <b>validate_only</b> is 0, and the line is well-formed, then add
4256 * the bridge described in the line to our internal bridge list. */
4257 static int
4258 parse_bridge_line(const char *line, int validate_only)
4260 smartlist_t *items = NULL;
4261 int r;
4262 char *addrport=NULL, *fingerprint=NULL;
4263 tor_addr_t addr;
4264 uint16_t port = 0;
4265 char digest[DIGEST_LEN];
4267 items = smartlist_create();
4268 smartlist_split_string(items, line, NULL,
4269 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
4270 if (smartlist_len(items) < 1) {
4271 log_warn(LD_CONFIG, "Too few arguments to Bridge line.");
4272 goto err;
4274 addrport = smartlist_get(items, 0);
4275 smartlist_del_keeporder(items, 0);
4276 if (tor_addr_port_parse(addrport, &addr, &port)<0) {
4277 log_warn(LD_CONFIG, "Error parsing Bridge address '%s'", addrport);
4278 goto err;
4280 if (!port) {
4281 log_info(LD_CONFIG,
4282 "Bridge address '%s' has no port; using default port 443.",
4283 addrport);
4284 port = 443;
4287 if (smartlist_len(items)) {
4288 fingerprint = smartlist_join_strings(items, "", 0, NULL);
4289 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
4290 log_warn(LD_CONFIG, "Key digest for Bridge is wrong length.");
4291 goto err;
4293 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
4294 log_warn(LD_CONFIG, "Unable to decode Bridge key digest.");
4295 goto err;
4299 if (!validate_only) {
4300 log_debug(LD_DIR, "Bridge at %s:%d (%s)", fmt_addr(&addr),
4301 (int)port,
4302 fingerprint ? fingerprint : "no key listed");
4303 bridge_add_from_config(&addr, port, fingerprint ? digest : NULL);
4306 r = 0;
4307 goto done;
4309 err:
4310 r = -1;
4312 done:
4313 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
4314 smartlist_free(items);
4315 tor_free(addrport);
4316 tor_free(fingerprint);
4317 return r;
4320 /** Read the contents of a DirServer line from <b>line</b>. If
4321 * <b>validate_only</b> is 0, and the line is well-formed, and it
4322 * shares any bits with <b>required_type</b> or <b>required_type</b>
4323 * is 0, then add the dirserver described in the line (minus whatever
4324 * bits it's missing) as a valid authority. Return 0 on success,
4325 * or -1 if the line isn't well-formed or if we can't add it. */
4326 static int
4327 parse_dir_server_line(const char *line, authority_type_t required_type,
4328 int validate_only)
4330 smartlist_t *items = NULL;
4331 int r;
4332 char *addrport=NULL, *address=NULL, *nickname=NULL, *fingerprint=NULL;
4333 uint16_t dir_port = 0, or_port = 0;
4334 char digest[DIGEST_LEN];
4335 char v3_digest[DIGEST_LEN];
4336 authority_type_t type = V2_AUTHORITY;
4337 int is_not_hidserv_authority = 0, is_not_v2_authority = 0;
4339 items = smartlist_create();
4340 smartlist_split_string(items, line, NULL,
4341 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
4342 if (smartlist_len(items) < 1) {
4343 log_warn(LD_CONFIG, "No arguments on DirServer line.");
4344 goto err;
4347 if (is_legal_nickname(smartlist_get(items, 0))) {
4348 nickname = smartlist_get(items, 0);
4349 smartlist_del_keeporder(items, 0);
4352 while (smartlist_len(items)) {
4353 char *flag = smartlist_get(items, 0);
4354 if (TOR_ISDIGIT(flag[0]))
4355 break;
4356 if (!strcasecmp(flag, "v1")) {
4357 type |= (V1_AUTHORITY | HIDSERV_AUTHORITY);
4358 } else if (!strcasecmp(flag, "hs")) {
4359 type |= HIDSERV_AUTHORITY;
4360 } else if (!strcasecmp(flag, "no-hs")) {
4361 is_not_hidserv_authority = 1;
4362 } else if (!strcasecmp(flag, "bridge")) {
4363 type |= BRIDGE_AUTHORITY;
4364 } else if (!strcasecmp(flag, "no-v2")) {
4365 is_not_v2_authority = 1;
4366 } else if (!strcasecmpstart(flag, "orport=")) {
4367 int ok;
4368 char *portstring = flag + strlen("orport=");
4369 or_port = (uint16_t) tor_parse_long(portstring, 10, 1, 65535, &ok, NULL);
4370 if (!ok)
4371 log_warn(LD_CONFIG, "Invalid orport '%s' on DirServer line.",
4372 portstring);
4373 } else if (!strcasecmpstart(flag, "v3ident=")) {
4374 char *idstr = flag + strlen("v3ident=");
4375 if (strlen(idstr) != HEX_DIGEST_LEN ||
4376 base16_decode(v3_digest, DIGEST_LEN, idstr, HEX_DIGEST_LEN)<0) {
4377 log_warn(LD_CONFIG, "Bad v3 identity digest '%s' on DirServer line",
4378 flag);
4379 } else {
4380 type |= V3_AUTHORITY;
4382 } else {
4383 log_warn(LD_CONFIG, "Unrecognized flag '%s' on DirServer line",
4384 flag);
4386 tor_free(flag);
4387 smartlist_del_keeporder(items, 0);
4389 if (is_not_hidserv_authority)
4390 type &= ~HIDSERV_AUTHORITY;
4391 if (is_not_v2_authority)
4392 type &= ~V2_AUTHORITY;
4394 if (smartlist_len(items) < 2) {
4395 log_warn(LD_CONFIG, "Too few arguments to DirServer line.");
4396 goto err;
4398 addrport = smartlist_get(items, 0);
4399 smartlist_del_keeporder(items, 0);
4400 if (parse_addr_port(LOG_WARN, addrport, &address, NULL, &dir_port)<0) {
4401 log_warn(LD_CONFIG, "Error parsing DirServer address '%s'", addrport);
4402 goto err;
4404 if (!dir_port) {
4405 log_warn(LD_CONFIG, "Missing port in DirServer address '%s'",addrport);
4406 goto err;
4409 fingerprint = smartlist_join_strings(items, "", 0, NULL);
4410 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
4411 log_warn(LD_CONFIG, "Key digest for DirServer is wrong length %d.",
4412 (int)strlen(fingerprint));
4413 goto err;
4415 if (!strcmp(fingerprint, "E623F7625FBE0C87820F11EC5F6D5377ED816294")) {
4416 /* a known bad fingerprint. refuse to use it. We can remove this
4417 * clause once Tor 0.1.2.17 is obsolete. */
4418 log_warn(LD_CONFIG, "Dangerous dirserver line. To correct, erase your "
4419 "torrc file (%s), or reinstall Tor and use the default torrc.",
4420 get_torrc_fname());
4421 goto err;
4423 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
4424 log_warn(LD_CONFIG, "Unable to decode DirServer key digest.");
4425 goto err;
4428 if (!validate_only && (!required_type || required_type & type)) {
4429 if (required_type)
4430 type &= required_type; /* pare down what we think of them as an
4431 * authority for. */
4432 log_debug(LD_DIR, "Trusted %d dirserver at %s:%d (%s)", (int)type,
4433 address, (int)dir_port, (char*)smartlist_get(items,0));
4434 if (!add_trusted_dir_server(nickname, address, dir_port, or_port,
4435 digest, v3_digest, type))
4436 goto err;
4439 r = 0;
4440 goto done;
4442 err:
4443 r = -1;
4445 done:
4446 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
4447 smartlist_free(items);
4448 tor_free(addrport);
4449 tor_free(address);
4450 tor_free(nickname);
4451 tor_free(fingerprint);
4452 return r;
4455 /** Adjust the value of options->DataDirectory, or fill it in if it's
4456 * absent. Return 0 on success, -1 on failure. */
4457 static int
4458 normalize_data_directory(or_options_t *options)
4460 #ifdef MS_WINDOWS
4461 char *p;
4462 if (options->DataDirectory)
4463 return 0; /* all set */
4464 p = tor_malloc(MAX_PATH);
4465 strlcpy(p,get_windows_conf_root(),MAX_PATH);
4466 options->DataDirectory = p;
4467 return 0;
4468 #else
4469 const char *d = options->DataDirectory;
4470 if (!d)
4471 d = "~/.tor";
4473 if (strncmp(d,"~/",2) == 0) {
4474 char *fn = expand_filename(d);
4475 if (!fn) {
4476 log_warn(LD_CONFIG,"Failed to expand filename \"%s\".", d);
4477 return -1;
4479 if (!options->DataDirectory && !strcmp(fn,"/.tor")) {
4480 /* If our homedir is /, we probably don't want to use it. */
4481 /* Default to LOCALSTATEDIR/tor which is probably closer to what we
4482 * want. */
4483 log_warn(LD_CONFIG,
4484 "Default DataDirectory is \"~/.tor\". This expands to "
4485 "\"%s\", which is probably not what you want. Using "
4486 "\"%s"PATH_SEPARATOR"tor\" instead", fn, LOCALSTATEDIR);
4487 tor_free(fn);
4488 fn = tor_strdup(LOCALSTATEDIR PATH_SEPARATOR "tor");
4490 tor_free(options->DataDirectory);
4491 options->DataDirectory = fn;
4493 return 0;
4494 #endif
4497 /** Check and normalize the value of options->DataDirectory; return 0 if it
4498 * is sane, -1 otherwise. */
4499 static int
4500 validate_data_directory(or_options_t *options)
4502 if (normalize_data_directory(options) < 0)
4503 return -1;
4504 tor_assert(options->DataDirectory);
4505 if (strlen(options->DataDirectory) > (512-128)) {
4506 log_warn(LD_CONFIG, "DataDirectory is too long.");
4507 return -1;
4509 return 0;
4512 /** This string must remain the same forevermore. It is how we
4513 * recognize that the torrc file doesn't need to be backed up. */
4514 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; " \
4515 "if you edit it, comments will not be preserved"
4516 /** This string can change; it tries to give the reader an idea
4517 * that editing this file by hand is not a good plan. */
4518 #define GENERATED_FILE_COMMENT "# The old torrc file was renamed " \
4519 "to torrc.orig.1 or similar, and Tor will ignore it"
4521 /** Save a configuration file for the configuration in <b>options</b>
4522 * into the file <b>fname</b>. If the file already exists, and
4523 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
4524 * replace it. Return 0 on success, -1 on failure. */
4525 static int
4526 write_configuration_file(const char *fname, or_options_t *options)
4528 char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
4529 int rename_old = 0, r;
4531 tor_assert(fname);
4533 switch (file_status(fname)) {
4534 case FN_FILE:
4535 old_val = read_file_to_str(fname, 0, NULL);
4536 if (strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
4537 rename_old = 1;
4539 tor_free(old_val);
4540 break;
4541 case FN_NOENT:
4542 break;
4543 case FN_ERROR:
4544 case FN_DIR:
4545 default:
4546 log_warn(LD_CONFIG,
4547 "Config file \"%s\" is not a file? Failing.", fname);
4548 return -1;
4551 if (!(new_conf = options_dump(options, 1))) {
4552 log_warn(LD_BUG, "Couldn't get configuration string");
4553 goto err;
4556 tor_asprintf(&new_val, "%s\n%s\n\n%s",
4557 GENERATED_FILE_PREFIX, GENERATED_FILE_COMMENT, new_conf);
4559 if (rename_old) {
4560 int i = 1;
4561 size_t fn_tmp_len = strlen(fname)+32;
4562 char *fn_tmp;
4563 tor_assert(fn_tmp_len > strlen(fname)); /*check for overflow*/
4564 fn_tmp = tor_malloc(fn_tmp_len);
4565 while (1) {
4566 if (tor_snprintf(fn_tmp, fn_tmp_len, "%s.orig.%d", fname, i)<0) {
4567 log_warn(LD_BUG, "tor_snprintf failed inexplicably");
4568 tor_free(fn_tmp);
4569 goto err;
4571 if (file_status(fn_tmp) == FN_NOENT)
4572 break;
4573 ++i;
4575 log_notice(LD_CONFIG, "Renaming old configuration file to \"%s\"", fn_tmp);
4576 if (rename(fname, fn_tmp) < 0) {
4577 log_warn(LD_FS,
4578 "Couldn't rename configuration file \"%s\" to \"%s\": %s",
4579 fname, fn_tmp, strerror(errno));
4580 tor_free(fn_tmp);
4581 goto err;
4583 tor_free(fn_tmp);
4586 if (write_str_to_file(fname, new_val, 0) < 0)
4587 goto err;
4589 r = 0;
4590 goto done;
4591 err:
4592 r = -1;
4593 done:
4594 tor_free(new_val);
4595 tor_free(new_conf);
4596 return r;
4600 * Save the current configuration file value to disk. Return 0 on
4601 * success, -1 on failure.
4604 options_save_current(void)
4606 /* This fails if we can't write to our configuration file.
4608 * If we try falling back to datadirectory or something, we have a better
4609 * chance of saving the configuration, but a better chance of doing
4610 * something the user never expected. */
4611 return write_configuration_file(get_torrc_fname(), get_options());
4614 /** Mapping from a unit name to a multiplier for converting that unit into a
4615 * base unit. */
4616 struct unit_table_t {
4617 const char *unit;
4618 uint64_t multiplier;
4621 /** Table to map the names of memory units to the number of bytes they
4622 * contain. */
4623 static struct unit_table_t memory_units[] = {
4624 { "", 1 },
4625 { "b", 1<< 0 },
4626 { "byte", 1<< 0 },
4627 { "bytes", 1<< 0 },
4628 { "kb", 1<<10 },
4629 { "kbyte", 1<<10 },
4630 { "kbytes", 1<<10 },
4631 { "kilobyte", 1<<10 },
4632 { "kilobytes", 1<<10 },
4633 { "m", 1<<20 },
4634 { "mb", 1<<20 },
4635 { "mbyte", 1<<20 },
4636 { "mbytes", 1<<20 },
4637 { "megabyte", 1<<20 },
4638 { "megabytes", 1<<20 },
4639 { "gb", 1<<30 },
4640 { "gbyte", 1<<30 },
4641 { "gbytes", 1<<30 },
4642 { "gigabyte", 1<<30 },
4643 { "gigabytes", 1<<30 },
4644 { "tb", U64_LITERAL(1)<<40 },
4645 { "terabyte", U64_LITERAL(1)<<40 },
4646 { "terabytes", U64_LITERAL(1)<<40 },
4647 { NULL, 0 },
4650 /** Table to map the names of time units to the number of seconds they
4651 * contain. */
4652 static struct unit_table_t time_units[] = {
4653 { "", 1 },
4654 { "second", 1 },
4655 { "seconds", 1 },
4656 { "minute", 60 },
4657 { "minutes", 60 },
4658 { "hour", 60*60 },
4659 { "hours", 60*60 },
4660 { "day", 24*60*60 },
4661 { "days", 24*60*60 },
4662 { "week", 7*24*60*60 },
4663 { "weeks", 7*24*60*60 },
4664 { NULL, 0 },
4667 /** Parse a string <b>val</b> containing a number, zero or more
4668 * spaces, and an optional unit string. If the unit appears in the
4669 * table <b>u</b>, then multiply the number by the unit multiplier.
4670 * On success, set *<b>ok</b> to 1 and return this product.
4671 * Otherwise, set *<b>ok</b> to 0.
4673 static uint64_t
4674 config_parse_units(const char *val, struct unit_table_t *u, int *ok)
4676 uint64_t v = 0;
4677 double d = 0;
4678 int use_float = 0;
4679 char *cp;
4681 tor_assert(ok);
4683 v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
4684 if (!*ok || (cp && *cp == '.')) {
4685 d = tor_parse_double(val, 0, UINT64_MAX, ok, &cp);
4686 if (!*ok)
4687 goto done;
4688 use_float = 1;
4691 if (!cp) {
4692 *ok = 1;
4693 v = use_float ? DBL_TO_U64(d) : v;
4694 goto done;
4697 cp = (char*) eat_whitespace(cp);
4699 for ( ;u->unit;++u) {
4700 if (!strcasecmp(u->unit, cp)) {
4701 if (use_float)
4702 v = u->multiplier * d;
4703 else
4704 v *= u->multiplier;
4705 *ok = 1;
4706 goto done;
4709 log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
4710 *ok = 0;
4711 done:
4713 if (*ok)
4714 return v;
4715 else
4716 return 0;
4719 /** Parse a string in the format "number unit", where unit is a unit of
4720 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
4721 * and return the number of bytes specified. Otherwise, set
4722 * *<b>ok</b> to false and return 0. */
4723 static uint64_t
4724 config_parse_memunit(const char *s, int *ok)
4726 uint64_t u = config_parse_units(s, memory_units, ok);
4727 return u;
4730 /** Parse a string in the format "number unit", where unit is a unit of time.
4731 * On success, set *<b>ok</b> to true and return the number of seconds in
4732 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
4734 static int
4735 config_parse_interval(const char *s, int *ok)
4737 uint64_t r;
4738 r = config_parse_units(s, time_units, ok);
4739 if (!ok)
4740 return -1;
4741 if (r > INT_MAX) {
4742 log_warn(LD_CONFIG, "Interval '%s' is too long", s);
4743 *ok = 0;
4744 return -1;
4746 return (int)r;
4750 * Initialize the libevent library.
4752 static void
4753 init_libevent(void)
4755 const char *badness=NULL;
4757 configure_libevent_logging();
4758 /* If the kernel complains that some method (say, epoll) doesn't
4759 * exist, we don't care about it, since libevent will cope.
4761 suppress_libevent_log_msg("Function not implemented");
4763 tor_check_libevent_header_compatibility();
4765 tor_libevent_initialize();
4767 suppress_libevent_log_msg(NULL);
4769 tor_check_libevent_version(tor_libevent_get_method(),
4770 get_options()->ORPort != 0,
4771 &badness);
4772 if (badness) {
4773 const char *v = tor_libevent_get_version_str();
4774 const char *m = tor_libevent_get_method();
4775 control_event_general_status(LOG_WARN,
4776 "BAD_LIBEVENT VERSION=%s METHOD=%s BADNESS=%s RECOVERED=NO",
4777 v, m, badness);
4781 /** Return the persistent state struct for this Tor. */
4782 or_state_t *
4783 get_or_state(void)
4785 tor_assert(global_state);
4786 return global_state;
4789 /** Return a newly allocated string holding a filename relative to the data
4790 * directory. If <b>sub1</b> is present, it is the first path component after
4791 * the data directory. If <b>sub2</b> is also present, it is the second path
4792 * component after the data directory. If <b>suffix</b> is present, it
4793 * is appended to the filename.
4795 * Examples:
4796 * get_datadir_fname2_suffix("a", NULL, NULL) -> $DATADIR/a
4797 * get_datadir_fname2_suffix("a", NULL, ".tmp") -> $DATADIR/a.tmp
4798 * get_datadir_fname2_suffix("a", "b", ".tmp") -> $DATADIR/a/b/.tmp
4799 * get_datadir_fname2_suffix("a", "b", NULL) -> $DATADIR/a/b
4801 * Note: Consider using the get_datadir_fname* macros in or.h.
4803 char *
4804 options_get_datadir_fname2_suffix(or_options_t *options,
4805 const char *sub1, const char *sub2,
4806 const char *suffix)
4808 char *fname = NULL;
4809 size_t len;
4810 tor_assert(options);
4811 tor_assert(options->DataDirectory);
4812 tor_assert(sub1 || !sub2); /* If sub2 is present, sub1 must be present. */
4813 len = strlen(options->DataDirectory);
4814 if (sub1) {
4815 len += strlen(sub1)+1;
4816 if (sub2)
4817 len += strlen(sub2)+1;
4819 if (suffix)
4820 len += strlen(suffix);
4821 len++;
4822 fname = tor_malloc(len);
4823 if (sub1) {
4824 if (sub2) {
4825 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s"PATH_SEPARATOR"%s",
4826 options->DataDirectory, sub1, sub2);
4827 } else {
4828 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s",
4829 options->DataDirectory, sub1);
4831 } else {
4832 strlcpy(fname, options->DataDirectory, len);
4834 if (suffix)
4835 strlcat(fname, suffix, len);
4836 return fname;
4839 /** Return 0 if every setting in <b>state</b> is reasonable, and a
4840 * permissible transition from <b>old_state</b>. Else warn and return -1.
4841 * Should have no side effects, except for normalizing the contents of
4842 * <b>state</b>.
4844 /* XXX from_setconf is here because of bug 238 */
4845 static int
4846 or_state_validate(or_state_t *old_state, or_state_t *state,
4847 int from_setconf, char **msg)
4849 /* We don't use these; only options do. Still, we need to match that
4850 * signature. */
4851 (void) from_setconf;
4852 (void) old_state;
4854 if (entry_guards_parse_state(state, 0, msg)<0)
4855 return -1;
4857 return 0;
4860 /** Replace the current persistent state with <b>new_state</b> */
4861 static int
4862 or_state_set(or_state_t *new_state)
4864 char *err = NULL;
4865 int ret = 0;
4866 tor_assert(new_state);
4867 config_free(&state_format, global_state);
4868 global_state = new_state;
4869 if (entry_guards_parse_state(global_state, 1, &err)<0) {
4870 log_warn(LD_GENERAL,"%s",err);
4871 tor_free(err);
4872 ret = -1;
4874 if (rep_hist_load_state(global_state, &err)<0) {
4875 log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
4876 tor_free(err);
4877 ret = -1;
4879 if (circuit_build_times_parse_state(&circ_times, global_state, &err) < 0) {
4880 log_warn(LD_GENERAL,"%s",err);
4881 tor_free(err);
4882 ret = -1;
4884 return ret;
4888 * Save a broken state file to a backup location.
4890 static void
4891 or_state_save_broken(char *fname)
4893 int i;
4894 file_status_t status;
4895 size_t len = strlen(fname)+16;
4896 char *fname2 = tor_malloc(len);
4897 for (i = 0; i < 100; ++i) {
4898 tor_snprintf(fname2, len, "%s.%d", fname, i);
4899 status = file_status(fname2);
4900 if (status == FN_NOENT)
4901 break;
4903 if (i == 100) {
4904 log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
4905 "state files to move aside. Discarding the old state file.",
4906 fname);
4907 unlink(fname);
4908 } else {
4909 log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
4910 "to \"%s\". This could be a bug in Tor; please tell "
4911 "the developers.", fname, fname2);
4912 if (rename(fname, fname2) < 0) {
4913 log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
4914 "OS gave an error of %s", strerror(errno));
4917 tor_free(fname2);
4920 /** Reload the persistent state from disk, generating a new state as needed.
4921 * Return 0 on success, less than 0 on failure.
4923 static int
4924 or_state_load(void)
4926 or_state_t *new_state = NULL;
4927 char *contents = NULL, *fname;
4928 char *errmsg = NULL;
4929 int r = -1, badstate = 0;
4931 fname = get_datadir_fname("state");
4932 switch (file_status(fname)) {
4933 case FN_FILE:
4934 if (!(contents = read_file_to_str(fname, 0, NULL))) {
4935 log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
4936 goto done;
4938 break;
4939 case FN_NOENT:
4940 break;
4941 case FN_ERROR:
4942 case FN_DIR:
4943 default:
4944 log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
4945 goto done;
4947 new_state = tor_malloc_zero(sizeof(or_state_t));
4948 new_state->_magic = OR_STATE_MAGIC;
4949 config_init(&state_format, new_state);
4950 if (contents) {
4951 config_line_t *lines=NULL;
4952 int assign_retval;
4953 if (config_get_lines(contents, &lines)<0)
4954 goto done;
4955 assign_retval = config_assign(&state_format, new_state,
4956 lines, 0, 0, &errmsg);
4957 config_free_lines(lines);
4958 if (assign_retval<0)
4959 badstate = 1;
4960 if (errmsg) {
4961 log_warn(LD_GENERAL, "%s", errmsg);
4962 tor_free(errmsg);
4966 if (!badstate && or_state_validate(NULL, new_state, 1, &errmsg) < 0)
4967 badstate = 1;
4969 if (errmsg) {
4970 log_warn(LD_GENERAL, "%s", errmsg);
4971 tor_free(errmsg);
4974 if (badstate && !contents) {
4975 log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
4976 " This is a bug in Tor.");
4977 goto done;
4978 } else if (badstate && contents) {
4979 or_state_save_broken(fname);
4981 tor_free(contents);
4982 config_free(&state_format, new_state);
4984 new_state = tor_malloc_zero(sizeof(or_state_t));
4985 new_state->_magic = OR_STATE_MAGIC;
4986 config_init(&state_format, new_state);
4987 } else if (contents) {
4988 log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
4989 } else {
4990 log_info(LD_GENERAL, "Initialized state");
4992 if (or_state_set(new_state) == -1) {
4993 or_state_save_broken(fname);
4995 new_state = NULL;
4996 if (!contents) {
4997 global_state->next_write = 0;
4998 or_state_save(time(NULL));
5000 r = 0;
5002 done:
5003 tor_free(fname);
5004 tor_free(contents);
5005 if (new_state)
5006 config_free(&state_format, new_state);
5008 return r;
5011 /** Write the persistent state to disk. Return 0 for success, <0 on failure. */
5013 or_state_save(time_t now)
5015 char *state, *contents;
5016 char tbuf[ISO_TIME_LEN+1];
5017 char *fname;
5019 tor_assert(global_state);
5021 if (global_state->next_write > now)
5022 return 0;
5024 /* Call everything else that might dirty the state even more, in order
5025 * to avoid redundant writes. */
5026 entry_guards_update_state(global_state);
5027 rep_hist_update_state(global_state);
5028 circuit_build_times_update_state(&circ_times, global_state);
5029 if (accounting_is_enabled(get_options()))
5030 accounting_run_housekeeping(now);
5032 tor_free(global_state->TorVersion);
5033 tor_asprintf(&global_state->TorVersion, "Tor %s", get_version());
5035 state = config_dump(&state_format, global_state, 1, 0);
5036 format_local_iso_time(tbuf, time(NULL));
5037 tor_asprintf(&contents,
5038 "# Tor state file last generated on %s local time\n"
5039 "# Other times below are in GMT\n"
5040 "# You *do not* need to edit this file.\n\n%s",
5041 tbuf, state);
5042 tor_free(state);
5043 fname = get_datadir_fname("state");
5044 if (write_str_to_file(fname, contents, 0)<0) {
5045 log_warn(LD_FS, "Unable to write state to file \"%s\"", fname);
5046 global_state->LastWritten = -1;
5047 tor_free(fname);
5048 tor_free(contents);
5049 return -1;
5052 global_state->LastWritten = time(NULL);
5053 log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
5054 tor_free(fname);
5055 tor_free(contents);
5057 global_state->next_write = TIME_MAX;
5058 return 0;
5061 /** Given a file name check to see whether the file exists but has not been
5062 * modified for a very long time. If so, remove it. */
5063 void
5064 remove_file_if_very_old(const char *fname, time_t now)
5066 #define VERY_OLD_FILE_AGE (28*24*60*60)
5067 struct stat st;
5069 if (stat(fname, &st)==0 && st.st_mtime < now-VERY_OLD_FILE_AGE) {
5070 char buf[ISO_TIME_LEN+1];
5071 format_local_iso_time(buf, st.st_mtime);
5072 log_notice(LD_GENERAL, "Obsolete file %s hasn't been modified since %s. "
5073 "Removing it.", fname, buf);
5074 unlink(fname);
5078 /** Helper to implement GETINFO functions about configuration variables (not
5079 * their values). Given a "config/names" question, set *<b>answer</b> to a
5080 * new string describing the supported configuration variables and their
5081 * types. */
5083 getinfo_helper_config(control_connection_t *conn,
5084 const char *question, char **answer,
5085 const char **errmsg)
5087 (void) conn;
5088 (void) errmsg;
5089 if (!strcmp(question, "config/names")) {
5090 smartlist_t *sl = smartlist_create();
5091 int i;
5092 for (i = 0; _option_vars[i].name; ++i) {
5093 config_var_t *var = &_option_vars[i];
5094 const char *type;
5095 char *line;
5096 switch (var->type) {
5097 case CONFIG_TYPE_STRING: type = "String"; break;
5098 case CONFIG_TYPE_FILENAME: type = "Filename"; break;
5099 case CONFIG_TYPE_UINT: type = "Integer"; break;
5100 case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
5101 case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
5102 case CONFIG_TYPE_DOUBLE: type = "Float"; break;
5103 case CONFIG_TYPE_BOOL: type = "Boolean"; break;
5104 case CONFIG_TYPE_ISOTIME: type = "Time"; break;
5105 case CONFIG_TYPE_ROUTERSET: type = "RouterList"; break;
5106 case CONFIG_TYPE_CSV: type = "CommaList"; break;
5107 case CONFIG_TYPE_LINELIST: type = "LineList"; break;
5108 case CONFIG_TYPE_LINELIST_S: type = "Dependant"; break;
5109 case CONFIG_TYPE_LINELIST_V: type = "Virtual"; break;
5110 default:
5111 case CONFIG_TYPE_OBSOLETE:
5112 type = NULL; break;
5114 if (!type)
5115 continue;
5116 tor_asprintf(&line, "%s %s\n",var->name,type);
5117 smartlist_add(sl, line);
5119 *answer = smartlist_join_strings(sl, "", 0, NULL);
5120 SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
5121 smartlist_free(sl);
5123 return 0;