Some tweaks to statistics.
[tor/rransom.git] / src / or / config.c
blob1811551556aa1320504c25eb11a7e86b1cd6c6af
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-2009, 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 #ifdef MS_WINDOWS
16 #include <shlobj.h>
17 #endif
19 /** Enumeration of types which option values can take */
20 typedef enum config_type_t {
21 CONFIG_TYPE_STRING = 0, /**< An arbitrary string. */
22 CONFIG_TYPE_FILENAME, /**< A filename: some prefixes get expanded. */
23 CONFIG_TYPE_UINT, /**< A non-negative integer less than MAX_INT */
24 CONFIG_TYPE_INTERVAL, /**< A number of seconds, with optional units*/
25 CONFIG_TYPE_MEMUNIT, /**< A number of bytes, with optional units*/
26 CONFIG_TYPE_DOUBLE, /**< A floating-point value */
27 CONFIG_TYPE_BOOL, /**< A boolean value, expressed as 0 or 1. */
28 CONFIG_TYPE_ISOTIME, /**< An ISO-formatted time relative to GMT. */
29 CONFIG_TYPE_CSV, /**< A list of strings, separated by commas and
30 * optional whitespace. */
31 CONFIG_TYPE_LINELIST, /**< Uninterpreted config lines */
32 CONFIG_TYPE_LINELIST_S, /**< Uninterpreted, context-sensitive config lines,
33 * mixed with other keywords. */
34 CONFIG_TYPE_LINELIST_V, /**< Catch-all "virtual" option to summarize
35 * context-sensitive config lines when fetching.
37 CONFIG_TYPE_ROUTERSET, /**< A list of router names, addrs, and fps,
38 * parsed into a routerset_t. */
39 CONFIG_TYPE_OBSOLETE, /**< Obsolete (ignored) option. */
40 } config_type_t;
42 /** An abbreviation for a configuration option allowed on the command line. */
43 typedef struct config_abbrev_t {
44 const char *abbreviated;
45 const char *full;
46 int commandline_only;
47 int warn;
48 } config_abbrev_t;
50 /* Handy macro for declaring "In the config file or on the command line,
51 * you can abbreviate <b>tok</b>s as <b>tok</b>". */
52 #define PLURAL(tok) { #tok, #tok "s", 0, 0 }
54 /** A list of abbreviations and aliases to map command-line options, obsolete
55 * option names, or alternative option names, to their current values. */
56 static config_abbrev_t _option_abbrevs[] = {
57 PLURAL(ExitNode),
58 PLURAL(EntryNode),
59 PLURAL(ExcludeNode),
60 PLURAL(FirewallPort),
61 PLURAL(LongLivedPort),
62 PLURAL(HiddenServiceNode),
63 PLURAL(HiddenServiceExcludeNode),
64 PLURAL(NumCpu),
65 PLURAL(RendNode),
66 PLURAL(RendExcludeNode),
67 PLURAL(StrictEntryNode),
68 PLURAL(StrictExitNode),
69 { "l", "Log", 1, 0},
70 { "AllowUnverifiedNodes", "AllowInvalidNodes", 0, 0},
71 { "AutomapHostSuffixes", "AutomapHostsSuffixes", 0, 0},
72 { "AutomapHostOnResolve", "AutomapHostsOnResolve", 0, 0},
73 { "BandwidthRateBytes", "BandwidthRate", 0, 0},
74 { "BandwidthBurstBytes", "BandwidthBurst", 0, 0},
75 { "DirFetchPostPeriod", "StatusFetchPeriod", 0, 0},
76 { "MaxConn", "ConnLimit", 0, 1},
77 { "ORBindAddress", "ORListenAddress", 0, 0},
78 { "DirBindAddress", "DirListenAddress", 0, 0},
79 { "SocksBindAddress", "SocksListenAddress", 0, 0},
80 { "UseHelperNodes", "UseEntryGuards", 0, 0},
81 { "NumHelperNodes", "NumEntryGuards", 0, 0},
82 { "UseEntryNodes", "UseEntryGuards", 0, 0},
83 { "NumEntryNodes", "NumEntryGuards", 0, 0},
84 { "ResolvConf", "ServerDNSResolvConfFile", 0, 1},
85 { "SearchDomains", "ServerDNSSearchDomains", 0, 1},
86 { "ServerDNSAllowBrokenResolvConf", "ServerDNSAllowBrokenConfig", 0, 0 },
87 { "PreferTunnelledDirConns", "PreferTunneledDirConns", 0, 0},
88 { "BridgeAuthoritativeDirectory", "BridgeAuthoritativeDir", 0, 0},
89 { "HashedControlPassword", "__HashedControlSessionPassword", 1, 0},
90 { NULL, NULL, 0, 0},
93 /** A list of state-file "abbreviations," for compatibility. */
94 static config_abbrev_t _state_abbrevs[] = {
95 { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
96 { "HelperNode", "EntryGuard", 0, 0 },
97 { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
98 { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
99 { "EntryNode", "EntryGuard", 0, 0 },
100 { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
101 { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
102 { NULL, NULL, 0, 0},
104 #undef PLURAL
106 /** A variable allowed in the configuration file or on the command line. */
107 typedef struct config_var_t {
108 const char *name; /**< The full keyword (case insensitive). */
109 config_type_t type; /**< How to interpret the type and turn it into a
110 * value. */
111 off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
112 const char *initvalue; /**< String (or null) describing initial value. */
113 } config_var_t;
115 /** An entry for config_vars: "The option <b>name</b> has type
116 * CONFIG_TYPE_<b>conftype</b>, and corresponds to
117 * or_options_t.<b>member</b>"
119 #define VAR(name,conftype,member,initvalue) \
120 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), \
121 initvalue }
122 /** As VAR, but the option name and member name are the same. */
123 #define V(member,conftype,initvalue) \
124 VAR(#member, conftype, member, initvalue)
125 /** An entry for config_vars: "The option <b>name</b> is obsolete." */
126 #define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
128 /** Array of configuration options. Until we disallow nonstandard
129 * abbreviations, order is significant, since the first matching option will
130 * be chosen first.
132 static config_var_t _option_vars[] = {
133 OBSOLETE("AccountingMaxKB"),
134 V(AccountingMax, MEMUNIT, "0 bytes"),
135 V(AccountingStart, STRING, NULL),
136 V(Address, STRING, NULL),
137 V(AllowInvalidNodes, CSV, "middle,rendezvous"),
138 V(AllowNonRFC953Hostnames, BOOL, "0"),
139 V(AllowSingleHopCircuits, BOOL, "0"),
140 V(AllowSingleHopExits, BOOL, "0"),
141 V(AlternateBridgeAuthority, LINELIST, NULL),
142 V(AlternateDirAuthority, LINELIST, NULL),
143 V(AlternateHSAuthority, LINELIST, NULL),
144 V(AssumeReachable, BOOL, "0"),
145 V(AuthDirBadDir, LINELIST, NULL),
146 V(AuthDirBadExit, LINELIST, NULL),
147 V(AuthDirInvalid, LINELIST, NULL),
148 V(AuthDirReject, LINELIST, NULL),
149 V(AuthDirRejectUnlisted, BOOL, "0"),
150 V(AuthDirListBadDirs, BOOL, "0"),
151 V(AuthDirListBadExits, BOOL, "0"),
152 V(AuthDirMaxServersPerAddr, UINT, "2"),
153 V(AuthDirMaxServersPerAuthAddr,UINT, "5"),
154 VAR("AuthoritativeDirectory", BOOL, AuthoritativeDir, "0"),
155 V(AutomapHostsOnResolve, BOOL, "0"),
156 V(AutomapHostsSuffixes, CSV, ".onion,.exit"),
157 V(AvoidDiskWrites, BOOL, "0"),
158 V(BandwidthBurst, MEMUNIT, "10 MB"),
159 V(BandwidthRate, MEMUNIT, "5 MB"),
160 V(BridgeAuthoritativeDir, BOOL, "0"),
161 VAR("Bridge", LINELIST, Bridges, NULL),
162 V(BridgePassword, STRING, NULL),
163 V(BridgeRecordUsageByCountry, BOOL, "1"),
164 V(BridgeRelay, BOOL, "0"),
165 V(CellStatistics, BOOL, "0"),
166 V(CircuitBuildTimeout, INTERVAL, "1 minute"),
167 V(CircuitIdleTimeout, INTERVAL, "1 hour"),
168 V(ClientDNSRejectInternalAddresses, BOOL,"1"),
169 V(ClientOnly, BOOL, "0"),
170 V(ConnLimit, UINT, "1000"),
171 V(ConstrainedSockets, BOOL, "0"),
172 V(ConstrainedSockSize, MEMUNIT, "8192"),
173 V(ContactInfo, STRING, NULL),
174 V(ControlListenAddress, LINELIST, NULL),
175 V(ControlPort, UINT, "0"),
176 V(ControlSocket, LINELIST, NULL),
177 V(CookieAuthentication, BOOL, "0"),
178 V(CookieAuthFileGroupReadable, BOOL, "0"),
179 V(CookieAuthFile, STRING, NULL),
180 V(DataDirectory, FILENAME, NULL),
181 OBSOLETE("DebugLogFile"),
182 V(DirAllowPrivateAddresses, BOOL, NULL),
183 V(TestingAuthDirTimeToLearnReachability, INTERVAL, "30 minutes"),
184 V(DirListenAddress, LINELIST, NULL),
185 OBSOLETE("DirFetchPeriod"),
186 V(DirPolicy, LINELIST, NULL),
187 V(DirPort, UINT, "0"),
188 V(DirPortFrontPage, FILENAME, NULL),
189 OBSOLETE("DirPostPeriod"),
190 #ifdef ENABLE_DIRREQ_STATS
191 OBSOLETE("DirRecordUsageByCountry"),
192 OBSOLETE("DirRecordUsageGranularity"),
193 OBSOLETE("DirRecordUsageRetainIPs"),
194 OBSOLETE("DirRecordUsageSaveInterval"),
195 #endif
196 V(DirReqStatistics, BOOL, "0"),
197 VAR("DirServer", LINELIST, DirServers, NULL),
198 V(DNSPort, UINT, "0"),
199 V(DNSListenAddress, LINELIST, NULL),
200 V(DownloadExtraInfo, BOOL, "0"),
201 V(EnforceDistinctSubnets, BOOL, "1"),
202 V(EntryNodes, ROUTERSET, NULL),
203 V(EntryStatistics, BOOL, "0"),
204 V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "10 minutes"),
205 V(ExcludeNodes, ROUTERSET, NULL),
206 V(ExcludeExitNodes, ROUTERSET, NULL),
207 V(ExcludeSingleHopRelays, BOOL, "1"),
208 V(ExitNodes, ROUTERSET, NULL),
209 V(ExitPolicy, LINELIST, NULL),
210 V(ExitPolicyRejectPrivate, BOOL, "1"),
211 V(ExitPortStatistics, BOOL, "0"),
212 V(FallbackNetworkstatusFile, FILENAME,
213 SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "fallback-consensus"),
214 V(FascistFirewall, BOOL, "0"),
215 V(FirewallPorts, CSV, ""),
216 V(FastFirstHopPK, BOOL, "1"),
217 V(FetchDirInfoEarly, BOOL, "0"),
218 V(FetchServerDescriptors, BOOL, "1"),
219 V(FetchHidServDescriptors, BOOL, "1"),
220 V(FetchUselessDescriptors, BOOL, "0"),
221 #ifdef WIN32
222 V(GeoIPFile, FILENAME, "<default>"),
223 #else
224 V(GeoIPFile, FILENAME,
225 SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "geoip"),
226 #endif
227 OBSOLETE("Group"),
228 V(HardwareAccel, BOOL, "0"),
229 V(AccelName, STRING, NULL),
230 V(AccelDir, FILENAME, NULL),
231 V(HashedControlPassword, LINELIST, NULL),
232 V(HidServDirectoryV2, BOOL, "1"),
233 VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
234 OBSOLETE("HiddenServiceExcludeNodes"),
235 OBSOLETE("HiddenServiceNodes"),
236 VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
237 VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
238 VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines, NULL),
239 VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL),
240 V(HidServAuth, LINELIST, NULL),
241 V(HSAuthoritativeDir, BOOL, "0"),
242 V(HSAuthorityRecordStats, BOOL, "0"),
243 V(HttpProxy, STRING, NULL),
244 V(HttpProxyAuthenticator, STRING, NULL),
245 V(HttpsProxy, STRING, NULL),
246 V(HttpsProxyAuthenticator, STRING, NULL),
247 OBSOLETE("IgnoreVersion"),
248 V(KeepalivePeriod, INTERVAL, "5 minutes"),
249 VAR("Log", LINELIST, Logs, NULL),
250 OBSOLETE("LinkPadding"),
251 OBSOLETE("LogLevel"),
252 OBSOLETE("LogFile"),
253 V(LongLivedPorts, CSV,
254 "21,22,706,1863,5050,5190,5222,5223,6667,6697,8300"),
255 VAR("MapAddress", LINELIST, AddressMap, NULL),
256 V(MaxAdvertisedBandwidth, MEMUNIT, "1 GB"),
257 V(MaxCircuitDirtiness, INTERVAL, "10 minutes"),
258 V(MaxOnionsPending, UINT, "100"),
259 OBSOLETE("MonthlyAccountingStart"),
260 V(MyFamily, STRING, NULL),
261 V(NewCircuitPeriod, INTERVAL, "30 seconds"),
262 VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "0"),
263 V(NatdListenAddress, LINELIST, NULL),
264 V(NatdPort, UINT, "0"),
265 V(Nickname, STRING, NULL),
266 V(NoPublish, BOOL, "0"),
267 VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
268 V(NumCpus, UINT, "1"),
269 V(NumEntryGuards, UINT, "3"),
270 V(ORListenAddress, LINELIST, NULL),
271 V(ORPort, UINT, "0"),
272 V(OutboundBindAddress, STRING, NULL),
273 OBSOLETE("PathlenCoinWeight"),
274 V(PidFile, STRING, NULL),
275 V(TestingTorNetwork, BOOL, "0"),
276 V(PreferTunneledDirConns, BOOL, "1"),
277 V(ProtocolWarnings, BOOL, "0"),
278 V(PublishServerDescriptor, CSV, "1"),
279 V(PublishHidServDescriptors, BOOL, "1"),
280 V(ReachableAddresses, LINELIST, NULL),
281 V(ReachableDirAddresses, LINELIST, NULL),
282 V(ReachableORAddresses, LINELIST, NULL),
283 V(RecommendedVersions, LINELIST, NULL),
284 V(RecommendedClientVersions, LINELIST, NULL),
285 V(RecommendedServerVersions, LINELIST, NULL),
286 OBSOLETE("RedirectExit"),
287 V(RejectPlaintextPorts, CSV, ""),
288 V(RelayBandwidthBurst, MEMUNIT, "0"),
289 V(RelayBandwidthRate, MEMUNIT, "0"),
290 OBSOLETE("RendExcludeNodes"),
291 OBSOLETE("RendNodes"),
292 V(RendPostPeriod, INTERVAL, "1 hour"),
293 V(RephistTrackTime, INTERVAL, "24 hours"),
294 OBSOLETE("RouterFile"),
295 V(RunAsDaemon, BOOL, "0"),
296 V(RunTesting, BOOL, "0"),
297 V(SafeLogging, BOOL, "1"),
298 V(SafeSocks, BOOL, "0"),
299 V(ServerDNSAllowBrokenConfig, BOOL, "1"),
300 V(ServerDNSAllowNonRFC953Hostnames, BOOL,"0"),
301 V(ServerDNSDetectHijacking, BOOL, "1"),
302 V(ServerDNSRandomizeCase, BOOL, "1"),
303 V(ServerDNSResolvConfFile, STRING, NULL),
304 V(ServerDNSSearchDomains, BOOL, "0"),
305 V(ServerDNSTestAddresses, CSV,
306 "www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"),
307 V(ShutdownWaitLength, INTERVAL, "30 seconds"),
308 V(SocksListenAddress, LINELIST, NULL),
309 V(SocksPolicy, LINELIST, NULL),
310 V(SocksPort, UINT, "9050"),
311 V(SocksTimeout, INTERVAL, "2 minutes"),
312 OBSOLETE("StatusFetchPeriod"),
313 V(StrictEntryNodes, BOOL, "0"),
314 V(StrictExitNodes, BOOL, "0"),
315 OBSOLETE("SysLog"),
316 V(TestSocks, BOOL, "0"),
317 OBSOLETE("TestVia"),
318 V(TrackHostExits, CSV, NULL),
319 V(TrackHostExitsExpire, INTERVAL, "30 minutes"),
320 OBSOLETE("TrafficShaping"),
321 V(TransListenAddress, LINELIST, NULL),
322 V(TransPort, UINT, "0"),
323 V(TunnelDirConns, BOOL, "1"),
324 V(UpdateBridgesFromAuthority, BOOL, "0"),
325 V(UseBridges, BOOL, "0"),
326 V(UseEntryGuards, BOOL, "1"),
327 V(User, STRING, NULL),
328 VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
329 VAR("V2AuthoritativeDirectory",BOOL, V2AuthoritativeDir, "0"),
330 VAR("V3AuthoritativeDirectory",BOOL, V3AuthoritativeDir, "0"),
331 V(TestingV3AuthInitialVotingInterval, INTERVAL, "30 minutes"),
332 V(TestingV3AuthInitialVoteDelay, INTERVAL, "5 minutes"),
333 V(TestingV3AuthInitialDistDelay, INTERVAL, "5 minutes"),
334 V(V3AuthVotingInterval, INTERVAL, "1 hour"),
335 V(V3AuthVoteDelay, INTERVAL, "5 minutes"),
336 V(V3AuthDistDelay, INTERVAL, "5 minutes"),
337 V(V3AuthNIntervalsValid, UINT, "3"),
338 V(V3AuthUseLegacyKey, BOOL, "0"),
339 VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
340 V(VirtualAddrNetwork, STRING, "127.192.0.0/10"),
341 V(WarnPlaintextPorts, CSV, "23,109,110,143"),
342 VAR("__ReloadTorrcOnSIGHUP", BOOL, ReloadTorrcOnSIGHUP, "1"),
343 VAR("__AllDirActionsPrivate", BOOL, AllDirActionsPrivate, "0"),
344 VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits, "0"),
345 VAR("__LeaveStreamsUnattached",BOOL, LeaveStreamsUnattached, "0"),
346 VAR("__HashedControlSessionPassword", LINELIST, HashedControlSessionPassword,
347 NULL),
348 V(MinUptimeHidServDirectoryV2, INTERVAL, "24 hours"),
349 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
352 /** Override default values with these if the user sets the TestingTorNetwork
353 * option. */
354 static config_var_t testing_tor_network_defaults[] = {
355 V(ServerDNSAllowBrokenConfig, BOOL, "1"),
356 V(DirAllowPrivateAddresses, BOOL, "1"),
357 V(EnforceDistinctSubnets, BOOL, "0"),
358 V(AssumeReachable, BOOL, "1"),
359 V(AuthDirMaxServersPerAddr, UINT, "0"),
360 V(AuthDirMaxServersPerAuthAddr,UINT, "0"),
361 V(ClientDNSRejectInternalAddresses, BOOL,"0"),
362 V(ExitPolicyRejectPrivate, BOOL, "0"),
363 V(V3AuthVotingInterval, INTERVAL, "5 minutes"),
364 V(V3AuthVoteDelay, INTERVAL, "20 seconds"),
365 V(V3AuthDistDelay, INTERVAL, "20 seconds"),
366 V(TestingV3AuthInitialVotingInterval, INTERVAL, "5 minutes"),
367 V(TestingV3AuthInitialVoteDelay, INTERVAL, "20 seconds"),
368 V(TestingV3AuthInitialDistDelay, INTERVAL, "20 seconds"),
369 V(TestingAuthDirTimeToLearnReachability, INTERVAL, "0 minutes"),
370 V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "0 minutes"),
371 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
373 #undef VAR
375 #define VAR(name,conftype,member,initvalue) \
376 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member), \
377 initvalue }
379 /** Array of "state" variables saved to the ~/.tor/state file. */
380 static config_var_t _state_vars[] = {
381 V(AccountingBytesReadInInterval, MEMUNIT, NULL),
382 V(AccountingBytesWrittenInInterval, MEMUNIT, NULL),
383 V(AccountingExpectedUsage, MEMUNIT, NULL),
384 V(AccountingIntervalStart, ISOTIME, NULL),
385 V(AccountingSecondsActive, INTERVAL, NULL),
387 VAR("EntryGuard", LINELIST_S, EntryGuards, NULL),
388 VAR("EntryGuardDownSince", LINELIST_S, EntryGuards, NULL),
389 VAR("EntryGuardUnlistedSince", LINELIST_S, EntryGuards, NULL),
390 VAR("EntryGuardAddedBy", LINELIST_S, EntryGuards, NULL),
391 V(EntryGuards, LINELIST_V, NULL),
393 V(BWHistoryReadEnds, ISOTIME, NULL),
394 V(BWHistoryReadInterval, UINT, "900"),
395 V(BWHistoryReadValues, CSV, ""),
396 V(BWHistoryWriteEnds, ISOTIME, NULL),
397 V(BWHistoryWriteInterval, UINT, "900"),
398 V(BWHistoryWriteValues, CSV, ""),
400 V(TorVersion, STRING, NULL),
402 V(LastRotatedOnionKey, ISOTIME, NULL),
403 V(LastWritten, ISOTIME, NULL),
405 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
408 #undef VAR
409 #undef V
410 #undef OBSOLETE
412 /** Represents an English description of a configuration variable; used when
413 * generating configuration file comments. */
414 typedef struct config_var_description_t {
415 const char *name;
416 const char *description;
417 } config_var_description_t;
419 /** Descriptions of the configuration options, to be displayed by online
420 * option browsers */
421 /* XXXX022 did anybody want this? at all? If not, kill it.*/
422 static config_var_description_t options_description[] = {
423 /* ==== general options */
424 { "AvoidDiskWrites", "If non-zero, try to write to disk less frequently than"
425 " we would otherwise." },
426 { "BandwidthRate", "A token bucket limits the average incoming bandwidth on "
427 "this node to the specified number of bytes per second." },
428 { "BandwidthBurst", "Limit the maximum token buffer size (also known as "
429 "burst) to the given number of bytes." },
430 { "ConnLimit", "Minimum number of simultaneous sockets we must have." },
431 { "ConstrainedSockets", "Shrink tx and rx buffers for sockets to avoid "
432 "system limits on vservers and related environments. See man page for "
433 "more information regarding this option." },
434 { "ConstrainedSockSize", "Limit socket buffers to this size when "
435 "ConstrainedSockets is enabled." },
436 /* ControlListenAddress */
437 { "ControlPort", "If set, Tor will accept connections from the same machine "
438 "(localhost only) on this port, and allow those connections to control "
439 "the Tor process using the Tor Control Protocol (described in "
440 "control-spec.txt).", },
441 { "CookieAuthentication", "If this option is set to 1, don't allow any "
442 "connections to the control port except when the connecting process "
443 "can read a file that Tor creates in its data directory." },
444 { "DataDirectory", "Store working data, state, keys, and caches here." },
445 { "DirServer", "Tor only trusts directories signed with one of these "
446 "servers' keys. Used to override the standard list of directory "
447 "authorities." },
448 /* { "FastFirstHopPK", "" }, */
449 /* FetchServerDescriptors, FetchHidServDescriptors,
450 * FetchUselessDescriptors */
451 { "HardwareAccel", "If set, Tor tries to use hardware crypto accelerators "
452 "when it can." },
453 { "AccelName", "If set, try to use hardware crypto accelerator with this "
454 "specific ID." },
455 { "AccelDir", "If set, look in this directory for the dynamic hardware "
456 "engine in addition to OpenSSL default path." },
457 /* HashedControlPassword */
458 { "HTTPProxy", "Force Tor to make all HTTP directory requests through this "
459 "host:port (or host:80 if port is not set)." },
460 { "HTTPProxyAuthenticator", "A username:password pair to be used with "
461 "HTTPProxy." },
462 { "HTTPSProxy", "Force Tor to make all TLS (SSL) connections through this "
463 "host:port (or host:80 if port is not set)." },
464 { "HTTPSProxyAuthenticator", "A username:password pair to be used with "
465 "HTTPSProxy." },
466 { "KeepalivePeriod", "Send a padding cell every N seconds to keep firewalls "
467 "from closing our connections while Tor is not in use." },
468 { "Log", "Where to send logging messages. Format is "
469 "minSeverity[-maxSeverity] (stderr|stdout|syslog|file FILENAME)." },
470 { "OutboundBindAddress", "Make all outbound connections originate from the "
471 "provided IP address (only useful for multiple network interfaces)." },
472 { "PIDFile", "On startup, write our PID to this file. On clean shutdown, "
473 "remove the file." },
474 { "PreferTunneledDirConns", "If non-zero, avoid directory servers that "
475 "don't support tunneled connections." },
476 /* PreferTunneledDirConns */
477 /* ProtocolWarnings */
478 /* RephistTrackTime */
479 { "RunAsDaemon", "If set, Tor forks and daemonizes to the background when "
480 "started. Unix only." },
481 { "SafeLogging", "If set to 0, Tor logs potentially sensitive strings "
482 "rather than replacing them with the string [scrubbed]." },
483 { "TunnelDirConns", "If non-zero, when a directory server we contact "
484 "supports it, we will build a one-hop circuit and make an encrypted "
485 "connection via its ORPort." },
486 { "User", "On startup, setuid to this user." },
488 /* ==== client options */
489 { "AllowInvalidNodes", "Where on our circuits should Tor allow servers "
490 "that the directory authorities haven't called \"valid\"?" },
491 { "AllowNonRFC953Hostnames", "If set to 1, we don't automatically reject "
492 "hostnames for having invalid characters." },
493 /* CircuitBuildTimeout, CircuitIdleTimeout */
494 { "ClientOnly", "If set to 1, Tor will under no circumstances run as a "
495 "server, even if ORPort is enabled." },
496 { "EntryNodes", "A list of preferred entry nodes to use for the first hop "
497 "in circuits, when possible." },
498 /* { "EnforceDistinctSubnets" , "" }, */
499 { "ExitNodes", "A list of preferred nodes to use for the last hop in "
500 "circuits, when possible." },
501 { "ExcludeNodes", "A list of nodes never to use when building a circuit." },
502 { "FascistFirewall", "If set, Tor will only create outgoing connections to "
503 "servers running on the ports listed in FirewallPorts." },
504 { "FirewallPorts", "A list of ports that we can connect to. Only used "
505 "when FascistFirewall is set." },
506 { "LongLivedPorts", "A list of ports for services that tend to require "
507 "high-uptime connections." },
508 { "MapAddress", "Force Tor to treat all requests for one address as if "
509 "they were for another." },
510 { "NewCircuitPeriod", "Force Tor to consider whether to build a new circuit "
511 "every NUM seconds." },
512 { "MaxCircuitDirtiness", "Do not attach new streams to a circuit that has "
513 "been used more than this many seconds ago." },
514 /* NatdPort, NatdListenAddress */
515 { "NodeFamily", "A list of servers that constitute a 'family' and should "
516 "never be used in the same circuit." },
517 { "NumEntryGuards", "How many entry guards should we keep at a time?" },
518 /* PathlenCoinWeight */
519 { "ReachableAddresses", "Addresses we can connect to, as IP/bits:port-port. "
520 "By default, we assume all addresses are reachable." },
521 /* reachablediraddresses, reachableoraddresses. */
522 /* SafeSOCKS */
523 { "SOCKSPort", "The port where we listen for SOCKS connections from "
524 "applications." },
525 { "SOCKSListenAddress", "Bind to this address to listen to connections from "
526 "SOCKS-speaking applications." },
527 { "SOCKSPolicy", "Set an entry policy to limit which addresses can connect "
528 "to the SOCKSPort." },
529 /* SocksTimeout */
530 { "StrictExitNodes", "If set, Tor will fail to operate when none of the "
531 "configured ExitNodes can be used." },
532 { "StrictEntryNodes", "If set, Tor will fail to operate when none of the "
533 "configured EntryNodes can be used." },
534 /* TestSocks */
535 { "TrackHostsExit", "Hosts and domains which should, if possible, be "
536 "accessed from the same exit node each time we connect to them." },
537 { "TrackHostsExitExpire", "Time after which we forget which exit we were "
538 "using to connect to hosts in TrackHostsExit." },
539 /* "TransPort", "TransListenAddress */
540 { "UseEntryGuards", "Set to 0 if we want to pick from the whole set of "
541 "servers for the first position in each circuit, rather than picking a "
542 "set of 'Guards' to prevent profiling attacks." },
544 /* === server options */
545 { "Address", "The advertised (external) address we should use." },
546 /* Accounting* options. */
547 /* AssumeReachable */
548 { "ContactInfo", "Administrative contact information to advertise for this "
549 "server." },
550 { "ExitPolicy", "Address/port ranges for which to accept or reject outgoing "
551 "connections on behalf of Tor users." },
552 /* { "ExitPolicyRejectPrivate, "" }, */
553 { "MaxAdvertisedBandwidth", "If set, we will not advertise more than this "
554 "amount of bandwidth for our bandwidth rate, regardless of how much "
555 "bandwidth we actually detect." },
556 { "MaxOnionsPending", "Reject new attempts to extend circuits when we "
557 "already have this many pending." },
558 { "MyFamily", "Declare a list of other servers as belonging to the same "
559 "family as this one, so that clients will not use two from the same "
560 "family in the same circuit." },
561 { "Nickname", "Set the server nickname." },
562 { "NoPublish", "{DEPRECATED}" },
563 { "NumCPUs", "How many processes to use at once for public-key crypto." },
564 { "ORPort", "Advertise this port to listen for connections from Tor clients "
565 "and servers." },
566 { "ORListenAddress", "Bind to this address to listen for connections from "
567 "clients and servers, instead of the default 0.0.0.0:ORPort." },
568 { "PublishServerDescriptor", "Set to 0 to keep the server from "
569 "uploading info to the directory authorities." },
570 /* ServerDNS: DetectHijacking, ResolvConfFile, SearchDomains */
571 { "ShutdownWaitLength", "Wait this long for clients to finish when "
572 "shutting down because of a SIGINT." },
574 /* === directory cache options */
575 { "DirPort", "Serve directory information from this port, and act as a "
576 "directory cache." },
577 { "DirPortFrontPage", "Serve a static html disclaimer on DirPort." },
578 { "DirListenAddress", "Bind to this address to listen for connections from "
579 "clients and servers, instead of the default 0.0.0.0:DirPort." },
580 { "DirPolicy", "Set a policy to limit who can connect to the directory "
581 "port." },
583 /* Authority options: AuthDirBadExit, AuthDirInvalid, AuthDirReject,
584 * AuthDirRejectUnlisted, AuthDirListBadExits, AuthoritativeDirectory,
585 * DirAllowPrivateAddresses, HSAuthoritativeDir,
586 * NamingAuthoritativeDirectory, RecommendedVersions,
587 * RecommendedClientVersions, RecommendedServerVersions, RendPostPeriod,
588 * RunTesting, V1AuthoritativeDirectory, VersioningAuthoritativeDirectory, */
590 /* Hidden service options: HiddenService: dir,excludenodes, nodes,
591 * options, port. PublishHidServDescriptor */
593 /* Nonpersistent options: __LeaveStreamsUnattached, __AllDirActionsPrivate */
594 { NULL, NULL },
597 /** Online description of state variables. */
598 static config_var_description_t state_description[] = {
599 { "AccountingBytesReadInInterval",
600 "How many bytes have we read in this accounting period?" },
601 { "AccountingBytesWrittenInInterval",
602 "How many bytes have we written in this accounting period?" },
603 { "AccountingExpectedUsage",
604 "How many bytes did we expect to use per minute? (0 for no estimate.)" },
605 { "AccountingIntervalStart", "When did this accounting period begin?" },
606 { "AccountingSecondsActive", "How long have we been awake in this period?" },
608 { "BWHistoryReadEnds", "When does the last-recorded read-interval end?" },
609 { "BWHistoryReadInterval", "How long is each read-interval (in seconds)?" },
610 { "BWHistoryReadValues", "Number of bytes read in each interval." },
611 { "BWHistoryWriteEnds", "When does the last-recorded write-interval end?" },
612 { "BWHistoryWriteInterval", "How long is each write-interval (in seconds)?"},
613 { "BWHistoryWriteValues", "Number of bytes written in each interval." },
615 { "EntryGuard", "One of the nodes we have chosen as a fixed entry" },
616 { "EntryGuardDownSince",
617 "The last entry guard has been unreachable since this time." },
618 { "EntryGuardUnlistedSince",
619 "The last entry guard has been unusable since this time." },
621 { "LastRotatedOnionKey",
622 "The last time at which we changed the medium-term private key used for "
623 "building circuits." },
624 { "LastWritten", "When was this state file last regenerated?" },
626 { "TorVersion", "Which version of Tor generated this state file?" },
627 { NULL, NULL },
630 /** Type of a callback to validate whether a given configuration is
631 * well-formed and consistent. See options_trial_assign() for documentation
632 * of arguments. */
633 typedef int (*validate_fn_t)(void*,void*,int,char**);
635 /** Information on the keys, value types, key-to-struct-member mappings,
636 * variable descriptions, validation functions, and abbreviations for a
637 * configuration or storage format. */
638 typedef struct {
639 size_t size; /**< Size of the struct that everything gets parsed into. */
640 uint32_t magic; /**< Required 'magic value' to make sure we have a struct
641 * of the right type. */
642 off_t magic_offset; /**< Offset of the magic value within the struct. */
643 config_abbrev_t *abbrevs; /**< List of abbreviations that we expand when
644 * parsing this format. */
645 config_var_t *vars; /**< List of variables we recognize, their default
646 * values, and where we stick them in the structure. */
647 validate_fn_t validate_fn; /**< Function to validate config. */
648 /** Documentation for configuration variables. */
649 config_var_description_t *descriptions;
650 /** If present, extra is a LINELIST variable for unrecognized
651 * lines. Otherwise, unrecognized lines are an error. */
652 config_var_t *extra;
653 } config_format_t;
655 /** Macro: assert that <b>cfg</b> has the right magic field for format
656 * <b>fmt</b>. */
657 #define CHECK(fmt, cfg) STMT_BEGIN \
658 tor_assert(fmt && cfg); \
659 tor_assert((fmt)->magic == \
660 *(uint32_t*)STRUCT_VAR_P(cfg,fmt->magic_offset)); \
661 STMT_END
663 #ifdef MS_WINDOWS
664 static char *get_windows_conf_root(void);
665 #endif
666 static void config_line_append(config_line_t **lst,
667 const char *key, const char *val);
668 static void option_clear(config_format_t *fmt, or_options_t *options,
669 config_var_t *var);
670 static void option_reset(config_format_t *fmt, or_options_t *options,
671 config_var_t *var, int use_defaults);
672 static void config_free(config_format_t *fmt, void *options);
673 static int config_lines_eq(config_line_t *a, config_line_t *b);
674 static int option_is_same(config_format_t *fmt,
675 or_options_t *o1, or_options_t *o2,
676 const char *name);
677 static or_options_t *options_dup(config_format_t *fmt, or_options_t *old);
678 static int options_validate(or_options_t *old_options, or_options_t *options,
679 int from_setconf, char **msg);
680 static int options_act_reversible(or_options_t *old_options, char **msg);
681 static int options_act(or_options_t *old_options);
682 static int options_transition_allowed(or_options_t *old, or_options_t *new,
683 char **msg);
684 static int options_transition_affects_workers(or_options_t *old_options,
685 or_options_t *new_options);
686 static int options_transition_affects_descriptor(or_options_t *old_options,
687 or_options_t *new_options);
688 static int check_nickname_list(const char *lst, const char *name, char **msg);
689 static void config_register_addressmaps(or_options_t *options);
691 static int parse_bridge_line(const char *line, int validate_only);
692 static int parse_dir_server_line(const char *line,
693 authority_type_t required_type,
694 int validate_only);
695 static int validate_data_directory(or_options_t *options);
696 static int write_configuration_file(const char *fname, or_options_t *options);
697 static config_line_t *get_assigned_option(config_format_t *fmt,
698 void *options, const char *key,
699 int escape_val);
700 static void config_init(config_format_t *fmt, void *options);
701 static int or_state_validate(or_state_t *old_options, or_state_t *options,
702 int from_setconf, char **msg);
703 static int or_state_load(void);
704 static int options_init_logs(or_options_t *options, int validate_only);
706 static int is_listening_on_low_port(uint16_t port_option,
707 const config_line_t *listen_options);
709 static uint64_t config_parse_memunit(const char *s, int *ok);
710 static int config_parse_interval(const char *s, int *ok);
711 static void init_libevent(void);
712 static int opt_streq(const char *s1, const char *s2);
714 /** Magic value for or_options_t. */
715 #define OR_OPTIONS_MAGIC 9090909
717 /** Configuration format for or_options_t. */
718 static config_format_t options_format = {
719 sizeof(or_options_t),
720 OR_OPTIONS_MAGIC,
721 STRUCT_OFFSET(or_options_t, _magic),
722 _option_abbrevs,
723 _option_vars,
724 (validate_fn_t)options_validate,
725 options_description,
726 NULL
729 /** Magic value for or_state_t. */
730 #define OR_STATE_MAGIC 0x57A73f57
732 /** "Extra" variable in the state that receives lines we can't parse. This
733 * lets us preserve options from versions of Tor newer than us. */
734 static config_var_t state_extra_var = {
735 "__extra", CONFIG_TYPE_LINELIST, STRUCT_OFFSET(or_state_t, ExtraLines), NULL
738 /** Configuration format for or_state_t. */
739 static config_format_t state_format = {
740 sizeof(or_state_t),
741 OR_STATE_MAGIC,
742 STRUCT_OFFSET(or_state_t, _magic),
743 _state_abbrevs,
744 _state_vars,
745 (validate_fn_t)or_state_validate,
746 state_description,
747 &state_extra_var,
751 * Functions to read and write the global options pointer.
754 /** Command-line and config-file options. */
755 static or_options_t *global_options = NULL;
756 /** Name of most recently read torrc file. */
757 static char *torrc_fname = NULL;
758 /** Persistent serialized state. */
759 static or_state_t *global_state = NULL;
760 /** Configuration Options set by command line. */
761 static config_line_t *global_cmdline_options = NULL;
762 /** Contents of most recently read DirPortFrontPage file. */
763 static char *global_dirfrontpagecontents = NULL;
765 /** Return the contents of our frontpage string, or NULL if not configured. */
766 const char *
767 get_dirportfrontpage(void)
769 return global_dirfrontpagecontents;
772 /** Allocate an empty configuration object of a given format type. */
773 static void *
774 config_alloc(config_format_t *fmt)
776 void *opts = tor_malloc_zero(fmt->size);
777 *(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
778 CHECK(fmt, opts);
779 return opts;
782 /** Return the currently configured options. */
783 or_options_t *
784 get_options(void)
786 tor_assert(global_options);
787 return global_options;
790 /** Change the current global options to contain <b>new_val</b> instead of
791 * their current value; take action based on the new value; free the old value
792 * as necessary. Returns 0 on success, -1 on failure.
795 set_options(or_options_t *new_val, char **msg)
797 or_options_t *old_options = global_options;
798 global_options = new_val;
799 /* Note that we pass the *old* options below, for comparison. It
800 * pulls the new options directly out of global_options. */
801 if (options_act_reversible(old_options, msg)<0) {
802 tor_assert(*msg);
803 global_options = old_options;
804 return -1;
806 if (options_act(old_options) < 0) { /* acting on the options failed. die. */
807 log_err(LD_BUG,
808 "Acting on config options left us in a broken state. Dying.");
809 exit(1);
811 if (old_options)
812 config_free(&options_format, old_options);
814 return 0;
817 extern const char tor_svn_revision[]; /* from tor_main.c */
819 /** The version of this Tor process, as parsed. */
820 static char *_version = NULL;
822 /** Return the current Tor version. */
823 const char *
824 get_version(void)
826 if (_version == NULL) {
827 if (strlen(tor_svn_revision)) {
828 size_t len = strlen(VERSION)+strlen(tor_svn_revision)+8;
829 _version = tor_malloc(len);
830 tor_snprintf(_version, len, "%s (r%s)", VERSION, tor_svn_revision);
831 } else {
832 _version = tor_strdup(VERSION);
835 return _version;
838 /** Release additional memory allocated in options
840 static void
841 or_options_free(or_options_t *options)
843 if (options->_ExcludeExitNodesUnion)
844 routerset_free(options->_ExcludeExitNodesUnion);
845 config_free(&options_format, options);
848 /** Release all memory and resources held by global configuration structures.
850 void
851 config_free_all(void)
853 if (global_options) {
854 or_options_free(global_options);
855 global_options = NULL;
857 if (global_state) {
858 config_free(&state_format, global_state);
859 global_state = NULL;
861 if (global_cmdline_options) {
862 config_free_lines(global_cmdline_options);
863 global_cmdline_options = NULL;
865 tor_free(torrc_fname);
866 tor_free(_version);
867 tor_free(global_dirfrontpagecontents);
870 /** If options->SafeLogging is on, return a not very useful string,
871 * else return address.
873 const char *
874 safe_str(const char *address)
876 tor_assert(address);
877 if (get_options()->SafeLogging)
878 return "[scrubbed]";
879 else
880 return address;
883 /** Equivalent to escaped(safe_str(address)). See reentrancy note on
884 * escaped(): don't use this outside the main thread, or twice in the same
885 * log statement. */
886 const char *
887 escaped_safe_str(const char *address)
889 if (get_options()->SafeLogging)
890 return "[scrubbed]";
891 else
892 return escaped(address);
895 /** Add the default directory authorities directly into the trusted dir list,
896 * but only add them insofar as they share bits with <b>type</b>. */
897 static void
898 add_default_trusted_dir_authorities(authority_type_t type)
900 int i;
901 const char *dirservers[] = {
902 "moria1 v1 orport=9001 v3ident=E2A2AF570166665D738736D0DD58169CC61D8A8B "
903 "128.31.0.34:9031 FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441",
904 "moria2 v1 orport=9002 128.31.0.34:9032 "
905 "719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF",
906 "tor26 v1 orport=443 v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
907 "86.59.21.38:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
908 "dizum orport=443 v3ident=E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58 "
909 "194.109.206.212:80 7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
910 "Tonga orport=443 bridge no-v2 82.94.251.206:80 "
911 "4A0C CD2D DC79 9508 3D73 F5D6 6710 0C8A 5831 F16D",
912 "ides orport=9090 no-v2 v3ident=27B6B5996C426270A5C95488AA5BCEB6BCC86956 "
913 "216.224.124.114:9030 F397 038A DC51 3361 35E7 B80B D99C A384 4360 292B",
914 "gabelmoo orport=443 no-v2 "
915 "v3ident=81349FC1F2DBA2C2C11B45CB9706637D480AB913 "
916 "80.190.246.100:80 6833 3D07 61BC F397 A587 A0C0 B963 E4A9 E99E C4D3",
917 "dannenberg orport=443 no-v2 "
918 "v3ident=585769C78764D58426B8B52B6651A5A71137189A "
919 "213.73.91.31:80 7BE6 83E6 5D48 1413 21C5 ED92 F075 C553 64AC 7123",
920 NULL
922 for (i=0; dirservers[i]; i++) {
923 if (parse_dir_server_line(dirservers[i], type, 0)<0) {
924 log_err(LD_BUG, "Couldn't parse internal dirserver line %s",
925 dirservers[i]);
930 /** Look at all the config options for using alternate directory
931 * authorities, and make sure none of them are broken. Also, warn the
932 * user if we changed any dangerous ones.
934 static int
935 validate_dir_authorities(or_options_t *options, or_options_t *old_options)
937 config_line_t *cl;
939 if (options->DirServers &&
940 (options->AlternateDirAuthority || options->AlternateBridgeAuthority ||
941 options->AlternateHSAuthority)) {
942 log_warn(LD_CONFIG,
943 "You cannot set both DirServers and Alternate*Authority.");
944 return -1;
947 /* do we want to complain to the user about being partitionable? */
948 if ((options->DirServers &&
949 (!old_options ||
950 !config_lines_eq(options->DirServers, old_options->DirServers))) ||
951 (options->AlternateDirAuthority &&
952 (!old_options ||
953 !config_lines_eq(options->AlternateDirAuthority,
954 old_options->AlternateDirAuthority)))) {
955 log_warn(LD_CONFIG,
956 "You have used DirServer or AlternateDirAuthority to "
957 "specify alternate directory authorities in "
958 "your configuration. This is potentially dangerous: it can "
959 "make you look different from all other Tor users, and hurt "
960 "your anonymity. Even if you've specified the same "
961 "authorities as Tor uses by default, the defaults could "
962 "change in the future. Be sure you know what you're doing.");
965 /* Now go through the four ways you can configure an alternate
966 * set of directory authorities, and make sure none are broken. */
967 for (cl = options->DirServers; cl; cl = cl->next)
968 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
969 return -1;
970 for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
971 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
972 return -1;
973 for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
974 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
975 return -1;
976 for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
977 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
978 return -1;
979 return 0;
982 /** Look at all the config options and assign new dir authorities
983 * as appropriate.
985 static int
986 consider_adding_dir_authorities(or_options_t *options,
987 or_options_t *old_options)
989 config_line_t *cl;
990 int need_to_update =
991 !smartlist_len(router_get_trusted_dir_servers()) || !old_options ||
992 !config_lines_eq(options->DirServers, old_options->DirServers) ||
993 !config_lines_eq(options->AlternateBridgeAuthority,
994 old_options->AlternateBridgeAuthority) ||
995 !config_lines_eq(options->AlternateDirAuthority,
996 old_options->AlternateDirAuthority) ||
997 !config_lines_eq(options->AlternateHSAuthority,
998 old_options->AlternateHSAuthority);
1000 if (!need_to_update)
1001 return 0; /* all done */
1003 /* Start from a clean slate. */
1004 clear_trusted_dir_servers();
1006 if (!options->DirServers) {
1007 /* then we may want some of the defaults */
1008 authority_type_t type = NO_AUTHORITY;
1009 if (!options->AlternateBridgeAuthority)
1010 type |= BRIDGE_AUTHORITY;
1011 if (!options->AlternateDirAuthority)
1012 type |= V1_AUTHORITY | V2_AUTHORITY | V3_AUTHORITY;
1013 if (!options->AlternateHSAuthority)
1014 type |= HIDSERV_AUTHORITY;
1015 add_default_trusted_dir_authorities(type);
1018 for (cl = options->DirServers; cl; cl = cl->next)
1019 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
1020 return -1;
1021 for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
1022 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
1023 return -1;
1024 for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
1025 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
1026 return -1;
1027 for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
1028 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
1029 return -1;
1030 return 0;
1033 /** Fetch the active option list, and take actions based on it. All of the
1034 * things we do should survive being done repeatedly. If present,
1035 * <b>old_options</b> contains the previous value of the options.
1037 * Return 0 if all goes well, return -1 if things went badly.
1039 static int
1040 options_act_reversible(or_options_t *old_options, char **msg)
1042 smartlist_t *new_listeners = smartlist_create();
1043 smartlist_t *replaced_listeners = smartlist_create();
1044 static int libevent_initialized = 0;
1045 or_options_t *options = get_options();
1046 int running_tor = options->command == CMD_RUN_TOR;
1047 int set_conn_limit = 0;
1048 int r = -1;
1049 int logs_marked = 0;
1051 /* Daemonize _first_, since we only want to open most of this stuff in
1052 * the subprocess. Libevent bases can't be reliably inherited across
1053 * processes. */
1054 if (running_tor && options->RunAsDaemon) {
1055 /* No need to roll back, since you can't change the value. */
1056 start_daemon();
1059 #ifndef HAVE_SYS_UN_H
1060 if (options->ControlSocket) {
1061 *msg = tor_strdup("Unix domain sockets (ControlSocket) not supported"
1062 " on this OS/with this build.");
1063 goto rollback;
1065 #endif
1067 if (running_tor) {
1068 /* We need to set the connection limit before we can open the listeners. */
1069 if (set_max_file_descriptors((unsigned)options->ConnLimit,
1070 &options->_ConnLimit) < 0) {
1071 *msg = tor_strdup("Problem with ConnLimit value. See logs for details.");
1072 goto rollback;
1074 set_conn_limit = 1;
1076 /* Set up libevent. (We need to do this before we can register the
1077 * listeners as listeners.) */
1078 if (running_tor && !libevent_initialized) {
1079 init_libevent();
1080 libevent_initialized = 1;
1083 /* Launch the listeners. (We do this before we setuid, so we can bind to
1084 * ports under 1024.) */
1085 if (retry_all_listeners(replaced_listeners, new_listeners) < 0) {
1086 *msg = tor_strdup("Failed to bind one of the listener ports.");
1087 goto rollback;
1091 #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
1092 /* Open /dev/pf before dropping privileges. */
1093 if (options->TransPort) {
1094 if (get_pf_socket() < 0) {
1095 *msg = tor_strdup("Unable to open /dev/pf for transparent proxy.");
1096 goto rollback;
1099 #endif
1101 /* Setuid/setgid as appropriate */
1102 if (options->User) {
1103 if (switch_id(options->User) != 0) {
1104 /* No need to roll back, since you can't change the value. */
1105 *msg = tor_strdup("Problem with User value. See logs for details.");
1106 goto done;
1110 /* Ensure data directory is private; create if possible. */
1111 if (check_private_dir(options->DataDirectory,
1112 running_tor ? CPD_CREATE : CPD_CHECK)<0) {
1113 char buf[1024];
1114 int tmp = tor_snprintf(buf, sizeof(buf),
1115 "Couldn't access/create private data directory \"%s\"",
1116 options->DataDirectory);
1117 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
1118 goto done;
1119 /* No need to roll back, since you can't change the value. */
1122 if (directory_caches_v2_dir_info(options)) {
1123 size_t len = strlen(options->DataDirectory)+32;
1124 char *fn = tor_malloc(len);
1125 tor_snprintf(fn, len, "%s"PATH_SEPARATOR"cached-status",
1126 options->DataDirectory);
1127 if (check_private_dir(fn, running_tor ? CPD_CREATE : CPD_CHECK) < 0) {
1128 char buf[1024];
1129 int tmp = tor_snprintf(buf, sizeof(buf),
1130 "Couldn't access/create private data directory \"%s\"", fn);
1131 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
1132 tor_free(fn);
1133 goto done;
1135 tor_free(fn);
1138 /* Bail out at this point if we're not going to be a client or server:
1139 * we don't run Tor itself. */
1140 if (!running_tor)
1141 goto commit;
1143 mark_logs_temp(); /* Close current logs once new logs are open. */
1144 logs_marked = 1;
1145 if (options_init_logs(options, 0)<0) { /* Configure the log(s) */
1146 *msg = tor_strdup("Failed to init Log options. See logs for details.");
1147 goto rollback;
1150 commit:
1151 r = 0;
1152 if (logs_marked) {
1153 log_severity_list_t *severity =
1154 tor_malloc_zero(sizeof(log_severity_list_t));
1155 close_temp_logs();
1156 add_callback_log(severity, control_event_logmsg);
1157 control_adjust_event_log_severity();
1158 tor_free(severity);
1160 SMARTLIST_FOREACH(replaced_listeners, connection_t *, conn,
1162 log_notice(LD_NET, "Closing old %s on %s:%d",
1163 conn_type_to_string(conn->type), conn->address, conn->port);
1164 connection_close_immediate(conn);
1165 connection_mark_for_close(conn);
1167 goto done;
1169 rollback:
1170 r = -1;
1171 tor_assert(*msg);
1173 if (logs_marked) {
1174 rollback_log_changes();
1175 control_adjust_event_log_severity();
1178 if (set_conn_limit && old_options)
1179 set_max_file_descriptors((unsigned)old_options->ConnLimit,
1180 &options->_ConnLimit);
1182 SMARTLIST_FOREACH(new_listeners, connection_t *, conn,
1184 log_notice(LD_NET, "Closing partially-constructed listener %s on %s:%d",
1185 conn_type_to_string(conn->type), conn->address, conn->port);
1186 connection_close_immediate(conn);
1187 connection_mark_for_close(conn);
1190 done:
1191 smartlist_free(new_listeners);
1192 smartlist_free(replaced_listeners);
1193 return r;
1196 /** If we need to have a GEOIP ip-to-country map to run with our configured
1197 * options, return 1 and set *<b>reason_out</b> to a description of why. */
1199 options_need_geoip_info(or_options_t *options, const char **reason_out)
1201 int bridge_usage =
1202 options->BridgeRelay && options->BridgeRecordUsageByCountry;
1203 int routerset_usage =
1204 routerset_needs_geoip(options->EntryNodes) ||
1205 routerset_needs_geoip(options->ExitNodes) ||
1206 routerset_needs_geoip(options->ExcludeExitNodes) ||
1207 routerset_needs_geoip(options->ExcludeNodes);
1209 if (routerset_usage && reason_out) {
1210 *reason_out = "We've been configured to use (or avoid) nodes in certain "
1211 "countries, and we need GEOIP information to figure out which ones they "
1212 "are.";
1213 } else if (bridge_usage && reason_out) {
1214 *reason_out = "We've been configured to see which countries can access "
1215 "us as a bridge, and we need GEOIP information to tell which countries "
1216 "clients are in.";
1218 return bridge_usage || routerset_usage;
1221 /** Fetch the active option list, and take actions based on it. All of the
1222 * things we do should survive being done repeatedly. If present,
1223 * <b>old_options</b> contains the previous value of the options.
1225 * Return 0 if all goes well, return -1 if it's time to die.
1227 * Note: We haven't moved all the "act on new configuration" logic
1228 * here yet. Some is still in do_hup() and other places.
1230 static int
1231 options_act(or_options_t *old_options)
1233 config_line_t *cl;
1234 or_options_t *options = get_options();
1235 int running_tor = options->command == CMD_RUN_TOR;
1236 char *msg;
1238 if (running_tor && !have_lockfile()) {
1239 if (try_locking(options, 1) < 0)
1240 return -1;
1243 if (consider_adding_dir_authorities(options, old_options) < 0)
1244 return -1;
1246 if (options->Bridges) {
1247 clear_bridge_list();
1248 for (cl = options->Bridges; cl; cl = cl->next) {
1249 if (parse_bridge_line(cl->value, 0)<0) {
1250 log_warn(LD_BUG,
1251 "Previously validated Bridge line could not be added!");
1252 return -1;
1257 if (running_tor && rend_config_services(options, 0)<0) {
1258 log_warn(LD_BUG,
1259 "Previously validated hidden services line could not be added!");
1260 return -1;
1263 if (running_tor && rend_parse_service_authorization(options, 0) < 0) {
1264 log_warn(LD_BUG, "Previously validated client authorization for "
1265 "hidden services could not be added!");
1266 return -1;
1269 /* Load state */
1270 if (! global_state && running_tor) {
1271 if (or_state_load())
1272 return -1;
1273 rep_hist_load_mtbf_data(time(NULL));
1276 /* Bail out at this point if we're not going to be a client or server:
1277 * we want to not fork, and to log stuff to stderr. */
1278 if (!running_tor)
1279 return 0;
1281 /* Finish backgrounding the process */
1282 if (options->RunAsDaemon) {
1283 /* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
1284 finish_daemon(options->DataDirectory);
1287 /* Write our PID to the PID file. If we do not have write permissions we
1288 * will log a warning */
1289 if (options->PidFile)
1290 write_pidfile(options->PidFile);
1292 /* Register addressmap directives */
1293 config_register_addressmaps(options);
1294 parse_virtual_addr_network(options->VirtualAddrNetwork, 0, &msg);
1296 /* Update address policies. */
1297 if (policies_parse_from_options(options) < 0) {
1298 /* This should be impossible, but let's be sure. */
1299 log_warn(LD_BUG,"Error parsing already-validated policy options.");
1300 return -1;
1303 if (init_cookie_authentication(options->CookieAuthentication) < 0) {
1304 log_warn(LD_CONFIG,"Error creating cookie authentication file.");
1305 return -1;
1308 /* reload keys as needed for rendezvous services. */
1309 if (rend_service_load_keys()<0) {
1310 log_warn(LD_GENERAL,"Error loading rendezvous service keys");
1311 return -1;
1314 /* Set up accounting */
1315 if (accounting_parse_options(options, 0)<0) {
1316 log_warn(LD_CONFIG,"Error in accounting options");
1317 return -1;
1319 if (accounting_is_enabled(options))
1320 configure_accounting(time(NULL));
1322 /* Check for transitions that need action. */
1323 if (old_options) {
1324 if (options->UseEntryGuards && !old_options->UseEntryGuards) {
1325 log_info(LD_CIRC,
1326 "Switching to entry guards; abandoning previous circuits");
1327 circuit_mark_all_unused_circs();
1328 circuit_expire_all_dirty_circs();
1331 if (! bool_eq(options->BridgeRelay, old_options->BridgeRelay)) {
1332 log_info(LD_GENERAL, "Bridge status changed. Forgetting GeoIP stats.");
1333 geoip_remove_old_clients(time(NULL)+(2*60*60));
1336 if (options_transition_affects_workers(old_options, options)) {
1337 log_info(LD_GENERAL,
1338 "Worker-related options changed. Rotating workers.");
1339 if (server_mode(options) && !server_mode(old_options)) {
1340 if (init_keys() < 0) {
1341 log_warn(LD_BUG,"Error initializing keys; exiting");
1342 return -1;
1344 ip_address_changed(0);
1345 if (has_completed_circuit || !any_predicted_circuits(time(NULL)))
1346 inform_testing_reachability();
1348 cpuworkers_rotate();
1349 if (dns_reset())
1350 return -1;
1351 } else {
1352 if (dns_reset())
1353 return -1;
1356 if (options->V3AuthoritativeDir && !old_options->V3AuthoritativeDir)
1357 init_keys();
1360 /* Maybe load geoip file */
1361 if (options->GeoIPFile &&
1362 ((!old_options || !opt_streq(old_options->GeoIPFile, options->GeoIPFile))
1363 || !geoip_is_loaded())) {
1364 /* XXXX Don't use this "<default>" junk; make our filename options
1365 * understand prefixes somehow. -NM */
1366 /* XXXX021 Reload GeoIPFile on SIGHUP. -NM */
1367 char *actual_fname = tor_strdup(options->GeoIPFile);
1368 #ifdef WIN32
1369 if (!strcmp(actual_fname, "<default>")) {
1370 const char *conf_root = get_windows_conf_root();
1371 size_t len = strlen(conf_root)+16;
1372 tor_free(actual_fname);
1373 actual_fname = tor_malloc(len+1);
1374 tor_snprintf(actual_fname, len, "%s\\geoip", conf_root);
1376 #endif
1377 geoip_load_file(actual_fname, options);
1378 tor_free(actual_fname);
1381 #ifdef ENABLE_DIRREQ_STATS
1382 if (options->DirReqStatistics) {
1383 /* Check if GeoIP database could be loaded. */
1384 if (!geoip_is_loaded()) {
1385 log_warn(LD_CONFIG, "Configured to measure directory request "
1386 "statistics, but no GeoIP database found!");
1387 return -1;
1389 log_notice(LD_CONFIG, "Configured to count directory requests by "
1390 "country and write aggregate statistics to disk. Check the "
1391 "dirreq-stats file in your data directory that will first "
1392 "be written in 24 hours from now.");
1394 #else
1395 log_warn(LD_CONFIG, "DirReqStatistics enabled, but Tor was built "
1396 "without support for directory request statistics.");
1397 #endif
1399 #ifdef ENABLE_EXIT_STATS
1400 if (options->ExitPortStatistics)
1401 log_notice(LD_CONFIG, "Configured to measure exit port statistics. "
1402 "Look for the exit-stats file that will first be written to "
1403 "the data directory in 24 hours from now.");
1404 #else
1405 if (options->ExitPortStatistics)
1406 log_warn(LD_CONFIG, "ExitPortStatistics enabled, but Tor was built "
1407 "without port statistics support.");
1408 #endif
1410 #ifdef ENABLE_BUFFER_STATS
1411 if (options->CellStatistics)
1412 log_notice(LD_CONFIG, "Configured to measure cell statistics. Look "
1413 "for the buffer-stats file that will first be written to "
1414 "the data directory in 24 hours from now.");
1415 #else
1416 if (options->CellStatistics)
1417 log_warn(LD_CONFIG, "CellStatistics enabled, but Tor was built "
1418 "without cell statistics support.");
1419 #endif
1421 #ifdef ENABLE_ENTRY_STATS
1422 if (options->EntryStatistics) {
1423 if (should_record_bridge_info(options)) {
1424 /* Don't allow measuring statistics on entry guards when configured
1425 * as bridge. */
1426 log_warn(LD_CONFIG, "Bridges cannot be configured to measure "
1427 "additional GeoIP statistics as entry guards.");
1428 return -1;
1429 } else if (!geoip_is_loaded()) {
1430 /* Check if GeoIP database could be loaded. */
1431 log_warn(LD_CONFIG, "Configured to measure entry node statistics, "
1432 "but no GeoIP database found!");
1433 return -1;
1434 } else
1435 log_notice(LD_CONFIG, "Configured to measure entry node "
1436 "statistics. Look for the entry-stats file that will "
1437 "first be written to the data directory in 24 hours "
1438 "from now.");
1440 #else
1441 if (options->EntryStatistics)
1442 log_warn(LD_CONFIG, "EntryStatistics enabled, but Tor was built "
1443 "without entry node statistics support.");
1444 #endif
1445 /* Check if we need to parse and add the EntryNodes config option. */
1446 if (options->EntryNodes &&
1447 (!old_options ||
1448 (!routerset_equal(old_options->EntryNodes,options->EntryNodes))))
1449 entry_nodes_should_be_added();
1451 /* Since our options changed, we might need to regenerate and upload our
1452 * server descriptor.
1454 if (!old_options ||
1455 options_transition_affects_descriptor(old_options, options))
1456 mark_my_descriptor_dirty();
1458 /* We may need to reschedule some directory stuff if our status changed. */
1459 if (old_options) {
1460 if (authdir_mode_v3(options) && !authdir_mode_v3(old_options))
1461 dirvote_recalculate_timing(options, time(NULL));
1462 if (!bool_eq(directory_fetches_dir_info_early(options),
1463 directory_fetches_dir_info_early(old_options)) ||
1464 !bool_eq(directory_fetches_dir_info_later(options),
1465 directory_fetches_dir_info_later(old_options))) {
1466 /* Make sure update_router_have_min_dir_info gets called. */
1467 router_dir_info_changed();
1468 /* We might need to download a new consensus status later or sooner than
1469 * we had expected. */
1470 update_consensus_networkstatus_fetch_time(time(NULL));
1474 /* Load the webpage we're going to serve every time someone asks for '/' on
1475 our DirPort. */
1476 tor_free(global_dirfrontpagecontents);
1477 if (options->DirPortFrontPage) {
1478 global_dirfrontpagecontents =
1479 read_file_to_str(options->DirPortFrontPage, 0, NULL);
1480 if (!global_dirfrontpagecontents) {
1481 log_warn(LD_CONFIG,
1482 "DirPortFrontPage file '%s' not found. Continuing anyway.",
1483 options->DirPortFrontPage);
1487 return 0;
1491 * Functions to parse config options
1494 /** If <b>option</b> is an official abbreviation for a longer option,
1495 * return the longer option. Otherwise return <b>option</b>.
1496 * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
1497 * apply abbreviations that work for the config file and the command line.
1498 * If <b>warn_obsolete</b> is set, warn about deprecated names. */
1499 static const char *
1500 expand_abbrev(config_format_t *fmt, const char *option, int command_line,
1501 int warn_obsolete)
1503 int i;
1504 if (! fmt->abbrevs)
1505 return option;
1506 for (i=0; fmt->abbrevs[i].abbreviated; ++i) {
1507 /* Abbreviations are case insensitive. */
1508 if (!strcasecmp(option,fmt->abbrevs[i].abbreviated) &&
1509 (command_line || !fmt->abbrevs[i].commandline_only)) {
1510 if (warn_obsolete && fmt->abbrevs[i].warn) {
1511 log_warn(LD_CONFIG,
1512 "The configuration option '%s' is deprecated; "
1513 "use '%s' instead.",
1514 fmt->abbrevs[i].abbreviated,
1515 fmt->abbrevs[i].full);
1517 return fmt->abbrevs[i].full;
1520 return option;
1523 /** Helper: Read a list of configuration options from the command line.
1524 * If successful, put them in *<b>result</b> and return 0, and return
1525 * -1 and leave *<b>result</b> alone. */
1526 static int
1527 config_get_commandlines(int argc, char **argv, config_line_t **result)
1529 config_line_t *front = NULL;
1530 config_line_t **new = &front;
1531 char *s;
1532 int i = 1;
1534 while (i < argc) {
1535 if (!strcmp(argv[i],"-f") ||
1536 !strcmp(argv[i],"--hash-password")) {
1537 i += 2; /* command-line option with argument. ignore them. */
1538 continue;
1539 } else if (!strcmp(argv[i],"--list-fingerprint") ||
1540 !strcmp(argv[i],"--verify-config") ||
1541 !strcmp(argv[i],"--ignore-missing-torrc") ||
1542 !strcmp(argv[i],"--quiet") ||
1543 !strcmp(argv[i],"--hush")) {
1544 i += 1; /* command-line option. ignore it. */
1545 continue;
1546 } else if (!strcmp(argv[i],"--nt-service") ||
1547 !strcmp(argv[i],"-nt-service")) {
1548 i += 1;
1549 continue;
1552 if (i == argc-1) {
1553 log_warn(LD_CONFIG,"Command-line option '%s' with no value. Failing.",
1554 argv[i]);
1555 config_free_lines(front);
1556 return -1;
1559 *new = tor_malloc_zero(sizeof(config_line_t));
1560 s = argv[i];
1562 while (*s == '-')
1563 s++;
1565 (*new)->key = tor_strdup(expand_abbrev(&options_format, s, 1, 1));
1566 (*new)->value = tor_strdup(argv[i+1]);
1567 (*new)->next = NULL;
1568 log(LOG_DEBUG, LD_CONFIG, "command line: parsed keyword '%s', value '%s'",
1569 (*new)->key, (*new)->value);
1571 new = &((*new)->next);
1572 i += 2;
1574 *result = front;
1575 return 0;
1578 /** Helper: allocate a new configuration option mapping 'key' to 'val',
1579 * append it to *<b>lst</b>. */
1580 static void
1581 config_line_append(config_line_t **lst,
1582 const char *key,
1583 const char *val)
1585 config_line_t *newline;
1587 newline = tor_malloc(sizeof(config_line_t));
1588 newline->key = tor_strdup(key);
1589 newline->value = tor_strdup(val);
1590 newline->next = NULL;
1591 while (*lst)
1592 lst = &((*lst)->next);
1594 (*lst) = newline;
1597 /** Helper: parse the config string and strdup into key/value
1598 * strings. Set *result to the list, or NULL if parsing the string
1599 * failed. Return 0 on success, -1 on failure. Warn and ignore any
1600 * misformatted lines. */
1602 config_get_lines(const char *string, config_line_t **result)
1604 config_line_t *list = NULL, **next;
1605 char *k, *v;
1607 next = &list;
1608 do {
1609 k = v = NULL;
1610 string = parse_config_line_from_str(string, &k, &v);
1611 if (!string) {
1612 config_free_lines(list);
1613 tor_free(k);
1614 tor_free(v);
1615 return -1;
1617 if (k && v) {
1618 /* This list can get long, so we keep a pointer to the end of it
1619 * rather than using config_line_append over and over and getting
1620 * n^2 performance. */
1621 *next = tor_malloc(sizeof(config_line_t));
1622 (*next)->key = k;
1623 (*next)->value = v;
1624 (*next)->next = NULL;
1625 next = &((*next)->next);
1626 } else {
1627 tor_free(k);
1628 tor_free(v);
1630 } while (*string);
1632 *result = list;
1633 return 0;
1637 * Free all the configuration lines on the linked list <b>front</b>.
1639 void
1640 config_free_lines(config_line_t *front)
1642 config_line_t *tmp;
1644 while (front) {
1645 tmp = front;
1646 front = tmp->next;
1648 tor_free(tmp->key);
1649 tor_free(tmp->value);
1650 tor_free(tmp);
1654 /** Return the description for a given configuration variable, or NULL if no
1655 * description exists. */
1656 static const char *
1657 config_find_description(config_format_t *fmt, const char *name)
1659 int i;
1660 for (i=0; fmt->descriptions[i].name; ++i) {
1661 if (!strcasecmp(name, fmt->descriptions[i].name))
1662 return fmt->descriptions[i].description;
1664 return NULL;
1667 /** If <b>key</b> is a configuration option, return the corresponding
1668 * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
1669 * warn, and return the corresponding config_var_t. Otherwise return NULL.
1671 static config_var_t *
1672 config_find_option(config_format_t *fmt, const char *key)
1674 int i;
1675 size_t keylen = strlen(key);
1676 if (!keylen)
1677 return NULL; /* if they say "--" on the command line, it's not an option */
1678 /* First, check for an exact (case-insensitive) match */
1679 for (i=0; fmt->vars[i].name; ++i) {
1680 if (!strcasecmp(key, fmt->vars[i].name)) {
1681 return &fmt->vars[i];
1684 /* If none, check for an abbreviated match */
1685 for (i=0; fmt->vars[i].name; ++i) {
1686 if (!strncasecmp(key, fmt->vars[i].name, keylen)) {
1687 log_warn(LD_CONFIG, "The abbreviation '%s' is deprecated. "
1688 "Please use '%s' instead",
1689 key, fmt->vars[i].name);
1690 return &fmt->vars[i];
1693 /* Okay, unrecognized option */
1694 return NULL;
1698 * Functions to assign config options.
1701 /** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
1702 * with <b>c</b>-\>value and return 0, or return -1 if bad value.
1704 * Called from config_assign_line() and option_reset().
1706 static int
1707 config_assign_value(config_format_t *fmt, or_options_t *options,
1708 config_line_t *c, char **msg)
1710 int i, r, ok;
1711 char buf[1024];
1712 config_var_t *var;
1713 void *lvalue;
1715 CHECK(fmt, options);
1717 var = config_find_option(fmt, c->key);
1718 tor_assert(var);
1720 lvalue = STRUCT_VAR_P(options, var->var_offset);
1722 switch (var->type) {
1724 case CONFIG_TYPE_UINT:
1725 i = (int)tor_parse_long(c->value, 10, 0, INT_MAX, &ok, NULL);
1726 if (!ok) {
1727 r = tor_snprintf(buf, sizeof(buf),
1728 "Int keyword '%s %s' is malformed or out of bounds.",
1729 c->key, c->value);
1730 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1731 return -1;
1733 *(int *)lvalue = i;
1734 break;
1736 case CONFIG_TYPE_INTERVAL: {
1737 i = config_parse_interval(c->value, &ok);
1738 if (!ok) {
1739 r = tor_snprintf(buf, sizeof(buf),
1740 "Interval '%s %s' is malformed or out of bounds.",
1741 c->key, c->value);
1742 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1743 return -1;
1745 *(int *)lvalue = i;
1746 break;
1749 case CONFIG_TYPE_MEMUNIT: {
1750 uint64_t u64 = config_parse_memunit(c->value, &ok);
1751 if (!ok) {
1752 r = tor_snprintf(buf, sizeof(buf),
1753 "Value '%s %s' is malformed or out of bounds.",
1754 c->key, c->value);
1755 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1756 return -1;
1758 *(uint64_t *)lvalue = u64;
1759 break;
1762 case CONFIG_TYPE_BOOL:
1763 i = (int)tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
1764 if (!ok) {
1765 r = tor_snprintf(buf, sizeof(buf),
1766 "Boolean '%s %s' expects 0 or 1.",
1767 c->key, c->value);
1768 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1769 return -1;
1771 *(int *)lvalue = i;
1772 break;
1774 case CONFIG_TYPE_STRING:
1775 case CONFIG_TYPE_FILENAME:
1776 tor_free(*(char **)lvalue);
1777 *(char **)lvalue = tor_strdup(c->value);
1778 break;
1780 case CONFIG_TYPE_DOUBLE:
1781 *(double *)lvalue = atof(c->value);
1782 break;
1784 case CONFIG_TYPE_ISOTIME:
1785 if (parse_iso_time(c->value, (time_t *)lvalue)) {
1786 r = tor_snprintf(buf, sizeof(buf),
1787 "Invalid time '%s' for keyword '%s'", c->value, c->key);
1788 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1789 return -1;
1791 break;
1793 case CONFIG_TYPE_ROUTERSET:
1794 if (*(routerset_t**)lvalue) {
1795 routerset_free(*(routerset_t**)lvalue);
1797 *(routerset_t**)lvalue = routerset_new();
1798 if (routerset_parse(*(routerset_t**)lvalue, c->value, c->key)<0) {
1799 tor_snprintf(buf, sizeof(buf), "Invalid exit list '%s' for option '%s'",
1800 c->value, c->key);
1801 *msg = tor_strdup(buf);
1802 return -1;
1804 break;
1806 case CONFIG_TYPE_CSV:
1807 if (*(smartlist_t**)lvalue) {
1808 SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
1809 smartlist_clear(*(smartlist_t**)lvalue);
1810 } else {
1811 *(smartlist_t**)lvalue = smartlist_create();
1814 smartlist_split_string(*(smartlist_t**)lvalue, c->value, ",",
1815 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1816 break;
1818 case CONFIG_TYPE_LINELIST:
1819 case CONFIG_TYPE_LINELIST_S:
1820 config_line_append((config_line_t**)lvalue, c->key, c->value);
1821 break;
1822 case CONFIG_TYPE_OBSOLETE:
1823 log_warn(LD_CONFIG, "Skipping obsolete configuration option '%s'", c->key);
1824 break;
1825 case CONFIG_TYPE_LINELIST_V:
1826 r = tor_snprintf(buf, sizeof(buf),
1827 "You may not provide a value for virtual option '%s'", c->key);
1828 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1829 return -1;
1830 default:
1831 tor_assert(0);
1832 break;
1834 return 0;
1837 /** If <b>c</b> is a syntactically valid configuration line, update
1838 * <b>options</b> with its value and return 0. Otherwise return -1 for bad
1839 * key, -2 for bad value.
1841 * If <b>clear_first</b> is set, clear the value first. Then if
1842 * <b>use_defaults</b> is set, set the value to the default.
1844 * Called from config_assign().
1846 static int
1847 config_assign_line(config_format_t *fmt, or_options_t *options,
1848 config_line_t *c, int use_defaults,
1849 int clear_first, char **msg)
1851 config_var_t *var;
1853 CHECK(fmt, options);
1855 var = config_find_option(fmt, c->key);
1856 if (!var) {
1857 if (fmt->extra) {
1858 void *lvalue = STRUCT_VAR_P(options, fmt->extra->var_offset);
1859 log_info(LD_CONFIG,
1860 "Found unrecognized option '%s'; saving it.", c->key);
1861 config_line_append((config_line_t**)lvalue, c->key, c->value);
1862 return 0;
1863 } else {
1864 char buf[1024];
1865 int tmp = tor_snprintf(buf, sizeof(buf),
1866 "Unknown option '%s'. Failing.", c->key);
1867 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
1868 return -1;
1871 /* Put keyword into canonical case. */
1872 if (strcmp(var->name, c->key)) {
1873 tor_free(c->key);
1874 c->key = tor_strdup(var->name);
1877 if (!strlen(c->value)) {
1878 /* reset or clear it, then return */
1879 if (!clear_first) {
1880 if (var->type == CONFIG_TYPE_LINELIST ||
1881 var->type == CONFIG_TYPE_LINELIST_S) {
1882 /* We got an empty linelist from the torrc or command line.
1883 As a special case, call this an error. Warn and ignore. */
1884 log_warn(LD_CONFIG,
1885 "Linelist option '%s' has no value. Skipping.", c->key);
1886 } else { /* not already cleared */
1887 option_reset(fmt, options, var, use_defaults);
1890 return 0;
1893 if (config_assign_value(fmt, options, c, msg) < 0)
1894 return -2;
1895 return 0;
1898 /** Restore the option named <b>key</b> in options to its default value.
1899 * Called from config_assign(). */
1900 static void
1901 config_reset_line(config_format_t *fmt, or_options_t *options,
1902 const char *key, int use_defaults)
1904 config_var_t *var;
1906 CHECK(fmt, options);
1908 var = config_find_option(fmt, key);
1909 if (!var)
1910 return; /* give error on next pass. */
1912 option_reset(fmt, options, var, use_defaults);
1915 /** Return true iff key is a valid configuration option. */
1917 option_is_recognized(const char *key)
1919 config_var_t *var = config_find_option(&options_format, key);
1920 return (var != NULL);
1923 /** Return the canonical name of a configuration option, or NULL
1924 * if no such option exists. */
1925 const char *
1926 option_get_canonical_name(const char *key)
1928 config_var_t *var = config_find_option(&options_format, key);
1929 return var ? var->name : NULL;
1932 /** Return a canonical list of the options assigned for key.
1934 config_line_t *
1935 option_get_assignment(or_options_t *options, const char *key)
1937 return get_assigned_option(&options_format, options, key, 1);
1940 /** Return true iff value needs to be quoted and escaped to be used in
1941 * a configuration file. */
1942 static int
1943 config_value_needs_escape(const char *value)
1945 if (*value == '\"')
1946 return 1;
1947 while (*value) {
1948 switch (*value)
1950 case '\r':
1951 case '\n':
1952 case '#':
1953 /* Note: quotes and backspaces need special handling when we are using
1954 * quotes, not otherwise, so they don't trigger escaping on their
1955 * own. */
1956 return 1;
1957 default:
1958 if (!TOR_ISPRINT(*value))
1959 return 1;
1961 ++value;
1963 return 0;
1966 /** Return a newly allocated deep copy of the lines in <b>inp</b>. */
1967 static config_line_t *
1968 config_lines_dup(const config_line_t *inp)
1970 config_line_t *result = NULL;
1971 config_line_t **next_out = &result;
1972 while (inp) {
1973 *next_out = tor_malloc(sizeof(config_line_t));
1974 (*next_out)->key = tor_strdup(inp->key);
1975 (*next_out)->value = tor_strdup(inp->value);
1976 inp = inp->next;
1977 next_out = &((*next_out)->next);
1979 (*next_out) = NULL;
1980 return result;
1983 /** Return newly allocated line or lines corresponding to <b>key</b> in the
1984 * configuration <b>options</b>. If <b>escape_val</b> is true and a
1985 * value needs to be quoted before it's put in a config file, quote and
1986 * escape that value. Return NULL if no such key exists. */
1987 static config_line_t *
1988 get_assigned_option(config_format_t *fmt, void *options,
1989 const char *key, int escape_val)
1991 config_var_t *var;
1992 const void *value;
1993 char buf[32];
1994 config_line_t *result;
1995 tor_assert(options && key);
1997 CHECK(fmt, options);
1999 var = config_find_option(fmt, key);
2000 if (!var) {
2001 log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key);
2002 return NULL;
2004 value = STRUCT_VAR_P(options, var->var_offset);
2006 result = tor_malloc_zero(sizeof(config_line_t));
2007 result->key = tor_strdup(var->name);
2008 switch (var->type)
2010 case CONFIG_TYPE_STRING:
2011 case CONFIG_TYPE_FILENAME:
2012 if (*(char**)value) {
2013 result->value = tor_strdup(*(char**)value);
2014 } else {
2015 tor_free(result->key);
2016 tor_free(result);
2017 return NULL;
2019 break;
2020 case CONFIG_TYPE_ISOTIME:
2021 if (*(time_t*)value) {
2022 result->value = tor_malloc(ISO_TIME_LEN+1);
2023 format_iso_time(result->value, *(time_t*)value);
2024 } else {
2025 tor_free(result->key);
2026 tor_free(result);
2028 escape_val = 0; /* Can't need escape. */
2029 break;
2030 case CONFIG_TYPE_INTERVAL:
2031 case CONFIG_TYPE_UINT:
2032 /* This means every or_options_t uint or bool element
2033 * needs to be an int. Not, say, a uint16_t or char. */
2034 tor_snprintf(buf, sizeof(buf), "%d", *(int*)value);
2035 result->value = tor_strdup(buf);
2036 escape_val = 0; /* Can't need escape. */
2037 break;
2038 case CONFIG_TYPE_MEMUNIT:
2039 tor_snprintf(buf, sizeof(buf), U64_FORMAT,
2040 U64_PRINTF_ARG(*(uint64_t*)value));
2041 result->value = tor_strdup(buf);
2042 escape_val = 0; /* Can't need escape. */
2043 break;
2044 case CONFIG_TYPE_DOUBLE:
2045 tor_snprintf(buf, sizeof(buf), "%f", *(double*)value);
2046 result->value = tor_strdup(buf);
2047 escape_val = 0; /* Can't need escape. */
2048 break;
2049 case CONFIG_TYPE_BOOL:
2050 result->value = tor_strdup(*(int*)value ? "1" : "0");
2051 escape_val = 0; /* Can't need escape. */
2052 break;
2053 case CONFIG_TYPE_ROUTERSET:
2054 result->value = routerset_to_string(*(routerset_t**)value);
2055 break;
2056 case CONFIG_TYPE_CSV:
2057 if (*(smartlist_t**)value)
2058 result->value =
2059 smartlist_join_strings(*(smartlist_t**)value, ",", 0, NULL);
2060 else
2061 result->value = tor_strdup("");
2062 break;
2063 case CONFIG_TYPE_OBSOLETE:
2064 log_fn(LOG_PROTOCOL_WARN, LD_CONFIG,
2065 "You asked me for the value of an obsolete config option '%s'.",
2066 key);
2067 tor_free(result->key);
2068 tor_free(result);
2069 return NULL;
2070 case CONFIG_TYPE_LINELIST_S:
2071 log_warn(LD_CONFIG,
2072 "Can't return context-sensitive '%s' on its own", key);
2073 tor_free(result->key);
2074 tor_free(result);
2075 return NULL;
2076 case CONFIG_TYPE_LINELIST:
2077 case CONFIG_TYPE_LINELIST_V:
2078 tor_free(result->key);
2079 tor_free(result);
2080 result = config_lines_dup(*(const config_line_t**)value);
2081 break;
2082 default:
2083 tor_free(result->key);
2084 tor_free(result);
2085 log_warn(LD_BUG,"Unknown type %d for known key '%s'",
2086 var->type, key);
2087 return NULL;
2090 if (escape_val) {
2091 config_line_t *line;
2092 for (line = result; line; line = line->next) {
2093 if (line->value && config_value_needs_escape(line->value)) {
2094 char *newval = esc_for_log(line->value);
2095 tor_free(line->value);
2096 line->value = newval;
2101 return result;
2104 /** Iterate through the linked list of requested options <b>list</b>.
2105 * For each item, convert as appropriate and assign to <b>options</b>.
2106 * If an item is unrecognized, set *msg and return -1 immediately,
2107 * else return 0 for success.
2109 * If <b>clear_first</b>, interpret config options as replacing (not
2110 * extending) their previous values. If <b>clear_first</b> is set,
2111 * then <b>use_defaults</b> to decide if you set to defaults after
2112 * clearing, or make the value 0 or NULL.
2114 * Here are the use cases:
2115 * 1. A non-empty AllowInvalid line in your torrc. Appends to current
2116 * if linelist, replaces current if csv.
2117 * 2. An empty AllowInvalid line in your torrc. Should clear it.
2118 * 3. "RESETCONF AllowInvalid" sets it to default.
2119 * 4. "SETCONF AllowInvalid" makes it NULL.
2120 * 5. "SETCONF AllowInvalid=foo" clears it and sets it to "foo".
2122 * Use_defaults Clear_first
2123 * 0 0 "append"
2124 * 1 0 undefined, don't use
2125 * 0 1 "set to null first"
2126 * 1 1 "set to defaults first"
2127 * Return 0 on success, -1 on bad key, -2 on bad value.
2129 * As an additional special case, if a LINELIST config option has
2130 * no value and clear_first is 0, then warn and ignore it.
2134 There are three call cases for config_assign() currently.
2136 Case one: Torrc entry
2137 options_init_from_torrc() calls config_assign(0, 0)
2138 calls config_assign_line(0, 0).
2139 if value is empty, calls option_reset(0) and returns.
2140 calls config_assign_value(), appends.
2142 Case two: setconf
2143 options_trial_assign() calls config_assign(0, 1)
2144 calls config_reset_line(0)
2145 calls option_reset(0)
2146 calls option_clear().
2147 calls config_assign_line(0, 1).
2148 if value is empty, returns.
2149 calls config_assign_value(), appends.
2151 Case three: resetconf
2152 options_trial_assign() calls config_assign(1, 1)
2153 calls config_reset_line(1)
2154 calls option_reset(1)
2155 calls option_clear().
2156 calls config_assign_value(default)
2157 calls config_assign_line(1, 1).
2158 returns.
2160 static int
2161 config_assign(config_format_t *fmt, void *options, config_line_t *list,
2162 int use_defaults, int clear_first, char **msg)
2164 config_line_t *p;
2166 CHECK(fmt, options);
2168 /* pass 1: normalize keys */
2169 for (p = list; p; p = p->next) {
2170 const char *full = expand_abbrev(fmt, p->key, 0, 1);
2171 if (strcmp(full,p->key)) {
2172 tor_free(p->key);
2173 p->key = tor_strdup(full);
2177 /* pass 2: if we're reading from a resetting source, clear all
2178 * mentioned config options, and maybe set to their defaults. */
2179 if (clear_first) {
2180 for (p = list; p; p = p->next)
2181 config_reset_line(fmt, options, p->key, use_defaults);
2184 /* pass 3: assign. */
2185 while (list) {
2186 int r;
2187 if ((r=config_assign_line(fmt, options, list, use_defaults,
2188 clear_first, msg)))
2189 return r;
2190 list = list->next;
2192 return 0;
2195 /** Try assigning <b>list</b> to the global options. You do this by duping
2196 * options, assigning list to the new one, then validating it. If it's
2197 * ok, then throw out the old one and stick with the new one. Else,
2198 * revert to old and return failure. Return SETOPT_OK on success, or
2199 * a setopt_err_t on failure.
2201 * If not success, point *<b>msg</b> to a newly allocated string describing
2202 * what went wrong.
2204 setopt_err_t
2205 options_trial_assign(config_line_t *list, int use_defaults,
2206 int clear_first, char **msg)
2208 int r;
2209 or_options_t *trial_options = options_dup(&options_format, get_options());
2211 if ((r=config_assign(&options_format, trial_options,
2212 list, use_defaults, clear_first, msg)) < 0) {
2213 config_free(&options_format, trial_options);
2214 return r;
2217 if (options_validate(get_options(), trial_options, 1, msg) < 0) {
2218 config_free(&options_format, trial_options);
2219 return SETOPT_ERR_PARSE; /*XXX make this a separate return value. */
2222 if (options_transition_allowed(get_options(), trial_options, msg) < 0) {
2223 config_free(&options_format, trial_options);
2224 return SETOPT_ERR_TRANSITION;
2227 if (set_options(trial_options, msg)<0) {
2228 config_free(&options_format, trial_options);
2229 return SETOPT_ERR_SETTING;
2232 /* we liked it. put it in place. */
2233 return SETOPT_OK;
2236 /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
2237 * Called from option_reset() and config_free(). */
2238 static void
2239 option_clear(config_format_t *fmt, or_options_t *options, config_var_t *var)
2241 void *lvalue = STRUCT_VAR_P(options, var->var_offset);
2242 (void)fmt; /* unused */
2243 switch (var->type) {
2244 case CONFIG_TYPE_STRING:
2245 case CONFIG_TYPE_FILENAME:
2246 tor_free(*(char**)lvalue);
2247 break;
2248 case CONFIG_TYPE_DOUBLE:
2249 *(double*)lvalue = 0.0;
2250 break;
2251 case CONFIG_TYPE_ISOTIME:
2252 *(time_t*)lvalue = 0;
2253 case CONFIG_TYPE_INTERVAL:
2254 case CONFIG_TYPE_UINT:
2255 case CONFIG_TYPE_BOOL:
2256 *(int*)lvalue = 0;
2257 break;
2258 case CONFIG_TYPE_MEMUNIT:
2259 *(uint64_t*)lvalue = 0;
2260 break;
2261 case CONFIG_TYPE_ROUTERSET:
2262 if (*(routerset_t**)lvalue) {
2263 routerset_free(*(routerset_t**)lvalue);
2264 *(routerset_t**)lvalue = NULL;
2266 case CONFIG_TYPE_CSV:
2267 if (*(smartlist_t**)lvalue) {
2268 SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
2269 smartlist_free(*(smartlist_t **)lvalue);
2270 *(smartlist_t **)lvalue = NULL;
2272 break;
2273 case CONFIG_TYPE_LINELIST:
2274 case CONFIG_TYPE_LINELIST_S:
2275 config_free_lines(*(config_line_t **)lvalue);
2276 *(config_line_t **)lvalue = NULL;
2277 break;
2278 case CONFIG_TYPE_LINELIST_V:
2279 /* handled by linelist_s. */
2280 break;
2281 case CONFIG_TYPE_OBSOLETE:
2282 break;
2286 /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
2287 * <b>use_defaults</b>, set it to its default value.
2288 * Called by config_init() and option_reset_line() and option_assign_line(). */
2289 static void
2290 option_reset(config_format_t *fmt, or_options_t *options,
2291 config_var_t *var, int use_defaults)
2293 config_line_t *c;
2294 char *msg = NULL;
2295 CHECK(fmt, options);
2296 option_clear(fmt, options, var); /* clear it first */
2297 if (!use_defaults)
2298 return; /* all done */
2299 if (var->initvalue) {
2300 c = tor_malloc_zero(sizeof(config_line_t));
2301 c->key = tor_strdup(var->name);
2302 c->value = tor_strdup(var->initvalue);
2303 if (config_assign_value(fmt, options, c, &msg) < 0) {
2304 log_warn(LD_BUG, "Failed to assign default: %s", msg);
2305 tor_free(msg); /* if this happens it's a bug */
2307 config_free_lines(c);
2311 /** Print a usage message for tor. */
2312 static void
2313 print_usage(void)
2315 printf(
2316 "Copyright (c) 2001-2004, Roger Dingledine\n"
2317 "Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson\n"
2318 "Copyright (c) 2007-2009, The Tor Project, Inc.\n\n"
2319 "tor -f <torrc> [args]\n"
2320 "See man page for options, or https://www.torproject.org/ for "
2321 "documentation.\n");
2324 /** Print all non-obsolete torrc options. */
2325 static void
2326 list_torrc_options(void)
2328 int i;
2329 smartlist_t *lines = smartlist_create();
2330 for (i = 0; _option_vars[i].name; ++i) {
2331 config_var_t *var = &_option_vars[i];
2332 const char *desc;
2333 if (var->type == CONFIG_TYPE_OBSOLETE ||
2334 var->type == CONFIG_TYPE_LINELIST_V)
2335 continue;
2336 desc = config_find_description(&options_format, var->name);
2337 printf("%s\n", var->name);
2338 if (desc) {
2339 wrap_string(lines, desc, 76, " ", " ");
2340 SMARTLIST_FOREACH(lines, char *, cp, {
2341 printf("%s", cp);
2342 tor_free(cp);
2344 smartlist_clear(lines);
2347 smartlist_free(lines);
2350 /** Last value actually set by resolve_my_address. */
2351 static uint32_t last_resolved_addr = 0;
2353 * Based on <b>options-\>Address</b>, guess our public IP address and put it
2354 * (in host order) into *<b>addr_out</b>. If <b>hostname_out</b> is provided,
2355 * set *<b>hostname_out</b> to a new string holding the hostname we used to
2356 * get the address. Return 0 if all is well, or -1 if we can't find a suitable
2357 * public IP address.
2360 resolve_my_address(int warn_severity, or_options_t *options,
2361 uint32_t *addr_out, char **hostname_out)
2363 struct in_addr in;
2364 struct hostent *rent;
2365 char hostname[256];
2366 int explicit_ip=1;
2367 int explicit_hostname=1;
2368 int from_interface=0;
2369 char tmpbuf[INET_NTOA_BUF_LEN];
2370 const char *address = options->Address;
2371 int notice_severity = warn_severity <= LOG_NOTICE ?
2372 LOG_NOTICE : warn_severity;
2374 tor_assert(addr_out);
2376 if (address && *address) {
2377 strlcpy(hostname, address, sizeof(hostname));
2378 } else { /* then we need to guess our address */
2379 explicit_ip = 0; /* it's implicit */
2380 explicit_hostname = 0; /* it's implicit */
2382 if (gethostname(hostname, sizeof(hostname)) < 0) {
2383 log_fn(warn_severity, LD_NET,"Error obtaining local hostname");
2384 return -1;
2386 log_debug(LD_CONFIG,"Guessed local host name as '%s'",hostname);
2389 /* now we know hostname. resolve it and keep only the IP address */
2391 if (tor_inet_aton(hostname, &in) == 0) {
2392 /* then we have to resolve it */
2393 explicit_ip = 0;
2394 rent = (struct hostent *)gethostbyname(hostname);
2395 if (!rent) {
2396 uint32_t interface_ip;
2398 if (explicit_hostname) {
2399 log_fn(warn_severity, LD_CONFIG,
2400 "Could not resolve local Address '%s'. Failing.", hostname);
2401 return -1;
2403 log_fn(notice_severity, LD_CONFIG,
2404 "Could not resolve guessed local hostname '%s'. "
2405 "Trying something else.", hostname);
2406 if (get_interface_address(warn_severity, &interface_ip)) {
2407 log_fn(warn_severity, LD_CONFIG,
2408 "Could not get local interface IP address. Failing.");
2409 return -1;
2411 from_interface = 1;
2412 in.s_addr = htonl(interface_ip);
2413 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2414 log_fn(notice_severity, LD_CONFIG, "Learned IP address '%s' for "
2415 "local interface. Using that.", tmpbuf);
2416 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
2417 } else {
2418 tor_assert(rent->h_length == 4);
2419 memcpy(&in.s_addr, rent->h_addr, rent->h_length);
2421 if (!explicit_hostname &&
2422 is_internal_IP(ntohl(in.s_addr), 0)) {
2423 uint32_t interface_ip;
2425 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2426 log_fn(notice_severity, LD_CONFIG, "Guessed local hostname '%s' "
2427 "resolves to a private IP address (%s). Trying something "
2428 "else.", hostname, tmpbuf);
2430 if (get_interface_address(warn_severity, &interface_ip)) {
2431 log_fn(warn_severity, LD_CONFIG,
2432 "Could not get local interface IP address. Too bad.");
2433 } else if (is_internal_IP(interface_ip, 0)) {
2434 struct in_addr in2;
2435 in2.s_addr = htonl(interface_ip);
2436 tor_inet_ntoa(&in2,tmpbuf,sizeof(tmpbuf));
2437 log_fn(notice_severity, LD_CONFIG,
2438 "Interface IP address '%s' is a private address too. "
2439 "Ignoring.", tmpbuf);
2440 } else {
2441 from_interface = 1;
2442 in.s_addr = htonl(interface_ip);
2443 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2444 log_fn(notice_severity, LD_CONFIG,
2445 "Learned IP address '%s' for local interface."
2446 " Using that.", tmpbuf);
2447 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
2453 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2454 if (is_internal_IP(ntohl(in.s_addr), 0) &&
2455 options->_PublishServerDescriptor) {
2456 /* make sure we're ok with publishing an internal IP */
2457 if (!options->DirServers && !options->AlternateDirAuthority) {
2458 /* if they are using the default dirservers, disallow internal IPs
2459 * always. */
2460 log_fn(warn_severity, LD_CONFIG,
2461 "Address '%s' resolves to private IP address '%s'. "
2462 "Tor servers that use the default DirServers must have public "
2463 "IP addresses.", hostname, tmpbuf);
2464 return -1;
2466 if (!explicit_ip) {
2467 /* even if they've set their own dirservers, require an explicit IP if
2468 * they're using an internal address. */
2469 log_fn(warn_severity, LD_CONFIG, "Address '%s' resolves to private "
2470 "IP address '%s'. Please set the Address config option to be "
2471 "the IP address you want to use.", hostname, tmpbuf);
2472 return -1;
2476 log_debug(LD_CONFIG, "Resolved Address to '%s'.", tmpbuf);
2477 *addr_out = ntohl(in.s_addr);
2478 if (last_resolved_addr && last_resolved_addr != *addr_out) {
2479 /* Leave this as a notice, regardless of the requested severity,
2480 * at least until dynamic IP address support becomes bulletproof. */
2481 log_notice(LD_NET,
2482 "Your IP address seems to have changed to %s. Updating.",
2483 tmpbuf);
2484 ip_address_changed(0);
2486 if (last_resolved_addr != *addr_out) {
2487 const char *method;
2488 const char *h = hostname;
2489 if (explicit_ip) {
2490 method = "CONFIGURED";
2491 h = NULL;
2492 } else if (explicit_hostname) {
2493 method = "RESOLVED";
2494 } else if (from_interface) {
2495 method = "INTERFACE";
2496 h = NULL;
2497 } else {
2498 method = "GETHOSTNAME";
2500 control_event_server_status(LOG_NOTICE,
2501 "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s %s%s",
2502 tmpbuf, method, h?"HOSTNAME=":"", h);
2504 last_resolved_addr = *addr_out;
2505 if (hostname_out)
2506 *hostname_out = tor_strdup(hostname);
2507 return 0;
2510 /** Return true iff <b>addr</b> is judged to be on the same network as us, or
2511 * on a private network.
2514 is_local_addr(const tor_addr_t *addr)
2516 if (tor_addr_is_internal(addr, 0))
2517 return 1;
2518 /* Check whether ip is on the same /24 as we are. */
2519 if (get_options()->EnforceDistinctSubnets == 0)
2520 return 0;
2521 if (tor_addr_family(addr) == AF_INET) {
2522 /*XXXX022 IP6 what corresponds to an /24? */
2523 uint32_t ip = tor_addr_to_ipv4h(addr);
2525 /* It's possible that this next check will hit before the first time
2526 * resolve_my_address actually succeeds. (For clients, it is likely that
2527 * resolve_my_address will never be called at all). In those cases,
2528 * last_resolved_addr will be 0, and so checking to see whether ip is on
2529 * the same /24 as last_resolved_addr will be the same as checking whether
2530 * it was on net 0, which is already done by is_internal_IP.
2532 if ((last_resolved_addr & 0xffffff00ul) == (ip & 0xffffff00ul))
2533 return 1;
2535 return 0;
2538 /** Called when we don't have a nickname set. Try to guess a good nickname
2539 * based on the hostname, and return it in a newly allocated string. If we
2540 * can't, return NULL and let the caller warn if it wants to. */
2541 static char *
2542 get_default_nickname(void)
2544 static const char * const bad_default_nicknames[] = {
2545 "localhost",
2546 NULL,
2548 char localhostname[256];
2549 char *cp, *out, *outp;
2550 int i;
2552 if (gethostname(localhostname, sizeof(localhostname)) < 0)
2553 return NULL;
2555 /* Put it in lowercase; stop at the first dot. */
2556 if ((cp = strchr(localhostname, '.')))
2557 *cp = '\0';
2558 tor_strlower(localhostname);
2560 /* Strip invalid characters. */
2561 cp = localhostname;
2562 out = outp = tor_malloc(strlen(localhostname) + 1);
2563 while (*cp) {
2564 if (strchr(LEGAL_NICKNAME_CHARACTERS, *cp))
2565 *outp++ = *cp++;
2566 else
2567 cp++;
2569 *outp = '\0';
2571 /* Enforce length. */
2572 if (strlen(out) > MAX_NICKNAME_LEN)
2573 out[MAX_NICKNAME_LEN]='\0';
2575 /* Check for dumb names. */
2576 for (i = 0; bad_default_nicknames[i]; ++i) {
2577 if (!strcmp(out, bad_default_nicknames[i])) {
2578 tor_free(out);
2579 return NULL;
2583 return out;
2586 /** Release storage held by <b>options</b>. */
2587 static void
2588 config_free(config_format_t *fmt, void *options)
2590 int i;
2592 tor_assert(options);
2594 for (i=0; fmt->vars[i].name; ++i)
2595 option_clear(fmt, options, &(fmt->vars[i]));
2596 if (fmt->extra) {
2597 config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->var_offset);
2598 config_free_lines(*linep);
2599 *linep = NULL;
2601 tor_free(options);
2604 /** Return true iff a and b contain identical keys and values in identical
2605 * order. */
2606 static int
2607 config_lines_eq(config_line_t *a, config_line_t *b)
2609 while (a && b) {
2610 if (strcasecmp(a->key, b->key) || strcmp(a->value, b->value))
2611 return 0;
2612 a = a->next;
2613 b = b->next;
2615 if (a || b)
2616 return 0;
2617 return 1;
2620 /** Return true iff the option <b>name</b> has the same value in <b>o1</b>
2621 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
2623 static int
2624 option_is_same(config_format_t *fmt,
2625 or_options_t *o1, or_options_t *o2, const char *name)
2627 config_line_t *c1, *c2;
2628 int r = 1;
2629 CHECK(fmt, o1);
2630 CHECK(fmt, o2);
2632 c1 = get_assigned_option(fmt, o1, name, 0);
2633 c2 = get_assigned_option(fmt, o2, name, 0);
2634 r = config_lines_eq(c1, c2);
2635 config_free_lines(c1);
2636 config_free_lines(c2);
2637 return r;
2640 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
2641 static or_options_t *
2642 options_dup(config_format_t *fmt, or_options_t *old)
2644 or_options_t *newopts;
2645 int i;
2646 config_line_t *line;
2648 newopts = config_alloc(fmt);
2649 for (i=0; fmt->vars[i].name; ++i) {
2650 if (fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2651 continue;
2652 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE)
2653 continue;
2654 line = get_assigned_option(fmt, old, fmt->vars[i].name, 0);
2655 if (line) {
2656 char *msg = NULL;
2657 if (config_assign(fmt, newopts, line, 0, 0, &msg) < 0) {
2658 log_err(LD_BUG, "Config_get_assigned_option() generated "
2659 "something we couldn't config_assign(): %s", msg);
2660 tor_free(msg);
2661 tor_assert(0);
2664 config_free_lines(line);
2666 return newopts;
2669 /** Return a new empty or_options_t. Used for testing. */
2670 or_options_t *
2671 options_new(void)
2673 return config_alloc(&options_format);
2676 /** Set <b>options</b> to hold reasonable defaults for most options.
2677 * Each option defaults to zero. */
2678 void
2679 options_init(or_options_t *options)
2681 config_init(&options_format, options);
2684 /* Check if the port number given in <b>port_option</b> in combination with
2685 * the specified port in <b>listen_options</b> will result in Tor actually
2686 * opening a low port (meaning a port lower than 1024). Return 1 if
2687 * it is, or 0 if it isn't or the concept of a low port isn't applicable for
2688 * the platform we're on. */
2689 static int
2690 is_listening_on_low_port(uint16_t port_option,
2691 const config_line_t *listen_options)
2693 #ifdef MS_WINDOWS
2694 return 0; /* No port is too low for windows. */
2695 #else
2696 const config_line_t *l;
2697 uint16_t p;
2698 if (port_option == 0)
2699 return 0; /* We're not listening */
2700 if (listen_options == NULL)
2701 return (port_option < 1024);
2703 for (l = listen_options; l; l = l->next) {
2704 parse_addr_port(LOG_WARN, l->value, NULL, NULL, &p);
2705 if (p<1024) {
2706 return 1;
2709 return 0;
2710 #endif
2713 /** Set all vars in the configuration object <b>options</b> to their default
2714 * values. */
2715 static void
2716 config_init(config_format_t *fmt, void *options)
2718 int i;
2719 config_var_t *var;
2720 CHECK(fmt, options);
2722 for (i=0; fmt->vars[i].name; ++i) {
2723 var = &fmt->vars[i];
2724 if (!var->initvalue)
2725 continue; /* defaults to NULL or 0 */
2726 option_reset(fmt, options, var, 1);
2730 /** Allocate and return a new string holding the written-out values of the vars
2731 * in 'options'. If 'minimal', do not write out any default-valued vars.
2732 * Else, if comment_defaults, write default values as comments.
2734 static char *
2735 config_dump(config_format_t *fmt, void *options, int minimal,
2736 int comment_defaults)
2738 smartlist_t *elements;
2739 or_options_t *defaults;
2740 config_line_t *line, *assigned;
2741 char *result;
2742 int i;
2743 const char *desc;
2744 char *msg = NULL;
2746 defaults = config_alloc(fmt);
2747 config_init(fmt, defaults);
2749 /* XXX use a 1 here so we don't add a new log line while dumping */
2750 if (fmt->validate_fn(NULL,defaults, 1, &msg) < 0) {
2751 log_err(LD_BUG, "Failed to validate default config.");
2752 tor_free(msg);
2753 tor_assert(0);
2756 elements = smartlist_create();
2757 for (i=0; fmt->vars[i].name; ++i) {
2758 int comment_option = 0;
2759 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE ||
2760 fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2761 continue;
2762 /* Don't save 'hidden' control variables. */
2763 if (!strcmpstart(fmt->vars[i].name, "__"))
2764 continue;
2765 if (minimal && option_is_same(fmt, options, defaults, fmt->vars[i].name))
2766 continue;
2767 else if (comment_defaults &&
2768 option_is_same(fmt, options, defaults, fmt->vars[i].name))
2769 comment_option = 1;
2771 desc = config_find_description(fmt, fmt->vars[i].name);
2772 line = assigned = get_assigned_option(fmt, options, fmt->vars[i].name, 1);
2774 if (line && desc) {
2775 /* Only dump the description if there's something to describe. */
2776 wrap_string(elements, desc, 78, "# ", "# ");
2779 for (; line; line = line->next) {
2780 size_t len = strlen(line->key) + strlen(line->value) + 5;
2781 char *tmp;
2782 tmp = tor_malloc(len);
2783 if (tor_snprintf(tmp, len, "%s%s %s\n",
2784 comment_option ? "# " : "",
2785 line->key, line->value)<0) {
2786 log_err(LD_BUG,"Internal error writing option value");
2787 tor_assert(0);
2789 smartlist_add(elements, tmp);
2791 config_free_lines(assigned);
2794 if (fmt->extra) {
2795 line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->var_offset);
2796 for (; line; line = line->next) {
2797 size_t len = strlen(line->key) + strlen(line->value) + 3;
2798 char *tmp;
2799 tmp = tor_malloc(len);
2800 if (tor_snprintf(tmp, len, "%s %s\n", line->key, line->value)<0) {
2801 log_err(LD_BUG,"Internal error writing option value");
2802 tor_assert(0);
2804 smartlist_add(elements, tmp);
2808 result = smartlist_join_strings(elements, "", 0, NULL);
2809 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2810 smartlist_free(elements);
2811 config_free(fmt, defaults);
2812 return result;
2815 /** Return a string containing a possible configuration file that would give
2816 * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
2817 * include options that are the same as Tor's defaults.
2819 static char *
2820 options_dump(or_options_t *options, int minimal)
2822 return config_dump(&options_format, options, minimal, 0);
2825 /** Return 0 if every element of sl is a string holding a decimal
2826 * representation of a port number, or if sl is NULL.
2827 * Otherwise set *msg and return -1. */
2828 static int
2829 validate_ports_csv(smartlist_t *sl, const char *name, char **msg)
2831 int i;
2832 char buf[1024];
2833 tor_assert(name);
2835 if (!sl)
2836 return 0;
2838 SMARTLIST_FOREACH(sl, const char *, cp,
2840 i = atoi(cp);
2841 if (i < 1 || i > 65535) {
2842 int r = tor_snprintf(buf, sizeof(buf),
2843 "Port '%s' out of range in %s", cp, name);
2844 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2845 return -1;
2848 return 0;
2851 /** If <b>value</b> exceeds ROUTER_MAX_DECLARED_BANDWIDTH, write
2852 * a complaint into *<b>msg</b> using string <b>desc</b>, and return -1.
2853 * Else return 0.
2855 static int
2856 ensure_bandwidth_cap(uint64_t *value, const char *desc, char **msg)
2858 int r;
2859 char buf[1024];
2860 if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
2861 /* This handles an understandable special case where somebody says "2gb"
2862 * whereas our actual maximum is 2gb-1 (INT_MAX) */
2863 --*value;
2865 if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
2866 r = tor_snprintf(buf, sizeof(buf), "%s ("U64_FORMAT") must be at most %d",
2867 desc, U64_PRINTF_ARG(*value),
2868 ROUTER_MAX_DECLARED_BANDWIDTH);
2869 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2870 return -1;
2872 return 0;
2875 /** Parse an authority type from <b>options</b>-\>PublishServerDescriptor
2876 * and write it to <b>options</b>-\>_PublishServerDescriptor. Treat "1"
2877 * as "v2,v3" unless BridgeRelay is 1, in which case treat it as "bridge".
2878 * Treat "0" as "".
2879 * Return 0 on success or -1 if not a recognized authority type (in which
2880 * case the value of _PublishServerDescriptor is undefined). */
2881 static int
2882 compute_publishserverdescriptor(or_options_t *options)
2884 smartlist_t *list = options->PublishServerDescriptor;
2885 authority_type_t *auth = &options->_PublishServerDescriptor;
2886 *auth = NO_AUTHORITY;
2887 if (!list) /* empty list, answer is none */
2888 return 0;
2889 SMARTLIST_FOREACH(list, const char *, string, {
2890 if (!strcasecmp(string, "v1"))
2891 *auth |= V1_AUTHORITY;
2892 else if (!strcmp(string, "1"))
2893 if (options->BridgeRelay)
2894 *auth |= BRIDGE_AUTHORITY;
2895 else
2896 *auth |= V2_AUTHORITY | V3_AUTHORITY;
2897 else if (!strcasecmp(string, "v2"))
2898 *auth |= V2_AUTHORITY;
2899 else if (!strcasecmp(string, "v3"))
2900 *auth |= V3_AUTHORITY;
2901 else if (!strcasecmp(string, "bridge"))
2902 *auth |= BRIDGE_AUTHORITY;
2903 else if (!strcasecmp(string, "hidserv"))
2904 *auth |= HIDSERV_AUTHORITY;
2905 else if (!strcasecmp(string, "") || !strcmp(string, "0"))
2906 /* no authority */;
2907 else
2908 return -1;
2910 return 0;
2913 /** Lowest allowable value for RendPostPeriod; if this is too low, hidden
2914 * services can overload the directory system. */
2915 #define MIN_REND_POST_PERIOD (10*60)
2917 /** Highest allowable value for RendPostPeriod. */
2918 #define MAX_DIR_PERIOD (MIN_ONION_KEY_LIFETIME/2)
2920 /** Lowest allowable value for CircuitBuildTimeout; values too low will
2921 * increase network load because of failing connections being retried, and
2922 * might prevent users from connecting to the network at all. */
2923 #define MIN_CIRCUIT_BUILD_TIMEOUT 30
2925 /** Lowest allowable value for MaxCircuitDirtiness; if this is too low, Tor
2926 * will generate too many circuits and potentially overload the network. */
2927 #define MIN_MAX_CIRCUIT_DIRTINESS 10
2929 /** Return 0 if every setting in <b>options</b> is reasonable, and a
2930 * permissible transition from <b>old_options</b>. Else return -1.
2931 * Should have no side effects, except for normalizing the contents of
2932 * <b>options</b>.
2934 * On error, tor_strdup an error explanation into *<b>msg</b>.
2936 * XXX
2937 * If <b>from_setconf</b>, we were called by the controller, and our
2938 * Log line should stay empty. If it's 0, then give us a default log
2939 * if there are no logs defined.
2941 static int
2942 options_validate(or_options_t *old_options, or_options_t *options,
2943 int from_setconf, char **msg)
2945 int i, r;
2946 config_line_t *cl;
2947 const char *uname = get_uname();
2948 char buf[1024];
2949 #define REJECT(arg) \
2950 STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
2951 #define COMPLAIN(arg) STMT_BEGIN log(LOG_WARN, LD_CONFIG, arg); STMT_END
2953 tor_assert(msg);
2954 *msg = NULL;
2956 if (options->ORPort < 0 || options->ORPort > 65535)
2957 REJECT("ORPort option out of bounds.");
2959 if (server_mode(options) &&
2960 (!strcmpstart(uname, "Windows 95") ||
2961 !strcmpstart(uname, "Windows 98") ||
2962 !strcmpstart(uname, "Windows Me"))) {
2963 log(LOG_WARN, LD_CONFIG, "Tor is running as a server, but you are "
2964 "running %s; this probably won't work. See "
2965 "https://wiki.torproject.org/TheOnionRouter/TorFAQ#ServerOS "
2966 "for details.", uname);
2969 if (options->ORPort == 0 && options->ORListenAddress != NULL)
2970 REJECT("ORPort must be defined if ORListenAddress is defined.");
2972 if (options->DirPort == 0 && options->DirListenAddress != NULL)
2973 REJECT("DirPort must be defined if DirListenAddress is defined.");
2975 if (options->DNSPort == 0 && options->DNSListenAddress != NULL)
2976 REJECT("DNSPort must be defined if DNSListenAddress is defined.");
2978 if (options->ControlPort == 0 && options->ControlListenAddress != NULL)
2979 REJECT("ControlPort must be defined if ControlListenAddress is defined.");
2981 if (options->TransPort == 0 && options->TransListenAddress != NULL)
2982 REJECT("TransPort must be defined if TransListenAddress is defined.");
2984 if (options->NatdPort == 0 && options->NatdListenAddress != NULL)
2985 REJECT("NatdPort must be defined if NatdListenAddress is defined.");
2987 /* Don't gripe about SocksPort 0 with SocksListenAddress set; a standard
2988 * configuration does this. */
2990 for (i = 0; i < 3; ++i) {
2991 int is_socks = i==0;
2992 int is_trans = i==1;
2993 config_line_t *line, *opt, *old;
2994 const char *tp;
2995 if (is_socks) {
2996 opt = options->SocksListenAddress;
2997 old = old_options ? old_options->SocksListenAddress : NULL;
2998 tp = "SOCKS proxy";
2999 } else if (is_trans) {
3000 opt = options->TransListenAddress;
3001 old = old_options ? old_options->TransListenAddress : NULL;
3002 tp = "transparent proxy";
3003 } else {
3004 opt = options->NatdListenAddress;
3005 old = old_options ? old_options->NatdListenAddress : NULL;
3006 tp = "natd proxy";
3009 for (line = opt; line; line = line->next) {
3010 char *address = NULL;
3011 uint16_t port;
3012 uint32_t addr;
3013 if (parse_addr_port(LOG_WARN, line->value, &address, &addr, &port)<0)
3014 continue; /* We'll warn about this later. */
3015 if (!is_internal_IP(addr, 1) &&
3016 (!old_options || !config_lines_eq(old, opt))) {
3017 log_warn(LD_CONFIG,
3018 "You specified a public address '%s' for a %s. Other "
3019 "people on the Internet might find your computer and use it as "
3020 "an open %s. Please don't allow this unless you have "
3021 "a good reason.", address, tp, tp);
3023 tor_free(address);
3027 if (validate_data_directory(options)<0)
3028 REJECT("Invalid DataDirectory");
3030 if (options->Nickname == NULL) {
3031 if (server_mode(options)) {
3032 if (!(options->Nickname = get_default_nickname())) {
3033 log_notice(LD_CONFIG, "Couldn't pick a nickname based on "
3034 "our hostname; using %s instead.", UNNAMED_ROUTER_NICKNAME);
3035 options->Nickname = tor_strdup(UNNAMED_ROUTER_NICKNAME);
3036 } else {
3037 log_notice(LD_CONFIG, "Choosing default nickname '%s'",
3038 options->Nickname);
3041 } else {
3042 if (!is_legal_nickname(options->Nickname)) {
3043 r = tor_snprintf(buf, sizeof(buf),
3044 "Nickname '%s' is wrong length or contains illegal characters.",
3045 options->Nickname);
3046 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3047 return -1;
3051 if (server_mode(options) && !options->ContactInfo)
3052 log(LOG_NOTICE, LD_CONFIG, "Your ContactInfo config option is not set. "
3053 "Please consider setting it, so we can contact you if your server is "
3054 "misconfigured or something else goes wrong.");
3056 /* Special case on first boot if no Log options are given. */
3057 if (!options->Logs && !options->RunAsDaemon && !from_setconf)
3058 config_line_append(&options->Logs, "Log", "notice stdout");
3060 if (options_init_logs(options, 1)<0) /* Validate the log(s) */
3061 REJECT("Failed to validate Log options. See logs for details.");
3063 if (options->NoPublish) {
3064 log(LOG_WARN, LD_CONFIG,
3065 "NoPublish is obsolete. Use PublishServerDescriptor instead.");
3066 SMARTLIST_FOREACH(options->PublishServerDescriptor, char *, s,
3067 tor_free(s));
3068 smartlist_clear(options->PublishServerDescriptor);
3071 if (authdir_mode(options)) {
3072 /* confirm that our address isn't broken, so we can complain now */
3073 uint32_t tmp;
3074 if (resolve_my_address(LOG_WARN, options, &tmp, NULL) < 0)
3075 REJECT("Failed to resolve/guess local address. See logs for details.");
3078 #ifndef MS_WINDOWS
3079 if (options->RunAsDaemon && torrc_fname && path_is_relative(torrc_fname))
3080 REJECT("Can't use a relative path to torrc when RunAsDaemon is set.");
3081 #endif
3083 if (options->SocksPort < 0 || options->SocksPort > 65535)
3084 REJECT("SocksPort option out of bounds.");
3086 if (options->DNSPort < 0 || options->DNSPort > 65535)
3087 REJECT("DNSPort option out of bounds.");
3089 if (options->TransPort < 0 || options->TransPort > 65535)
3090 REJECT("TransPort option out of bounds.");
3092 if (options->NatdPort < 0 || options->NatdPort > 65535)
3093 REJECT("NatdPort option out of bounds.");
3095 if (options->SocksPort == 0 && options->TransPort == 0 &&
3096 options->NatdPort == 0 && options->ORPort == 0 &&
3097 options->DNSPort == 0 && !options->RendConfigLines)
3098 log(LOG_WARN, LD_CONFIG,
3099 "SocksPort, TransPort, NatdPort, DNSPort, and ORPort are all "
3100 "undefined, and there aren't any hidden services configured. "
3101 "Tor will still run, but probably won't do anything.");
3103 if (options->ControlPort < 0 || options->ControlPort > 65535)
3104 REJECT("ControlPort option out of bounds.");
3106 if (options->DirPort < 0 || options->DirPort > 65535)
3107 REJECT("DirPort option out of bounds.");
3109 #ifndef USE_TRANSPARENT
3110 if (options->TransPort || options->TransListenAddress)
3111 REJECT("TransPort and TransListenAddress are disabled in this build.");
3112 #endif
3114 if (options->AccountingMax &&
3115 (is_listening_on_low_port(options->ORPort, options->ORListenAddress) ||
3116 is_listening_on_low_port(options->DirPort, options->DirListenAddress)))
3118 log(LOG_WARN, LD_CONFIG,
3119 "You have set AccountingMax to use hibernation. You have also "
3120 "chosen a low DirPort or OrPort. This combination can make Tor stop "
3121 "working when it tries to re-attach the port after a period of "
3122 "hibernation. Please choose a different port or turn off "
3123 "hibernation unless you know this combination will work on your "
3124 "platform.");
3127 if (options->ExcludeExitNodes || options->ExcludeNodes) {
3128 options->_ExcludeExitNodesUnion = routerset_new();
3129 routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeExitNodes);
3130 routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeNodes);
3133 if (options->StrictExitNodes &&
3134 (!options->ExitNodes) &&
3135 (!old_options ||
3136 (old_options->StrictExitNodes != options->StrictExitNodes) ||
3137 (!routerset_equal(old_options->ExitNodes,options->ExitNodes))))
3138 COMPLAIN("StrictExitNodes set, but no ExitNodes listed.");
3140 if (options->StrictEntryNodes &&
3141 (!options->EntryNodes) &&
3142 (!old_options ||
3143 (old_options->StrictEntryNodes != options->StrictEntryNodes) ||
3144 (!routerset_equal(old_options->EntryNodes,options->EntryNodes))))
3145 COMPLAIN("StrictEntryNodes set, but no EntryNodes listed.");
3147 if (options->EntryNodes && !routerset_is_list(options->EntryNodes)) {
3148 /* XXXX fix this; see entry_guards_prepend_from_config(). */
3149 REJECT("IPs or countries are not yet supported in EntryNodes.");
3152 if (options->AuthoritativeDir) {
3153 if (!options->ContactInfo && !options->TestingTorNetwork)
3154 REJECT("Authoritative directory servers must set ContactInfo");
3155 if (options->V1AuthoritativeDir && !options->RecommendedVersions)
3156 REJECT("V1 authoritative dir servers must set RecommendedVersions.");
3157 if (!options->RecommendedClientVersions)
3158 options->RecommendedClientVersions =
3159 config_lines_dup(options->RecommendedVersions);
3160 if (!options->RecommendedServerVersions)
3161 options->RecommendedServerVersions =
3162 config_lines_dup(options->RecommendedVersions);
3163 if (options->VersioningAuthoritativeDir &&
3164 (!options->RecommendedClientVersions ||
3165 !options->RecommendedServerVersions))
3166 REJECT("Versioning authoritative dir servers must set "
3167 "Recommended*Versions.");
3168 if (options->UseEntryGuards) {
3169 log_info(LD_CONFIG, "Authoritative directory servers can't set "
3170 "UseEntryGuards. Disabling.");
3171 options->UseEntryGuards = 0;
3173 if (!options->DownloadExtraInfo && authdir_mode_any_main(options)) {
3174 log_info(LD_CONFIG, "Authoritative directories always try to download "
3175 "extra-info documents. Setting DownloadExtraInfo.");
3176 options->DownloadExtraInfo = 1;
3178 if (!(options->BridgeAuthoritativeDir || options->HSAuthoritativeDir ||
3179 options->V1AuthoritativeDir || options->V2AuthoritativeDir ||
3180 options->V3AuthoritativeDir))
3181 REJECT("AuthoritativeDir is set, but none of "
3182 "(Bridge/HS/V1/V2/V3)AuthoritativeDir is set.");
3185 if (options->AuthoritativeDir && !options->DirPort)
3186 REJECT("Running as authoritative directory, but no DirPort set.");
3188 if (options->AuthoritativeDir && !options->ORPort)
3189 REJECT("Running as authoritative directory, but no ORPort set.");
3191 if (options->AuthoritativeDir && options->ClientOnly)
3192 REJECT("Running as authoritative directory, but ClientOnly also set.");
3194 if (options->HSAuthorityRecordStats && !options->HSAuthoritativeDir)
3195 REJECT("HSAuthorityRecordStats is set but we're not running as "
3196 "a hidden service authority.");
3198 if (options->ConnLimit <= 0) {
3199 r = tor_snprintf(buf, sizeof(buf),
3200 "ConnLimit must be greater than 0, but was set to %d",
3201 options->ConnLimit);
3202 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3203 return -1;
3206 if (validate_ports_csv(options->FirewallPorts, "FirewallPorts", msg) < 0)
3207 return -1;
3209 if (validate_ports_csv(options->LongLivedPorts, "LongLivedPorts", msg) < 0)
3210 return -1;
3212 if (validate_ports_csv(options->RejectPlaintextPorts,
3213 "RejectPlaintextPorts", msg) < 0)
3214 return -1;
3216 if (validate_ports_csv(options->WarnPlaintextPorts,
3217 "WarnPlaintextPorts", msg) < 0)
3218 return -1;
3220 if (options->FascistFirewall && !options->ReachableAddresses) {
3221 if (options->FirewallPorts && smartlist_len(options->FirewallPorts)) {
3222 /* We already have firewall ports set, so migrate them to
3223 * ReachableAddresses, which will set ReachableORAddresses and
3224 * ReachableDirAddresses if they aren't set explicitly. */
3225 smartlist_t *instead = smartlist_create();
3226 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3227 new_line->key = tor_strdup("ReachableAddresses");
3228 /* If we're configured with the old format, we need to prepend some
3229 * open ports. */
3230 SMARTLIST_FOREACH(options->FirewallPorts, const char *, portno,
3232 int p = atoi(portno);
3233 char *s;
3234 if (p<0) continue;
3235 s = tor_malloc(16);
3236 tor_snprintf(s, 16, "*:%d", p);
3237 smartlist_add(instead, s);
3239 new_line->value = smartlist_join_strings(instead,",",0,NULL);
3240 /* These have been deprecated since 0.1.1.5-alpha-cvs */
3241 log(LOG_NOTICE, LD_CONFIG,
3242 "Converting FascistFirewall and FirewallPorts "
3243 "config options to new format: \"ReachableAddresses %s\"",
3244 new_line->value);
3245 options->ReachableAddresses = new_line;
3246 SMARTLIST_FOREACH(instead, char *, cp, tor_free(cp));
3247 smartlist_free(instead);
3248 } else {
3249 /* We do not have FirewallPorts set, so add 80 to
3250 * ReachableDirAddresses, and 443 to ReachableORAddresses. */
3251 if (!options->ReachableDirAddresses) {
3252 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3253 new_line->key = tor_strdup("ReachableDirAddresses");
3254 new_line->value = tor_strdup("*:80");
3255 options->ReachableDirAddresses = new_line;
3256 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
3257 "to new format: \"ReachableDirAddresses *:80\"");
3259 if (!options->ReachableORAddresses) {
3260 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3261 new_line->key = tor_strdup("ReachableORAddresses");
3262 new_line->value = tor_strdup("*:443");
3263 options->ReachableORAddresses = new_line;
3264 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
3265 "to new format: \"ReachableORAddresses *:443\"");
3270 for (i=0; i<3; i++) {
3271 config_line_t **linep =
3272 (i==0) ? &options->ReachableAddresses :
3273 (i==1) ? &options->ReachableORAddresses :
3274 &options->ReachableDirAddresses;
3275 if (!*linep)
3276 continue;
3277 /* We need to end with a reject *:*, not an implicit accept *:* */
3278 for (;;) {
3279 if (!strcmp((*linep)->value, "reject *:*")) /* already there */
3280 break;
3281 linep = &((*linep)->next);
3282 if (!*linep) {
3283 *linep = tor_malloc_zero(sizeof(config_line_t));
3284 (*linep)->key = tor_strdup(
3285 (i==0) ? "ReachableAddresses" :
3286 (i==1) ? "ReachableORAddresses" :
3287 "ReachableDirAddresses");
3288 (*linep)->value = tor_strdup("reject *:*");
3289 break;
3294 if ((options->ReachableAddresses ||
3295 options->ReachableORAddresses ||
3296 options->ReachableDirAddresses) &&
3297 server_mode(options))
3298 REJECT("Servers must be able to freely connect to the rest "
3299 "of the Internet, so they must not set Reachable*Addresses "
3300 "or FascistFirewall.");
3302 if (options->UseBridges &&
3303 server_mode(options))
3304 REJECT("Servers must be able to freely connect to the rest "
3305 "of the Internet, so they must not set UseBridges.");
3307 options->_AllowInvalid = 0;
3308 if (options->AllowInvalidNodes) {
3309 SMARTLIST_FOREACH(options->AllowInvalidNodes, const char *, cp, {
3310 if (!strcasecmp(cp, "entry"))
3311 options->_AllowInvalid |= ALLOW_INVALID_ENTRY;
3312 else if (!strcasecmp(cp, "exit"))
3313 options->_AllowInvalid |= ALLOW_INVALID_EXIT;
3314 else if (!strcasecmp(cp, "middle"))
3315 options->_AllowInvalid |= ALLOW_INVALID_MIDDLE;
3316 else if (!strcasecmp(cp, "introduction"))
3317 options->_AllowInvalid |= ALLOW_INVALID_INTRODUCTION;
3318 else if (!strcasecmp(cp, "rendezvous"))
3319 options->_AllowInvalid |= ALLOW_INVALID_RENDEZVOUS;
3320 else {
3321 r = tor_snprintf(buf, sizeof(buf),
3322 "Unrecognized value '%s' in AllowInvalidNodes", cp);
3323 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3324 return -1;
3329 if (compute_publishserverdescriptor(options) < 0) {
3330 r = tor_snprintf(buf, sizeof(buf),
3331 "Unrecognized value in PublishServerDescriptor");
3332 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3333 return -1;
3336 if ((options->BridgeRelay
3337 || options->_PublishServerDescriptor & BRIDGE_AUTHORITY)
3338 && (options->_PublishServerDescriptor
3339 & (V1_AUTHORITY|V2_AUTHORITY|V3_AUTHORITY))) {
3340 REJECT("Bridges are not supposed to publish router descriptors to the "
3341 "directory authorities. Please correct your "
3342 "PublishServerDescriptor line.");
3345 if (options->MinUptimeHidServDirectoryV2 < 0) {
3346 log_warn(LD_CONFIG, "MinUptimeHidServDirectoryV2 option must be at "
3347 "least 0 seconds. Changing to 0.");
3348 options->MinUptimeHidServDirectoryV2 = 0;
3351 if (options->RendPostPeriod < MIN_REND_POST_PERIOD) {
3352 log(LOG_WARN,LD_CONFIG,"RendPostPeriod option is too short; "
3353 "raising to %d seconds.", MIN_REND_POST_PERIOD);
3354 options->RendPostPeriod = MIN_REND_POST_PERIOD;
3357 if (options->RendPostPeriod > MAX_DIR_PERIOD) {
3358 log(LOG_WARN, LD_CONFIG, "RendPostPeriod is too large; clipping to %ds.",
3359 MAX_DIR_PERIOD);
3360 options->RendPostPeriod = MAX_DIR_PERIOD;
3363 if (options->CircuitBuildTimeout < MIN_CIRCUIT_BUILD_TIMEOUT) {
3364 log(LOG_WARN, LD_CONFIG, "CircuitBuildTimeout option is too short; "
3365 "raising to %d seconds.", MIN_CIRCUIT_BUILD_TIMEOUT);
3366 options->CircuitBuildTimeout = MIN_CIRCUIT_BUILD_TIMEOUT;
3369 if (options->MaxCircuitDirtiness < MIN_MAX_CIRCUIT_DIRTINESS) {
3370 log(LOG_WARN, LD_CONFIG, "MaxCircuitDirtiness option is too short; "
3371 "raising to %d seconds.", MIN_MAX_CIRCUIT_DIRTINESS);
3372 options->MaxCircuitDirtiness = MIN_MAX_CIRCUIT_DIRTINESS;
3375 if (options->KeepalivePeriod < 1)
3376 REJECT("KeepalivePeriod option must be positive.");
3378 if (ensure_bandwidth_cap(&options->BandwidthRate,
3379 "BandwidthRate", msg) < 0)
3380 return -1;
3381 if (ensure_bandwidth_cap(&options->BandwidthBurst,
3382 "BandwidthBurst", msg) < 0)
3383 return -1;
3384 if (ensure_bandwidth_cap(&options->MaxAdvertisedBandwidth,
3385 "MaxAdvertisedBandwidth", msg) < 0)
3386 return -1;
3387 if (ensure_bandwidth_cap(&options->RelayBandwidthRate,
3388 "RelayBandwidthRate", msg) < 0)
3389 return -1;
3390 if (ensure_bandwidth_cap(&options->RelayBandwidthBurst,
3391 "RelayBandwidthBurst", msg) < 0)
3392 return -1;
3394 if (server_mode(options)) {
3395 if (options->BandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
3396 r = tor_snprintf(buf, sizeof(buf),
3397 "BandwidthRate is set to %d bytes/second. "
3398 "For servers, it must be at least %d.",
3399 (int)options->BandwidthRate,
3400 ROUTER_REQUIRED_MIN_BANDWIDTH);
3401 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3402 return -1;
3403 } else if (options->MaxAdvertisedBandwidth <
3404 ROUTER_REQUIRED_MIN_BANDWIDTH/2) {
3405 r = tor_snprintf(buf, sizeof(buf),
3406 "MaxAdvertisedBandwidth is set to %d bytes/second. "
3407 "For servers, it must be at least %d.",
3408 (int)options->MaxAdvertisedBandwidth,
3409 ROUTER_REQUIRED_MIN_BANDWIDTH/2);
3410 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3411 return -1;
3413 if (options->RelayBandwidthRate &&
3414 options->RelayBandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
3415 r = tor_snprintf(buf, sizeof(buf),
3416 "RelayBandwidthRate is set to %d bytes/second. "
3417 "For servers, it must be at least %d.",
3418 (int)options->RelayBandwidthRate,
3419 ROUTER_REQUIRED_MIN_BANDWIDTH);
3420 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3421 return -1;
3425 if (options->RelayBandwidthRate && !options->RelayBandwidthBurst)
3426 options->RelayBandwidthBurst = options->RelayBandwidthRate;
3428 if (options->RelayBandwidthRate > options->RelayBandwidthBurst)
3429 REJECT("RelayBandwidthBurst must be at least equal "
3430 "to RelayBandwidthRate.");
3432 if (options->BandwidthRate > options->BandwidthBurst)
3433 REJECT("BandwidthBurst must be at least equal to BandwidthRate.");
3435 /* if they set relaybandwidth* really high but left bandwidth*
3436 * at the default, raise the defaults. */
3437 if (options->RelayBandwidthRate > options->BandwidthRate)
3438 options->BandwidthRate = options->RelayBandwidthRate;
3439 if (options->RelayBandwidthBurst > options->BandwidthBurst)
3440 options->BandwidthBurst = options->RelayBandwidthBurst;
3442 if (accounting_parse_options(options, 1)<0)
3443 REJECT("Failed to parse accounting options. See logs for details.");
3445 if (options->HttpProxy) { /* parse it now */
3446 if (parse_addr_port(LOG_WARN, options->HttpProxy, NULL,
3447 &options->HttpProxyAddr, &options->HttpProxyPort) < 0)
3448 REJECT("HttpProxy failed to parse or resolve. Please fix.");
3449 if (options->HttpProxyPort == 0) { /* give it a default */
3450 options->HttpProxyPort = 80;
3454 if (options->HttpProxyAuthenticator) {
3455 if (strlen(options->HttpProxyAuthenticator) >= 48)
3456 REJECT("HttpProxyAuthenticator is too long (>= 48 chars).");
3459 if (options->HttpsProxy) { /* parse it now */
3460 if (parse_addr_port(LOG_WARN, options->HttpsProxy, NULL,
3461 &options->HttpsProxyAddr, &options->HttpsProxyPort) <0)
3462 REJECT("HttpsProxy failed to parse or resolve. Please fix.");
3463 if (options->HttpsProxyPort == 0) { /* give it a default */
3464 options->HttpsProxyPort = 443;
3468 if (options->HttpsProxyAuthenticator) {
3469 if (strlen(options->HttpsProxyAuthenticator) >= 48)
3470 REJECT("HttpsProxyAuthenticator is too long (>= 48 chars).");
3473 if (options->HashedControlPassword) {
3474 smartlist_t *sl = decode_hashed_passwords(options->HashedControlPassword);
3475 if (!sl) {
3476 REJECT("Bad HashedControlPassword: wrong length or bad encoding");
3477 } else {
3478 SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
3479 smartlist_free(sl);
3483 if (options->HashedControlSessionPassword) {
3484 smartlist_t *sl = decode_hashed_passwords(
3485 options->HashedControlSessionPassword);
3486 if (!sl) {
3487 REJECT("Bad HashedControlSessionPassword: wrong length or bad encoding");
3488 } else {
3489 SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
3490 smartlist_free(sl);
3494 if (options->ControlListenAddress) {
3495 int all_are_local = 1;
3496 config_line_t *ln;
3497 for (ln = options->ControlListenAddress; ln; ln = ln->next) {
3498 if (strcmpstart(ln->value, "127."))
3499 all_are_local = 0;
3501 if (!all_are_local) {
3502 if (!options->HashedControlPassword &&
3503 !options->HashedControlSessionPassword &&
3504 !options->CookieAuthentication) {
3505 log_warn(LD_CONFIG,
3506 "You have a ControlListenAddress set to accept "
3507 "unauthenticated connections from a non-local address. "
3508 "This means that programs not running on your computer "
3509 "can reconfigure your Tor, without even having to guess a "
3510 "password. That's so bad that I'm closing your ControlPort "
3511 "for you. If you need to control your Tor remotely, try "
3512 "enabling authentication and using a tool like stunnel or "
3513 "ssh to encrypt remote access.");
3514 options->ControlPort = 0;
3515 } else {
3516 log_warn(LD_CONFIG, "You have a ControlListenAddress set to accept "
3517 "connections from a non-local address. This means that "
3518 "programs not running on your computer can reconfigure your "
3519 "Tor. That's pretty bad, since the controller "
3520 "protocol isn't encrypted! Maybe you should just listen on "
3521 "127.0.0.1 and use a tool like stunnel or ssh to encrypt "
3522 "remote connections to your control port.");
3527 if (options->ControlPort && !options->HashedControlPassword &&
3528 !options->HashedControlSessionPassword &&
3529 !options->CookieAuthentication) {
3530 log_warn(LD_CONFIG, "ControlPort is open, but no authentication method "
3531 "has been configured. This means that any program on your "
3532 "computer can reconfigure your Tor. That's bad! You should "
3533 "upgrade your Tor controller as soon as possible.");
3536 if (options->UseEntryGuards && ! options->NumEntryGuards)
3537 REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0");
3539 if (check_nickname_list(options->MyFamily, "MyFamily", msg))
3540 return -1;
3541 for (cl = options->NodeFamilies; cl; cl = cl->next) {
3542 if (check_nickname_list(cl->value, "NodeFamily", msg))
3543 return -1;
3546 if (validate_addr_policies(options, msg) < 0)
3547 return -1;
3549 if (validate_dir_authorities(options, old_options) < 0)
3550 REJECT("Directory authority line did not parse. See logs for details.");
3552 if (options->UseBridges && !options->Bridges)
3553 REJECT("If you set UseBridges, you must specify at least one bridge.");
3554 if (options->UseBridges && !options->TunnelDirConns)
3555 REJECT("If you set UseBridges, you must set TunnelDirConns.");
3556 if (options->Bridges) {
3557 for (cl = options->Bridges; cl; cl = cl->next) {
3558 if (parse_bridge_line(cl->value, 1)<0)
3559 REJECT("Bridge line did not parse. See logs for details.");
3563 if (options->ConstrainedSockets) {
3564 /* If the user wants to constrain socket buffer use, make sure the desired
3565 * limit is between MIN|MAX_TCPSOCK_BUFFER in k increments. */
3566 if (options->ConstrainedSockSize < MIN_CONSTRAINED_TCP_BUFFER ||
3567 options->ConstrainedSockSize > MAX_CONSTRAINED_TCP_BUFFER ||
3568 options->ConstrainedSockSize % 1024) {
3569 r = tor_snprintf(buf, sizeof(buf),
3570 "ConstrainedSockSize is invalid. Must be a value between %d and %d "
3571 "in 1024 byte increments.",
3572 MIN_CONSTRAINED_TCP_BUFFER, MAX_CONSTRAINED_TCP_BUFFER);
3573 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3574 return -1;
3576 if (options->DirPort) {
3577 /* Providing cached directory entries while system TCP buffers are scarce
3578 * will exacerbate the socket errors. Suggest that this be disabled. */
3579 COMPLAIN("You have requested constrained socket buffers while also "
3580 "serving directory entries via DirPort. It is strongly "
3581 "suggested that you disable serving directory requests when "
3582 "system TCP buffer resources are scarce.");
3586 if (options->V3AuthVoteDelay + options->V3AuthDistDelay >=
3587 options->V3AuthVotingInterval/2) {
3588 REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than half "
3589 "V3AuthVotingInterval");
3591 if (options->V3AuthVoteDelay < MIN_VOTE_SECONDS)
3592 REJECT("V3AuthVoteDelay is way too low.");
3593 if (options->V3AuthDistDelay < MIN_DIST_SECONDS)
3594 REJECT("V3AuthDistDelay is way too low.");
3596 if (options->V3AuthNIntervalsValid < 2)
3597 REJECT("V3AuthNIntervalsValid must be at least 2.");
3599 if (options->V3AuthVotingInterval < MIN_VOTE_INTERVAL) {
3600 REJECT("V3AuthVotingInterval is insanely low.");
3601 } else if (options->V3AuthVotingInterval > 24*60*60) {
3602 REJECT("V3AuthVotingInterval is insanely high.");
3603 } else if (((24*60*60) % options->V3AuthVotingInterval) != 0) {
3604 COMPLAIN("V3AuthVotingInterval does not divide evenly into 24 hours.");
3607 if (rend_config_services(options, 1) < 0)
3608 REJECT("Failed to configure rendezvous options. See logs for details.");
3610 /* Parse client-side authorization for hidden services. */
3611 if (rend_parse_service_authorization(options, 1) < 0)
3612 REJECT("Failed to configure client authorization for hidden services. "
3613 "See logs for details.");
3615 if (parse_virtual_addr_network(options->VirtualAddrNetwork, 1, NULL)<0)
3616 return -1;
3618 if (options->PreferTunneledDirConns && !options->TunnelDirConns)
3619 REJECT("Must set TunnelDirConns if PreferTunneledDirConns is set.");
3621 if (options->AutomapHostsSuffixes) {
3622 SMARTLIST_FOREACH(options->AutomapHostsSuffixes, char *, suf,
3624 size_t len = strlen(suf);
3625 if (len && suf[len-1] == '.')
3626 suf[len-1] = '\0';
3630 if (options->TestingTorNetwork && !options->DirServers) {
3631 REJECT("TestingTorNetwork may only be configured in combination with "
3632 "a non-default set of DirServers.");
3635 /*XXXX022 checking for defaults manually like this is a bit fragile.*/
3637 /* Keep changes to hard-coded values synchronous to man page and default
3638 * values table. */
3639 if (options->TestingV3AuthInitialVotingInterval != 30*60 &&
3640 !options->TestingTorNetwork) {
3641 REJECT("TestingV3AuthInitialVotingInterval may only be changed in testing "
3642 "Tor networks!");
3643 } else if (options->TestingV3AuthInitialVotingInterval < MIN_VOTE_INTERVAL) {
3644 REJECT("TestingV3AuthInitialVotingInterval is insanely low.");
3645 } else if (((30*60) % options->TestingV3AuthInitialVotingInterval) != 0) {
3646 REJECT("TestingV3AuthInitialVotingInterval does not divide evenly into "
3647 "30 minutes.");
3650 if (options->TestingV3AuthInitialVoteDelay != 5*60 &&
3651 !options->TestingTorNetwork) {
3652 REJECT("TestingV3AuthInitialVoteDelay may only be changed in testing "
3653 "Tor networks!");
3654 } else if (options->TestingV3AuthInitialVoteDelay < MIN_VOTE_SECONDS) {
3655 REJECT("TestingV3AuthInitialVoteDelay is way too low.");
3658 if (options->TestingV3AuthInitialDistDelay != 5*60 &&
3659 !options->TestingTorNetwork) {
3660 REJECT("TestingV3AuthInitialDistDelay may only be changed in testing "
3661 "Tor networks!");
3662 } else if (options->TestingV3AuthInitialDistDelay < MIN_DIST_SECONDS) {
3663 REJECT("TestingV3AuthInitialDistDelay is way too low.");
3666 if (options->TestingV3AuthInitialVoteDelay +
3667 options->TestingV3AuthInitialDistDelay >=
3668 options->TestingV3AuthInitialVotingInterval/2) {
3669 REJECT("TestingV3AuthInitialVoteDelay plus TestingV3AuthInitialDistDelay "
3670 "must be less than half TestingV3AuthInitialVotingInterval");
3673 if (options->TestingAuthDirTimeToLearnReachability != 30*60 &&
3674 !options->TestingTorNetwork) {
3675 REJECT("TestingAuthDirTimeToLearnReachability may only be changed in "
3676 "testing Tor networks!");
3677 } else if (options->TestingAuthDirTimeToLearnReachability < 0) {
3678 REJECT("TestingAuthDirTimeToLearnReachability must be non-negative.");
3679 } else if (options->TestingAuthDirTimeToLearnReachability > 2*60*60) {
3680 COMPLAIN("TestingAuthDirTimeToLearnReachability is insanely high.");
3683 if (options->TestingEstimatedDescriptorPropagationTime != 10*60 &&
3684 !options->TestingTorNetwork) {
3685 REJECT("TestingEstimatedDescriptorPropagationTime may only be changed in "
3686 "testing Tor networks!");
3687 } else if (options->TestingEstimatedDescriptorPropagationTime < 0) {
3688 REJECT("TestingEstimatedDescriptorPropagationTime must be non-negative.");
3689 } else if (options->TestingEstimatedDescriptorPropagationTime > 60*60) {
3690 COMPLAIN("TestingEstimatedDescriptorPropagationTime is insanely high.");
3693 if (options->TestingTorNetwork) {
3694 log_warn(LD_CONFIG, "TestingTorNetwork is set. This will make your node "
3695 "almost unusable in the public Tor network, and is "
3696 "therefore only advised if you are building a "
3697 "testing Tor network!");
3700 if (options->AccelName && !options->HardwareAccel)
3701 options->HardwareAccel = 1;
3702 if (options->AccelDir && !options->AccelName)
3703 REJECT("Can't use hardware crypto accelerator dir without engine name.");
3705 return 0;
3706 #undef REJECT
3707 #undef COMPLAIN
3710 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
3711 * equal strings. */
3712 static int
3713 opt_streq(const char *s1, const char *s2)
3715 if (!s1 && !s2)
3716 return 1;
3717 else if (s1 && s2 && !strcmp(s1,s2))
3718 return 1;
3719 else
3720 return 0;
3723 /** Check if any of the previous options have changed but aren't allowed to. */
3724 static int
3725 options_transition_allowed(or_options_t *old, or_options_t *new_val,
3726 char **msg)
3728 if (!old)
3729 return 0;
3731 if (!opt_streq(old->PidFile, new_val->PidFile)) {
3732 *msg = tor_strdup("PidFile is not allowed to change.");
3733 return -1;
3736 if (old->RunAsDaemon != new_val->RunAsDaemon) {
3737 *msg = tor_strdup("While Tor is running, changing RunAsDaemon "
3738 "is not allowed.");
3739 return -1;
3742 if (strcmp(old->DataDirectory,new_val->DataDirectory)!=0) {
3743 char buf[1024];
3744 int r = tor_snprintf(buf, sizeof(buf),
3745 "While Tor is running, changing DataDirectory "
3746 "(\"%s\"->\"%s\") is not allowed.",
3747 old->DataDirectory, new_val->DataDirectory);
3748 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3749 return -1;
3752 if (!opt_streq(old->User, new_val->User)) {
3753 *msg = tor_strdup("While Tor is running, changing User is not allowed.");
3754 return -1;
3757 if (!opt_streq(old->Group, new_val->Group)) {
3758 *msg = tor_strdup("While Tor is running, changing Group is not allowed.");
3759 return -1;
3762 if ((old->HardwareAccel != new_val->HardwareAccel)
3763 || !opt_streq(old->AccelName, new_val->AccelName)
3764 || !opt_streq(old->AccelDir, new_val->AccelDir)) {
3765 *msg = tor_strdup("While Tor is running, changing OpenSSL hardware "
3766 "acceleration engine is not allowed.");
3767 return -1;
3770 if (old->TestingTorNetwork != new_val->TestingTorNetwork) {
3771 *msg = tor_strdup("While Tor is running, changing TestingTorNetwork "
3772 "is not allowed.");
3773 return -1;
3776 return 0;
3779 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
3780 * will require us to rotate the CPU and DNS workers; else return 0. */
3781 static int
3782 options_transition_affects_workers(or_options_t *old_options,
3783 or_options_t *new_options)
3785 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
3786 old_options->NumCpus != new_options->NumCpus ||
3787 old_options->ORPort != new_options->ORPort ||
3788 old_options->ServerDNSSearchDomains !=
3789 new_options->ServerDNSSearchDomains ||
3790 old_options->SafeLogging != new_options->SafeLogging ||
3791 old_options->ClientOnly != new_options->ClientOnly ||
3792 !config_lines_eq(old_options->Logs, new_options->Logs))
3793 return 1;
3795 /* Check whether log options match. */
3797 /* Nothing that changed matters. */
3798 return 0;
3801 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
3802 * will require us to generate a new descriptor; else return 0. */
3803 static int
3804 options_transition_affects_descriptor(or_options_t *old_options,
3805 or_options_t *new_options)
3807 /* XXX We can be smarter here. If your DirPort isn't being
3808 * published and you just turned it off, no need to republish. If
3809 * you changed your bandwidthrate but maxadvertisedbandwidth still
3810 * trumps, no need to republish. Etc. */
3811 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
3812 !opt_streq(old_options->Nickname,new_options->Nickname) ||
3813 !opt_streq(old_options->Address,new_options->Address) ||
3814 !config_lines_eq(old_options->ExitPolicy,new_options->ExitPolicy) ||
3815 old_options->ExitPolicyRejectPrivate !=
3816 new_options->ExitPolicyRejectPrivate ||
3817 old_options->ORPort != new_options->ORPort ||
3818 old_options->DirPort != new_options->DirPort ||
3819 old_options->ClientOnly != new_options->ClientOnly ||
3820 old_options->NoPublish != new_options->NoPublish ||
3821 old_options->_PublishServerDescriptor !=
3822 new_options->_PublishServerDescriptor ||
3823 old_options->BandwidthRate != new_options->BandwidthRate ||
3824 old_options->BandwidthBurst != new_options->BandwidthBurst ||
3825 old_options->MaxAdvertisedBandwidth !=
3826 new_options->MaxAdvertisedBandwidth ||
3827 !opt_streq(old_options->ContactInfo, new_options->ContactInfo) ||
3828 !opt_streq(old_options->MyFamily, new_options->MyFamily) ||
3829 !opt_streq(old_options->AccountingStart, new_options->AccountingStart) ||
3830 old_options->AccountingMax != new_options->AccountingMax)
3831 return 1;
3833 return 0;
3836 #ifdef MS_WINDOWS
3837 /** Return the directory on windows where we expect to find our application
3838 * data. */
3839 static char *
3840 get_windows_conf_root(void)
3842 static int is_set = 0;
3843 static char path[MAX_PATH+1];
3845 LPITEMIDLIST idl;
3846 IMalloc *m;
3847 HRESULT result;
3849 if (is_set)
3850 return path;
3852 /* Find X:\documents and settings\username\application data\ .
3853 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
3855 #ifdef ENABLE_LOCAL_APPDATA
3856 #define APPDATA_PATH CSIDL_LOCAL_APPDATA
3857 #else
3858 #define APPDATA_PATH CSIDL_APPDATA
3859 #endif
3860 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, APPDATA_PATH, &idl))) {
3861 GetCurrentDirectory(MAX_PATH, path);
3862 is_set = 1;
3863 log_warn(LD_CONFIG,
3864 "I couldn't find your application data folder: are you "
3865 "running an ancient version of Windows 95? Defaulting to \"%s\"",
3866 path);
3867 return path;
3869 /* Convert the path from an "ID List" (whatever that is!) to a path. */
3870 result = SHGetPathFromIDList(idl, path);
3871 /* Now we need to free the */
3872 SHGetMalloc(&m);
3873 if (m) {
3874 m->lpVtbl->Free(m, idl);
3875 m->lpVtbl->Release(m);
3877 if (!SUCCEEDED(result)) {
3878 return NULL;
3880 strlcat(path,"\\tor",MAX_PATH);
3881 is_set = 1;
3882 return path;
3884 #endif
3886 /** Return the default location for our torrc file. */
3887 static const char *
3888 get_default_conf_file(void)
3890 #ifdef MS_WINDOWS
3891 static char path[MAX_PATH+1];
3892 strlcpy(path, get_windows_conf_root(), MAX_PATH);
3893 strlcat(path,"\\torrc",MAX_PATH);
3894 return path;
3895 #else
3896 return (CONFDIR "/torrc");
3897 #endif
3900 /** Verify whether lst is a string containing valid-looking comma-separated
3901 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
3903 static int
3904 check_nickname_list(const char *lst, const char *name, char **msg)
3906 int r = 0;
3907 smartlist_t *sl;
3909 if (!lst)
3910 return 0;
3911 sl = smartlist_create();
3913 smartlist_split_string(sl, lst, ",",
3914 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0);
3916 SMARTLIST_FOREACH(sl, const char *, s,
3918 if (!is_legal_nickname_or_hexdigest(s)) {
3919 char buf[1024];
3920 int tmp = tor_snprintf(buf, sizeof(buf),
3921 "Invalid nickname '%s' in %s line", s, name);
3922 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
3923 r = -1;
3924 break;
3927 SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
3928 smartlist_free(sl);
3929 return r;
3932 /** Learn config file name from command line arguments, or use the default */
3933 static char *
3934 find_torrc_filename(int argc, char **argv,
3935 int *using_default_torrc, int *ignore_missing_torrc)
3937 char *fname=NULL;
3938 int i;
3940 for (i = 1; i < argc; ++i) {
3941 if (i < argc-1 && !strcmp(argv[i],"-f")) {
3942 if (fname) {
3943 log(LOG_WARN, LD_CONFIG, "Duplicate -f options on command line.");
3944 tor_free(fname);
3946 #ifdef MS_WINDOWS
3947 /* XXX one day we might want to extend expand_filename to work
3948 * under Windows as well. */
3949 fname = tor_strdup(argv[i+1]);
3950 #else
3951 fname = expand_filename(argv[i+1]);
3952 #endif
3953 *using_default_torrc = 0;
3954 ++i;
3955 } else if (!strcmp(argv[i],"--ignore-missing-torrc")) {
3956 *ignore_missing_torrc = 1;
3960 if (*using_default_torrc) {
3961 /* didn't find one, try CONFDIR */
3962 const char *dflt = get_default_conf_file();
3963 if (dflt && file_status(dflt) == FN_FILE) {
3964 fname = tor_strdup(dflt);
3965 } else {
3966 #ifndef MS_WINDOWS
3967 char *fn;
3968 fn = expand_filename("~/.torrc");
3969 if (fn && file_status(fn) == FN_FILE) {
3970 fname = fn;
3971 } else {
3972 tor_free(fn);
3973 fname = tor_strdup(dflt);
3975 #else
3976 fname = tor_strdup(dflt);
3977 #endif
3980 return fname;
3983 /** Load torrc from disk, setting torrc_fname if successful */
3984 static char *
3985 load_torrc_from_disk(int argc, char **argv)
3987 char *fname=NULL;
3988 char *cf = NULL;
3989 int using_default_torrc = 1;
3990 int ignore_missing_torrc = 0;
3992 fname = find_torrc_filename(argc, argv,
3993 &using_default_torrc, &ignore_missing_torrc);
3994 tor_assert(fname);
3995 log(LOG_DEBUG, LD_CONFIG, "Opening config file \"%s\"", fname);
3997 tor_free(torrc_fname);
3998 torrc_fname = fname;
4000 /* Open config file */
4001 if (file_status(fname) != FN_FILE ||
4002 !(cf = read_file_to_str(fname,0,NULL))) {
4003 if (using_default_torrc == 1 || ignore_missing_torrc ) {
4004 log(LOG_NOTICE, LD_CONFIG, "Configuration file \"%s\" not present, "
4005 "using reasonable defaults.", fname);
4006 tor_free(fname); /* sets fname to NULL */
4007 torrc_fname = NULL;
4008 cf = tor_strdup("");
4009 } else {
4010 log(LOG_WARN, LD_CONFIG,
4011 "Unable to open configuration file \"%s\".", fname);
4012 goto err;
4016 return cf;
4017 err:
4018 tor_free(fname);
4019 torrc_fname = NULL;
4020 return NULL;
4023 /** Read a configuration file into <b>options</b>, finding the configuration
4024 * file location based on the command line. After loading the file
4025 * call options_init_from_string() to load the config.
4026 * Return 0 if success, -1 if failure. */
4028 options_init_from_torrc(int argc, char **argv)
4030 char *cf=NULL;
4031 int i, retval, command;
4032 static char **backup_argv;
4033 static int backup_argc;
4034 char *command_arg = NULL;
4035 char *errmsg=NULL;
4037 if (argv) { /* first time we're called. save command line args */
4038 backup_argv = argv;
4039 backup_argc = argc;
4040 } else { /* we're reloading. need to clean up old options first. */
4041 argv = backup_argv;
4042 argc = backup_argc;
4044 if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
4045 print_usage();
4046 exit(0);
4048 if (argc > 1 && !strcmp(argv[1], "--list-torrc-options")) {
4049 /* For documenting validating whether we've documented everything. */
4050 list_torrc_options();
4051 exit(0);
4054 if (argc > 1 && (!strcmp(argv[1],"--version"))) {
4055 printf("Tor version %s.\n",get_version());
4056 exit(0);
4058 if (argc > 1 && (!strcmp(argv[1],"--digests"))) {
4059 printf("Tor version %s.\n",get_version());
4060 printf("%s", libor_get_digests());
4061 printf("%s", tor_get_digests());
4062 exit(0);
4065 /* Go through command-line variables */
4066 if (!global_cmdline_options) {
4067 /* Or we could redo the list every time we pass this place.
4068 * It does not really matter */
4069 if (config_get_commandlines(argc, argv, &global_cmdline_options) < 0) {
4070 goto err;
4074 command = CMD_RUN_TOR;
4075 for (i = 1; i < argc; ++i) {
4076 if (!strcmp(argv[i],"--list-fingerprint")) {
4077 command = CMD_LIST_FINGERPRINT;
4078 } else if (!strcmp(argv[i],"--hash-password")) {
4079 command = CMD_HASH_PASSWORD;
4080 command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : "");
4081 ++i;
4082 } else if (!strcmp(argv[i],"--verify-config")) {
4083 command = CMD_VERIFY_CONFIG;
4087 if (command == CMD_HASH_PASSWORD) {
4088 cf = tor_strdup("");
4089 } else {
4090 cf = load_torrc_from_disk(argc, argv);
4091 if (!cf)
4092 goto err;
4095 retval = options_init_from_string(cf, command, command_arg, &errmsg);
4096 tor_free(cf);
4097 if (retval < 0)
4098 goto err;
4100 return 0;
4102 err:
4103 if (errmsg) {
4104 log(LOG_WARN,LD_CONFIG,"%s", errmsg);
4105 tor_free(errmsg);
4107 return -1;
4110 /** Load the options from the configuration in <b>cf</b>, validate
4111 * them for consistency and take actions based on them.
4113 * Return 0 if success, negative on error:
4114 * * -1 for general errors.
4115 * * -2 for failure to parse/validate,
4116 * * -3 for transition not allowed
4117 * * -4 for error while setting the new options
4119 setopt_err_t
4120 options_init_from_string(const char *cf,
4121 int command, const char *command_arg,
4122 char **msg)
4124 or_options_t *oldoptions, *newoptions;
4125 config_line_t *cl;
4126 int retval;
4127 setopt_err_t err = SETOPT_ERR_MISC;
4128 tor_assert(msg);
4130 oldoptions = global_options; /* get_options unfortunately asserts if
4131 this is the first time we run*/
4133 newoptions = tor_malloc_zero(sizeof(or_options_t));
4134 newoptions->_magic = OR_OPTIONS_MAGIC;
4135 options_init(newoptions);
4136 newoptions->command = command;
4137 newoptions->command_arg = command_arg;
4139 /* get config lines, assign them */
4140 retval = config_get_lines(cf, &cl);
4141 if (retval < 0) {
4142 err = SETOPT_ERR_PARSE;
4143 goto err;
4145 retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
4146 config_free_lines(cl);
4147 if (retval < 0) {
4148 err = SETOPT_ERR_PARSE;
4149 goto err;
4152 /* Go through command-line variables too */
4153 retval = config_assign(&options_format, newoptions,
4154 global_cmdline_options, 0, 0, msg);
4155 if (retval < 0) {
4156 err = SETOPT_ERR_PARSE;
4157 goto err;
4160 /* If this is a testing network configuration, change defaults
4161 * for a list of dependent config options, re-initialize newoptions
4162 * with the new defaults, and assign all options to it second time. */
4163 if (newoptions->TestingTorNetwork) {
4164 /* XXXX this is a bit of a kludge. perhaps there's a better way to do
4165 * this? We could, for example, make the parsing algorithm do two passes
4166 * over the configuration. If it finds any "suite" options like
4167 * TestingTorNetwork, it could change the defaults before its second pass.
4168 * Not urgent so long as this seems to work, but at any sign of trouble,
4169 * let's clean it up. -NM */
4171 /* Change defaults. */
4172 int i;
4173 for (i = 0; testing_tor_network_defaults[i].name; ++i) {
4174 config_var_t *new_var = &testing_tor_network_defaults[i];
4175 config_var_t *old_var =
4176 config_find_option(&options_format, new_var->name);
4177 tor_assert(new_var);
4178 tor_assert(old_var);
4179 old_var->initvalue = new_var->initvalue;
4182 /* Clear newoptions and re-initialize them with new defaults. */
4183 config_free(&options_format, newoptions);
4184 newoptions = tor_malloc_zero(sizeof(or_options_t));
4185 newoptions->_magic = OR_OPTIONS_MAGIC;
4186 options_init(newoptions);
4187 newoptions->command = command;
4188 newoptions->command_arg = command_arg;
4190 /* Assign all options a second time. */
4191 retval = config_get_lines(cf, &cl);
4192 if (retval < 0) {
4193 err = SETOPT_ERR_PARSE;
4194 goto err;
4196 retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
4197 config_free_lines(cl);
4198 if (retval < 0) {
4199 err = SETOPT_ERR_PARSE;
4200 goto err;
4202 retval = config_assign(&options_format, newoptions,
4203 global_cmdline_options, 0, 0, msg);
4204 if (retval < 0) {
4205 err = SETOPT_ERR_PARSE;
4206 goto err;
4210 /* Validate newoptions */
4211 if (options_validate(oldoptions, newoptions, 0, msg) < 0) {
4212 err = SETOPT_ERR_PARSE; /*XXX make this a separate return value.*/
4213 goto err;
4216 if (options_transition_allowed(oldoptions, newoptions, msg) < 0) {
4217 err = SETOPT_ERR_TRANSITION;
4218 goto err;
4221 if (set_options(newoptions, msg)) {
4222 err = SETOPT_ERR_SETTING;
4223 goto err; /* frees and replaces old options */
4226 return SETOPT_OK;
4228 err:
4229 config_free(&options_format, newoptions);
4230 if (*msg) {
4231 int len = strlen(*msg)+256;
4232 char *newmsg = tor_malloc(len);
4234 tor_snprintf(newmsg, len, "Failed to parse/validate config: %s", *msg);
4235 tor_free(*msg);
4236 *msg = newmsg;
4238 return err;
4241 /** Return the location for our configuration file.
4243 const char *
4244 get_torrc_fname(void)
4246 if (torrc_fname)
4247 return torrc_fname;
4248 else
4249 return get_default_conf_file();
4252 /** Adjust the address map based on the MapAddress elements in the
4253 * configuration <b>options</b>
4255 static void
4256 config_register_addressmaps(or_options_t *options)
4258 smartlist_t *elts;
4259 config_line_t *opt;
4260 char *from, *to;
4262 addressmap_clear_configured();
4263 elts = smartlist_create();
4264 for (opt = options->AddressMap; opt; opt = opt->next) {
4265 smartlist_split_string(elts, opt->value, NULL,
4266 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
4267 if (smartlist_len(elts) >= 2) {
4268 from = smartlist_get(elts,0);
4269 to = smartlist_get(elts,1);
4270 if (address_is_invalid_destination(to, 1)) {
4271 log_warn(LD_CONFIG,
4272 "Skipping invalid argument '%s' to MapAddress", to);
4273 } else {
4274 addressmap_register(from, tor_strdup(to), 0, ADDRMAPSRC_TORRC);
4275 if (smartlist_len(elts)>2) {
4276 log_warn(LD_CONFIG,"Ignoring extra arguments to MapAddress.");
4279 } else {
4280 log_warn(LD_CONFIG,"MapAddress '%s' has too few arguments. Ignoring.",
4281 opt->value);
4283 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
4284 smartlist_clear(elts);
4286 smartlist_free(elts);
4290 * Initialize the logs based on the configuration file.
4292 static int
4293 options_init_logs(or_options_t *options, int validate_only)
4295 config_line_t *opt;
4296 int ok;
4297 smartlist_t *elts;
4298 int daemon =
4299 #ifdef MS_WINDOWS
4301 #else
4302 options->RunAsDaemon;
4303 #endif
4305 ok = 1;
4306 elts = smartlist_create();
4308 for (opt = options->Logs; opt; opt = opt->next) {
4309 log_severity_list_t *severity;
4310 const char *cfg = opt->value;
4311 severity = tor_malloc_zero(sizeof(log_severity_list_t));
4312 if (parse_log_severity_config(&cfg, severity) < 0) {
4313 log_warn(LD_CONFIG, "Couldn't parse log levels in Log option 'Log %s'",
4314 opt->value);
4315 ok = 0; goto cleanup;
4318 smartlist_split_string(elts, cfg, NULL,
4319 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
4321 if (smartlist_len(elts) == 0)
4322 smartlist_add(elts, tor_strdup("stdout"));
4324 if (smartlist_len(elts) == 1 &&
4325 (!strcasecmp(smartlist_get(elts,0), "stdout") ||
4326 !strcasecmp(smartlist_get(elts,0), "stderr"))) {
4327 int err = smartlist_len(elts) &&
4328 !strcasecmp(smartlist_get(elts,0), "stderr");
4329 if (!validate_only) {
4330 if (daemon) {
4331 log_warn(LD_CONFIG,
4332 "Can't log to %s with RunAsDaemon set; skipping stdout",
4333 err?"stderr":"stdout");
4334 } else {
4335 add_stream_log(severity, err?"<stderr>":"<stdout>",
4336 fileno(err?stderr:stdout));
4339 goto cleanup;
4341 if (smartlist_len(elts) == 1 &&
4342 !strcasecmp(smartlist_get(elts,0), "syslog")) {
4343 #ifdef HAVE_SYSLOG_H
4344 if (!validate_only) {
4345 add_syslog_log(severity);
4347 #else
4348 log_warn(LD_CONFIG, "Syslog is not supported on this system. Sorry.");
4349 #endif
4350 goto cleanup;
4353 if (smartlist_len(elts) == 2 &&
4354 !strcasecmp(smartlist_get(elts,0), "file")) {
4355 if (!validate_only) {
4356 if (add_file_log(severity, smartlist_get(elts, 1)) < 0) {
4357 log_warn(LD_CONFIG, "Couldn't open file for 'Log %s': %s",
4358 opt->value, strerror(errno));
4359 ok = 0;
4362 goto cleanup;
4365 log_warn(LD_CONFIG, "Bad syntax on file Log option 'Log %s'",
4366 opt->value);
4367 ok = 0; goto cleanup;
4369 cleanup:
4370 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
4371 smartlist_clear(elts);
4372 tor_free(severity);
4374 smartlist_free(elts);
4376 return ok?0:-1;
4379 /** Read the contents of a Bridge line from <b>line</b>. Return 0
4380 * if the line is well-formed, and -1 if it isn't. If
4381 * <b>validate_only</b> is 0, and the line is well-formed, then add
4382 * the bridge described in the line to our internal bridge list. */
4383 static int
4384 parse_bridge_line(const char *line, int validate_only)
4386 smartlist_t *items = NULL;
4387 int r;
4388 char *addrport=NULL, *fingerprint=NULL;
4389 tor_addr_t addr;
4390 uint16_t port = 0;
4391 char digest[DIGEST_LEN];
4393 items = smartlist_create();
4394 smartlist_split_string(items, line, NULL,
4395 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
4396 if (smartlist_len(items) < 1) {
4397 log_warn(LD_CONFIG, "Too few arguments to Bridge line.");
4398 goto err;
4400 addrport = smartlist_get(items, 0);
4401 smartlist_del_keeporder(items, 0);
4402 if (tor_addr_port_parse(addrport, &addr, &port)<0) {
4403 log_warn(LD_CONFIG, "Error parsing Bridge address '%s'", addrport);
4404 goto err;
4406 if (!port) {
4407 log_info(LD_CONFIG,
4408 "Bridge address '%s' has no port; using default port 443.",
4409 addrport);
4410 port = 443;
4413 if (smartlist_len(items)) {
4414 fingerprint = smartlist_join_strings(items, "", 0, NULL);
4415 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
4416 log_warn(LD_CONFIG, "Key digest for Bridge is wrong length.");
4417 goto err;
4419 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
4420 log_warn(LD_CONFIG, "Unable to decode Bridge key digest.");
4421 goto err;
4425 if (!validate_only) {
4426 log_debug(LD_DIR, "Bridge at %s:%d (%s)", fmt_addr(&addr),
4427 (int)port,
4428 fingerprint ? fingerprint : "no key listed");
4429 bridge_add_from_config(&addr, port, fingerprint ? digest : NULL);
4432 r = 0;
4433 goto done;
4435 err:
4436 r = -1;
4438 done:
4439 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
4440 smartlist_free(items);
4441 tor_free(addrport);
4442 tor_free(fingerprint);
4443 return r;
4446 /** Read the contents of a DirServer line from <b>line</b>. If
4447 * <b>validate_only</b> is 0, and the line is well-formed, and it
4448 * shares any bits with <b>required_type</b> or <b>required_type</b>
4449 * is 0, then add the dirserver described in the line (minus whatever
4450 * bits it's missing) as a valid authority. Return 0 on success,
4451 * or -1 if the line isn't well-formed or if we can't add it. */
4452 static int
4453 parse_dir_server_line(const char *line, authority_type_t required_type,
4454 int validate_only)
4456 smartlist_t *items = NULL;
4457 int r;
4458 char *addrport=NULL, *address=NULL, *nickname=NULL, *fingerprint=NULL;
4459 uint16_t dir_port = 0, or_port = 0;
4460 char digest[DIGEST_LEN];
4461 char v3_digest[DIGEST_LEN];
4462 authority_type_t type = V2_AUTHORITY;
4463 int is_not_hidserv_authority = 0, is_not_v2_authority = 0;
4465 items = smartlist_create();
4466 smartlist_split_string(items, line, NULL,
4467 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
4468 if (smartlist_len(items) < 1) {
4469 log_warn(LD_CONFIG, "No arguments on DirServer line.");
4470 goto err;
4473 if (is_legal_nickname(smartlist_get(items, 0))) {
4474 nickname = smartlist_get(items, 0);
4475 smartlist_del_keeporder(items, 0);
4478 while (smartlist_len(items)) {
4479 char *flag = smartlist_get(items, 0);
4480 if (TOR_ISDIGIT(flag[0]))
4481 break;
4482 if (!strcasecmp(flag, "v1")) {
4483 type |= (V1_AUTHORITY | HIDSERV_AUTHORITY);
4484 } else if (!strcasecmp(flag, "hs")) {
4485 type |= HIDSERV_AUTHORITY;
4486 } else if (!strcasecmp(flag, "no-hs")) {
4487 is_not_hidserv_authority = 1;
4488 } else if (!strcasecmp(flag, "bridge")) {
4489 type |= BRIDGE_AUTHORITY;
4490 } else if (!strcasecmp(flag, "no-v2")) {
4491 is_not_v2_authority = 1;
4492 } else if (!strcasecmpstart(flag, "orport=")) {
4493 int ok;
4494 char *portstring = flag + strlen("orport=");
4495 or_port = (uint16_t) tor_parse_long(portstring, 10, 1, 65535, &ok, NULL);
4496 if (!ok)
4497 log_warn(LD_CONFIG, "Invalid orport '%s' on DirServer line.",
4498 portstring);
4499 } else if (!strcasecmpstart(flag, "v3ident=")) {
4500 char *idstr = flag + strlen("v3ident=");
4501 if (strlen(idstr) != HEX_DIGEST_LEN ||
4502 base16_decode(v3_digest, DIGEST_LEN, idstr, HEX_DIGEST_LEN)<0) {
4503 log_warn(LD_CONFIG, "Bad v3 identity digest '%s' on DirServer line",
4504 flag);
4505 } else {
4506 type |= V3_AUTHORITY;
4508 } else {
4509 log_warn(LD_CONFIG, "Unrecognized flag '%s' on DirServer line",
4510 flag);
4512 tor_free(flag);
4513 smartlist_del_keeporder(items, 0);
4515 if (is_not_hidserv_authority)
4516 type &= ~HIDSERV_AUTHORITY;
4517 if (is_not_v2_authority)
4518 type &= ~V2_AUTHORITY;
4520 if (smartlist_len(items) < 2) {
4521 log_warn(LD_CONFIG, "Too few arguments to DirServer line.");
4522 goto err;
4524 addrport = smartlist_get(items, 0);
4525 smartlist_del_keeporder(items, 0);
4526 if (parse_addr_port(LOG_WARN, addrport, &address, NULL, &dir_port)<0) {
4527 log_warn(LD_CONFIG, "Error parsing DirServer address '%s'", addrport);
4528 goto err;
4530 if (!dir_port) {
4531 log_warn(LD_CONFIG, "Missing port in DirServer address '%s'",addrport);
4532 goto err;
4535 fingerprint = smartlist_join_strings(items, "", 0, NULL);
4536 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
4537 log_warn(LD_CONFIG, "Key digest for DirServer is wrong length %d.",
4538 (int)strlen(fingerprint));
4539 goto err;
4541 if (!strcmp(fingerprint, "E623F7625FBE0C87820F11EC5F6D5377ED816294")) {
4542 /* a known bad fingerprint. refuse to use it. We can remove this
4543 * clause once Tor 0.1.2.17 is obsolete. */
4544 log_warn(LD_CONFIG, "Dangerous dirserver line. To correct, erase your "
4545 "torrc file (%s), or reinstall Tor and use the default torrc.",
4546 get_torrc_fname());
4547 goto err;
4549 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
4550 log_warn(LD_CONFIG, "Unable to decode DirServer key digest.");
4551 goto err;
4554 if (!validate_only && (!required_type || required_type & type)) {
4555 if (required_type)
4556 type &= required_type; /* pare down what we think of them as an
4557 * authority for. */
4558 log_debug(LD_DIR, "Trusted %d dirserver at %s:%d (%s)", (int)type,
4559 address, (int)dir_port, (char*)smartlist_get(items,0));
4560 if (!add_trusted_dir_server(nickname, address, dir_port, or_port,
4561 digest, v3_digest, type))
4562 goto err;
4565 r = 0;
4566 goto done;
4568 err:
4569 r = -1;
4571 done:
4572 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
4573 smartlist_free(items);
4574 tor_free(addrport);
4575 tor_free(address);
4576 tor_free(nickname);
4577 tor_free(fingerprint);
4578 return r;
4581 /** Adjust the value of options->DataDirectory, or fill it in if it's
4582 * absent. Return 0 on success, -1 on failure. */
4583 static int
4584 normalize_data_directory(or_options_t *options)
4586 #ifdef MS_WINDOWS
4587 char *p;
4588 if (options->DataDirectory)
4589 return 0; /* all set */
4590 p = tor_malloc(MAX_PATH);
4591 strlcpy(p,get_windows_conf_root(),MAX_PATH);
4592 options->DataDirectory = p;
4593 return 0;
4594 #else
4595 const char *d = options->DataDirectory;
4596 if (!d)
4597 d = "~/.tor";
4599 if (strncmp(d,"~/",2) == 0) {
4600 char *fn = expand_filename(d);
4601 if (!fn) {
4602 log_warn(LD_CONFIG,"Failed to expand filename \"%s\".", d);
4603 return -1;
4605 if (!options->DataDirectory && !strcmp(fn,"/.tor")) {
4606 /* If our homedir is /, we probably don't want to use it. */
4607 /* Default to LOCALSTATEDIR/tor which is probably closer to what we
4608 * want. */
4609 log_warn(LD_CONFIG,
4610 "Default DataDirectory is \"~/.tor\". This expands to "
4611 "\"%s\", which is probably not what you want. Using "
4612 "\"%s"PATH_SEPARATOR"tor\" instead", fn, LOCALSTATEDIR);
4613 tor_free(fn);
4614 fn = tor_strdup(LOCALSTATEDIR PATH_SEPARATOR "tor");
4616 tor_free(options->DataDirectory);
4617 options->DataDirectory = fn;
4619 return 0;
4620 #endif
4623 /** Check and normalize the value of options->DataDirectory; return 0 if it
4624 * sane, -1 otherwise. */
4625 static int
4626 validate_data_directory(or_options_t *options)
4628 if (normalize_data_directory(options) < 0)
4629 return -1;
4630 tor_assert(options->DataDirectory);
4631 if (strlen(options->DataDirectory) > (512-128)) {
4632 log_warn(LD_CONFIG, "DataDirectory is too long.");
4633 return -1;
4635 return 0;
4638 /** This string must remain the same forevermore. It is how we
4639 * recognize that the torrc file doesn't need to be backed up. */
4640 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; " \
4641 "if you edit it, comments will not be preserved"
4642 /** This string can change; it tries to give the reader an idea
4643 * that editing this file by hand is not a good plan. */
4644 #define GENERATED_FILE_COMMENT "# The old torrc file was renamed " \
4645 "to torrc.orig.1 or similar, and Tor will ignore it"
4647 /** Save a configuration file for the configuration in <b>options</b>
4648 * into the file <b>fname</b>. If the file already exists, and
4649 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
4650 * replace it. Return 0 on success, -1 on failure. */
4651 static int
4652 write_configuration_file(const char *fname, or_options_t *options)
4654 char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
4655 int rename_old = 0, r;
4656 size_t len;
4658 tor_assert(fname);
4660 switch (file_status(fname)) {
4661 case FN_FILE:
4662 old_val = read_file_to_str(fname, 0, NULL);
4663 if (strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
4664 rename_old = 1;
4666 tor_free(old_val);
4667 break;
4668 case FN_NOENT:
4669 break;
4670 case FN_ERROR:
4671 case FN_DIR:
4672 default:
4673 log_warn(LD_CONFIG,
4674 "Config file \"%s\" is not a file? Failing.", fname);
4675 return -1;
4678 if (!(new_conf = options_dump(options, 1))) {
4679 log_warn(LD_BUG, "Couldn't get configuration string");
4680 goto err;
4683 len = strlen(new_conf)+256;
4684 new_val = tor_malloc(len);
4685 tor_snprintf(new_val, len, "%s\n%s\n\n%s",
4686 GENERATED_FILE_PREFIX, GENERATED_FILE_COMMENT, new_conf);
4688 if (rename_old) {
4689 int i = 1;
4690 size_t fn_tmp_len = strlen(fname)+32;
4691 char *fn_tmp;
4692 tor_assert(fn_tmp_len > strlen(fname)); /*check for overflow*/
4693 fn_tmp = tor_malloc(fn_tmp_len);
4694 while (1) {
4695 if (tor_snprintf(fn_tmp, fn_tmp_len, "%s.orig.%d", fname, i)<0) {
4696 log_warn(LD_BUG, "tor_snprintf failed inexplicably");
4697 tor_free(fn_tmp);
4698 goto err;
4700 if (file_status(fn_tmp) == FN_NOENT)
4701 break;
4702 ++i;
4704 log_notice(LD_CONFIG, "Renaming old configuration file to \"%s\"", fn_tmp);
4705 if (rename(fname, fn_tmp) < 0) {
4706 log_warn(LD_FS,
4707 "Couldn't rename configuration file \"%s\" to \"%s\": %s",
4708 fname, fn_tmp, strerror(errno));
4709 tor_free(fn_tmp);
4710 goto err;
4712 tor_free(fn_tmp);
4715 if (write_str_to_file(fname, new_val, 0) < 0)
4716 goto err;
4718 r = 0;
4719 goto done;
4720 err:
4721 r = -1;
4722 done:
4723 tor_free(new_val);
4724 tor_free(new_conf);
4725 return r;
4729 * Save the current configuration file value to disk. Return 0 on
4730 * success, -1 on failure.
4733 options_save_current(void)
4735 if (torrc_fname) {
4736 /* This fails if we can't write to our configuration file.
4738 * If we try falling back to datadirectory or something, we have a better
4739 * chance of saving the configuration, but a better chance of doing
4740 * something the user never expected. Let's just warn instead. */
4741 return write_configuration_file(torrc_fname, get_options());
4743 return write_configuration_file(get_default_conf_file(), get_options());
4746 /** Mapping from a unit name to a multiplier for converting that unit into a
4747 * base unit. */
4748 struct unit_table_t {
4749 const char *unit;
4750 uint64_t multiplier;
4753 /** Table to map the names of memory units to the number of bytes they
4754 * contain. */
4755 static struct unit_table_t memory_units[] = {
4756 { "", 1 },
4757 { "b", 1<< 0 },
4758 { "byte", 1<< 0 },
4759 { "bytes", 1<< 0 },
4760 { "kb", 1<<10 },
4761 { "kbyte", 1<<10 },
4762 { "kbytes", 1<<10 },
4763 { "kilobyte", 1<<10 },
4764 { "kilobytes", 1<<10 },
4765 { "m", 1<<20 },
4766 { "mb", 1<<20 },
4767 { "mbyte", 1<<20 },
4768 { "mbytes", 1<<20 },
4769 { "megabyte", 1<<20 },
4770 { "megabytes", 1<<20 },
4771 { "gb", 1<<30 },
4772 { "gbyte", 1<<30 },
4773 { "gbytes", 1<<30 },
4774 { "gigabyte", 1<<30 },
4775 { "gigabytes", 1<<30 },
4776 { "tb", U64_LITERAL(1)<<40 },
4777 { "terabyte", U64_LITERAL(1)<<40 },
4778 { "terabytes", U64_LITERAL(1)<<40 },
4779 { NULL, 0 },
4782 /** Table to map the names of time units to the number of seconds they
4783 * contain. */
4784 static struct unit_table_t time_units[] = {
4785 { "", 1 },
4786 { "second", 1 },
4787 { "seconds", 1 },
4788 { "minute", 60 },
4789 { "minutes", 60 },
4790 { "hour", 60*60 },
4791 { "hours", 60*60 },
4792 { "day", 24*60*60 },
4793 { "days", 24*60*60 },
4794 { "week", 7*24*60*60 },
4795 { "weeks", 7*24*60*60 },
4796 { NULL, 0 },
4799 /** Parse a string <b>val</b> containing a number, zero or more
4800 * spaces, and an optional unit string. If the unit appears in the
4801 * table <b>u</b>, then multiply the number by the unit multiplier.
4802 * On success, set *<b>ok</b> to 1 and return this product.
4803 * Otherwise, set *<b>ok</b> to 0.
4805 static uint64_t
4806 config_parse_units(const char *val, struct unit_table_t *u, int *ok)
4808 uint64_t v;
4809 char *cp;
4811 tor_assert(ok);
4813 v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
4814 if (!*ok)
4815 return 0;
4816 if (!cp) {
4817 *ok = 1;
4818 return v;
4820 while (TOR_ISSPACE(*cp))
4821 ++cp;
4822 for ( ;u->unit;++u) {
4823 if (!strcasecmp(u->unit, cp)) {
4824 v *= u->multiplier;
4825 *ok = 1;
4826 return v;
4829 log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
4830 *ok = 0;
4831 return 0;
4834 /** Parse a string in the format "number unit", where unit is a unit of
4835 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
4836 * and return the number of bytes specified. Otherwise, set
4837 * *<b>ok</b> to false and return 0. */
4838 static uint64_t
4839 config_parse_memunit(const char *s, int *ok)
4841 return config_parse_units(s, memory_units, ok);
4844 /** Parse a string in the format "number unit", where unit is a unit of time.
4845 * On success, set *<b>ok</b> to true and return the number of seconds in
4846 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
4848 static int
4849 config_parse_interval(const char *s, int *ok)
4851 uint64_t r;
4852 r = config_parse_units(s, time_units, ok);
4853 if (!ok)
4854 return -1;
4855 if (r > INT_MAX) {
4856 log_warn(LD_CONFIG, "Interval '%s' is too long", s);
4857 *ok = 0;
4858 return -1;
4860 return (int)r;
4864 * Initialize the libevent library.
4866 static void
4867 init_libevent(void)
4869 const char *badness=NULL;
4871 configure_libevent_logging();
4872 /* If the kernel complains that some method (say, epoll) doesn't
4873 * exist, we don't care about it, since libevent will cope.
4875 suppress_libevent_log_msg("Function not implemented");
4877 tor_check_libevent_header_compatibility();
4879 tor_libevent_initialize();
4881 suppress_libevent_log_msg(NULL);
4883 tor_check_libevent_version(tor_libevent_get_method(),
4884 get_options()->ORPort != 0,
4885 &badness);
4886 if (badness) {
4887 const char *v = tor_libevent_get_version_str();
4888 const char *m = tor_libevent_get_method();
4889 control_event_general_status(LOG_WARN,
4890 "BAD_LIBEVENT VERSION=%s METHOD=%s BADNESS=%s RECOVERED=NO",
4891 v, m, badness);
4895 /** Return the persistent state struct for this Tor. */
4896 or_state_t *
4897 get_or_state(void)
4899 tor_assert(global_state);
4900 return global_state;
4903 /** Return a newly allocated string holding a filename relative to the data
4904 * directory. If <b>sub1</b> is present, it is the first path component after
4905 * the data directory. If <b>sub2</b> is also present, it is the second path
4906 * component after the data directory. If <b>suffix</b> is present, it
4907 * is appended to the filename.
4909 * Examples:
4910 * get_datadir_fname2_suffix("a", NULL, NULL) -> $DATADIR/a
4911 * get_datadir_fname2_suffix("a", NULL, ".tmp") -> $DATADIR/a.tmp
4912 * get_datadir_fname2_suffix("a", "b", ".tmp") -> $DATADIR/a/b/.tmp
4913 * get_datadir_fname2_suffix("a", "b", NULL) -> $DATADIR/a/b
4915 * Note: Consider using the get_datadir_fname* macros in or.h.
4917 char *
4918 options_get_datadir_fname2_suffix(or_options_t *options,
4919 const char *sub1, const char *sub2,
4920 const char *suffix)
4922 char *fname = NULL;
4923 size_t len;
4924 tor_assert(options);
4925 tor_assert(options->DataDirectory);
4926 tor_assert(sub1 || !sub2); /* If sub2 is present, sub1 must be present. */
4927 len = strlen(options->DataDirectory);
4928 if (sub1) {
4929 len += strlen(sub1)+1;
4930 if (sub2)
4931 len += strlen(sub2)+1;
4933 if (suffix)
4934 len += strlen(suffix);
4935 len++;
4936 fname = tor_malloc(len);
4937 if (sub1) {
4938 if (sub2) {
4939 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s"PATH_SEPARATOR"%s",
4940 options->DataDirectory, sub1, sub2);
4941 } else {
4942 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s",
4943 options->DataDirectory, sub1);
4945 } else {
4946 strlcpy(fname, options->DataDirectory, len);
4948 if (suffix)
4949 strlcat(fname, suffix, len);
4950 return fname;
4953 /** Return 0 if every setting in <b>state</b> is reasonable, and a
4954 * permissible transition from <b>old_state</b>. Else warn and return -1.
4955 * Should have no side effects, except for normalizing the contents of
4956 * <b>state</b>.
4958 /* XXX from_setconf is here because of bug 238 */
4959 static int
4960 or_state_validate(or_state_t *old_state, or_state_t *state,
4961 int from_setconf, char **msg)
4963 /* We don't use these; only options do. Still, we need to match that
4964 * signature. */
4965 (void) from_setconf;
4966 (void) old_state;
4968 if (entry_guards_parse_state(state, 0, msg)<0)
4969 return -1;
4971 return 0;
4974 /** Replace the current persistent state with <b>new_state</b> */
4975 static void
4976 or_state_set(or_state_t *new_state)
4978 char *err = NULL;
4979 tor_assert(new_state);
4980 if (global_state)
4981 config_free(&state_format, global_state);
4982 global_state = new_state;
4983 if (entry_guards_parse_state(global_state, 1, &err)<0) {
4984 log_warn(LD_GENERAL,"%s",err);
4985 tor_free(err);
4987 if (rep_hist_load_state(global_state, &err)<0) {
4988 log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
4989 tor_free(err);
4993 /** Reload the persistent state from disk, generating a new state as needed.
4994 * Return 0 on success, less than 0 on failure.
4996 static int
4997 or_state_load(void)
4999 or_state_t *new_state = NULL;
5000 char *contents = NULL, *fname;
5001 char *errmsg = NULL;
5002 int r = -1, badstate = 0;
5004 fname = get_datadir_fname("state");
5005 switch (file_status(fname)) {
5006 case FN_FILE:
5007 if (!(contents = read_file_to_str(fname, 0, NULL))) {
5008 log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
5009 goto done;
5011 break;
5012 case FN_NOENT:
5013 break;
5014 case FN_ERROR:
5015 case FN_DIR:
5016 default:
5017 log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
5018 goto done;
5020 new_state = tor_malloc_zero(sizeof(or_state_t));
5021 new_state->_magic = OR_STATE_MAGIC;
5022 config_init(&state_format, new_state);
5023 if (contents) {
5024 config_line_t *lines=NULL;
5025 int assign_retval;
5026 if (config_get_lines(contents, &lines)<0)
5027 goto done;
5028 assign_retval = config_assign(&state_format, new_state,
5029 lines, 0, 0, &errmsg);
5030 config_free_lines(lines);
5031 if (assign_retval<0)
5032 badstate = 1;
5033 if (errmsg) {
5034 log_warn(LD_GENERAL, "%s", errmsg);
5035 tor_free(errmsg);
5039 if (!badstate && or_state_validate(NULL, new_state, 1, &errmsg) < 0)
5040 badstate = 1;
5042 if (errmsg) {
5043 log_warn(LD_GENERAL, "%s", errmsg);
5044 tor_free(errmsg);
5047 if (badstate && !contents) {
5048 log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
5049 " This is a bug in Tor.");
5050 goto done;
5051 } else if (badstate && contents) {
5052 int i;
5053 file_status_t status;
5054 size_t len = strlen(fname)+16;
5055 char *fname2 = tor_malloc(len);
5056 for (i = 0; i < 100; ++i) {
5057 tor_snprintf(fname2, len, "%s.%d", fname, i);
5058 status = file_status(fname2);
5059 if (status == FN_NOENT)
5060 break;
5062 if (i == 100) {
5063 log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
5064 "state files to move aside. Discarding the old state file.",
5065 fname);
5066 unlink(fname);
5067 } else {
5068 log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
5069 "to \"%s\". This could be a bug in Tor; please tell "
5070 "the developers.", fname, fname2);
5071 if (rename(fname, fname2) < 0) {
5072 log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
5073 "OS gave an error of %s", strerror(errno));
5076 tor_free(fname2);
5077 tor_free(contents);
5078 config_free(&state_format, new_state);
5080 new_state = tor_malloc_zero(sizeof(or_state_t));
5081 new_state->_magic = OR_STATE_MAGIC;
5082 config_init(&state_format, new_state);
5083 } else if (contents) {
5084 log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
5085 } else {
5086 log_info(LD_GENERAL, "Initialized state");
5088 or_state_set(new_state);
5089 new_state = NULL;
5090 if (!contents) {
5091 global_state->next_write = 0;
5092 or_state_save(time(NULL));
5094 r = 0;
5096 done:
5097 tor_free(fname);
5098 tor_free(contents);
5099 if (new_state)
5100 config_free(&state_format, new_state);
5102 return r;
5105 /** Write the persistent state to disk. Return 0 for success, <0 on failure. */
5107 or_state_save(time_t now)
5109 char *state, *contents;
5110 char tbuf[ISO_TIME_LEN+1];
5111 size_t len;
5112 char *fname;
5114 tor_assert(global_state);
5116 if (global_state->next_write > now)
5117 return 0;
5119 /* Call everything else that might dirty the state even more, in order
5120 * to avoid redundant writes. */
5121 entry_guards_update_state(global_state);
5122 rep_hist_update_state(global_state);
5123 if (accounting_is_enabled(get_options()))
5124 accounting_run_housekeeping(now);
5126 global_state->LastWritten = time(NULL);
5127 tor_free(global_state->TorVersion);
5128 len = strlen(get_version())+8;
5129 global_state->TorVersion = tor_malloc(len);
5130 tor_snprintf(global_state->TorVersion, len, "Tor %s", get_version());
5132 state = config_dump(&state_format, global_state, 1, 0);
5133 len = strlen(state)+256;
5134 contents = tor_malloc(len);
5135 format_local_iso_time(tbuf, time(NULL));
5136 tor_snprintf(contents, len,
5137 "# Tor state file last generated on %s local time\n"
5138 "# Other times below are in GMT\n"
5139 "# You *do not* need to edit this file.\n\n%s",
5140 tbuf, state);
5141 tor_free(state);
5142 fname = get_datadir_fname("state");
5143 if (write_str_to_file(fname, contents, 0)<0) {
5144 log_warn(LD_FS, "Unable to write state to file \"%s\"", fname);
5145 tor_free(fname);
5146 tor_free(contents);
5147 return -1;
5149 log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
5150 tor_free(fname);
5151 tor_free(contents);
5153 global_state->next_write = TIME_MAX;
5154 return 0;
5157 /** Given a file name check to see whether the file exists but has not been
5158 * modified for a very long time. If so, remove it. */
5159 void
5160 remove_file_if_very_old(const char *fname, time_t now)
5162 #define VERY_OLD_FILE_AGE (28*24*60*60)
5163 struct stat st;
5165 if (stat(fname, &st)==0 && st.st_mtime < now-VERY_OLD_FILE_AGE) {
5166 char buf[ISO_TIME_LEN+1];
5167 format_local_iso_time(buf, st.st_mtime);
5168 log_notice(LD_GENERAL, "Obsolete file %s hasn't been modified since %s. "
5169 "Removing it.", fname, buf);
5170 unlink(fname);
5174 /** Helper to implement GETINFO functions about configuration variables (not
5175 * their values). Given a "config/names" question, set *<b>answer</b> to a
5176 * new string describing the supported configuration variables and their
5177 * types. */
5179 getinfo_helper_config(control_connection_t *conn,
5180 const char *question, char **answer)
5182 (void) conn;
5183 if (!strcmp(question, "config/names")) {
5184 smartlist_t *sl = smartlist_create();
5185 int i;
5186 for (i = 0; _option_vars[i].name; ++i) {
5187 config_var_t *var = &_option_vars[i];
5188 const char *type, *desc;
5189 char *line;
5190 size_t len;
5191 desc = config_find_description(&options_format, var->name);
5192 switch (var->type) {
5193 case CONFIG_TYPE_STRING: type = "String"; break;
5194 case CONFIG_TYPE_FILENAME: type = "Filename"; break;
5195 case CONFIG_TYPE_UINT: type = "Integer"; break;
5196 case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
5197 case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
5198 case CONFIG_TYPE_DOUBLE: type = "Float"; break;
5199 case CONFIG_TYPE_BOOL: type = "Boolean"; break;
5200 case CONFIG_TYPE_ISOTIME: type = "Time"; break;
5201 case CONFIG_TYPE_ROUTERSET: type = "RouterList"; break;
5202 case CONFIG_TYPE_CSV: type = "CommaList"; break;
5203 case CONFIG_TYPE_LINELIST: type = "LineList"; break;
5204 case CONFIG_TYPE_LINELIST_S: type = "Dependant"; break;
5205 case CONFIG_TYPE_LINELIST_V: type = "Virtual"; break;
5206 default:
5207 case CONFIG_TYPE_OBSOLETE:
5208 type = NULL; break;
5210 if (!type)
5211 continue;
5212 len = strlen(var->name)+strlen(type)+16;
5213 if (desc)
5214 len += strlen(desc);
5215 line = tor_malloc(len);
5216 if (desc)
5217 tor_snprintf(line, len, "%s %s %s\n",var->name,type,desc);
5218 else
5219 tor_snprintf(line, len, "%s %s\n",var->name,type);
5220 smartlist_add(sl, line);
5222 *answer = smartlist_join_strings(sl, "", 0, NULL);
5223 SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
5224 smartlist_free(sl);
5226 return 0;