Fix a compile warning on OS X 10.6
[tor/rransom.git] / src / or / config.c
blob0a26c84be7d0b27600fe29db6af51b8f4dd6dcdb
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;
1563 /** Return the number of option entries in <b>fmt</b>. */
1564 static int
1565 config_count_options(config_format_t *fmt)
1567 int i;
1568 for (i=0; fmt->vars[i].name; ++i)
1570 return i;
1574 * Functions to assign config options.
1577 /** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
1578 * with <b>c</b>-\>value and return 0, or return -1 if bad value.
1580 * Called from config_assign_line() and option_reset().
1582 static int
1583 config_assign_value(config_format_t *fmt, or_options_t *options,
1584 config_line_t *c, char **msg)
1586 int i, ok;
1587 config_var_t *var;
1588 void *lvalue;
1590 CHECK(fmt, options);
1592 var = config_find_option(fmt, c->key);
1593 tor_assert(var);
1595 lvalue = STRUCT_VAR_P(options, var->var_offset);
1597 switch (var->type) {
1599 case CONFIG_TYPE_UINT:
1600 i = (int)tor_parse_long(c->value, 10, 0, INT_MAX, &ok, NULL);
1601 if (!ok) {
1602 tor_asprintf(msg,
1603 "Int keyword '%s %s' is malformed or out of bounds.",
1604 c->key, c->value);
1605 return -1;
1607 *(int *)lvalue = i;
1608 break;
1610 case CONFIG_TYPE_INTERVAL: {
1611 i = config_parse_interval(c->value, &ok);
1612 if (!ok) {
1613 tor_asprintf(msg,
1614 "Interval '%s %s' is malformed or out of bounds.",
1615 c->key, c->value);
1616 return -1;
1618 *(int *)lvalue = i;
1619 break;
1622 case CONFIG_TYPE_MEMUNIT: {
1623 uint64_t u64 = config_parse_memunit(c->value, &ok);
1624 if (!ok) {
1625 tor_asprintf(msg,
1626 "Value '%s %s' is malformed or out of bounds.",
1627 c->key, c->value);
1628 return -1;
1630 *(uint64_t *)lvalue = u64;
1631 break;
1634 case CONFIG_TYPE_BOOL:
1635 i = (int)tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
1636 if (!ok) {
1637 tor_asprintf(msg,
1638 "Boolean '%s %s' expects 0 or 1.",
1639 c->key, c->value);
1640 return -1;
1642 *(int *)lvalue = i;
1643 break;
1645 case CONFIG_TYPE_STRING:
1646 case CONFIG_TYPE_FILENAME:
1647 tor_free(*(char **)lvalue);
1648 *(char **)lvalue = tor_strdup(c->value);
1649 break;
1651 case CONFIG_TYPE_DOUBLE:
1652 *(double *)lvalue = atof(c->value);
1653 break;
1655 case CONFIG_TYPE_ISOTIME:
1656 if (parse_iso_time(c->value, (time_t *)lvalue)) {
1657 tor_asprintf(msg,
1658 "Invalid time '%s' for keyword '%s'", c->value, c->key);
1659 return -1;
1661 break;
1663 case CONFIG_TYPE_ROUTERSET:
1664 if (*(routerset_t**)lvalue) {
1665 routerset_free(*(routerset_t**)lvalue);
1667 *(routerset_t**)lvalue = routerset_new();
1668 if (routerset_parse(*(routerset_t**)lvalue, c->value, c->key)<0) {
1669 tor_asprintf(msg, "Invalid exit list '%s' for option '%s'",
1670 c->value, c->key);
1671 return -1;
1673 break;
1675 case CONFIG_TYPE_CSV:
1676 if (*(smartlist_t**)lvalue) {
1677 SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
1678 smartlist_clear(*(smartlist_t**)lvalue);
1679 } else {
1680 *(smartlist_t**)lvalue = smartlist_create();
1683 smartlist_split_string(*(smartlist_t**)lvalue, c->value, ",",
1684 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1685 break;
1687 case CONFIG_TYPE_LINELIST:
1688 case CONFIG_TYPE_LINELIST_S:
1689 config_line_append((config_line_t**)lvalue, c->key, c->value);
1690 break;
1691 case CONFIG_TYPE_OBSOLETE:
1692 log_warn(LD_CONFIG, "Skipping obsolete configuration option '%s'", c->key);
1693 break;
1694 case CONFIG_TYPE_LINELIST_V:
1695 tor_asprintf(msg,
1696 "You may not provide a value for virtual option '%s'", c->key);
1697 return -1;
1698 default:
1699 tor_assert(0);
1700 break;
1702 return 0;
1705 /** If <b>c</b> is a syntactically valid configuration line, update
1706 * <b>options</b> with its value and return 0. Otherwise return -1 for bad
1707 * key, -2 for bad value.
1709 * If <b>clear_first</b> is set, clear the value first. Then if
1710 * <b>use_defaults</b> is set, set the value to the default.
1712 * Called from config_assign().
1714 static int
1715 config_assign_line(config_format_t *fmt, or_options_t *options,
1716 config_line_t *c, int use_defaults,
1717 int clear_first, bitarray_t *options_seen, char **msg)
1719 config_var_t *var;
1721 CHECK(fmt, options);
1723 var = config_find_option(fmt, c->key);
1724 if (!var) {
1725 if (fmt->extra) {
1726 void *lvalue = STRUCT_VAR_P(options, fmt->extra->var_offset);
1727 log_info(LD_CONFIG,
1728 "Found unrecognized option '%s'; saving it.", c->key);
1729 config_line_append((config_line_t**)lvalue, c->key, c->value);
1730 return 0;
1731 } else {
1732 tor_asprintf(msg,
1733 "Unknown option '%s'. Failing.", c->key);
1734 return -1;
1738 /* Put keyword into canonical case. */
1739 if (strcmp(var->name, c->key)) {
1740 tor_free(c->key);
1741 c->key = tor_strdup(var->name);
1744 if (!strlen(c->value)) {
1745 /* reset or clear it, then return */
1746 if (!clear_first) {
1747 if (var->type == CONFIG_TYPE_LINELIST ||
1748 var->type == CONFIG_TYPE_LINELIST_S) {
1749 /* We got an empty linelist from the torrc or command line.
1750 As a special case, call this an error. Warn and ignore. */
1751 log_warn(LD_CONFIG,
1752 "Linelist option '%s' has no value. Skipping.", c->key);
1753 } else { /* not already cleared */
1754 option_reset(fmt, options, var, use_defaults);
1757 return 0;
1760 if (options_seen && (var->type != CONFIG_TYPE_LINELIST &&
1761 var->type != CONFIG_TYPE_LINELIST_S)) {
1762 /* We're tracking which options we've seen, and this option is not
1763 * supposed to occur more than once. */
1764 int var_index = (int)(var - fmt->vars);
1765 if (bitarray_is_set(options_seen, var_index)) {
1766 log_warn(LD_CONFIG, "Option '%s' used more than once; all but the last "
1767 "value will be ignored.", var->name);
1769 bitarray_set(options_seen, var_index);
1772 if (config_assign_value(fmt, options, c, msg) < 0)
1773 return -2;
1774 return 0;
1777 /** Restore the option named <b>key</b> in options to its default value.
1778 * Called from config_assign(). */
1779 static void
1780 config_reset_line(config_format_t *fmt, or_options_t *options,
1781 const char *key, int use_defaults)
1783 config_var_t *var;
1785 CHECK(fmt, options);
1787 var = config_find_option(fmt, key);
1788 if (!var)
1789 return; /* give error on next pass. */
1791 option_reset(fmt, options, var, use_defaults);
1794 /** Return true iff key is a valid configuration option. */
1796 option_is_recognized(const char *key)
1798 config_var_t *var = config_find_option(&options_format, key);
1799 return (var != NULL);
1802 /** Return the canonical name of a configuration option, or NULL
1803 * if no such option exists. */
1804 const char *
1805 option_get_canonical_name(const char *key)
1807 config_var_t *var = config_find_option(&options_format, key);
1808 return var ? var->name : NULL;
1811 /** Return a canonical list of the options assigned for key.
1813 config_line_t *
1814 option_get_assignment(or_options_t *options, const char *key)
1816 return get_assigned_option(&options_format, options, key, 1);
1819 /** Return true iff value needs to be quoted and escaped to be used in
1820 * a configuration file. */
1821 static int
1822 config_value_needs_escape(const char *value)
1824 if (*value == '\"')
1825 return 1;
1826 while (*value) {
1827 switch (*value)
1829 case '\r':
1830 case '\n':
1831 case '#':
1832 /* Note: quotes and backspaces need special handling when we are using
1833 * quotes, not otherwise, so they don't trigger escaping on their
1834 * own. */
1835 return 1;
1836 default:
1837 if (!TOR_ISPRINT(*value))
1838 return 1;
1840 ++value;
1842 return 0;
1845 /** Return a newly allocated deep copy of the lines in <b>inp</b>. */
1846 static config_line_t *
1847 config_lines_dup(const config_line_t *inp)
1849 config_line_t *result = NULL;
1850 config_line_t **next_out = &result;
1851 while (inp) {
1852 *next_out = tor_malloc(sizeof(config_line_t));
1853 (*next_out)->key = tor_strdup(inp->key);
1854 (*next_out)->value = tor_strdup(inp->value);
1855 inp = inp->next;
1856 next_out = &((*next_out)->next);
1858 (*next_out) = NULL;
1859 return result;
1862 /** Return newly allocated line or lines corresponding to <b>key</b> in the
1863 * configuration <b>options</b>. If <b>escape_val</b> is true and a
1864 * value needs to be quoted before it's put in a config file, quote and
1865 * escape that value. Return NULL if no such key exists. */
1866 static config_line_t *
1867 get_assigned_option(config_format_t *fmt, void *options,
1868 const char *key, int escape_val)
1870 config_var_t *var;
1871 const void *value;
1872 config_line_t *result;
1873 tor_assert(options && key);
1875 CHECK(fmt, options);
1877 var = config_find_option(fmt, key);
1878 if (!var) {
1879 log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key);
1880 return NULL;
1882 value = STRUCT_VAR_P(options, var->var_offset);
1884 result = tor_malloc_zero(sizeof(config_line_t));
1885 result->key = tor_strdup(var->name);
1886 switch (var->type)
1888 case CONFIG_TYPE_STRING:
1889 case CONFIG_TYPE_FILENAME:
1890 if (*(char**)value) {
1891 result->value = tor_strdup(*(char**)value);
1892 } else {
1893 tor_free(result->key);
1894 tor_free(result);
1895 return NULL;
1897 break;
1898 case CONFIG_TYPE_ISOTIME:
1899 if (*(time_t*)value) {
1900 result->value = tor_malloc(ISO_TIME_LEN+1);
1901 format_iso_time(result->value, *(time_t*)value);
1902 } else {
1903 tor_free(result->key);
1904 tor_free(result);
1906 escape_val = 0; /* Can't need escape. */
1907 break;
1908 case CONFIG_TYPE_INTERVAL:
1909 case CONFIG_TYPE_UINT:
1910 /* This means every or_options_t uint or bool element
1911 * needs to be an int. Not, say, a uint16_t or char. */
1912 tor_asprintf(&result->value, "%d", *(int*)value);
1913 escape_val = 0; /* Can't need escape. */
1914 break;
1915 case CONFIG_TYPE_MEMUNIT:
1916 tor_asprintf(&result->value, U64_FORMAT,
1917 U64_PRINTF_ARG(*(uint64_t*)value));
1918 escape_val = 0; /* Can't need escape. */
1919 break;
1920 case CONFIG_TYPE_DOUBLE:
1921 tor_asprintf(&result->value, "%f", *(double*)value);
1922 escape_val = 0; /* Can't need escape. */
1923 break;
1924 case CONFIG_TYPE_BOOL:
1925 result->value = tor_strdup(*(int*)value ? "1" : "0");
1926 escape_val = 0; /* Can't need escape. */
1927 break;
1928 case CONFIG_TYPE_ROUTERSET:
1929 result->value = routerset_to_string(*(routerset_t**)value);
1930 break;
1931 case CONFIG_TYPE_CSV:
1932 if (*(smartlist_t**)value)
1933 result->value =
1934 smartlist_join_strings(*(smartlist_t**)value, ",", 0, NULL);
1935 else
1936 result->value = tor_strdup("");
1937 break;
1938 case CONFIG_TYPE_OBSOLETE:
1939 log_fn(LOG_PROTOCOL_WARN, LD_CONFIG,
1940 "You asked me for the value of an obsolete config option '%s'.",
1941 key);
1942 tor_free(result->key);
1943 tor_free(result);
1944 return NULL;
1945 case CONFIG_TYPE_LINELIST_S:
1946 log_warn(LD_CONFIG,
1947 "Can't return context-sensitive '%s' on its own", key);
1948 tor_free(result->key);
1949 tor_free(result);
1950 return NULL;
1951 case CONFIG_TYPE_LINELIST:
1952 case CONFIG_TYPE_LINELIST_V:
1953 tor_free(result->key);
1954 tor_free(result);
1955 result = config_lines_dup(*(const config_line_t**)value);
1956 break;
1957 default:
1958 tor_free(result->key);
1959 tor_free(result);
1960 log_warn(LD_BUG,"Unknown type %d for known key '%s'",
1961 var->type, key);
1962 return NULL;
1965 if (escape_val) {
1966 config_line_t *line;
1967 for (line = result; line; line = line->next) {
1968 if (line->value && config_value_needs_escape(line->value)) {
1969 char *newval = esc_for_log(line->value);
1970 tor_free(line->value);
1971 line->value = newval;
1976 return result;
1979 /** Iterate through the linked list of requested options <b>list</b>.
1980 * For each item, convert as appropriate and assign to <b>options</b>.
1981 * If an item is unrecognized, set *msg and return -1 immediately,
1982 * else return 0 for success.
1984 * If <b>clear_first</b>, interpret config options as replacing (not
1985 * extending) their previous values. If <b>clear_first</b> is set,
1986 * then <b>use_defaults</b> to decide if you set to defaults after
1987 * clearing, or make the value 0 or NULL.
1989 * Here are the use cases:
1990 * 1. A non-empty AllowInvalid line in your torrc. Appends to current
1991 * if linelist, replaces current if csv.
1992 * 2. An empty AllowInvalid line in your torrc. Should clear it.
1993 * 3. "RESETCONF AllowInvalid" sets it to default.
1994 * 4. "SETCONF AllowInvalid" makes it NULL.
1995 * 5. "SETCONF AllowInvalid=foo" clears it and sets it to "foo".
1997 * Use_defaults Clear_first
1998 * 0 0 "append"
1999 * 1 0 undefined, don't use
2000 * 0 1 "set to null first"
2001 * 1 1 "set to defaults first"
2002 * Return 0 on success, -1 on bad key, -2 on bad value.
2004 * As an additional special case, if a LINELIST config option has
2005 * no value and clear_first is 0, then warn and ignore it.
2009 There are three call cases for config_assign() currently.
2011 Case one: Torrc entry
2012 options_init_from_torrc() calls config_assign(0, 0)
2013 calls config_assign_line(0, 0).
2014 if value is empty, calls option_reset(0) and returns.
2015 calls config_assign_value(), appends.
2017 Case two: setconf
2018 options_trial_assign() calls config_assign(0, 1)
2019 calls config_reset_line(0)
2020 calls option_reset(0)
2021 calls option_clear().
2022 calls config_assign_line(0, 1).
2023 if value is empty, returns.
2024 calls config_assign_value(), appends.
2026 Case three: resetconf
2027 options_trial_assign() calls config_assign(1, 1)
2028 calls config_reset_line(1)
2029 calls option_reset(1)
2030 calls option_clear().
2031 calls config_assign_value(default)
2032 calls config_assign_line(1, 1).
2033 returns.
2035 static int
2036 config_assign(config_format_t *fmt, void *options, config_line_t *list,
2037 int use_defaults, int clear_first, char **msg)
2039 config_line_t *p;
2040 bitarray_t *options_seen;
2041 const int n_options = config_count_options(fmt);
2043 CHECK(fmt, options);
2045 /* pass 1: normalize keys */
2046 for (p = list; p; p = p->next) {
2047 const char *full = expand_abbrev(fmt, p->key, 0, 1);
2048 if (strcmp(full,p->key)) {
2049 tor_free(p->key);
2050 p->key = tor_strdup(full);
2054 /* pass 2: if we're reading from a resetting source, clear all
2055 * mentioned config options, and maybe set to their defaults. */
2056 if (clear_first) {
2057 for (p = list; p; p = p->next)
2058 config_reset_line(fmt, options, p->key, use_defaults);
2061 options_seen = bitarray_init_zero(n_options);
2062 /* pass 3: assign. */
2063 while (list) {
2064 int r;
2065 if ((r=config_assign_line(fmt, options, list, use_defaults,
2066 clear_first, options_seen, msg))) {
2067 bitarray_free(options_seen);
2068 return r;
2070 list = list->next;
2072 bitarray_free(options_seen);
2073 return 0;
2076 /** Try assigning <b>list</b> to the global options. You do this by duping
2077 * options, assigning list to the new one, then validating it. If it's
2078 * ok, then throw out the old one and stick with the new one. Else,
2079 * revert to old and return failure. Return SETOPT_OK on success, or
2080 * a setopt_err_t on failure.
2082 * If not success, point *<b>msg</b> to a newly allocated string describing
2083 * what went wrong.
2085 setopt_err_t
2086 options_trial_assign(config_line_t *list, int use_defaults,
2087 int clear_first, char **msg)
2089 int r;
2090 or_options_t *trial_options = options_dup(&options_format, get_options());
2092 if ((r=config_assign(&options_format, trial_options,
2093 list, use_defaults, clear_first, msg)) < 0) {
2094 config_free(&options_format, trial_options);
2095 return r;
2098 if (options_validate(get_options(), trial_options, 1, msg) < 0) {
2099 config_free(&options_format, trial_options);
2100 return SETOPT_ERR_PARSE; /*XXX make this a separate return value. */
2103 if (options_transition_allowed(get_options(), trial_options, msg) < 0) {
2104 config_free(&options_format, trial_options);
2105 return SETOPT_ERR_TRANSITION;
2108 if (set_options(trial_options, msg)<0) {
2109 config_free(&options_format, trial_options);
2110 return SETOPT_ERR_SETTING;
2113 /* we liked it. put it in place. */
2114 return SETOPT_OK;
2117 /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
2118 * Called from option_reset() and config_free(). */
2119 static void
2120 option_clear(config_format_t *fmt, or_options_t *options, config_var_t *var)
2122 void *lvalue = STRUCT_VAR_P(options, var->var_offset);
2123 (void)fmt; /* unused */
2124 switch (var->type) {
2125 case CONFIG_TYPE_STRING:
2126 case CONFIG_TYPE_FILENAME:
2127 tor_free(*(char**)lvalue);
2128 break;
2129 case CONFIG_TYPE_DOUBLE:
2130 *(double*)lvalue = 0.0;
2131 break;
2132 case CONFIG_TYPE_ISOTIME:
2133 *(time_t*)lvalue = 0;
2134 break;
2135 case CONFIG_TYPE_INTERVAL:
2136 case CONFIG_TYPE_UINT:
2137 case CONFIG_TYPE_BOOL:
2138 *(int*)lvalue = 0;
2139 break;
2140 case CONFIG_TYPE_MEMUNIT:
2141 *(uint64_t*)lvalue = 0;
2142 break;
2143 case CONFIG_TYPE_ROUTERSET:
2144 if (*(routerset_t**)lvalue) {
2145 routerset_free(*(routerset_t**)lvalue);
2146 *(routerset_t**)lvalue = NULL;
2148 break;
2149 case CONFIG_TYPE_CSV:
2150 if (*(smartlist_t**)lvalue) {
2151 SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
2152 smartlist_free(*(smartlist_t **)lvalue);
2153 *(smartlist_t **)lvalue = NULL;
2155 break;
2156 case CONFIG_TYPE_LINELIST:
2157 case CONFIG_TYPE_LINELIST_S:
2158 config_free_lines(*(config_line_t **)lvalue);
2159 *(config_line_t **)lvalue = NULL;
2160 break;
2161 case CONFIG_TYPE_LINELIST_V:
2162 /* handled by linelist_s. */
2163 break;
2164 case CONFIG_TYPE_OBSOLETE:
2165 break;
2169 /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
2170 * <b>use_defaults</b>, set it to its default value.
2171 * Called by config_init() and option_reset_line() and option_assign_line(). */
2172 static void
2173 option_reset(config_format_t *fmt, or_options_t *options,
2174 config_var_t *var, int use_defaults)
2176 config_line_t *c;
2177 char *msg = NULL;
2178 CHECK(fmt, options);
2179 option_clear(fmt, options, var); /* clear it first */
2180 if (!use_defaults)
2181 return; /* all done */
2182 if (var->initvalue) {
2183 c = tor_malloc_zero(sizeof(config_line_t));
2184 c->key = tor_strdup(var->name);
2185 c->value = tor_strdup(var->initvalue);
2186 if (config_assign_value(fmt, options, c, &msg) < 0) {
2187 log_warn(LD_BUG, "Failed to assign default: %s", msg);
2188 tor_free(msg); /* if this happens it's a bug */
2190 config_free_lines(c);
2194 /** Print a usage message for tor. */
2195 static void
2196 print_usage(void)
2198 printf(
2199 "Copyright (c) 2001-2004, Roger Dingledine\n"
2200 "Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson\n"
2201 "Copyright (c) 2007-2010, The Tor Project, Inc.\n\n"
2202 "tor -f <torrc> [args]\n"
2203 "See man page for options, or https://www.torproject.org/ for "
2204 "documentation.\n");
2207 /** Print all non-obsolete torrc options. */
2208 static void
2209 list_torrc_options(void)
2211 int i;
2212 smartlist_t *lines = smartlist_create();
2213 for (i = 0; _option_vars[i].name; ++i) {
2214 config_var_t *var = &_option_vars[i];
2215 if (var->type == CONFIG_TYPE_OBSOLETE ||
2216 var->type == CONFIG_TYPE_LINELIST_V)
2217 continue;
2218 printf("%s\n", var->name);
2220 smartlist_free(lines);
2223 /** Last value actually set by resolve_my_address. */
2224 static uint32_t last_resolved_addr = 0;
2226 * Based on <b>options-\>Address</b>, guess our public IP address and put it
2227 * (in host order) into *<b>addr_out</b>. If <b>hostname_out</b> is provided,
2228 * set *<b>hostname_out</b> to a new string holding the hostname we used to
2229 * get the address. Return 0 if all is well, or -1 if we can't find a suitable
2230 * public IP address.
2233 resolve_my_address(int warn_severity, or_options_t *options,
2234 uint32_t *addr_out, char **hostname_out)
2236 struct in_addr in;
2237 uint32_t addr; /* host order */
2238 char hostname[256];
2239 int explicit_ip=1;
2240 int explicit_hostname=1;
2241 int from_interface=0;
2242 char tmpbuf[INET_NTOA_BUF_LEN];
2243 const char *address = options->Address;
2244 int notice_severity = warn_severity <= LOG_NOTICE ?
2245 LOG_NOTICE : warn_severity;
2247 tor_assert(addr_out);
2249 if (address && *address) {
2250 strlcpy(hostname, address, sizeof(hostname));
2251 } else { /* then we need to guess our address */
2252 explicit_ip = 0; /* it's implicit */
2253 explicit_hostname = 0; /* it's implicit */
2255 if (gethostname(hostname, sizeof(hostname)) < 0) {
2256 log_fn(warn_severity, LD_NET,"Error obtaining local hostname");
2257 return -1;
2259 log_debug(LD_CONFIG,"Guessed local host name as '%s'",hostname);
2262 /* now we know hostname. resolve it and keep only the IP address */
2264 if (tor_inet_aton(hostname, &in) == 0) {
2265 /* then we have to resolve it */
2266 explicit_ip = 0;
2267 if (tor_lookup_hostname(hostname, &addr)) { /* failed to resolve */
2268 uint32_t interface_ip; /* host order */
2270 if (explicit_hostname) {
2271 log_fn(warn_severity, LD_CONFIG,
2272 "Could not resolve local Address '%s'. Failing.", hostname);
2273 return -1;
2275 log_fn(notice_severity, LD_CONFIG,
2276 "Could not resolve guessed local hostname '%s'. "
2277 "Trying something else.", hostname);
2278 if (get_interface_address(warn_severity, &interface_ip)) {
2279 log_fn(warn_severity, LD_CONFIG,
2280 "Could not get local interface IP address. Failing.");
2281 return -1;
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, "Learned IP address '%s' for "
2287 "local interface. Using that.", tmpbuf);
2288 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
2289 } else { /* resolved hostname into addr */
2290 in.s_addr = htonl(addr);
2292 if (!explicit_hostname &&
2293 is_internal_IP(ntohl(in.s_addr), 0)) {
2294 uint32_t interface_ip;
2296 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2297 log_fn(notice_severity, LD_CONFIG, "Guessed local hostname '%s' "
2298 "resolves to a private IP address (%s). Trying something "
2299 "else.", hostname, tmpbuf);
2301 if (get_interface_address(warn_severity, &interface_ip)) {
2302 log_fn(warn_severity, LD_CONFIG,
2303 "Could not get local interface IP address. Too bad.");
2304 } else if (is_internal_IP(interface_ip, 0)) {
2305 struct in_addr in2;
2306 in2.s_addr = htonl(interface_ip);
2307 tor_inet_ntoa(&in2,tmpbuf,sizeof(tmpbuf));
2308 log_fn(notice_severity, LD_CONFIG,
2309 "Interface IP address '%s' is a private address too. "
2310 "Ignoring.", tmpbuf);
2311 } else {
2312 from_interface = 1;
2313 in.s_addr = htonl(interface_ip);
2314 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2315 log_fn(notice_severity, LD_CONFIG,
2316 "Learned IP address '%s' for local interface."
2317 " Using that.", tmpbuf);
2318 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
2324 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2325 if (is_internal_IP(ntohl(in.s_addr), 0) &&
2326 options->_PublishServerDescriptor) {
2327 /* make sure we're ok with publishing an internal IP */
2328 if (!options->DirServers && !options->AlternateDirAuthority) {
2329 /* if they are using the default dirservers, disallow internal IPs
2330 * always. */
2331 log_fn(warn_severity, LD_CONFIG,
2332 "Address '%s' resolves to private IP address '%s'. "
2333 "Tor servers that use the default DirServers must have public "
2334 "IP addresses.", hostname, tmpbuf);
2335 return -1;
2337 if (!explicit_ip) {
2338 /* even if they've set their own dirservers, require an explicit IP if
2339 * they're using an internal address. */
2340 log_fn(warn_severity, LD_CONFIG, "Address '%s' resolves to private "
2341 "IP address '%s'. Please set the Address config option to be "
2342 "the IP address you want to use.", hostname, tmpbuf);
2343 return -1;
2347 log_debug(LD_CONFIG, "Resolved Address to '%s'.", tmpbuf);
2348 *addr_out = ntohl(in.s_addr);
2349 if (last_resolved_addr && last_resolved_addr != *addr_out) {
2350 /* Leave this as a notice, regardless of the requested severity,
2351 * at least until dynamic IP address support becomes bulletproof. */
2352 log_notice(LD_NET,
2353 "Your IP address seems to have changed to %s. Updating.",
2354 tmpbuf);
2355 ip_address_changed(0);
2357 if (last_resolved_addr != *addr_out) {
2358 const char *method;
2359 const char *h = hostname;
2360 if (explicit_ip) {
2361 method = "CONFIGURED";
2362 h = NULL;
2363 } else if (explicit_hostname) {
2364 method = "RESOLVED";
2365 } else if (from_interface) {
2366 method = "INTERFACE";
2367 h = NULL;
2368 } else {
2369 method = "GETHOSTNAME";
2371 control_event_server_status(LOG_NOTICE,
2372 "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s %s%s",
2373 tmpbuf, method, h?"HOSTNAME=":"", h);
2375 last_resolved_addr = *addr_out;
2376 if (hostname_out)
2377 *hostname_out = tor_strdup(hostname);
2378 return 0;
2381 /** Return true iff <b>addr</b> is judged to be on the same network as us, or
2382 * on a private network.
2385 is_local_addr(const tor_addr_t *addr)
2387 if (tor_addr_is_internal(addr, 0))
2388 return 1;
2389 /* Check whether ip is on the same /24 as we are. */
2390 if (get_options()->EnforceDistinctSubnets == 0)
2391 return 0;
2392 if (tor_addr_family(addr) == AF_INET) {
2393 /*XXXX022 IP6 what corresponds to an /24? */
2394 uint32_t ip = tor_addr_to_ipv4h(addr);
2396 /* It's possible that this next check will hit before the first time
2397 * resolve_my_address actually succeeds. (For clients, it is likely that
2398 * resolve_my_address will never be called at all). In those cases,
2399 * last_resolved_addr will be 0, and so checking to see whether ip is on
2400 * the same /24 as last_resolved_addr will be the same as checking whether
2401 * it was on net 0, which is already done by is_internal_IP.
2403 if ((last_resolved_addr & (uint32_t)0xffffff00ul)
2404 == (ip & (uint32_t)0xffffff00ul))
2405 return 1;
2407 return 0;
2410 /** Called when we don't have a nickname set. Try to guess a good nickname
2411 * based on the hostname, and return it in a newly allocated string. If we
2412 * can't, return NULL and let the caller warn if it wants to. */
2413 static char *
2414 get_default_nickname(void)
2416 static const char * const bad_default_nicknames[] = {
2417 "localhost",
2418 NULL,
2420 char localhostname[256];
2421 char *cp, *out, *outp;
2422 int i;
2424 if (gethostname(localhostname, sizeof(localhostname)) < 0)
2425 return NULL;
2427 /* Put it in lowercase; stop at the first dot. */
2428 if ((cp = strchr(localhostname, '.')))
2429 *cp = '\0';
2430 tor_strlower(localhostname);
2432 /* Strip invalid characters. */
2433 cp = localhostname;
2434 out = outp = tor_malloc(strlen(localhostname) + 1);
2435 while (*cp) {
2436 if (strchr(LEGAL_NICKNAME_CHARACTERS, *cp))
2437 *outp++ = *cp++;
2438 else
2439 cp++;
2441 *outp = '\0';
2443 /* Enforce length. */
2444 if (strlen(out) > MAX_NICKNAME_LEN)
2445 out[MAX_NICKNAME_LEN]='\0';
2447 /* Check for dumb names. */
2448 for (i = 0; bad_default_nicknames[i]; ++i) {
2449 if (!strcmp(out, bad_default_nicknames[i])) {
2450 tor_free(out);
2451 return NULL;
2455 return out;
2458 /** Release storage held by <b>options</b>. */
2459 static void
2460 config_free(config_format_t *fmt, void *options)
2462 int i;
2464 if (!options)
2465 return;
2467 tor_assert(fmt);
2469 for (i=0; fmt->vars[i].name; ++i)
2470 option_clear(fmt, options, &(fmt->vars[i]));
2471 if (fmt->extra) {
2472 config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->var_offset);
2473 config_free_lines(*linep);
2474 *linep = NULL;
2476 tor_free(options);
2479 /** Return true iff a and b contain identical keys and values in identical
2480 * order. */
2481 static int
2482 config_lines_eq(config_line_t *a, config_line_t *b)
2484 while (a && b) {
2485 if (strcasecmp(a->key, b->key) || strcmp(a->value, b->value))
2486 return 0;
2487 a = a->next;
2488 b = b->next;
2490 if (a || b)
2491 return 0;
2492 return 1;
2495 /** Return true iff the option <b>name</b> has the same value in <b>o1</b>
2496 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
2498 static int
2499 option_is_same(config_format_t *fmt,
2500 or_options_t *o1, or_options_t *o2, const char *name)
2502 config_line_t *c1, *c2;
2503 int r = 1;
2504 CHECK(fmt, o1);
2505 CHECK(fmt, o2);
2507 c1 = get_assigned_option(fmt, o1, name, 0);
2508 c2 = get_assigned_option(fmt, o2, name, 0);
2509 r = config_lines_eq(c1, c2);
2510 config_free_lines(c1);
2511 config_free_lines(c2);
2512 return r;
2515 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
2516 static or_options_t *
2517 options_dup(config_format_t *fmt, or_options_t *old)
2519 or_options_t *newopts;
2520 int i;
2521 config_line_t *line;
2523 newopts = config_alloc(fmt);
2524 for (i=0; fmt->vars[i].name; ++i) {
2525 if (fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2526 continue;
2527 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE)
2528 continue;
2529 line = get_assigned_option(fmt, old, fmt->vars[i].name, 0);
2530 if (line) {
2531 char *msg = NULL;
2532 if (config_assign(fmt, newopts, line, 0, 0, &msg) < 0) {
2533 log_err(LD_BUG, "Config_get_assigned_option() generated "
2534 "something we couldn't config_assign(): %s", msg);
2535 tor_free(msg);
2536 tor_assert(0);
2539 config_free_lines(line);
2541 return newopts;
2544 /** Return a new empty or_options_t. Used for testing. */
2545 or_options_t *
2546 options_new(void)
2548 return config_alloc(&options_format);
2551 /** Set <b>options</b> to hold reasonable defaults for most options.
2552 * Each option defaults to zero. */
2553 void
2554 options_init(or_options_t *options)
2556 config_init(&options_format, options);
2559 /* Check if the port number given in <b>port_option</b> in combination with
2560 * the specified port in <b>listen_options</b> will result in Tor actually
2561 * opening a low port (meaning a port lower than 1024). Return 1 if
2562 * it is, or 0 if it isn't or the concept of a low port isn't applicable for
2563 * the platform we're on. */
2564 static int
2565 is_listening_on_low_port(uint16_t port_option,
2566 const config_line_t *listen_options)
2568 #ifdef MS_WINDOWS
2569 (void) port_option;
2570 (void) listen_options;
2571 return 0; /* No port is too low for windows. */
2572 #else
2573 const config_line_t *l;
2574 uint16_t p;
2575 if (port_option == 0)
2576 return 0; /* We're not listening */
2577 if (listen_options == NULL)
2578 return (port_option < 1024);
2580 for (l = listen_options; l; l = l->next) {
2581 parse_addr_port(LOG_WARN, l->value, NULL, NULL, &p);
2582 if (p<1024) {
2583 return 1;
2586 return 0;
2587 #endif
2590 /** Set all vars in the configuration object <b>options</b> to their default
2591 * values. */
2592 static void
2593 config_init(config_format_t *fmt, void *options)
2595 int i;
2596 config_var_t *var;
2597 CHECK(fmt, options);
2599 for (i=0; fmt->vars[i].name; ++i) {
2600 var = &fmt->vars[i];
2601 if (!var->initvalue)
2602 continue; /* defaults to NULL or 0 */
2603 option_reset(fmt, options, var, 1);
2607 /** Allocate and return a new string holding the written-out values of the vars
2608 * in 'options'. If 'minimal', do not write out any default-valued vars.
2609 * Else, if comment_defaults, write default values as comments.
2611 static char *
2612 config_dump(config_format_t *fmt, void *options, int minimal,
2613 int comment_defaults)
2615 smartlist_t *elements;
2616 or_options_t *defaults;
2617 config_line_t *line, *assigned;
2618 char *result;
2619 int i;
2620 char *msg = NULL;
2622 defaults = config_alloc(fmt);
2623 config_init(fmt, defaults);
2625 /* XXX use a 1 here so we don't add a new log line while dumping */
2626 if (fmt->validate_fn(NULL,defaults, 1, &msg) < 0) {
2627 log_err(LD_BUG, "Failed to validate default config.");
2628 tor_free(msg);
2629 tor_assert(0);
2632 elements = smartlist_create();
2633 for (i=0; fmt->vars[i].name; ++i) {
2634 int comment_option = 0;
2635 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE ||
2636 fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2637 continue;
2638 /* Don't save 'hidden' control variables. */
2639 if (!strcmpstart(fmt->vars[i].name, "__"))
2640 continue;
2641 if (minimal && option_is_same(fmt, options, defaults, fmt->vars[i].name))
2642 continue;
2643 else if (comment_defaults &&
2644 option_is_same(fmt, options, defaults, fmt->vars[i].name))
2645 comment_option = 1;
2647 line = assigned = get_assigned_option(fmt, options, fmt->vars[i].name, 1);
2649 for (; line; line = line->next) {
2650 char *tmp;
2651 tor_asprintf(&tmp, "%s%s %s\n",
2652 comment_option ? "# " : "",
2653 line->key, line->value);
2654 smartlist_add(elements, tmp);
2656 config_free_lines(assigned);
2659 if (fmt->extra) {
2660 line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->var_offset);
2661 for (; line; line = line->next) {
2662 char *tmp;
2663 tor_asprintf(&tmp, "%s %s\n", line->key, line->value);
2664 smartlist_add(elements, tmp);
2668 result = smartlist_join_strings(elements, "", 0, NULL);
2669 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2670 smartlist_free(elements);
2671 config_free(fmt, defaults);
2672 return result;
2675 /** Return a string containing a possible configuration file that would give
2676 * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
2677 * include options that are the same as Tor's defaults.
2679 char *
2680 options_dump(or_options_t *options, int minimal)
2682 return config_dump(&options_format, options, minimal, 0);
2685 /** Return 0 if every element of sl is a string holding a decimal
2686 * representation of a port number, or if sl is NULL.
2687 * Otherwise set *msg and return -1. */
2688 static int
2689 validate_ports_csv(smartlist_t *sl, const char *name, char **msg)
2691 int i;
2692 tor_assert(name);
2694 if (!sl)
2695 return 0;
2697 SMARTLIST_FOREACH(sl, const char *, cp,
2699 i = atoi(cp);
2700 if (i < 1 || i > 65535) {
2701 tor_asprintf(msg, "Port '%s' out of range in %s", cp, name);
2702 return -1;
2705 return 0;
2708 /** If <b>value</b> exceeds ROUTER_MAX_DECLARED_BANDWIDTH, write
2709 * a complaint into *<b>msg</b> using string <b>desc</b>, and return -1.
2710 * Else return 0.
2712 static int
2713 ensure_bandwidth_cap(uint64_t *value, const char *desc, char **msg)
2715 if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
2716 /* This handles an understandable special case where somebody says "2gb"
2717 * whereas our actual maximum is 2gb-1 (INT_MAX) */
2718 --*value;
2720 if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
2721 tor_asprintf(msg, "%s ("U64_FORMAT") must be at most %d",
2722 desc, U64_PRINTF_ARG(*value),
2723 ROUTER_MAX_DECLARED_BANDWIDTH);
2724 return -1;
2726 return 0;
2729 /** Parse an authority type from <b>options</b>-\>PublishServerDescriptor
2730 * and write it to <b>options</b>-\>_PublishServerDescriptor. Treat "1"
2731 * as "v2,v3" unless BridgeRelay is 1, in which case treat it as "bridge".
2732 * Treat "0" as "".
2733 * Return 0 on success or -1 if not a recognized authority type (in which
2734 * case the value of _PublishServerDescriptor is undefined). */
2735 static int
2736 compute_publishserverdescriptor(or_options_t *options)
2738 smartlist_t *list = options->PublishServerDescriptor;
2739 authority_type_t *auth = &options->_PublishServerDescriptor;
2740 *auth = NO_AUTHORITY;
2741 if (!list) /* empty list, answer is none */
2742 return 0;
2743 SMARTLIST_FOREACH(list, const char *, string, {
2744 if (!strcasecmp(string, "v1"))
2745 *auth |= V1_AUTHORITY;
2746 else if (!strcmp(string, "1"))
2747 if (options->BridgeRelay)
2748 *auth |= BRIDGE_AUTHORITY;
2749 else
2750 *auth |= V2_AUTHORITY | V3_AUTHORITY;
2751 else if (!strcasecmp(string, "v2"))
2752 *auth |= V2_AUTHORITY;
2753 else if (!strcasecmp(string, "v3"))
2754 *auth |= V3_AUTHORITY;
2755 else if (!strcasecmp(string, "bridge"))
2756 *auth |= BRIDGE_AUTHORITY;
2757 else if (!strcasecmp(string, "hidserv"))
2758 *auth |= HIDSERV_AUTHORITY;
2759 else if (!strcasecmp(string, "") || !strcmp(string, "0"))
2760 /* no authority */;
2761 else
2762 return -1;
2764 return 0;
2767 /** Lowest allowable value for RendPostPeriod; if this is too low, hidden
2768 * services can overload the directory system. */
2769 #define MIN_REND_POST_PERIOD (10*60)
2771 /** Highest allowable value for RendPostPeriod. */
2772 #define MAX_DIR_PERIOD (MIN_ONION_KEY_LIFETIME/2)
2774 /** Lowest allowable value for MaxCircuitDirtiness; if this is too low, Tor
2775 * will generate too many circuits and potentially overload the network. */
2776 #define MIN_MAX_CIRCUIT_DIRTINESS 10
2778 /** Lowest allowable value for CircuitStreamTimeout; if this is too low, Tor
2779 * will generate too many circuits and potentially overload the network. */
2780 #define MIN_CIRCUIT_STREAM_TIMEOUT 10
2782 /** Return 0 if every setting in <b>options</b> is reasonable, and a
2783 * permissible transition from <b>old_options</b>. Else return -1.
2784 * Should have no side effects, except for normalizing the contents of
2785 * <b>options</b>.
2787 * On error, tor_strdup an error explanation into *<b>msg</b>.
2789 * XXX
2790 * If <b>from_setconf</b>, we were called by the controller, and our
2791 * Log line should stay empty. If it's 0, then give us a default log
2792 * if there are no logs defined.
2794 static int
2795 options_validate(or_options_t *old_options, or_options_t *options,
2796 int from_setconf, char **msg)
2798 int i;
2799 config_line_t *cl;
2800 const char *uname = get_uname();
2801 #define REJECT(arg) \
2802 STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
2803 #define COMPLAIN(arg) STMT_BEGIN log(LOG_WARN, LD_CONFIG, arg); STMT_END
2805 tor_assert(msg);
2806 *msg = NULL;
2808 if (options->ORPort < 0 || options->ORPort > 65535)
2809 REJECT("ORPort option out of bounds.");
2811 if (server_mode(options) &&
2812 (!strcmpstart(uname, "Windows 95") ||
2813 !strcmpstart(uname, "Windows 98") ||
2814 !strcmpstart(uname, "Windows Me"))) {
2815 log(LOG_WARN, LD_CONFIG, "Tor is running as a server, but you are "
2816 "running %s; this probably won't work. See "
2817 "https://wiki.torproject.org/TheOnionRouter/TorFAQ#ServerOS "
2818 "for details.", uname);
2821 if (options->ORPort == 0 && options->ORListenAddress != NULL)
2822 REJECT("ORPort must be defined if ORListenAddress is defined.");
2824 if (options->DirPort == 0 && options->DirListenAddress != NULL)
2825 REJECT("DirPort must be defined if DirListenAddress is defined.");
2827 if (options->DNSPort == 0 && options->DNSListenAddress != NULL)
2828 REJECT("DNSPort must be defined if DNSListenAddress is defined.");
2830 if (options->ControlPort == 0 && options->ControlListenAddress != NULL)
2831 REJECT("ControlPort must be defined if ControlListenAddress is defined.");
2833 if (options->TransPort == 0 && options->TransListenAddress != NULL)
2834 REJECT("TransPort must be defined if TransListenAddress is defined.");
2836 if (options->NatdPort == 0 && options->NatdListenAddress != NULL)
2837 REJECT("NatdPort must be defined if NatdListenAddress is defined.");
2839 /* Don't gripe about SocksPort 0 with SocksListenAddress set; a standard
2840 * configuration does this. */
2842 for (i = 0; i < 3; ++i) {
2843 int is_socks = i==0;
2844 int is_trans = i==1;
2845 config_line_t *line, *opt, *old;
2846 const char *tp;
2847 if (is_socks) {
2848 opt = options->SocksListenAddress;
2849 old = old_options ? old_options->SocksListenAddress : NULL;
2850 tp = "SOCKS proxy";
2851 } else if (is_trans) {
2852 opt = options->TransListenAddress;
2853 old = old_options ? old_options->TransListenAddress : NULL;
2854 tp = "transparent proxy";
2855 } else {
2856 opt = options->NatdListenAddress;
2857 old = old_options ? old_options->NatdListenAddress : NULL;
2858 tp = "natd proxy";
2861 for (line = opt; line; line = line->next) {
2862 char *address = NULL;
2863 uint16_t port;
2864 uint32_t addr;
2865 if (parse_addr_port(LOG_WARN, line->value, &address, &addr, &port)<0)
2866 continue; /* We'll warn about this later. */
2867 if (!is_internal_IP(addr, 1) &&
2868 (!old_options || !config_lines_eq(old, opt))) {
2869 log_warn(LD_CONFIG,
2870 "You specified a public address '%s' for a %s. Other "
2871 "people on the Internet might find your computer and use it as "
2872 "an open %s. Please don't allow this unless you have "
2873 "a good reason.", address, tp, tp);
2875 tor_free(address);
2879 if (validate_data_directory(options)<0)
2880 REJECT("Invalid DataDirectory");
2882 if (options->Nickname == NULL) {
2883 if (server_mode(options)) {
2884 if (!(options->Nickname = get_default_nickname())) {
2885 log_notice(LD_CONFIG, "Couldn't pick a nickname based on "
2886 "our hostname; using %s instead.", UNNAMED_ROUTER_NICKNAME);
2887 options->Nickname = tor_strdup(UNNAMED_ROUTER_NICKNAME);
2888 } else {
2889 log_notice(LD_CONFIG, "Choosing default nickname '%s'",
2890 options->Nickname);
2893 } else {
2894 if (!is_legal_nickname(options->Nickname)) {
2895 tor_asprintf(msg,
2896 "Nickname '%s' is wrong length or contains illegal characters.",
2897 options->Nickname);
2898 return -1;
2902 if (server_mode(options) && !options->ContactInfo)
2903 log(LOG_NOTICE, LD_CONFIG, "Your ContactInfo config option is not set. "
2904 "Please consider setting it, so we can contact you if your server is "
2905 "misconfigured or something else goes wrong.");
2907 /* Special case on first boot if no Log options are given. */
2908 if (!options->Logs && !options->RunAsDaemon && !from_setconf)
2909 config_line_append(&options->Logs, "Log", "notice stdout");
2911 if (options_init_logs(options, 1)<0) /* Validate the log(s) */
2912 REJECT("Failed to validate Log options. See logs for details.");
2914 if (options->NoPublish) {
2915 log(LOG_WARN, LD_CONFIG,
2916 "NoPublish is obsolete. Use PublishServerDescriptor instead.");
2917 SMARTLIST_FOREACH(options->PublishServerDescriptor, char *, s,
2918 tor_free(s));
2919 smartlist_clear(options->PublishServerDescriptor);
2922 if (authdir_mode(options)) {
2923 /* confirm that our address isn't broken, so we can complain now */
2924 uint32_t tmp;
2925 if (resolve_my_address(LOG_WARN, options, &tmp, NULL) < 0)
2926 REJECT("Failed to resolve/guess local address. See logs for details.");
2929 #ifndef MS_WINDOWS
2930 if (options->RunAsDaemon && torrc_fname && path_is_relative(torrc_fname))
2931 REJECT("Can't use a relative path to torrc when RunAsDaemon is set.");
2932 #endif
2934 if (options->SocksPort < 0 || options->SocksPort > 65535)
2935 REJECT("SocksPort option out of bounds.");
2937 if (options->DNSPort < 0 || options->DNSPort > 65535)
2938 REJECT("DNSPort option out of bounds.");
2940 if (options->TransPort < 0 || options->TransPort > 65535)
2941 REJECT("TransPort option out of bounds.");
2943 if (options->NatdPort < 0 || options->NatdPort > 65535)
2944 REJECT("NatdPort option out of bounds.");
2946 if (options->SocksPort == 0 && options->TransPort == 0 &&
2947 options->NatdPort == 0 && options->ORPort == 0 &&
2948 options->DNSPort == 0 && !options->RendConfigLines)
2949 log(LOG_WARN, LD_CONFIG,
2950 "SocksPort, TransPort, NatdPort, DNSPort, and ORPort are all "
2951 "undefined, and there aren't any hidden services configured. "
2952 "Tor will still run, but probably won't do anything.");
2954 if (options->ControlPort < 0 || options->ControlPort > 65535)
2955 REJECT("ControlPort option out of bounds.");
2957 if (options->DirPort < 0 || options->DirPort > 65535)
2958 REJECT("DirPort option out of bounds.");
2960 #ifndef USE_TRANSPARENT
2961 if (options->TransPort || options->TransListenAddress)
2962 REJECT("TransPort and TransListenAddress are disabled in this build.");
2963 #endif
2965 if (options->AccountingMax &&
2966 (is_listening_on_low_port(options->ORPort, options->ORListenAddress) ||
2967 is_listening_on_low_port(options->DirPort, options->DirListenAddress)))
2969 log(LOG_WARN, LD_CONFIG,
2970 "You have set AccountingMax to use hibernation. You have also "
2971 "chosen a low DirPort or OrPort. This combination can make Tor stop "
2972 "working when it tries to re-attach the port after a period of "
2973 "hibernation. Please choose a different port or turn off "
2974 "hibernation unless you know this combination will work on your "
2975 "platform.");
2978 if (options->ExcludeExitNodes || options->ExcludeNodes) {
2979 options->_ExcludeExitNodesUnion = routerset_new();
2980 routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeExitNodes);
2981 routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeNodes);
2984 if (options->ExcludeNodes && options->StrictNodes) {
2985 COMPLAIN("You have asked to exclude certain relays from all positions "
2986 "in your circuits. Expect hidden services and other Tor "
2987 "features to be broken in unpredictable ways.");
2990 if (options->EntryNodes && !routerset_is_list(options->EntryNodes)) {
2991 /* XXXX fix this; see entry_guards_prepend_from_config(). */
2992 REJECT("IPs or countries are not yet supported in EntryNodes.");
2995 if (options->AuthoritativeDir) {
2996 if (!options->ContactInfo && !options->TestingTorNetwork)
2997 REJECT("Authoritative directory servers must set ContactInfo");
2998 if (options->V1AuthoritativeDir && !options->RecommendedVersions)
2999 REJECT("V1 authoritative dir servers must set RecommendedVersions.");
3000 if (!options->RecommendedClientVersions)
3001 options->RecommendedClientVersions =
3002 config_lines_dup(options->RecommendedVersions);
3003 if (!options->RecommendedServerVersions)
3004 options->RecommendedServerVersions =
3005 config_lines_dup(options->RecommendedVersions);
3006 if (options->VersioningAuthoritativeDir &&
3007 (!options->RecommendedClientVersions ||
3008 !options->RecommendedServerVersions))
3009 REJECT("Versioning authoritative dir servers must set "
3010 "Recommended*Versions.");
3011 if (options->UseEntryGuards) {
3012 log_info(LD_CONFIG, "Authoritative directory servers can't set "
3013 "UseEntryGuards. Disabling.");
3014 options->UseEntryGuards = 0;
3016 if (!options->DownloadExtraInfo && authdir_mode_any_main(options)) {
3017 log_info(LD_CONFIG, "Authoritative directories always try to download "
3018 "extra-info documents. Setting DownloadExtraInfo.");
3019 options->DownloadExtraInfo = 1;
3021 if (!(options->BridgeAuthoritativeDir || options->HSAuthoritativeDir ||
3022 options->V1AuthoritativeDir || options->V2AuthoritativeDir ||
3023 options->V3AuthoritativeDir))
3024 REJECT("AuthoritativeDir is set, but none of "
3025 "(Bridge/HS/V1/V2/V3)AuthoritativeDir is set.");
3026 /* If we have a v3bandwidthsfile and it's broken, complain on startup */
3027 if (options->V3BandwidthsFile && !old_options) {
3028 dirserv_read_measured_bandwidths(options->V3BandwidthsFile, NULL);
3032 if (options->AuthoritativeDir && !options->DirPort)
3033 REJECT("Running as authoritative directory, but no DirPort set.");
3035 if (options->AuthoritativeDir && !options->ORPort)
3036 REJECT("Running as authoritative directory, but no ORPort set.");
3038 if (options->AuthoritativeDir && options->ClientOnly)
3039 REJECT("Running as authoritative directory, but ClientOnly also set.");
3041 if (options->FetchDirInfoExtraEarly && !options->FetchDirInfoEarly)
3042 REJECT("FetchDirInfoExtraEarly requires that you also set "
3043 "FetchDirInfoEarly");
3045 if (options->ConnLimit <= 0) {
3046 tor_asprintf(msg,
3047 "ConnLimit must be greater than 0, but was set to %d",
3048 options->ConnLimit);
3049 return -1;
3052 if (validate_ports_csv(options->FirewallPorts, "FirewallPorts", msg) < 0)
3053 return -1;
3055 if (validate_ports_csv(options->LongLivedPorts, "LongLivedPorts", msg) < 0)
3056 return -1;
3058 if (validate_ports_csv(options->RejectPlaintextPorts,
3059 "RejectPlaintextPorts", msg) < 0)
3060 return -1;
3062 if (validate_ports_csv(options->WarnPlaintextPorts,
3063 "WarnPlaintextPorts", msg) < 0)
3064 return -1;
3066 if (options->FascistFirewall && !options->ReachableAddresses) {
3067 if (options->FirewallPorts && smartlist_len(options->FirewallPorts)) {
3068 /* We already have firewall ports set, so migrate them to
3069 * ReachableAddresses, which will set ReachableORAddresses and
3070 * ReachableDirAddresses if they aren't set explicitly. */
3071 smartlist_t *instead = smartlist_create();
3072 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3073 new_line->key = tor_strdup("ReachableAddresses");
3074 /* If we're configured with the old format, we need to prepend some
3075 * open ports. */
3076 SMARTLIST_FOREACH(options->FirewallPorts, const char *, portno,
3078 int p = atoi(portno);
3079 char *s;
3080 if (p<0) continue;
3081 s = tor_malloc(16);
3082 tor_snprintf(s, 16, "*:%d", p);
3083 smartlist_add(instead, s);
3085 new_line->value = smartlist_join_strings(instead,",",0,NULL);
3086 /* These have been deprecated since 0.1.1.5-alpha-cvs */
3087 log(LOG_NOTICE, LD_CONFIG,
3088 "Converting FascistFirewall and FirewallPorts "
3089 "config options to new format: \"ReachableAddresses %s\"",
3090 new_line->value);
3091 options->ReachableAddresses = new_line;
3092 SMARTLIST_FOREACH(instead, char *, cp, tor_free(cp));
3093 smartlist_free(instead);
3094 } else {
3095 /* We do not have FirewallPorts set, so add 80 to
3096 * ReachableDirAddresses, and 443 to ReachableORAddresses. */
3097 if (!options->ReachableDirAddresses) {
3098 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3099 new_line->key = tor_strdup("ReachableDirAddresses");
3100 new_line->value = tor_strdup("*:80");
3101 options->ReachableDirAddresses = new_line;
3102 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
3103 "to new format: \"ReachableDirAddresses *:80\"");
3105 if (!options->ReachableORAddresses) {
3106 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3107 new_line->key = tor_strdup("ReachableORAddresses");
3108 new_line->value = tor_strdup("*:443");
3109 options->ReachableORAddresses = new_line;
3110 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
3111 "to new format: \"ReachableORAddresses *:443\"");
3116 for (i=0; i<3; i++) {
3117 config_line_t **linep =
3118 (i==0) ? &options->ReachableAddresses :
3119 (i==1) ? &options->ReachableORAddresses :
3120 &options->ReachableDirAddresses;
3121 if (!*linep)
3122 continue;
3123 /* We need to end with a reject *:*, not an implicit accept *:* */
3124 for (;;) {
3125 if (!strcmp((*linep)->value, "reject *:*")) /* already there */
3126 break;
3127 linep = &((*linep)->next);
3128 if (!*linep) {
3129 *linep = tor_malloc_zero(sizeof(config_line_t));
3130 (*linep)->key = tor_strdup(
3131 (i==0) ? "ReachableAddresses" :
3132 (i==1) ? "ReachableORAddresses" :
3133 "ReachableDirAddresses");
3134 (*linep)->value = tor_strdup("reject *:*");
3135 break;
3140 if ((options->ReachableAddresses ||
3141 options->ReachableORAddresses ||
3142 options->ReachableDirAddresses) &&
3143 server_mode(options))
3144 REJECT("Servers must be able to freely connect to the rest "
3145 "of the Internet, so they must not set Reachable*Addresses "
3146 "or FascistFirewall.");
3148 if (options->UseBridges &&
3149 server_mode(options))
3150 REJECT("Servers must be able to freely connect to the rest "
3151 "of the Internet, so they must not set UseBridges.");
3153 options->_AllowInvalid = 0;
3154 if (options->AllowInvalidNodes) {
3155 SMARTLIST_FOREACH(options->AllowInvalidNodes, const char *, cp, {
3156 if (!strcasecmp(cp, "entry"))
3157 options->_AllowInvalid |= ALLOW_INVALID_ENTRY;
3158 else if (!strcasecmp(cp, "exit"))
3159 options->_AllowInvalid |= ALLOW_INVALID_EXIT;
3160 else if (!strcasecmp(cp, "middle"))
3161 options->_AllowInvalid |= ALLOW_INVALID_MIDDLE;
3162 else if (!strcasecmp(cp, "introduction"))
3163 options->_AllowInvalid |= ALLOW_INVALID_INTRODUCTION;
3164 else if (!strcasecmp(cp, "rendezvous"))
3165 options->_AllowInvalid |= ALLOW_INVALID_RENDEZVOUS;
3166 else {
3167 tor_asprintf(msg,
3168 "Unrecognized value '%s' in AllowInvalidNodes", cp);
3169 return -1;
3174 if (!options->SafeLogging ||
3175 !strcasecmp(options->SafeLogging, "0")) {
3176 options->_SafeLogging = SAFELOG_SCRUB_NONE;
3177 } else if (!strcasecmp(options->SafeLogging, "relay")) {
3178 options->_SafeLogging = SAFELOG_SCRUB_RELAY;
3179 } else if (!strcasecmp(options->SafeLogging, "1")) {
3180 options->_SafeLogging = SAFELOG_SCRUB_ALL;
3181 } else {
3182 tor_asprintf(msg,
3183 "Unrecognized value '%s' in SafeLogging",
3184 escaped(options->SafeLogging));
3185 return -1;
3188 if (compute_publishserverdescriptor(options) < 0) {
3189 tor_asprintf(msg, "Unrecognized value in PublishServerDescriptor");
3190 return -1;
3193 if ((options->BridgeRelay
3194 || options->_PublishServerDescriptor & BRIDGE_AUTHORITY)
3195 && (options->_PublishServerDescriptor
3196 & (V1_AUTHORITY|V2_AUTHORITY|V3_AUTHORITY))) {
3197 REJECT("Bridges are not supposed to publish router descriptors to the "
3198 "directory authorities. Please correct your "
3199 "PublishServerDescriptor line.");
3202 if (options->MinUptimeHidServDirectoryV2 < 0) {
3203 log_warn(LD_CONFIG, "MinUptimeHidServDirectoryV2 option must be at "
3204 "least 0 seconds. Changing to 0.");
3205 options->MinUptimeHidServDirectoryV2 = 0;
3208 if (options->RendPostPeriod < MIN_REND_POST_PERIOD) {
3209 log_warn(LD_CONFIG, "RendPostPeriod option is too short; "
3210 "raising to %d seconds.", MIN_REND_POST_PERIOD);
3211 options->RendPostPeriod = MIN_REND_POST_PERIOD;
3214 if (options->RendPostPeriod > MAX_DIR_PERIOD) {
3215 log_warn(LD_CONFIG, "RendPostPeriod is too large; clipping to %ds.",
3216 MAX_DIR_PERIOD);
3217 options->RendPostPeriod = MAX_DIR_PERIOD;
3220 if (options->MaxCircuitDirtiness < MIN_MAX_CIRCUIT_DIRTINESS) {
3221 log_warn(LD_CONFIG, "MaxCircuitDirtiness option is too short; "
3222 "raising to %d seconds.", MIN_MAX_CIRCUIT_DIRTINESS);
3223 options->MaxCircuitDirtiness = MIN_MAX_CIRCUIT_DIRTINESS;
3226 if (options->CircuitStreamTimeout &&
3227 options->CircuitStreamTimeout < MIN_CIRCUIT_STREAM_TIMEOUT) {
3228 log_warn(LD_CONFIG, "CircuitStreamTimeout option is too short; "
3229 "raising to %d seconds.", MIN_CIRCUIT_STREAM_TIMEOUT);
3230 options->CircuitStreamTimeout = MIN_CIRCUIT_STREAM_TIMEOUT;
3233 if (options->KeepalivePeriod < 1)
3234 REJECT("KeepalivePeriod option must be positive.");
3236 if (ensure_bandwidth_cap(&options->BandwidthRate,
3237 "BandwidthRate", msg) < 0)
3238 return -1;
3239 if (ensure_bandwidth_cap(&options->BandwidthBurst,
3240 "BandwidthBurst", msg) < 0)
3241 return -1;
3242 if (ensure_bandwidth_cap(&options->MaxAdvertisedBandwidth,
3243 "MaxAdvertisedBandwidth", msg) < 0)
3244 return -1;
3245 if (ensure_bandwidth_cap(&options->RelayBandwidthRate,
3246 "RelayBandwidthRate", msg) < 0)
3247 return -1;
3248 if (ensure_bandwidth_cap(&options->RelayBandwidthBurst,
3249 "RelayBandwidthBurst", msg) < 0)
3250 return -1;
3251 if (ensure_bandwidth_cap(&options->PerConnBWRate,
3252 "PerConnBWRate", msg) < 0)
3253 return -1;
3254 if (ensure_bandwidth_cap(&options->PerConnBWBurst,
3255 "PerConnBWBurst", msg) < 0)
3256 return -1;
3258 if (server_mode(options)) {
3259 if (options->BandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
3260 tor_asprintf(msg,
3261 "BandwidthRate is set to %d bytes/second. "
3262 "For servers, it must be at least %d.",
3263 (int)options->BandwidthRate,
3264 ROUTER_REQUIRED_MIN_BANDWIDTH);
3265 return -1;
3266 } else if (options->MaxAdvertisedBandwidth <
3267 ROUTER_REQUIRED_MIN_BANDWIDTH/2) {
3268 tor_asprintf(msg,
3269 "MaxAdvertisedBandwidth is set to %d bytes/second. "
3270 "For servers, it must be at least %d.",
3271 (int)options->MaxAdvertisedBandwidth,
3272 ROUTER_REQUIRED_MIN_BANDWIDTH/2);
3273 return -1;
3275 if (options->RelayBandwidthRate &&
3276 options->RelayBandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
3277 tor_asprintf(msg,
3278 "RelayBandwidthRate is set to %d bytes/second. "
3279 "For servers, it must be at least %d.",
3280 (int)options->RelayBandwidthRate,
3281 ROUTER_REQUIRED_MIN_BANDWIDTH);
3282 return -1;
3286 if (options->RelayBandwidthRate && !options->RelayBandwidthBurst)
3287 options->RelayBandwidthBurst = options->RelayBandwidthRate;
3289 if (options->RelayBandwidthRate > options->RelayBandwidthBurst)
3290 REJECT("RelayBandwidthBurst must be at least equal "
3291 "to RelayBandwidthRate.");
3293 if (options->BandwidthRate > options->BandwidthBurst)
3294 REJECT("BandwidthBurst must be at least equal to BandwidthRate.");
3296 /* if they set relaybandwidth* really high but left bandwidth*
3297 * at the default, raise the defaults. */
3298 if (options->RelayBandwidthRate > options->BandwidthRate)
3299 options->BandwidthRate = options->RelayBandwidthRate;
3300 if (options->RelayBandwidthBurst > options->BandwidthBurst)
3301 options->BandwidthBurst = options->RelayBandwidthBurst;
3303 if (accounting_parse_options(options, 1)<0)
3304 REJECT("Failed to parse accounting options. See logs for details.");
3306 if (options->HttpProxy) { /* parse it now */
3307 if (tor_addr_port_parse(options->HttpProxy,
3308 &options->HttpProxyAddr, &options->HttpProxyPort) < 0)
3309 REJECT("HttpProxy failed to parse or resolve. Please fix.");
3310 if (options->HttpProxyPort == 0) { /* give it a default */
3311 options->HttpProxyPort = 80;
3315 if (options->HttpProxyAuthenticator) {
3316 if (strlen(options->HttpProxyAuthenticator) >= 48)
3317 REJECT("HttpProxyAuthenticator is too long (>= 48 chars).");
3320 if (options->HttpsProxy) { /* parse it now */
3321 if (tor_addr_port_parse(options->HttpsProxy,
3322 &options->HttpsProxyAddr, &options->HttpsProxyPort) <0)
3323 REJECT("HttpsProxy failed to parse or resolve. Please fix.");
3324 if (options->HttpsProxyPort == 0) { /* give it a default */
3325 options->HttpsProxyPort = 443;
3329 if (options->HttpsProxyAuthenticator) {
3330 if (strlen(options->HttpsProxyAuthenticator) >= 48)
3331 REJECT("HttpsProxyAuthenticator is too long (>= 48 chars).");
3334 if (options->Socks4Proxy) { /* parse it now */
3335 if (tor_addr_port_parse(options->Socks4Proxy,
3336 &options->Socks4ProxyAddr,
3337 &options->Socks4ProxyPort) <0)
3338 REJECT("Socks4Proxy failed to parse or resolve. Please fix.");
3339 if (options->Socks4ProxyPort == 0) { /* give it a default */
3340 options->Socks4ProxyPort = 1080;
3344 if (options->Socks5Proxy) { /* parse it now */
3345 if (tor_addr_port_parse(options->Socks5Proxy,
3346 &options->Socks5ProxyAddr,
3347 &options->Socks5ProxyPort) <0)
3348 REJECT("Socks5Proxy failed to parse or resolve. Please fix.");
3349 if (options->Socks5ProxyPort == 0) { /* give it a default */
3350 options->Socks5ProxyPort = 1080;
3354 if (options->Socks4Proxy && options->Socks5Proxy)
3355 REJECT("You cannot specify both Socks4Proxy and SOCKS5Proxy");
3357 if (options->Socks5ProxyUsername) {
3358 size_t len;
3360 len = strlen(options->Socks5ProxyUsername);
3361 if (len < 1 || len > 255)
3362 REJECT("Socks5ProxyUsername must be between 1 and 255 characters.");
3364 if (!options->Socks5ProxyPassword)
3365 REJECT("Socks5ProxyPassword must be included with Socks5ProxyUsername.");
3367 len = strlen(options->Socks5ProxyPassword);
3368 if (len < 1 || len > 255)
3369 REJECT("Socks5ProxyPassword must be between 1 and 255 characters.");
3370 } else if (options->Socks5ProxyPassword)
3371 REJECT("Socks5ProxyPassword must be included with Socks5ProxyUsername.");
3373 if (options->HashedControlPassword) {
3374 smartlist_t *sl = decode_hashed_passwords(options->HashedControlPassword);
3375 if (!sl) {
3376 REJECT("Bad HashedControlPassword: wrong length or bad encoding");
3377 } else {
3378 SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
3379 smartlist_free(sl);
3383 if (options->HashedControlSessionPassword) {
3384 smartlist_t *sl = decode_hashed_passwords(
3385 options->HashedControlSessionPassword);
3386 if (!sl) {
3387 REJECT("Bad HashedControlSessionPassword: wrong length or bad encoding");
3388 } else {
3389 SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
3390 smartlist_free(sl);
3394 if (options->ControlListenAddress) {
3395 int all_are_local = 1;
3396 config_line_t *ln;
3397 for (ln = options->ControlListenAddress; ln; ln = ln->next) {
3398 if (strcmpstart(ln->value, "127."))
3399 all_are_local = 0;
3401 if (!all_are_local) {
3402 if (!options->HashedControlPassword &&
3403 !options->HashedControlSessionPassword &&
3404 !options->CookieAuthentication) {
3405 log_warn(LD_CONFIG,
3406 "You have a ControlListenAddress set to accept "
3407 "unauthenticated connections from a non-local address. "
3408 "This means that programs not running on your computer "
3409 "can reconfigure your Tor, without even having to guess a "
3410 "password. That's so bad that I'm closing your ControlPort "
3411 "for you. If you need to control your Tor remotely, try "
3412 "enabling authentication and using a tool like stunnel or "
3413 "ssh to encrypt remote access.");
3414 options->ControlPort = 0;
3415 } else {
3416 log_warn(LD_CONFIG, "You have a ControlListenAddress set to accept "
3417 "connections from a non-local address. This means that "
3418 "programs not running on your computer can reconfigure your "
3419 "Tor. That's pretty bad, since the controller "
3420 "protocol isn't encrypted! Maybe you should just listen on "
3421 "127.0.0.1 and use a tool like stunnel or ssh to encrypt "
3422 "remote connections to your control port.");
3427 if (options->ControlPort && !options->HashedControlPassword &&
3428 !options->HashedControlSessionPassword &&
3429 !options->CookieAuthentication) {
3430 log_warn(LD_CONFIG, "ControlPort is open, but no authentication method "
3431 "has been configured. This means that any program on your "
3432 "computer can reconfigure your Tor. That's bad! You should "
3433 "upgrade your Tor controller as soon as possible.");
3436 if (options->UseEntryGuards && ! options->NumEntryGuards)
3437 REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0");
3439 if (check_nickname_list(options->MyFamily, "MyFamily", msg))
3440 return -1;
3441 for (cl = options->NodeFamilies; cl; cl = cl->next) {
3442 if (check_nickname_list(cl->value, "NodeFamily", msg))
3443 return -1;
3446 if (validate_addr_policies(options, msg) < 0)
3447 return -1;
3449 if (validate_dir_authorities(options, old_options) < 0)
3450 REJECT("Directory authority line did not parse. See logs for details.");
3452 if (options->UseBridges && !options->Bridges)
3453 REJECT("If you set UseBridges, you must specify at least one bridge.");
3454 if (options->UseBridges && !options->TunnelDirConns)
3455 REJECT("If you set UseBridges, you must set TunnelDirConns.");
3456 if (options->Bridges) {
3457 for (cl = options->Bridges; cl; cl = cl->next) {
3458 if (parse_bridge_line(cl->value, 1)<0)
3459 REJECT("Bridge line did not parse. See logs for details.");
3463 if (options->ConstrainedSockets) {
3464 /* If the user wants to constrain socket buffer use, make sure the desired
3465 * limit is between MIN|MAX_TCPSOCK_BUFFER in k increments. */
3466 if (options->ConstrainedSockSize < MIN_CONSTRAINED_TCP_BUFFER ||
3467 options->ConstrainedSockSize > MAX_CONSTRAINED_TCP_BUFFER ||
3468 options->ConstrainedSockSize % 1024) {
3469 tor_asprintf(msg,
3470 "ConstrainedSockSize is invalid. Must be a value between %d and %d "
3471 "in 1024 byte increments.",
3472 MIN_CONSTRAINED_TCP_BUFFER, MAX_CONSTRAINED_TCP_BUFFER);
3473 return -1;
3475 if (options->DirPort) {
3476 /* Providing cached directory entries while system TCP buffers are scarce
3477 * will exacerbate the socket errors. Suggest that this be disabled. */
3478 COMPLAIN("You have requested constrained socket buffers while also "
3479 "serving directory entries via DirPort. It is strongly "
3480 "suggested that you disable serving directory requests when "
3481 "system TCP buffer resources are scarce.");
3485 if (options->V3AuthVoteDelay + options->V3AuthDistDelay >=
3486 options->V3AuthVotingInterval/2) {
3487 REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than half "
3488 "V3AuthVotingInterval");
3490 if (options->V3AuthVoteDelay < MIN_VOTE_SECONDS)
3491 REJECT("V3AuthVoteDelay is way too low.");
3492 if (options->V3AuthDistDelay < MIN_DIST_SECONDS)
3493 REJECT("V3AuthDistDelay is way too low.");
3495 if (options->V3AuthNIntervalsValid < 2)
3496 REJECT("V3AuthNIntervalsValid must be at least 2.");
3498 if (options->V3AuthVotingInterval < MIN_VOTE_INTERVAL) {
3499 REJECT("V3AuthVotingInterval is insanely low.");
3500 } else if (options->V3AuthVotingInterval > 24*60*60) {
3501 REJECT("V3AuthVotingInterval is insanely high.");
3502 } else if (((24*60*60) % options->V3AuthVotingInterval) != 0) {
3503 COMPLAIN("V3AuthVotingInterval does not divide evenly into 24 hours.");
3506 if (rend_config_services(options, 1) < 0)
3507 REJECT("Failed to configure rendezvous options. See logs for details.");
3509 /* Parse client-side authorization for hidden services. */
3510 if (rend_parse_service_authorization(options, 1) < 0)
3511 REJECT("Failed to configure client authorization for hidden services. "
3512 "See logs for details.");
3514 if (parse_virtual_addr_network(options->VirtualAddrNetwork, 1, NULL)<0)
3515 return -1;
3517 if (options->PreferTunneledDirConns && !options->TunnelDirConns)
3518 REJECT("Must set TunnelDirConns if PreferTunneledDirConns is set.");
3520 if ((options->Socks4Proxy || options->Socks5Proxy) &&
3521 !options->HttpProxy && !options->PreferTunneledDirConns)
3522 REJECT("When Socks4Proxy or Socks5Proxy is configured, "
3523 "PreferTunneledDirConns and TunnelDirConns must both be "
3524 "set to 1, or HttpProxy must be configured.");
3526 if (options->AutomapHostsSuffixes) {
3527 SMARTLIST_FOREACH(options->AutomapHostsSuffixes, char *, suf,
3529 size_t len = strlen(suf);
3530 if (len && suf[len-1] == '.')
3531 suf[len-1] = '\0';
3535 if (options->TestingTorNetwork && !options->DirServers) {
3536 REJECT("TestingTorNetwork may only be configured in combination with "
3537 "a non-default set of DirServers.");
3540 /*XXXX022 checking for defaults manually like this is a bit fragile.*/
3542 /* Keep changes to hard-coded values synchronous to man page and default
3543 * values table. */
3544 if (options->TestingV3AuthInitialVotingInterval != 30*60 &&
3545 !options->TestingTorNetwork) {
3546 REJECT("TestingV3AuthInitialVotingInterval may only be changed in testing "
3547 "Tor networks!");
3548 } else if (options->TestingV3AuthInitialVotingInterval < MIN_VOTE_INTERVAL) {
3549 REJECT("TestingV3AuthInitialVotingInterval is insanely low.");
3550 } else if (((30*60) % options->TestingV3AuthInitialVotingInterval) != 0) {
3551 REJECT("TestingV3AuthInitialVotingInterval does not divide evenly into "
3552 "30 minutes.");
3555 if (options->TestingV3AuthInitialVoteDelay != 5*60 &&
3556 !options->TestingTorNetwork) {
3557 REJECT("TestingV3AuthInitialVoteDelay may only be changed in testing "
3558 "Tor networks!");
3559 } else if (options->TestingV3AuthInitialVoteDelay < MIN_VOTE_SECONDS) {
3560 REJECT("TestingV3AuthInitialVoteDelay is way too low.");
3563 if (options->TestingV3AuthInitialDistDelay != 5*60 &&
3564 !options->TestingTorNetwork) {
3565 REJECT("TestingV3AuthInitialDistDelay may only be changed in testing "
3566 "Tor networks!");
3567 } else if (options->TestingV3AuthInitialDistDelay < MIN_DIST_SECONDS) {
3568 REJECT("TestingV3AuthInitialDistDelay is way too low.");
3571 if (options->TestingV3AuthInitialVoteDelay +
3572 options->TestingV3AuthInitialDistDelay >=
3573 options->TestingV3AuthInitialVotingInterval/2) {
3574 REJECT("TestingV3AuthInitialVoteDelay plus TestingV3AuthInitialDistDelay "
3575 "must be less than half TestingV3AuthInitialVotingInterval");
3578 if (options->TestingAuthDirTimeToLearnReachability != 30*60 &&
3579 !options->TestingTorNetwork) {
3580 REJECT("TestingAuthDirTimeToLearnReachability may only be changed in "
3581 "testing Tor networks!");
3582 } else if (options->TestingAuthDirTimeToLearnReachability < 0) {
3583 REJECT("TestingAuthDirTimeToLearnReachability must be non-negative.");
3584 } else if (options->TestingAuthDirTimeToLearnReachability > 2*60*60) {
3585 COMPLAIN("TestingAuthDirTimeToLearnReachability is insanely high.");
3588 if (options->TestingEstimatedDescriptorPropagationTime != 10*60 &&
3589 !options->TestingTorNetwork) {
3590 REJECT("TestingEstimatedDescriptorPropagationTime may only be changed in "
3591 "testing Tor networks!");
3592 } else if (options->TestingEstimatedDescriptorPropagationTime < 0) {
3593 REJECT("TestingEstimatedDescriptorPropagationTime must be non-negative.");
3594 } else if (options->TestingEstimatedDescriptorPropagationTime > 60*60) {
3595 COMPLAIN("TestingEstimatedDescriptorPropagationTime is insanely high.");
3598 if (options->TestingTorNetwork) {
3599 log_warn(LD_CONFIG, "TestingTorNetwork is set. This will make your node "
3600 "almost unusable in the public Tor network, and is "
3601 "therefore only advised if you are building a "
3602 "testing Tor network!");
3605 if (options->AccelName && !options->HardwareAccel)
3606 options->HardwareAccel = 1;
3607 if (options->AccelDir && !options->AccelName)
3608 REJECT("Can't use hardware crypto accelerator dir without engine name.");
3610 return 0;
3611 #undef REJECT
3612 #undef COMPLAIN
3615 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
3616 * equal strings. */
3617 static int
3618 opt_streq(const char *s1, const char *s2)
3620 if (!s1 && !s2)
3621 return 1;
3622 else if (s1 && s2 && !strcmp(s1,s2))
3623 return 1;
3624 else
3625 return 0;
3628 /** Check if any of the previous options have changed but aren't allowed to. */
3629 static int
3630 options_transition_allowed(or_options_t *old, or_options_t *new_val,
3631 char **msg)
3633 if (!old)
3634 return 0;
3636 if (!opt_streq(old->PidFile, new_val->PidFile)) {
3637 *msg = tor_strdup("PidFile is not allowed to change.");
3638 return -1;
3641 if (old->RunAsDaemon != new_val->RunAsDaemon) {
3642 *msg = tor_strdup("While Tor is running, changing RunAsDaemon "
3643 "is not allowed.");
3644 return -1;
3647 if (strcmp(old->DataDirectory,new_val->DataDirectory)!=0) {
3648 tor_asprintf(msg,
3649 "While Tor is running, changing DataDirectory "
3650 "(\"%s\"->\"%s\") is not allowed.",
3651 old->DataDirectory, new_val->DataDirectory);
3652 return -1;
3655 if (!opt_streq(old->User, new_val->User)) {
3656 *msg = tor_strdup("While Tor is running, changing User is not allowed.");
3657 return -1;
3660 if ((old->HardwareAccel != new_val->HardwareAccel)
3661 || !opt_streq(old->AccelName, new_val->AccelName)
3662 || !opt_streq(old->AccelDir, new_val->AccelDir)) {
3663 *msg = tor_strdup("While Tor is running, changing OpenSSL hardware "
3664 "acceleration engine is not allowed.");
3665 return -1;
3668 if (old->TestingTorNetwork != new_val->TestingTorNetwork) {
3669 *msg = tor_strdup("While Tor is running, changing TestingTorNetwork "
3670 "is not allowed.");
3671 return -1;
3674 if (old->CellStatistics != new_val->CellStatistics ||
3675 old->DirReqStatistics != new_val->DirReqStatistics ||
3676 old->EntryStatistics != new_val->EntryStatistics ||
3677 old->ExitPortStatistics != new_val->ExitPortStatistics) {
3678 *msg = tor_strdup("While Tor is running, changing either "
3679 "CellStatistics, DirReqStatistics, EntryStatistics, "
3680 "or ExitPortStatistics is not allowed.");
3681 return -1;
3684 if (old->DisableAllSwap != new_val->DisableAllSwap) {
3685 *msg = tor_strdup("While Tor is running, changing DisableAllSwap "
3686 "is not allowed.");
3687 return -1;
3690 return 0;
3693 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
3694 * will require us to rotate the CPU and DNS workers; else return 0. */
3695 static int
3696 options_transition_affects_workers(or_options_t *old_options,
3697 or_options_t *new_options)
3699 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
3700 old_options->NumCpus != new_options->NumCpus ||
3701 old_options->ORPort != new_options->ORPort ||
3702 old_options->ServerDNSSearchDomains !=
3703 new_options->ServerDNSSearchDomains ||
3704 old_options->SafeLogging != new_options->SafeLogging ||
3705 old_options->ClientOnly != new_options->ClientOnly ||
3706 !config_lines_eq(old_options->Logs, new_options->Logs))
3707 return 1;
3709 /* Check whether log options match. */
3711 /* Nothing that changed matters. */
3712 return 0;
3715 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
3716 * will require us to generate a new descriptor; else return 0. */
3717 static int
3718 options_transition_affects_descriptor(or_options_t *old_options,
3719 or_options_t *new_options)
3721 /* XXX We can be smarter here. If your DirPort isn't being
3722 * published and you just turned it off, no need to republish. Etc. */
3723 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
3724 !opt_streq(old_options->Nickname,new_options->Nickname) ||
3725 !opt_streq(old_options->Address,new_options->Address) ||
3726 !config_lines_eq(old_options->ExitPolicy,new_options->ExitPolicy) ||
3727 old_options->ExitPolicyRejectPrivate !=
3728 new_options->ExitPolicyRejectPrivate ||
3729 old_options->ORPort != new_options->ORPort ||
3730 old_options->DirPort != new_options->DirPort ||
3731 old_options->ClientOnly != new_options->ClientOnly ||
3732 old_options->NoPublish != new_options->NoPublish ||
3733 old_options->_PublishServerDescriptor !=
3734 new_options->_PublishServerDescriptor ||
3735 get_effective_bwrate(old_options) != get_effective_bwrate(new_options) ||
3736 get_effective_bwburst(old_options) !=
3737 get_effective_bwburst(new_options) ||
3738 !opt_streq(old_options->ContactInfo, new_options->ContactInfo) ||
3739 !opt_streq(old_options->MyFamily, new_options->MyFamily) ||
3740 !opt_streq(old_options->AccountingStart, new_options->AccountingStart) ||
3741 old_options->AccountingMax != new_options->AccountingMax)
3742 return 1;
3744 return 0;
3747 #ifdef MS_WINDOWS
3748 /** Return the directory on windows where we expect to find our application
3749 * data. */
3750 static char *
3751 get_windows_conf_root(void)
3753 static int is_set = 0;
3754 static char path[MAX_PATH+1];
3755 WCHAR wpath[MAX_PATH] = {0};
3757 LPITEMIDLIST idl;
3758 IMalloc *m;
3759 HRESULT result;
3761 if (is_set)
3762 return path;
3764 /* Find X:\documents and settings\username\application data\ .
3765 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
3767 #ifdef ENABLE_LOCAL_APPDATA
3768 #define APPDATA_PATH CSIDL_LOCAL_APPDATA
3769 #else
3770 #define APPDATA_PATH CSIDL_APPDATA
3771 #endif
3772 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, APPDATA_PATH, &idl))) {
3773 getcwd(path,MAX_PATH);
3774 is_set = 1;
3775 log_warn(LD_CONFIG,
3776 "I couldn't find your application data folder: are you "
3777 "running an ancient version of Windows 95? Defaulting to \"%s\"",
3778 path);
3779 return path;
3781 /* Convert the path from an "ID List" (whatever that is!) to a path. */
3782 result = SHGetPathFromIDListW(idl, wpath);
3783 wcstombs(path,wpath,MAX_PATH);
3785 /* Now we need to free the memory that the path-idl was stored in. In
3786 * typical Windows fashion, we can't just call 'free()' on it. */
3787 SHGetMalloc(&m);
3788 if (m) {
3789 m->lpVtbl->Free(m, idl);
3790 m->lpVtbl->Release(m);
3792 if (!SUCCEEDED(result)) {
3793 return NULL;
3795 strlcat(path,"\\tor",MAX_PATH);
3796 is_set = 1;
3797 return path;
3799 #endif
3801 /** Return the default location for our torrc file. */
3802 static const char *
3803 get_default_conf_file(void)
3805 #ifdef MS_WINDOWS
3806 static char path[MAX_PATH+1];
3807 strlcpy(path, get_windows_conf_root(), MAX_PATH);
3808 strlcat(path,"\\torrc",MAX_PATH);
3809 return path;
3810 #else
3811 return (CONFDIR "/torrc");
3812 #endif
3815 /** Verify whether lst is a string containing valid-looking comma-separated
3816 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
3818 static int
3819 check_nickname_list(const char *lst, const char *name, char **msg)
3821 int r = 0;
3822 smartlist_t *sl;
3824 if (!lst)
3825 return 0;
3826 sl = smartlist_create();
3828 smartlist_split_string(sl, lst, ",",
3829 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0);
3831 SMARTLIST_FOREACH(sl, const char *, s,
3833 if (!is_legal_nickname_or_hexdigest(s)) {
3834 tor_asprintf(msg, "Invalid nickname '%s' in %s line", s, name);
3835 r = -1;
3836 break;
3839 SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
3840 smartlist_free(sl);
3841 return r;
3844 /** Learn config file name from command line arguments, or use the default */
3845 static char *
3846 find_torrc_filename(int argc, char **argv,
3847 int *using_default_torrc, int *ignore_missing_torrc)
3849 char *fname=NULL;
3850 int i;
3852 for (i = 1; i < argc; ++i) {
3853 if (i < argc-1 && !strcmp(argv[i],"-f")) {
3854 if (fname) {
3855 log(LOG_WARN, LD_CONFIG, "Duplicate -f options on command line.");
3856 tor_free(fname);
3858 fname = expand_filename(argv[i+1]);
3859 *using_default_torrc = 0;
3860 ++i;
3861 } else if (!strcmp(argv[i],"--ignore-missing-torrc")) {
3862 *ignore_missing_torrc = 1;
3866 if (*using_default_torrc) {
3867 /* didn't find one, try CONFDIR */
3868 const char *dflt = get_default_conf_file();
3869 if (dflt && file_status(dflt) == FN_FILE) {
3870 fname = tor_strdup(dflt);
3871 } else {
3872 #ifndef MS_WINDOWS
3873 char *fn;
3874 fn = expand_filename("~/.torrc");
3875 if (fn && file_status(fn) == FN_FILE) {
3876 fname = fn;
3877 } else {
3878 tor_free(fn);
3879 fname = tor_strdup(dflt);
3881 #else
3882 fname = tor_strdup(dflt);
3883 #endif
3886 return fname;
3889 /** Load torrc from disk, setting torrc_fname if successful */
3890 static char *
3891 load_torrc_from_disk(int argc, char **argv)
3893 char *fname=NULL;
3894 char *cf = NULL;
3895 int using_default_torrc = 1;
3896 int ignore_missing_torrc = 0;
3898 fname = find_torrc_filename(argc, argv,
3899 &using_default_torrc, &ignore_missing_torrc);
3900 tor_assert(fname);
3901 log(LOG_DEBUG, LD_CONFIG, "Opening config file \"%s\"", fname);
3903 tor_free(torrc_fname);
3904 torrc_fname = fname;
3906 /* Open config file */
3907 if (file_status(fname) != FN_FILE ||
3908 !(cf = read_file_to_str(fname,0,NULL))) {
3909 if (using_default_torrc == 1 || ignore_missing_torrc ) {
3910 log(LOG_NOTICE, LD_CONFIG, "Configuration file \"%s\" not present, "
3911 "using reasonable defaults.", fname);
3912 tor_free(fname); /* sets fname to NULL */
3913 torrc_fname = NULL;
3914 cf = tor_strdup("");
3915 } else {
3916 log(LOG_WARN, LD_CONFIG,
3917 "Unable to open configuration file \"%s\".", fname);
3918 goto err;
3922 return cf;
3923 err:
3924 tor_free(fname);
3925 torrc_fname = NULL;
3926 return NULL;
3929 /** Read a configuration file into <b>options</b>, finding the configuration
3930 * file location based on the command line. After loading the file
3931 * call options_init_from_string() to load the config.
3932 * Return 0 if success, -1 if failure. */
3934 options_init_from_torrc(int argc, char **argv)
3936 char *cf=NULL;
3937 int i, retval, command;
3938 static char **backup_argv;
3939 static int backup_argc;
3940 char *command_arg = NULL;
3941 char *errmsg=NULL;
3943 if (argv) { /* first time we're called. save command line args */
3944 backup_argv = argv;
3945 backup_argc = argc;
3946 } else { /* we're reloading. need to clean up old options first. */
3947 argv = backup_argv;
3948 argc = backup_argc;
3950 if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
3951 print_usage();
3952 exit(0);
3954 if (argc > 1 && !strcmp(argv[1], "--list-torrc-options")) {
3955 /* For documenting validating whether we've documented everything. */
3956 list_torrc_options();
3957 exit(0);
3960 if (argc > 1 && (!strcmp(argv[1],"--version"))) {
3961 printf("Tor version %s.\n",get_version());
3962 exit(0);
3964 if (argc > 1 && (!strcmp(argv[1],"--digests"))) {
3965 printf("Tor version %s.\n",get_version());
3966 printf("%s", libor_get_digests());
3967 printf("%s", tor_get_digests());
3968 exit(0);
3971 /* Go through command-line variables */
3972 if (!global_cmdline_options) {
3973 /* Or we could redo the list every time we pass this place.
3974 * It does not really matter */
3975 if (config_get_commandlines(argc, argv, &global_cmdline_options) < 0) {
3976 goto err;
3980 command = CMD_RUN_TOR;
3981 for (i = 1; i < argc; ++i) {
3982 if (!strcmp(argv[i],"--list-fingerprint")) {
3983 command = CMD_LIST_FINGERPRINT;
3984 } else if (!strcmp(argv[i],"--hash-password")) {
3985 command = CMD_HASH_PASSWORD;
3986 command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : "");
3987 ++i;
3988 } else if (!strcmp(argv[i],"--verify-config")) {
3989 command = CMD_VERIFY_CONFIG;
3993 if (command == CMD_HASH_PASSWORD) {
3994 cf = tor_strdup("");
3995 } else {
3996 cf = load_torrc_from_disk(argc, argv);
3997 if (!cf)
3998 goto err;
4001 retval = options_init_from_string(cf, command, command_arg, &errmsg);
4002 tor_free(cf);
4003 if (retval < 0)
4004 goto err;
4006 return 0;
4008 err:
4009 if (errmsg) {
4010 log(LOG_WARN,LD_CONFIG,"%s", errmsg);
4011 tor_free(errmsg);
4013 return -1;
4016 /** Load the options from the configuration in <b>cf</b>, validate
4017 * them for consistency and take actions based on them.
4019 * Return 0 if success, negative on error:
4020 * * -1 for general errors.
4021 * * -2 for failure to parse/validate,
4022 * * -3 for transition not allowed
4023 * * -4 for error while setting the new options
4025 setopt_err_t
4026 options_init_from_string(const char *cf,
4027 int command, const char *command_arg,
4028 char **msg)
4030 or_options_t *oldoptions, *newoptions;
4031 config_line_t *cl;
4032 int retval;
4033 setopt_err_t err = SETOPT_ERR_MISC;
4034 tor_assert(msg);
4036 oldoptions = global_options; /* get_options unfortunately asserts if
4037 this is the first time we run*/
4039 newoptions = tor_malloc_zero(sizeof(or_options_t));
4040 newoptions->_magic = OR_OPTIONS_MAGIC;
4041 options_init(newoptions);
4042 newoptions->command = command;
4043 newoptions->command_arg = command_arg;
4045 /* get config lines, assign them */
4046 retval = config_get_lines(cf, &cl);
4047 if (retval < 0) {
4048 err = SETOPT_ERR_PARSE;
4049 goto err;
4051 retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
4052 config_free_lines(cl);
4053 if (retval < 0) {
4054 err = SETOPT_ERR_PARSE;
4055 goto err;
4058 /* Go through command-line variables too */
4059 retval = config_assign(&options_format, newoptions,
4060 global_cmdline_options, 0, 0, msg);
4061 if (retval < 0) {
4062 err = SETOPT_ERR_PARSE;
4063 goto err;
4066 /* If this is a testing network configuration, change defaults
4067 * for a list of dependent config options, re-initialize newoptions
4068 * with the new defaults, and assign all options to it second time. */
4069 if (newoptions->TestingTorNetwork) {
4070 /* XXXX this is a bit of a kludge. perhaps there's a better way to do
4071 * this? We could, for example, make the parsing algorithm do two passes
4072 * over the configuration. If it finds any "suite" options like
4073 * TestingTorNetwork, it could change the defaults before its second pass.
4074 * Not urgent so long as this seems to work, but at any sign of trouble,
4075 * let's clean it up. -NM */
4077 /* Change defaults. */
4078 int i;
4079 for (i = 0; testing_tor_network_defaults[i].name; ++i) {
4080 config_var_t *new_var = &testing_tor_network_defaults[i];
4081 config_var_t *old_var =
4082 config_find_option(&options_format, new_var->name);
4083 tor_assert(new_var);
4084 tor_assert(old_var);
4085 old_var->initvalue = new_var->initvalue;
4088 /* Clear newoptions and re-initialize them with new defaults. */
4089 config_free(&options_format, newoptions);
4090 newoptions = tor_malloc_zero(sizeof(or_options_t));
4091 newoptions->_magic = OR_OPTIONS_MAGIC;
4092 options_init(newoptions);
4093 newoptions->command = command;
4094 newoptions->command_arg = command_arg;
4096 /* Assign all options a second time. */
4097 retval = config_get_lines(cf, &cl);
4098 if (retval < 0) {
4099 err = SETOPT_ERR_PARSE;
4100 goto err;
4102 retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
4103 config_free_lines(cl);
4104 if (retval < 0) {
4105 err = SETOPT_ERR_PARSE;
4106 goto err;
4108 retval = config_assign(&options_format, newoptions,
4109 global_cmdline_options, 0, 0, msg);
4110 if (retval < 0) {
4111 err = SETOPT_ERR_PARSE;
4112 goto err;
4116 /* Validate newoptions */
4117 if (options_validate(oldoptions, newoptions, 0, msg) < 0) {
4118 err = SETOPT_ERR_PARSE; /*XXX make this a separate return value.*/
4119 goto err;
4122 if (options_transition_allowed(oldoptions, newoptions, msg) < 0) {
4123 err = SETOPT_ERR_TRANSITION;
4124 goto err;
4127 if (set_options(newoptions, msg)) {
4128 err = SETOPT_ERR_SETTING;
4129 goto err; /* frees and replaces old options */
4132 return SETOPT_OK;
4134 err:
4135 config_free(&options_format, newoptions);
4136 if (*msg) {
4137 char *old_msg = *msg;
4138 tor_asprintf(msg, "Failed to parse/validate config: %s", old_msg);
4139 tor_free(old_msg);
4141 return err;
4144 /** Return the location for our configuration file.
4146 const char *
4147 get_torrc_fname(void)
4149 if (torrc_fname)
4150 return torrc_fname;
4151 else
4152 return get_default_conf_file();
4155 /** Adjust the address map based on the MapAddress elements in the
4156 * configuration <b>options</b>
4158 static void
4159 config_register_addressmaps(or_options_t *options)
4161 smartlist_t *elts;
4162 config_line_t *opt;
4163 char *from, *to;
4165 addressmap_clear_configured();
4166 elts = smartlist_create();
4167 for (opt = options->AddressMap; opt; opt = opt->next) {
4168 smartlist_split_string(elts, opt->value, NULL,
4169 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
4170 if (smartlist_len(elts) >= 2) {
4171 from = smartlist_get(elts,0);
4172 to = smartlist_get(elts,1);
4173 if (address_is_invalid_destination(to, 1)) {
4174 log_warn(LD_CONFIG,
4175 "Skipping invalid argument '%s' to MapAddress", to);
4176 } else {
4177 addressmap_register(from, tor_strdup(to), 0, ADDRMAPSRC_TORRC);
4178 if (smartlist_len(elts)>2) {
4179 log_warn(LD_CONFIG,"Ignoring extra arguments to MapAddress.");
4182 } else {
4183 log_warn(LD_CONFIG,"MapAddress '%s' has too few arguments. Ignoring.",
4184 opt->value);
4186 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
4187 smartlist_clear(elts);
4189 smartlist_free(elts);
4193 * Initialize the logs based on the configuration file.
4195 static int
4196 options_init_logs(or_options_t *options, int validate_only)
4198 config_line_t *opt;
4199 int ok;
4200 smartlist_t *elts;
4201 int daemon =
4202 #ifdef MS_WINDOWS
4204 #else
4205 options->RunAsDaemon;
4206 #endif
4208 ok = 1;
4209 elts = smartlist_create();
4211 for (opt = options->Logs; opt; opt = opt->next) {
4212 log_severity_list_t *severity;
4213 const char *cfg = opt->value;
4214 severity = tor_malloc_zero(sizeof(log_severity_list_t));
4215 if (parse_log_severity_config(&cfg, severity) < 0) {
4216 log_warn(LD_CONFIG, "Couldn't parse log levels in Log option 'Log %s'",
4217 opt->value);
4218 ok = 0; goto cleanup;
4221 smartlist_split_string(elts, cfg, NULL,
4222 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
4224 if (smartlist_len(elts) == 0)
4225 smartlist_add(elts, tor_strdup("stdout"));
4227 if (smartlist_len(elts) == 1 &&
4228 (!strcasecmp(smartlist_get(elts,0), "stdout") ||
4229 !strcasecmp(smartlist_get(elts,0), "stderr"))) {
4230 int err = smartlist_len(elts) &&
4231 !strcasecmp(smartlist_get(elts,0), "stderr");
4232 if (!validate_only) {
4233 if (daemon) {
4234 log_warn(LD_CONFIG,
4235 "Can't log to %s with RunAsDaemon set; skipping stdout",
4236 err?"stderr":"stdout");
4237 } else {
4238 add_stream_log(severity, err?"<stderr>":"<stdout>",
4239 fileno(err?stderr:stdout));
4242 goto cleanup;
4244 if (smartlist_len(elts) == 1 &&
4245 !strcasecmp(smartlist_get(elts,0), "syslog")) {
4246 #ifdef HAVE_SYSLOG_H
4247 if (!validate_only) {
4248 add_syslog_log(severity);
4250 #else
4251 log_warn(LD_CONFIG, "Syslog is not supported on this system. Sorry.");
4252 #endif
4253 goto cleanup;
4256 if (smartlist_len(elts) == 2 &&
4257 !strcasecmp(smartlist_get(elts,0), "file")) {
4258 if (!validate_only) {
4259 if (add_file_log(severity, smartlist_get(elts, 1)) < 0) {
4260 log_warn(LD_CONFIG, "Couldn't open file for 'Log %s': %s",
4261 opt->value, strerror(errno));
4262 ok = 0;
4265 goto cleanup;
4268 log_warn(LD_CONFIG, "Bad syntax on file Log option 'Log %s'",
4269 opt->value);
4270 ok = 0; goto cleanup;
4272 cleanup:
4273 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
4274 smartlist_clear(elts);
4275 tor_free(severity);
4277 smartlist_free(elts);
4279 return ok?0:-1;
4282 /** Read the contents of a Bridge line from <b>line</b>. Return 0
4283 * if the line is well-formed, and -1 if it isn't. If
4284 * <b>validate_only</b> is 0, and the line is well-formed, then add
4285 * the bridge described in the line to our internal bridge list. */
4286 static int
4287 parse_bridge_line(const char *line, int validate_only)
4289 smartlist_t *items = NULL;
4290 int r;
4291 char *addrport=NULL, *fingerprint=NULL;
4292 tor_addr_t addr;
4293 uint16_t port = 0;
4294 char digest[DIGEST_LEN];
4296 items = smartlist_create();
4297 smartlist_split_string(items, line, NULL,
4298 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
4299 if (smartlist_len(items) < 1) {
4300 log_warn(LD_CONFIG, "Too few arguments to Bridge line.");
4301 goto err;
4303 addrport = smartlist_get(items, 0);
4304 smartlist_del_keeporder(items, 0);
4305 if (tor_addr_port_parse(addrport, &addr, &port)<0) {
4306 log_warn(LD_CONFIG, "Error parsing Bridge address '%s'", addrport);
4307 goto err;
4309 if (!port) {
4310 log_info(LD_CONFIG,
4311 "Bridge address '%s' has no port; using default port 443.",
4312 addrport);
4313 port = 443;
4316 if (smartlist_len(items)) {
4317 fingerprint = smartlist_join_strings(items, "", 0, NULL);
4318 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
4319 log_warn(LD_CONFIG, "Key digest for Bridge is wrong length.");
4320 goto err;
4322 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
4323 log_warn(LD_CONFIG, "Unable to decode Bridge key digest.");
4324 goto err;
4328 if (!validate_only) {
4329 log_debug(LD_DIR, "Bridge at %s:%d (%s)", fmt_addr(&addr),
4330 (int)port,
4331 fingerprint ? fingerprint : "no key listed");
4332 bridge_add_from_config(&addr, port, fingerprint ? digest : NULL);
4335 r = 0;
4336 goto done;
4338 err:
4339 r = -1;
4341 done:
4342 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
4343 smartlist_free(items);
4344 tor_free(addrport);
4345 tor_free(fingerprint);
4346 return r;
4349 /** Read the contents of a DirServer line from <b>line</b>. If
4350 * <b>validate_only</b> is 0, and the line is well-formed, and it
4351 * shares any bits with <b>required_type</b> or <b>required_type</b>
4352 * is 0, then add the dirserver described in the line (minus whatever
4353 * bits it's missing) as a valid authority. Return 0 on success,
4354 * or -1 if the line isn't well-formed or if we can't add it. */
4355 static int
4356 parse_dir_server_line(const char *line, authority_type_t required_type,
4357 int validate_only)
4359 smartlist_t *items = NULL;
4360 int r;
4361 char *addrport=NULL, *address=NULL, *nickname=NULL, *fingerprint=NULL;
4362 uint16_t dir_port = 0, or_port = 0;
4363 char digest[DIGEST_LEN];
4364 char v3_digest[DIGEST_LEN];
4365 authority_type_t type = V2_AUTHORITY;
4366 int is_not_hidserv_authority = 0, is_not_v2_authority = 0;
4368 items = smartlist_create();
4369 smartlist_split_string(items, line, NULL,
4370 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
4371 if (smartlist_len(items) < 1) {
4372 log_warn(LD_CONFIG, "No arguments on DirServer line.");
4373 goto err;
4376 if (is_legal_nickname(smartlist_get(items, 0))) {
4377 nickname = smartlist_get(items, 0);
4378 smartlist_del_keeporder(items, 0);
4381 while (smartlist_len(items)) {
4382 char *flag = smartlist_get(items, 0);
4383 if (TOR_ISDIGIT(flag[0]))
4384 break;
4385 if (!strcasecmp(flag, "v1")) {
4386 type |= (V1_AUTHORITY | HIDSERV_AUTHORITY);
4387 } else if (!strcasecmp(flag, "hs")) {
4388 type |= HIDSERV_AUTHORITY;
4389 } else if (!strcasecmp(flag, "no-hs")) {
4390 is_not_hidserv_authority = 1;
4391 } else if (!strcasecmp(flag, "bridge")) {
4392 type |= BRIDGE_AUTHORITY;
4393 } else if (!strcasecmp(flag, "no-v2")) {
4394 is_not_v2_authority = 1;
4395 } else if (!strcasecmpstart(flag, "orport=")) {
4396 int ok;
4397 char *portstring = flag + strlen("orport=");
4398 or_port = (uint16_t) tor_parse_long(portstring, 10, 1, 65535, &ok, NULL);
4399 if (!ok)
4400 log_warn(LD_CONFIG, "Invalid orport '%s' on DirServer line.",
4401 portstring);
4402 } else if (!strcasecmpstart(flag, "v3ident=")) {
4403 char *idstr = flag + strlen("v3ident=");
4404 if (strlen(idstr) != HEX_DIGEST_LEN ||
4405 base16_decode(v3_digest, DIGEST_LEN, idstr, HEX_DIGEST_LEN)<0) {
4406 log_warn(LD_CONFIG, "Bad v3 identity digest '%s' on DirServer line",
4407 flag);
4408 } else {
4409 type |= V3_AUTHORITY;
4411 } else {
4412 log_warn(LD_CONFIG, "Unrecognized flag '%s' on DirServer line",
4413 flag);
4415 tor_free(flag);
4416 smartlist_del_keeporder(items, 0);
4418 if (is_not_hidserv_authority)
4419 type &= ~HIDSERV_AUTHORITY;
4420 if (is_not_v2_authority)
4421 type &= ~V2_AUTHORITY;
4423 if (smartlist_len(items) < 2) {
4424 log_warn(LD_CONFIG, "Too few arguments to DirServer line.");
4425 goto err;
4427 addrport = smartlist_get(items, 0);
4428 smartlist_del_keeporder(items, 0);
4429 if (parse_addr_port(LOG_WARN, addrport, &address, NULL, &dir_port)<0) {
4430 log_warn(LD_CONFIG, "Error parsing DirServer address '%s'", addrport);
4431 goto err;
4433 if (!dir_port) {
4434 log_warn(LD_CONFIG, "Missing port in DirServer address '%s'",addrport);
4435 goto err;
4438 fingerprint = smartlist_join_strings(items, "", 0, NULL);
4439 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
4440 log_warn(LD_CONFIG, "Key digest for DirServer is wrong length %d.",
4441 (int)strlen(fingerprint));
4442 goto err;
4444 if (!strcmp(fingerprint, "E623F7625FBE0C87820F11EC5F6D5377ED816294")) {
4445 /* a known bad fingerprint. refuse to use it. We can remove this
4446 * clause once Tor 0.1.2.17 is obsolete. */
4447 log_warn(LD_CONFIG, "Dangerous dirserver line. To correct, erase your "
4448 "torrc file (%s), or reinstall Tor and use the default torrc.",
4449 get_torrc_fname());
4450 goto err;
4452 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
4453 log_warn(LD_CONFIG, "Unable to decode DirServer key digest.");
4454 goto err;
4457 if (!validate_only && (!required_type || required_type & type)) {
4458 if (required_type)
4459 type &= required_type; /* pare down what we think of them as an
4460 * authority for. */
4461 log_debug(LD_DIR, "Trusted %d dirserver at %s:%d (%s)", (int)type,
4462 address, (int)dir_port, (char*)smartlist_get(items,0));
4463 if (!add_trusted_dir_server(nickname, address, dir_port, or_port,
4464 digest, v3_digest, type))
4465 goto err;
4468 r = 0;
4469 goto done;
4471 err:
4472 r = -1;
4474 done:
4475 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
4476 smartlist_free(items);
4477 tor_free(addrport);
4478 tor_free(address);
4479 tor_free(nickname);
4480 tor_free(fingerprint);
4481 return r;
4484 /** Adjust the value of options->DataDirectory, or fill it in if it's
4485 * absent. Return 0 on success, -1 on failure. */
4486 static int
4487 normalize_data_directory(or_options_t *options)
4489 #ifdef MS_WINDOWS
4490 char *p;
4491 if (options->DataDirectory)
4492 return 0; /* all set */
4493 p = tor_malloc(MAX_PATH);
4494 strlcpy(p,get_windows_conf_root(),MAX_PATH);
4495 options->DataDirectory = p;
4496 return 0;
4497 #else
4498 const char *d = options->DataDirectory;
4499 if (!d)
4500 d = "~/.tor";
4502 if (strncmp(d,"~/",2) == 0) {
4503 char *fn = expand_filename(d);
4504 if (!fn) {
4505 log_warn(LD_CONFIG,"Failed to expand filename \"%s\".", d);
4506 return -1;
4508 if (!options->DataDirectory && !strcmp(fn,"/.tor")) {
4509 /* If our homedir is /, we probably don't want to use it. */
4510 /* Default to LOCALSTATEDIR/tor which is probably closer to what we
4511 * want. */
4512 log_warn(LD_CONFIG,
4513 "Default DataDirectory is \"~/.tor\". This expands to "
4514 "\"%s\", which is probably not what you want. Using "
4515 "\"%s"PATH_SEPARATOR"tor\" instead", fn, LOCALSTATEDIR);
4516 tor_free(fn);
4517 fn = tor_strdup(LOCALSTATEDIR PATH_SEPARATOR "tor");
4519 tor_free(options->DataDirectory);
4520 options->DataDirectory = fn;
4522 return 0;
4523 #endif
4526 /** Check and normalize the value of options->DataDirectory; return 0 if it
4527 * is sane, -1 otherwise. */
4528 static int
4529 validate_data_directory(or_options_t *options)
4531 if (normalize_data_directory(options) < 0)
4532 return -1;
4533 tor_assert(options->DataDirectory);
4534 if (strlen(options->DataDirectory) > (512-128)) {
4535 log_warn(LD_CONFIG, "DataDirectory is too long.");
4536 return -1;
4538 return 0;
4541 /** This string must remain the same forevermore. It is how we
4542 * recognize that the torrc file doesn't need to be backed up. */
4543 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; " \
4544 "if you edit it, comments will not be preserved"
4545 /** This string can change; it tries to give the reader an idea
4546 * that editing this file by hand is not a good plan. */
4547 #define GENERATED_FILE_COMMENT "# The old torrc file was renamed " \
4548 "to torrc.orig.1 or similar, and Tor will ignore it"
4550 /** Save a configuration file for the configuration in <b>options</b>
4551 * into the file <b>fname</b>. If the file already exists, and
4552 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
4553 * replace it. Return 0 on success, -1 on failure. */
4554 static int
4555 write_configuration_file(const char *fname, or_options_t *options)
4557 char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
4558 int rename_old = 0, r;
4560 tor_assert(fname);
4562 switch (file_status(fname)) {
4563 case FN_FILE:
4564 old_val = read_file_to_str(fname, 0, NULL);
4565 if (strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
4566 rename_old = 1;
4568 tor_free(old_val);
4569 break;
4570 case FN_NOENT:
4571 break;
4572 case FN_ERROR:
4573 case FN_DIR:
4574 default:
4575 log_warn(LD_CONFIG,
4576 "Config file \"%s\" is not a file? Failing.", fname);
4577 return -1;
4580 if (!(new_conf = options_dump(options, 1))) {
4581 log_warn(LD_BUG, "Couldn't get configuration string");
4582 goto err;
4585 tor_asprintf(&new_val, "%s\n%s\n\n%s",
4586 GENERATED_FILE_PREFIX, GENERATED_FILE_COMMENT, new_conf);
4588 if (rename_old) {
4589 int i = 1;
4590 size_t fn_tmp_len = strlen(fname)+32;
4591 char *fn_tmp;
4592 tor_assert(fn_tmp_len > strlen(fname)); /*check for overflow*/
4593 fn_tmp = tor_malloc(fn_tmp_len);
4594 while (1) {
4595 if (tor_snprintf(fn_tmp, fn_tmp_len, "%s.orig.%d", fname, i)<0) {
4596 log_warn(LD_BUG, "tor_snprintf failed inexplicably");
4597 tor_free(fn_tmp);
4598 goto err;
4600 if (file_status(fn_tmp) == FN_NOENT)
4601 break;
4602 ++i;
4604 log_notice(LD_CONFIG, "Renaming old configuration file to \"%s\"", fn_tmp);
4605 if (rename(fname, fn_tmp) < 0) {
4606 log_warn(LD_FS,
4607 "Couldn't rename configuration file \"%s\" to \"%s\": %s",
4608 fname, fn_tmp, strerror(errno));
4609 tor_free(fn_tmp);
4610 goto err;
4612 tor_free(fn_tmp);
4615 if (write_str_to_file(fname, new_val, 0) < 0)
4616 goto err;
4618 r = 0;
4619 goto done;
4620 err:
4621 r = -1;
4622 done:
4623 tor_free(new_val);
4624 tor_free(new_conf);
4625 return r;
4629 * Save the current configuration file value to disk. Return 0 on
4630 * success, -1 on failure.
4633 options_save_current(void)
4635 /* This fails if we can't write to our configuration file.
4637 * If we try falling back to datadirectory or something, we have a better
4638 * chance of saving the configuration, but a better chance of doing
4639 * something the user never expected. */
4640 return write_configuration_file(get_torrc_fname(), get_options());
4643 /** Mapping from a unit name to a multiplier for converting that unit into a
4644 * base unit. */
4645 struct unit_table_t {
4646 const char *unit;
4647 uint64_t multiplier;
4650 /** Table to map the names of memory units to the number of bytes they
4651 * contain. */
4652 static struct unit_table_t memory_units[] = {
4653 { "", 1 },
4654 { "b", 1<< 0 },
4655 { "byte", 1<< 0 },
4656 { "bytes", 1<< 0 },
4657 { "kb", 1<<10 },
4658 { "kbyte", 1<<10 },
4659 { "kbytes", 1<<10 },
4660 { "kilobyte", 1<<10 },
4661 { "kilobytes", 1<<10 },
4662 { "m", 1<<20 },
4663 { "mb", 1<<20 },
4664 { "mbyte", 1<<20 },
4665 { "mbytes", 1<<20 },
4666 { "megabyte", 1<<20 },
4667 { "megabytes", 1<<20 },
4668 { "gb", 1<<30 },
4669 { "gbyte", 1<<30 },
4670 { "gbytes", 1<<30 },
4671 { "gigabyte", 1<<30 },
4672 { "gigabytes", 1<<30 },
4673 { "tb", U64_LITERAL(1)<<40 },
4674 { "terabyte", U64_LITERAL(1)<<40 },
4675 { "terabytes", U64_LITERAL(1)<<40 },
4676 { NULL, 0 },
4679 /** Table to map the names of time units to the number of seconds they
4680 * contain. */
4681 static struct unit_table_t time_units[] = {
4682 { "", 1 },
4683 { "second", 1 },
4684 { "seconds", 1 },
4685 { "minute", 60 },
4686 { "minutes", 60 },
4687 { "hour", 60*60 },
4688 { "hours", 60*60 },
4689 { "day", 24*60*60 },
4690 { "days", 24*60*60 },
4691 { "week", 7*24*60*60 },
4692 { "weeks", 7*24*60*60 },
4693 { NULL, 0 },
4696 /** Parse a string <b>val</b> containing a number, zero or more
4697 * spaces, and an optional unit string. If the unit appears in the
4698 * table <b>u</b>, then multiply the number by the unit multiplier.
4699 * On success, set *<b>ok</b> to 1 and return this product.
4700 * Otherwise, set *<b>ok</b> to 0.
4702 static uint64_t
4703 config_parse_units(const char *val, struct unit_table_t *u, int *ok)
4705 uint64_t v = 0;
4706 double d = 0;
4707 int use_float = 0;
4708 char *cp;
4710 tor_assert(ok);
4712 v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
4713 if (!*ok || (cp && *cp == '.')) {
4714 d = tor_parse_double(val, 0, UINT64_MAX, ok, &cp);
4715 if (!*ok)
4716 goto done;
4717 use_float = 1;
4720 if (!cp) {
4721 *ok = 1;
4722 v = use_float ? DBL_TO_U64(d) : v;
4723 goto done;
4726 cp = (char*) eat_whitespace(cp);
4728 for ( ;u->unit;++u) {
4729 if (!strcasecmp(u->unit, cp)) {
4730 if (use_float)
4731 v = u->multiplier * d;
4732 else
4733 v *= u->multiplier;
4734 *ok = 1;
4735 goto done;
4738 log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
4739 *ok = 0;
4740 done:
4742 if (*ok)
4743 return v;
4744 else
4745 return 0;
4748 /** Parse a string in the format "number unit", where unit is a unit of
4749 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
4750 * and return the number of bytes specified. Otherwise, set
4751 * *<b>ok</b> to false and return 0. */
4752 static uint64_t
4753 config_parse_memunit(const char *s, int *ok)
4755 uint64_t u = config_parse_units(s, memory_units, ok);
4756 return u;
4759 /** Parse a string in the format "number unit", where unit is a unit of time.
4760 * On success, set *<b>ok</b> to true and return the number of seconds in
4761 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
4763 static int
4764 config_parse_interval(const char *s, int *ok)
4766 uint64_t r;
4767 r = config_parse_units(s, time_units, ok);
4768 if (!ok)
4769 return -1;
4770 if (r > INT_MAX) {
4771 log_warn(LD_CONFIG, "Interval '%s' is too long", s);
4772 *ok = 0;
4773 return -1;
4775 return (int)r;
4779 * Initialize the libevent library.
4781 static void
4782 init_libevent(void)
4784 const char *badness=NULL;
4786 configure_libevent_logging();
4787 /* If the kernel complains that some method (say, epoll) doesn't
4788 * exist, we don't care about it, since libevent will cope.
4790 suppress_libevent_log_msg("Function not implemented");
4792 tor_check_libevent_header_compatibility();
4794 tor_libevent_initialize();
4796 suppress_libevent_log_msg(NULL);
4798 tor_check_libevent_version(tor_libevent_get_method(),
4799 get_options()->ORPort != 0,
4800 &badness);
4801 if (badness) {
4802 const char *v = tor_libevent_get_version_str();
4803 const char *m = tor_libevent_get_method();
4804 control_event_general_status(LOG_WARN,
4805 "BAD_LIBEVENT VERSION=%s METHOD=%s BADNESS=%s RECOVERED=NO",
4806 v, m, badness);
4810 /** Return the persistent state struct for this Tor. */
4811 or_state_t *
4812 get_or_state(void)
4814 tor_assert(global_state);
4815 return global_state;
4818 /** Return a newly allocated string holding a filename relative to the data
4819 * directory. If <b>sub1</b> is present, it is the first path component after
4820 * the data directory. If <b>sub2</b> is also present, it is the second path
4821 * component after the data directory. If <b>suffix</b> is present, it
4822 * is appended to the filename.
4824 * Examples:
4825 * get_datadir_fname2_suffix("a", NULL, NULL) -> $DATADIR/a
4826 * get_datadir_fname2_suffix("a", NULL, ".tmp") -> $DATADIR/a.tmp
4827 * get_datadir_fname2_suffix("a", "b", ".tmp") -> $DATADIR/a/b/.tmp
4828 * get_datadir_fname2_suffix("a", "b", NULL) -> $DATADIR/a/b
4830 * Note: Consider using the get_datadir_fname* macros in or.h.
4832 char *
4833 options_get_datadir_fname2_suffix(or_options_t *options,
4834 const char *sub1, const char *sub2,
4835 const char *suffix)
4837 char *fname = NULL;
4838 size_t len;
4839 tor_assert(options);
4840 tor_assert(options->DataDirectory);
4841 tor_assert(sub1 || !sub2); /* If sub2 is present, sub1 must be present. */
4842 len = strlen(options->DataDirectory);
4843 if (sub1) {
4844 len += strlen(sub1)+1;
4845 if (sub2)
4846 len += strlen(sub2)+1;
4848 if (suffix)
4849 len += strlen(suffix);
4850 len++;
4851 fname = tor_malloc(len);
4852 if (sub1) {
4853 if (sub2) {
4854 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s"PATH_SEPARATOR"%s",
4855 options->DataDirectory, sub1, sub2);
4856 } else {
4857 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s",
4858 options->DataDirectory, sub1);
4860 } else {
4861 strlcpy(fname, options->DataDirectory, len);
4863 if (suffix)
4864 strlcat(fname, suffix, len);
4865 return fname;
4868 /** Return 0 if every setting in <b>state</b> is reasonable, and a
4869 * permissible transition from <b>old_state</b>. Else warn and return -1.
4870 * Should have no side effects, except for normalizing the contents of
4871 * <b>state</b>.
4873 /* XXX from_setconf is here because of bug 238 */
4874 static int
4875 or_state_validate(or_state_t *old_state, or_state_t *state,
4876 int from_setconf, char **msg)
4878 /* We don't use these; only options do. Still, we need to match that
4879 * signature. */
4880 (void) from_setconf;
4881 (void) old_state;
4883 if (entry_guards_parse_state(state, 0, msg)<0)
4884 return -1;
4886 return 0;
4889 /** Replace the current persistent state with <b>new_state</b> */
4890 static int
4891 or_state_set(or_state_t *new_state)
4893 char *err = NULL;
4894 int ret = 0;
4895 tor_assert(new_state);
4896 config_free(&state_format, global_state);
4897 global_state = new_state;
4898 if (entry_guards_parse_state(global_state, 1, &err)<0) {
4899 log_warn(LD_GENERAL,"%s",err);
4900 tor_free(err);
4901 ret = -1;
4903 if (rep_hist_load_state(global_state, &err)<0) {
4904 log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
4905 tor_free(err);
4906 ret = -1;
4908 if (circuit_build_times_parse_state(&circ_times, global_state, &err) < 0) {
4909 log_warn(LD_GENERAL,"%s",err);
4910 tor_free(err);
4911 ret = -1;
4913 return ret;
4917 * Save a broken state file to a backup location.
4919 static void
4920 or_state_save_broken(char *fname)
4922 int i;
4923 file_status_t status;
4924 size_t len = strlen(fname)+16;
4925 char *fname2 = tor_malloc(len);
4926 for (i = 0; i < 100; ++i) {
4927 tor_snprintf(fname2, len, "%s.%d", fname, i);
4928 status = file_status(fname2);
4929 if (status == FN_NOENT)
4930 break;
4932 if (i == 100) {
4933 log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
4934 "state files to move aside. Discarding the old state file.",
4935 fname);
4936 unlink(fname);
4937 } else {
4938 log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
4939 "to \"%s\". This could be a bug in Tor; please tell "
4940 "the developers.", fname, fname2);
4941 if (rename(fname, fname2) < 0) {
4942 log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
4943 "OS gave an error of %s", strerror(errno));
4946 tor_free(fname2);
4949 /** Reload the persistent state from disk, generating a new state as needed.
4950 * Return 0 on success, less than 0 on failure.
4952 static int
4953 or_state_load(void)
4955 or_state_t *new_state = NULL;
4956 char *contents = NULL, *fname;
4957 char *errmsg = NULL;
4958 int r = -1, badstate = 0;
4960 fname = get_datadir_fname("state");
4961 switch (file_status(fname)) {
4962 case FN_FILE:
4963 if (!(contents = read_file_to_str(fname, 0, NULL))) {
4964 log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
4965 goto done;
4967 break;
4968 case FN_NOENT:
4969 break;
4970 case FN_ERROR:
4971 case FN_DIR:
4972 default:
4973 log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
4974 goto done;
4976 new_state = tor_malloc_zero(sizeof(or_state_t));
4977 new_state->_magic = OR_STATE_MAGIC;
4978 config_init(&state_format, new_state);
4979 if (contents) {
4980 config_line_t *lines=NULL;
4981 int assign_retval;
4982 if (config_get_lines(contents, &lines)<0)
4983 goto done;
4984 assign_retval = config_assign(&state_format, new_state,
4985 lines, 0, 0, &errmsg);
4986 config_free_lines(lines);
4987 if (assign_retval<0)
4988 badstate = 1;
4989 if (errmsg) {
4990 log_warn(LD_GENERAL, "%s", errmsg);
4991 tor_free(errmsg);
4995 if (!badstate && or_state_validate(NULL, new_state, 1, &errmsg) < 0)
4996 badstate = 1;
4998 if (errmsg) {
4999 log_warn(LD_GENERAL, "%s", errmsg);
5000 tor_free(errmsg);
5003 if (badstate && !contents) {
5004 log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
5005 " This is a bug in Tor.");
5006 goto done;
5007 } else if (badstate && contents) {
5008 or_state_save_broken(fname);
5010 tor_free(contents);
5011 config_free(&state_format, new_state);
5013 new_state = tor_malloc_zero(sizeof(or_state_t));
5014 new_state->_magic = OR_STATE_MAGIC;
5015 config_init(&state_format, new_state);
5016 } else if (contents) {
5017 log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
5018 } else {
5019 log_info(LD_GENERAL, "Initialized state");
5021 if (or_state_set(new_state) == -1) {
5022 or_state_save_broken(fname);
5024 new_state = NULL;
5025 if (!contents) {
5026 global_state->next_write = 0;
5027 or_state_save(time(NULL));
5029 r = 0;
5031 done:
5032 tor_free(fname);
5033 tor_free(contents);
5034 if (new_state)
5035 config_free(&state_format, new_state);
5037 return r;
5040 /** Write the persistent state to disk. Return 0 for success, <0 on failure. */
5042 or_state_save(time_t now)
5044 char *state, *contents;
5045 char tbuf[ISO_TIME_LEN+1];
5046 char *fname;
5048 tor_assert(global_state);
5050 if (global_state->next_write > now)
5051 return 0;
5053 /* Call everything else that might dirty the state even more, in order
5054 * to avoid redundant writes. */
5055 entry_guards_update_state(global_state);
5056 rep_hist_update_state(global_state);
5057 circuit_build_times_update_state(&circ_times, global_state);
5058 if (accounting_is_enabled(get_options()))
5059 accounting_run_housekeeping(now);
5061 tor_free(global_state->TorVersion);
5062 tor_asprintf(&global_state->TorVersion, "Tor %s", get_version());
5064 state = config_dump(&state_format, global_state, 1, 0);
5065 format_local_iso_time(tbuf, time(NULL));
5066 tor_asprintf(&contents,
5067 "# Tor state file last generated on %s local time\n"
5068 "# Other times below are in GMT\n"
5069 "# You *do not* need to edit this file.\n\n%s",
5070 tbuf, state);
5071 tor_free(state);
5072 fname = get_datadir_fname("state");
5073 if (write_str_to_file(fname, contents, 0)<0) {
5074 log_warn(LD_FS, "Unable to write state to file \"%s\"", fname);
5075 global_state->LastWritten = -1;
5076 tor_free(fname);
5077 tor_free(contents);
5078 return -1;
5081 global_state->LastWritten = time(NULL);
5082 log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
5083 tor_free(fname);
5084 tor_free(contents);
5086 global_state->next_write = TIME_MAX;
5087 return 0;
5090 /** Given a file name check to see whether the file exists but has not been
5091 * modified for a very long time. If so, remove it. */
5092 void
5093 remove_file_if_very_old(const char *fname, time_t now)
5095 #define VERY_OLD_FILE_AGE (28*24*60*60)
5096 struct stat st;
5098 if (stat(fname, &st)==0 && st.st_mtime < now-VERY_OLD_FILE_AGE) {
5099 char buf[ISO_TIME_LEN+1];
5100 format_local_iso_time(buf, st.st_mtime);
5101 log_notice(LD_GENERAL, "Obsolete file %s hasn't been modified since %s. "
5102 "Removing it.", fname, buf);
5103 unlink(fname);
5107 /** Helper to implement GETINFO functions about configuration variables (not
5108 * their values). Given a "config/names" question, set *<b>answer</b> to a
5109 * new string describing the supported configuration variables and their
5110 * types. */
5112 getinfo_helper_config(control_connection_t *conn,
5113 const char *question, char **answer,
5114 const char **errmsg)
5116 (void) conn;
5117 (void) errmsg;
5118 if (!strcmp(question, "config/names")) {
5119 smartlist_t *sl = smartlist_create();
5120 int i;
5121 for (i = 0; _option_vars[i].name; ++i) {
5122 config_var_t *var = &_option_vars[i];
5123 const char *type;
5124 char *line;
5125 switch (var->type) {
5126 case CONFIG_TYPE_STRING: type = "String"; break;
5127 case CONFIG_TYPE_FILENAME: type = "Filename"; break;
5128 case CONFIG_TYPE_UINT: type = "Integer"; break;
5129 case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
5130 case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
5131 case CONFIG_TYPE_DOUBLE: type = "Float"; break;
5132 case CONFIG_TYPE_BOOL: type = "Boolean"; break;
5133 case CONFIG_TYPE_ISOTIME: type = "Time"; break;
5134 case CONFIG_TYPE_ROUTERSET: type = "RouterList"; break;
5135 case CONFIG_TYPE_CSV: type = "CommaList"; break;
5136 case CONFIG_TYPE_LINELIST: type = "LineList"; break;
5137 case CONFIG_TYPE_LINELIST_S: type = "Dependant"; break;
5138 case CONFIG_TYPE_LINELIST_V: type = "Virtual"; break;
5139 default:
5140 case CONFIG_TYPE_OBSOLETE:
5141 type = NULL; break;
5143 if (!type)
5144 continue;
5145 tor_asprintf(&line, "%s %s\n",var->name,type);
5146 smartlist_add(sl, line);
5148 *answer = smartlist_join_strings(sl, "", 0, NULL);
5149 SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
5150 smartlist_free(sl);
5152 return 0;