Simplify the math to round up to the next multiple of some value.
[tor/rransom.git] / src / or / config.c
blob5137f747929abb6e5127fa02cd4942275e45ce00
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_GEOIP_STATS
191 OBSOLETE("DirRecordUsageByCountry"),
192 OBSOLETE("DirRecordUsageGranularity"),
193 OBSOLETE("DirRecordUsageRetainIPs"),
194 OBSOLETE("DirRecordUsageSaveInterval"),
195 #endif
196 VAR("DirServer", LINELIST, DirServers, NULL),
197 V(DNSPort, UINT, "0"),
198 V(DNSListenAddress, LINELIST, NULL),
199 V(DownloadExtraInfo, BOOL, "0"),
200 V(EnforceDistinctSubnets, BOOL, "1"),
201 V(EntryNodes, ROUTERSET, NULL),
202 V(EntryStatistics, BOOL, "0"),
203 V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "10 minutes"),
204 V(ExcludeNodes, ROUTERSET, NULL),
205 V(ExcludeExitNodes, ROUTERSET, NULL),
206 V(ExcludeSingleHopRelays, BOOL, "1"),
207 V(ExitNodes, ROUTERSET, NULL),
208 V(ExitPolicy, LINELIST, NULL),
209 V(ExitPolicyRejectPrivate, BOOL, "1"),
210 V(ExitPortStatistics, BOOL, "0"),
211 V(FallbackNetworkstatusFile, FILENAME,
212 SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "fallback-consensus"),
213 V(FascistFirewall, BOOL, "0"),
214 V(FirewallPorts, CSV, ""),
215 V(FastFirstHopPK, BOOL, "1"),
216 V(FetchDirInfoEarly, BOOL, "0"),
217 V(FetchServerDescriptors, BOOL, "1"),
218 V(FetchHidServDescriptors, BOOL, "1"),
219 V(FetchUselessDescriptors, BOOL, "0"),
220 #ifdef WIN32
221 V(GeoIPFile, FILENAME, "<default>"),
222 #else
223 V(GeoIPFile, FILENAME,
224 SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "geoip"),
225 #endif
226 OBSOLETE("Group"),
227 V(HardwareAccel, BOOL, "0"),
228 V(AccelName, STRING, NULL),
229 V(AccelDir, FILENAME, NULL),
230 V(HashedControlPassword, LINELIST, NULL),
231 V(HidServDirectoryV2, BOOL, "1"),
232 VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
233 OBSOLETE("HiddenServiceExcludeNodes"),
234 OBSOLETE("HiddenServiceNodes"),
235 VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
236 VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
237 VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines, NULL),
238 VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL),
239 V(HidServAuth, LINELIST, NULL),
240 V(HSAuthoritativeDir, BOOL, "0"),
241 V(HSAuthorityRecordStats, BOOL, "0"),
242 V(HttpProxy, STRING, NULL),
243 V(HttpProxyAuthenticator, STRING, NULL),
244 V(HttpsProxy, STRING, NULL),
245 V(HttpsProxyAuthenticator, STRING, NULL),
246 OBSOLETE("IgnoreVersion"),
247 V(KeepalivePeriod, INTERVAL, "5 minutes"),
248 VAR("Log", LINELIST, Logs, NULL),
249 OBSOLETE("LinkPadding"),
250 OBSOLETE("LogLevel"),
251 OBSOLETE("LogFile"),
252 V(LongLivedPorts, CSV,
253 "21,22,706,1863,5050,5190,5222,5223,6667,6697,8300"),
254 VAR("MapAddress", LINELIST, AddressMap, NULL),
255 V(MaxAdvertisedBandwidth, MEMUNIT, "1 GB"),
256 V(MaxCircuitDirtiness, INTERVAL, "10 minutes"),
257 V(MaxOnionsPending, UINT, "100"),
258 OBSOLETE("MonthlyAccountingStart"),
259 V(MyFamily, STRING, NULL),
260 V(NewCircuitPeriod, INTERVAL, "30 seconds"),
261 VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "0"),
262 V(NatdListenAddress, LINELIST, NULL),
263 V(NatdPort, UINT, "0"),
264 V(Nickname, STRING, NULL),
265 V(NoPublish, BOOL, "0"),
266 VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
267 V(NumCpus, UINT, "1"),
268 V(NumEntryGuards, UINT, "3"),
269 V(ORListenAddress, LINELIST, NULL),
270 V(ORPort, UINT, "0"),
271 V(OutboundBindAddress, STRING, NULL),
272 OBSOLETE("PathlenCoinWeight"),
273 V(PidFile, STRING, NULL),
274 V(TestingTorNetwork, BOOL, "0"),
275 V(PreferTunneledDirConns, BOOL, "1"),
276 V(ProtocolWarnings, BOOL, "0"),
277 V(PublishServerDescriptor, CSV, "1"),
278 V(PublishHidServDescriptors, BOOL, "1"),
279 V(ReachableAddresses, LINELIST, NULL),
280 V(ReachableDirAddresses, LINELIST, NULL),
281 V(ReachableORAddresses, LINELIST, NULL),
282 V(RecommendedVersions, LINELIST, NULL),
283 V(RecommendedClientVersions, LINELIST, NULL),
284 V(RecommendedServerVersions, LINELIST, NULL),
285 OBSOLETE("RedirectExit"),
286 V(RejectPlaintextPorts, CSV, ""),
287 V(RelayBandwidthBurst, MEMUNIT, "0"),
288 V(RelayBandwidthRate, MEMUNIT, "0"),
289 OBSOLETE("RendExcludeNodes"),
290 OBSOLETE("RendNodes"),
291 V(RendPostPeriod, INTERVAL, "1 hour"),
292 V(RephistTrackTime, INTERVAL, "24 hours"),
293 OBSOLETE("RouterFile"),
294 V(RunAsDaemon, BOOL, "0"),
295 V(RunTesting, BOOL, "0"),
296 V(SafeLogging, BOOL, "1"),
297 V(SafeSocks, BOOL, "0"),
298 V(ServerDNSAllowBrokenConfig, BOOL, "1"),
299 V(ServerDNSAllowNonRFC953Hostnames, BOOL,"0"),
300 V(ServerDNSDetectHijacking, BOOL, "1"),
301 V(ServerDNSRandomizeCase, BOOL, "1"),
302 V(ServerDNSResolvConfFile, STRING, NULL),
303 V(ServerDNSSearchDomains, BOOL, "0"),
304 V(ServerDNSTestAddresses, CSV,
305 "www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"),
306 V(ShutdownWaitLength, INTERVAL, "30 seconds"),
307 V(SocksListenAddress, LINELIST, NULL),
308 V(SocksPolicy, LINELIST, NULL),
309 V(SocksPort, UINT, "9050"),
310 V(SocksTimeout, INTERVAL, "2 minutes"),
311 OBSOLETE("StatusFetchPeriod"),
312 V(StrictEntryNodes, BOOL, "0"),
313 V(StrictExitNodes, BOOL, "0"),
314 OBSOLETE("SysLog"),
315 V(TestSocks, BOOL, "0"),
316 OBSOLETE("TestVia"),
317 V(TrackHostExits, CSV, NULL),
318 V(TrackHostExitsExpire, INTERVAL, "30 minutes"),
319 OBSOLETE("TrafficShaping"),
320 V(TransListenAddress, LINELIST, NULL),
321 V(TransPort, UINT, "0"),
322 V(TunnelDirConns, BOOL, "1"),
323 V(UpdateBridgesFromAuthority, BOOL, "0"),
324 V(UseBridges, BOOL, "0"),
325 V(UseEntryGuards, BOOL, "1"),
326 V(User, STRING, NULL),
327 VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
328 VAR("V2AuthoritativeDirectory",BOOL, V2AuthoritativeDir, "0"),
329 VAR("V3AuthoritativeDirectory",BOOL, V3AuthoritativeDir, "0"),
330 V(TestingV3AuthInitialVotingInterval, INTERVAL, "30 minutes"),
331 V(TestingV3AuthInitialVoteDelay, INTERVAL, "5 minutes"),
332 V(TestingV3AuthInitialDistDelay, INTERVAL, "5 minutes"),
333 V(V3AuthVotingInterval, INTERVAL, "1 hour"),
334 V(V3AuthVoteDelay, INTERVAL, "5 minutes"),
335 V(V3AuthDistDelay, INTERVAL, "5 minutes"),
336 V(V3AuthNIntervalsValid, UINT, "3"),
337 V(V3AuthUseLegacyKey, BOOL, "0"),
338 VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
339 V(VirtualAddrNetwork, STRING, "127.192.0.0/10"),
340 V(WarnPlaintextPorts, CSV, "23,109,110,143"),
341 VAR("__ReloadTorrcOnSIGHUP", BOOL, ReloadTorrcOnSIGHUP, "1"),
342 VAR("__AllDirActionsPrivate", BOOL, AllDirActionsPrivate, "0"),
343 VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits, "0"),
344 VAR("__LeaveStreamsUnattached",BOOL, LeaveStreamsUnattached, "0"),
345 VAR("__HashedControlSessionPassword", LINELIST, HashedControlSessionPassword,
346 NULL),
347 V(MinUptimeHidServDirectoryV2, INTERVAL, "24 hours"),
348 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
351 /** Override default values with these if the user sets the TestingTorNetwork
352 * option. */
353 static config_var_t testing_tor_network_defaults[] = {
354 V(ServerDNSAllowBrokenConfig, BOOL, "1"),
355 V(DirAllowPrivateAddresses, BOOL, "1"),
356 V(EnforceDistinctSubnets, BOOL, "0"),
357 V(AssumeReachable, BOOL, "1"),
358 V(AuthDirMaxServersPerAddr, UINT, "0"),
359 V(AuthDirMaxServersPerAuthAddr,UINT, "0"),
360 V(ClientDNSRejectInternalAddresses, BOOL,"0"),
361 V(ExitPolicyRejectPrivate, BOOL, "0"),
362 V(V3AuthVotingInterval, INTERVAL, "5 minutes"),
363 V(V3AuthVoteDelay, INTERVAL, "20 seconds"),
364 V(V3AuthDistDelay, INTERVAL, "20 seconds"),
365 V(TestingV3AuthInitialVotingInterval, INTERVAL, "5 minutes"),
366 V(TestingV3AuthInitialVoteDelay, INTERVAL, "20 seconds"),
367 V(TestingV3AuthInitialDistDelay, INTERVAL, "20 seconds"),
368 V(TestingAuthDirTimeToLearnReachability, INTERVAL, "0 minutes"),
369 V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "0 minutes"),
370 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
372 #undef VAR
374 #define VAR(name,conftype,member,initvalue) \
375 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member), \
376 initvalue }
378 /** Array of "state" variables saved to the ~/.tor/state file. */
379 static config_var_t _state_vars[] = {
380 V(AccountingBytesReadInInterval, MEMUNIT, NULL),
381 V(AccountingBytesWrittenInInterval, MEMUNIT, NULL),
382 V(AccountingExpectedUsage, MEMUNIT, NULL),
383 V(AccountingIntervalStart, ISOTIME, NULL),
384 V(AccountingSecondsActive, INTERVAL, NULL),
386 VAR("EntryGuard", LINELIST_S, EntryGuards, NULL),
387 VAR("EntryGuardDownSince", LINELIST_S, EntryGuards, NULL),
388 VAR("EntryGuardUnlistedSince", LINELIST_S, EntryGuards, NULL),
389 VAR("EntryGuardAddedBy", LINELIST_S, EntryGuards, NULL),
390 V(EntryGuards, LINELIST_V, NULL),
392 V(BWHistoryReadEnds, ISOTIME, NULL),
393 V(BWHistoryReadInterval, UINT, "900"),
394 V(BWHistoryReadValues, CSV, ""),
395 V(BWHistoryWriteEnds, ISOTIME, NULL),
396 V(BWHistoryWriteInterval, UINT, "900"),
397 V(BWHistoryWriteValues, CSV, ""),
399 V(TorVersion, STRING, NULL),
401 V(LastRotatedOnionKey, ISOTIME, NULL),
402 V(LastWritten, ISOTIME, NULL),
404 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
407 #undef VAR
408 #undef V
409 #undef OBSOLETE
411 /** Represents an English description of a configuration variable; used when
412 * generating configuration file comments. */
413 typedef struct config_var_description_t {
414 const char *name;
415 const char *description;
416 } config_var_description_t;
418 /** Descriptions of the configuration options, to be displayed by online
419 * option browsers */
420 /* XXXX022 did anybody want this? at all? If not, kill it.*/
421 static config_var_description_t options_description[] = {
422 /* ==== general options */
423 { "AvoidDiskWrites", "If non-zero, try to write to disk less frequently than"
424 " we would otherwise." },
425 { "BandwidthRate", "A token bucket limits the average incoming bandwidth on "
426 "this node to the specified number of bytes per second." },
427 { "BandwidthBurst", "Limit the maximum token buffer size (also known as "
428 "burst) to the given number of bytes." },
429 { "ConnLimit", "Minimum number of simultaneous sockets we must have." },
430 { "ConstrainedSockets", "Shrink tx and rx buffers for sockets to avoid "
431 "system limits on vservers and related environments. See man page for "
432 "more information regarding this option." },
433 { "ConstrainedSockSize", "Limit socket buffers to this size when "
434 "ConstrainedSockets is enabled." },
435 /* ControlListenAddress */
436 { "ControlPort", "If set, Tor will accept connections from the same machine "
437 "(localhost only) on this port, and allow those connections to control "
438 "the Tor process using the Tor Control Protocol (described in "
439 "control-spec.txt).", },
440 { "CookieAuthentication", "If this option is set to 1, don't allow any "
441 "connections to the control port except when the connecting process "
442 "can read a file that Tor creates in its data directory." },
443 { "DataDirectory", "Store working data, state, keys, and caches here." },
444 { "DirServer", "Tor only trusts directories signed with one of these "
445 "servers' keys. Used to override the standard list of directory "
446 "authorities." },
447 /* { "FastFirstHopPK", "" }, */
448 /* FetchServerDescriptors, FetchHidServDescriptors,
449 * FetchUselessDescriptors */
450 { "HardwareAccel", "If set, Tor tries to use hardware crypto accelerators "
451 "when it can." },
452 { "AccelName", "If set, try to use hardware crypto accelerator with this "
453 "specific ID." },
454 { "AccelDir", "If set, look in this directory for the dynamic hardware "
455 "engine in addition to OpenSSL default path." },
456 /* HashedControlPassword */
457 { "HTTPProxy", "Force Tor to make all HTTP directory requests through this "
458 "host:port (or host:80 if port is not set)." },
459 { "HTTPProxyAuthenticator", "A username:password pair to be used with "
460 "HTTPProxy." },
461 { "HTTPSProxy", "Force Tor to make all TLS (SSL) connections through this "
462 "host:port (or host:80 if port is not set)." },
463 { "HTTPSProxyAuthenticator", "A username:password pair to be used with "
464 "HTTPSProxy." },
465 { "KeepalivePeriod", "Send a padding cell every N seconds to keep firewalls "
466 "from closing our connections while Tor is not in use." },
467 { "Log", "Where to send logging messages. Format is "
468 "minSeverity[-maxSeverity] (stderr|stdout|syslog|file FILENAME)." },
469 { "OutboundBindAddress", "Make all outbound connections originate from the "
470 "provided IP address (only useful for multiple network interfaces)." },
471 { "PIDFile", "On startup, write our PID to this file. On clean shutdown, "
472 "remove the file." },
473 { "PreferTunneledDirConns", "If non-zero, avoid directory servers that "
474 "don't support tunneled connections." },
475 /* PreferTunneledDirConns */
476 /* ProtocolWarnings */
477 /* RephistTrackTime */
478 { "RunAsDaemon", "If set, Tor forks and daemonizes to the background when "
479 "started. Unix only." },
480 { "SafeLogging", "If set to 0, Tor logs potentially sensitive strings "
481 "rather than replacing them with the string [scrubbed]." },
482 { "TunnelDirConns", "If non-zero, when a directory server we contact "
483 "supports it, we will build a one-hop circuit and make an encrypted "
484 "connection via its ORPort." },
485 { "User", "On startup, setuid to this user." },
487 /* ==== client options */
488 { "AllowInvalidNodes", "Where on our circuits should Tor allow servers "
489 "that the directory authorities haven't called \"valid\"?" },
490 { "AllowNonRFC953Hostnames", "If set to 1, we don't automatically reject "
491 "hostnames for having invalid characters." },
492 /* CircuitBuildTimeout, CircuitIdleTimeout */
493 { "ClientOnly", "If set to 1, Tor will under no circumstances run as a "
494 "server, even if ORPort is enabled." },
495 { "EntryNodes", "A list of preferred entry nodes to use for the first hop "
496 "in circuits, when possible." },
497 /* { "EnforceDistinctSubnets" , "" }, */
498 { "ExitNodes", "A list of preferred nodes to use for the last hop in "
499 "circuits, when possible." },
500 { "ExcludeNodes", "A list of nodes never to use when building a circuit." },
501 { "FascistFirewall", "If set, Tor will only create outgoing connections to "
502 "servers running on the ports listed in FirewallPorts." },
503 { "FirewallPorts", "A list of ports that we can connect to. Only used "
504 "when FascistFirewall is set." },
505 { "LongLivedPorts", "A list of ports for services that tend to require "
506 "high-uptime connections." },
507 { "MapAddress", "Force Tor to treat all requests for one address as if "
508 "they were for another." },
509 { "NewCircuitPeriod", "Force Tor to consider whether to build a new circuit "
510 "every NUM seconds." },
511 { "MaxCircuitDirtiness", "Do not attach new streams to a circuit that has "
512 "been used more than this many seconds ago." },
513 /* NatdPort, NatdListenAddress */
514 { "NodeFamily", "A list of servers that constitute a 'family' and should "
515 "never be used in the same circuit." },
516 { "NumEntryGuards", "How many entry guards should we keep at a time?" },
517 /* PathlenCoinWeight */
518 { "ReachableAddresses", "Addresses we can connect to, as IP/bits:port-port. "
519 "By default, we assume all addresses are reachable." },
520 /* reachablediraddresses, reachableoraddresses. */
521 /* SafeSOCKS */
522 { "SOCKSPort", "The port where we listen for SOCKS connections from "
523 "applications." },
524 { "SOCKSListenAddress", "Bind to this address to listen to connections from "
525 "SOCKS-speaking applications." },
526 { "SOCKSPolicy", "Set an entry policy to limit which addresses can connect "
527 "to the SOCKSPort." },
528 /* SocksTimeout */
529 { "StrictExitNodes", "If set, Tor will fail to operate when none of the "
530 "configured ExitNodes can be used." },
531 { "StrictEntryNodes", "If set, Tor will fail to operate when none of the "
532 "configured EntryNodes can be used." },
533 /* TestSocks */
534 { "TrackHostsExit", "Hosts and domains which should, if possible, be "
535 "accessed from the same exit node each time we connect to them." },
536 { "TrackHostsExitExpire", "Time after which we forget which exit we were "
537 "using to connect to hosts in TrackHostsExit." },
538 /* "TransPort", "TransListenAddress */
539 { "UseEntryGuards", "Set to 0 if we want to pick from the whole set of "
540 "servers for the first position in each circuit, rather than picking a "
541 "set of 'Guards' to prevent profiling attacks." },
543 /* === server options */
544 { "Address", "The advertised (external) address we should use." },
545 /* Accounting* options. */
546 /* AssumeReachable */
547 { "ContactInfo", "Administrative contact information to advertise for this "
548 "server." },
549 { "ExitPolicy", "Address/port ranges for which to accept or reject outgoing "
550 "connections on behalf of Tor users." },
551 /* { "ExitPolicyRejectPrivate, "" }, */
552 { "MaxAdvertisedBandwidth", "If set, we will not advertise more than this "
553 "amount of bandwidth for our bandwidth rate, regardless of how much "
554 "bandwidth we actually detect." },
555 { "MaxOnionsPending", "Reject new attempts to extend circuits when we "
556 "already have this many pending." },
557 { "MyFamily", "Declare a list of other servers as belonging to the same "
558 "family as this one, so that clients will not use two from the same "
559 "family in the same circuit." },
560 { "Nickname", "Set the server nickname." },
561 { "NoPublish", "{DEPRECATED}" },
562 { "NumCPUs", "How many processes to use at once for public-key crypto." },
563 { "ORPort", "Advertise this port to listen for connections from Tor clients "
564 "and servers." },
565 { "ORListenAddress", "Bind to this address to listen for connections from "
566 "clients and servers, instead of the default 0.0.0.0:ORPort." },
567 { "PublishServerDescriptor", "Set to 0 to keep the server from "
568 "uploading info to the directory authorities." },
569 /* ServerDNS: DetectHijacking, ResolvConfFile, SearchDomains */
570 { "ShutdownWaitLength", "Wait this long for clients to finish when "
571 "shutting down because of a SIGINT." },
573 /* === directory cache options */
574 { "DirPort", "Serve directory information from this port, and act as a "
575 "directory cache." },
576 { "DirPortFrontPage", "Serve a static html disclaimer on DirPort." },
577 { "DirListenAddress", "Bind to this address to listen for connections from "
578 "clients and servers, instead of the default 0.0.0.0:DirPort." },
579 { "DirPolicy", "Set a policy to limit who can connect to the directory "
580 "port." },
582 /* Authority options: AuthDirBadExit, AuthDirInvalid, AuthDirReject,
583 * AuthDirRejectUnlisted, AuthDirListBadExits, AuthoritativeDirectory,
584 * DirAllowPrivateAddresses, HSAuthoritativeDir,
585 * NamingAuthoritativeDirectory, RecommendedVersions,
586 * RecommendedClientVersions, RecommendedServerVersions, RendPostPeriod,
587 * RunTesting, V1AuthoritativeDirectory, VersioningAuthoritativeDirectory, */
589 /* Hidden service options: HiddenService: dir,excludenodes, nodes,
590 * options, port. PublishHidServDescriptor */
592 /* Nonpersistent options: __LeaveStreamsUnattached, __AllDirActionsPrivate */
593 { NULL, NULL },
596 /** Online description of state variables. */
597 static config_var_description_t state_description[] = {
598 { "AccountingBytesReadInInterval",
599 "How many bytes have we read in this accounting period?" },
600 { "AccountingBytesWrittenInInterval",
601 "How many bytes have we written in this accounting period?" },
602 { "AccountingExpectedUsage",
603 "How many bytes did we expect to use per minute? (0 for no estimate.)" },
604 { "AccountingIntervalStart", "When did this accounting period begin?" },
605 { "AccountingSecondsActive", "How long have we been awake in this period?" },
607 { "BWHistoryReadEnds", "When does the last-recorded read-interval end?" },
608 { "BWHistoryReadInterval", "How long is each read-interval (in seconds)?" },
609 { "BWHistoryReadValues", "Number of bytes read in each interval." },
610 { "BWHistoryWriteEnds", "When does the last-recorded write-interval end?" },
611 { "BWHistoryWriteInterval", "How long is each write-interval (in seconds)?"},
612 { "BWHistoryWriteValues", "Number of bytes written in each interval." },
614 { "EntryGuard", "One of the nodes we have chosen as a fixed entry" },
615 { "EntryGuardDownSince",
616 "The last entry guard has been unreachable since this time." },
617 { "EntryGuardUnlistedSince",
618 "The last entry guard has been unusable since this time." },
620 { "LastRotatedOnionKey",
621 "The last time at which we changed the medium-term private key used for "
622 "building circuits." },
623 { "LastWritten", "When was this state file last regenerated?" },
625 { "TorVersion", "Which version of Tor generated this state file?" },
626 { NULL, NULL },
629 /** Type of a callback to validate whether a given configuration is
630 * well-formed and consistent. See options_trial_assign() for documentation
631 * of arguments. */
632 typedef int (*validate_fn_t)(void*,void*,int,char**);
634 /** Information on the keys, value types, key-to-struct-member mappings,
635 * variable descriptions, validation functions, and abbreviations for a
636 * configuration or storage format. */
637 typedef struct {
638 size_t size; /**< Size of the struct that everything gets parsed into. */
639 uint32_t magic; /**< Required 'magic value' to make sure we have a struct
640 * of the right type. */
641 off_t magic_offset; /**< Offset of the magic value within the struct. */
642 config_abbrev_t *abbrevs; /**< List of abbreviations that we expand when
643 * parsing this format. */
644 config_var_t *vars; /**< List of variables we recognize, their default
645 * values, and where we stick them in the structure. */
646 validate_fn_t validate_fn; /**< Function to validate config. */
647 /** Documentation for configuration variables. */
648 config_var_description_t *descriptions;
649 /** If present, extra is a LINELIST variable for unrecognized
650 * lines. Otherwise, unrecognized lines are an error. */
651 config_var_t *extra;
652 } config_format_t;
654 /** Macro: assert that <b>cfg</b> has the right magic field for format
655 * <b>fmt</b>. */
656 #define CHECK(fmt, cfg) STMT_BEGIN \
657 tor_assert(fmt && cfg); \
658 tor_assert((fmt)->magic == \
659 *(uint32_t*)STRUCT_VAR_P(cfg,fmt->magic_offset)); \
660 STMT_END
662 #ifdef MS_WINDOWS
663 static char *get_windows_conf_root(void);
664 #endif
665 static void config_line_append(config_line_t **lst,
666 const char *key, const char *val);
667 static void option_clear(config_format_t *fmt, or_options_t *options,
668 config_var_t *var);
669 static void option_reset(config_format_t *fmt, or_options_t *options,
670 config_var_t *var, int use_defaults);
671 static void config_free(config_format_t *fmt, void *options);
672 static int config_lines_eq(config_line_t *a, config_line_t *b);
673 static int option_is_same(config_format_t *fmt,
674 or_options_t *o1, or_options_t *o2,
675 const char *name);
676 static or_options_t *options_dup(config_format_t *fmt, or_options_t *old);
677 static int options_validate(or_options_t *old_options, or_options_t *options,
678 int from_setconf, char **msg);
679 static int options_act_reversible(or_options_t *old_options, char **msg);
680 static int options_act(or_options_t *old_options);
681 static int options_transition_allowed(or_options_t *old, or_options_t *new,
682 char **msg);
683 static int options_transition_affects_workers(or_options_t *old_options,
684 or_options_t *new_options);
685 static int options_transition_affects_descriptor(or_options_t *old_options,
686 or_options_t *new_options);
687 static int check_nickname_list(const char *lst, const char *name, char **msg);
688 static void config_register_addressmaps(or_options_t *options);
690 static int parse_bridge_line(const char *line, int validate_only);
691 static int parse_dir_server_line(const char *line,
692 authority_type_t required_type,
693 int validate_only);
694 static int validate_data_directory(or_options_t *options);
695 static int write_configuration_file(const char *fname, or_options_t *options);
696 static config_line_t *get_assigned_option(config_format_t *fmt,
697 void *options, const char *key,
698 int escape_val);
699 static void config_init(config_format_t *fmt, void *options);
700 static int or_state_validate(or_state_t *old_options, or_state_t *options,
701 int from_setconf, char **msg);
702 static int or_state_load(void);
703 static int options_init_logs(or_options_t *options, int validate_only);
705 static int is_listening_on_low_port(uint16_t port_option,
706 const config_line_t *listen_options);
708 static uint64_t config_parse_memunit(const char *s, int *ok);
709 static int config_parse_interval(const char *s, int *ok);
710 static void init_libevent(void);
711 static int opt_streq(const char *s1, const char *s2);
713 /** Magic value for or_options_t. */
714 #define OR_OPTIONS_MAGIC 9090909
716 /** Configuration format for or_options_t. */
717 static config_format_t options_format = {
718 sizeof(or_options_t),
719 OR_OPTIONS_MAGIC,
720 STRUCT_OFFSET(or_options_t, _magic),
721 _option_abbrevs,
722 _option_vars,
723 (validate_fn_t)options_validate,
724 options_description,
725 NULL
728 /** Magic value for or_state_t. */
729 #define OR_STATE_MAGIC 0x57A73f57
731 /** "Extra" variable in the state that receives lines we can't parse. This
732 * lets us preserve options from versions of Tor newer than us. */
733 static config_var_t state_extra_var = {
734 "__extra", CONFIG_TYPE_LINELIST, STRUCT_OFFSET(or_state_t, ExtraLines), NULL
737 /** Configuration format for or_state_t. */
738 static config_format_t state_format = {
739 sizeof(or_state_t),
740 OR_STATE_MAGIC,
741 STRUCT_OFFSET(or_state_t, _magic),
742 _state_abbrevs,
743 _state_vars,
744 (validate_fn_t)or_state_validate,
745 state_description,
746 &state_extra_var,
750 * Functions to read and write the global options pointer.
753 /** Command-line and config-file options. */
754 static or_options_t *global_options = NULL;
755 /** Name of most recently read torrc file. */
756 static char *torrc_fname = NULL;
757 /** Persistent serialized state. */
758 static or_state_t *global_state = NULL;
759 /** Configuration Options set by command line. */
760 static config_line_t *global_cmdline_options = NULL;
761 /** Contents of most recently read DirPortFrontPage file. */
762 static char *global_dirfrontpagecontents = NULL;
764 /** Return the contents of our frontpage string, or NULL if not configured. */
765 const char *
766 get_dirportfrontpage(void)
768 return global_dirfrontpagecontents;
771 /** Allocate an empty configuration object of a given format type. */
772 static void *
773 config_alloc(config_format_t *fmt)
775 void *opts = tor_malloc_zero(fmt->size);
776 *(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
777 CHECK(fmt, opts);
778 return opts;
781 /** Return the currently configured options. */
782 or_options_t *
783 get_options(void)
785 tor_assert(global_options);
786 return global_options;
789 /** Change the current global options to contain <b>new_val</b> instead of
790 * their current value; take action based on the new value; free the old value
791 * as necessary. Returns 0 on success, -1 on failure.
794 set_options(or_options_t *new_val, char **msg)
796 or_options_t *old_options = global_options;
797 global_options = new_val;
798 /* Note that we pass the *old* options below, for comparison. It
799 * pulls the new options directly out of global_options. */
800 if (options_act_reversible(old_options, msg)<0) {
801 tor_assert(*msg);
802 global_options = old_options;
803 return -1;
805 if (options_act(old_options) < 0) { /* acting on the options failed. die. */
806 log_err(LD_BUG,
807 "Acting on config options left us in a broken state. Dying.");
808 exit(1);
810 if (old_options)
811 config_free(&options_format, old_options);
813 return 0;
816 extern const char tor_svn_revision[]; /* from tor_main.c */
818 /** The version of this Tor process, as parsed. */
819 static char *_version = NULL;
821 /** Return the current Tor version. */
822 const char *
823 get_version(void)
825 if (_version == NULL) {
826 if (strlen(tor_svn_revision)) {
827 size_t len = strlen(VERSION)+strlen(tor_svn_revision)+8;
828 _version = tor_malloc(len);
829 tor_snprintf(_version, len, "%s (r%s)", VERSION, tor_svn_revision);
830 } else {
831 _version = tor_strdup(VERSION);
834 return _version;
837 /** Release additional memory allocated in options
839 static void
840 or_options_free(or_options_t *options)
842 if (options->_ExcludeExitNodesUnion)
843 routerset_free(options->_ExcludeExitNodesUnion);
844 config_free(&options_format, options);
847 /** Release all memory and resources held by global configuration structures.
849 void
850 config_free_all(void)
852 if (global_options) {
853 or_options_free(global_options);
854 global_options = NULL;
856 if (global_state) {
857 config_free(&state_format, global_state);
858 global_state = NULL;
860 if (global_cmdline_options) {
861 config_free_lines(global_cmdline_options);
862 global_cmdline_options = NULL;
864 tor_free(torrc_fname);
865 tor_free(_version);
866 tor_free(global_dirfrontpagecontents);
869 /** If options->SafeLogging is on, return a not very useful string,
870 * else return address.
872 const char *
873 safe_str(const char *address)
875 tor_assert(address);
876 if (get_options()->SafeLogging)
877 return "[scrubbed]";
878 else
879 return address;
882 /** Equivalent to escaped(safe_str(address)). See reentrancy note on
883 * escaped(): don't use this outside the main thread, or twice in the same
884 * log statement. */
885 const char *
886 escaped_safe_str(const char *address)
888 if (get_options()->SafeLogging)
889 return "[scrubbed]";
890 else
891 return escaped(address);
894 /** Add the default directory authorities directly into the trusted dir list,
895 * but only add them insofar as they share bits with <b>type</b>. */
896 static void
897 add_default_trusted_dir_authorities(authority_type_t type)
899 int i;
900 const char *dirservers[] = {
901 "moria1 v1 orport=9001 v3ident=E2A2AF570166665D738736D0DD58169CC61D8A8B "
902 "128.31.0.34:9031 FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441",
903 "moria2 v1 orport=9002 128.31.0.34:9032 "
904 "719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF",
905 "tor26 v1 orport=443 v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
906 "86.59.21.38:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
907 "dizum orport=443 v3ident=E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58 "
908 "194.109.206.212:80 7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
909 "Tonga orport=443 bridge no-v2 82.94.251.206:80 "
910 "4A0C CD2D DC79 9508 3D73 F5D6 6710 0C8A 5831 F16D",
911 "ides orport=9090 no-v2 v3ident=27B6B5996C426270A5C95488AA5BCEB6BCC86956 "
912 "216.224.124.114:9030 F397 038A DC51 3361 35E7 B80B D99C A384 4360 292B",
913 "gabelmoo orport=443 no-v2 "
914 "v3ident=81349FC1F2DBA2C2C11B45CB9706637D480AB913 "
915 "80.190.246.100:80 6833 3D07 61BC F397 A587 A0C0 B963 E4A9 E99E C4D3",
916 "dannenberg orport=443 no-v2 "
917 "v3ident=585769C78764D58426B8B52B6651A5A71137189A "
918 "213.73.91.31:80 7BE6 83E6 5D48 1413 21C5 ED92 F075 C553 64AC 7123",
919 NULL
921 for (i=0; dirservers[i]; i++) {
922 if (parse_dir_server_line(dirservers[i], type, 0)<0) {
923 log_err(LD_BUG, "Couldn't parse internal dirserver line %s",
924 dirservers[i]);
929 /** Look at all the config options for using alternate directory
930 * authorities, and make sure none of them are broken. Also, warn the
931 * user if we changed any dangerous ones.
933 static int
934 validate_dir_authorities(or_options_t *options, or_options_t *old_options)
936 config_line_t *cl;
938 if (options->DirServers &&
939 (options->AlternateDirAuthority || options->AlternateBridgeAuthority ||
940 options->AlternateHSAuthority)) {
941 log_warn(LD_CONFIG,
942 "You cannot set both DirServers and Alternate*Authority.");
943 return -1;
946 /* do we want to complain to the user about being partitionable? */
947 if ((options->DirServers &&
948 (!old_options ||
949 !config_lines_eq(options->DirServers, old_options->DirServers))) ||
950 (options->AlternateDirAuthority &&
951 (!old_options ||
952 !config_lines_eq(options->AlternateDirAuthority,
953 old_options->AlternateDirAuthority)))) {
954 log_warn(LD_CONFIG,
955 "You have used DirServer or AlternateDirAuthority to "
956 "specify alternate directory authorities in "
957 "your configuration. This is potentially dangerous: it can "
958 "make you look different from all other Tor users, and hurt "
959 "your anonymity. Even if you've specified the same "
960 "authorities as Tor uses by default, the defaults could "
961 "change in the future. Be sure you know what you're doing.");
964 /* Now go through the four ways you can configure an alternate
965 * set of directory authorities, and make sure none are broken. */
966 for (cl = options->DirServers; cl; cl = cl->next)
967 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
968 return -1;
969 for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
970 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
971 return -1;
972 for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
973 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
974 return -1;
975 for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
976 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
977 return -1;
978 return 0;
981 /** Look at all the config options and assign new dir authorities
982 * as appropriate.
984 static int
985 consider_adding_dir_authorities(or_options_t *options,
986 or_options_t *old_options)
988 config_line_t *cl;
989 int need_to_update =
990 !smartlist_len(router_get_trusted_dir_servers()) || !old_options ||
991 !config_lines_eq(options->DirServers, old_options->DirServers) ||
992 !config_lines_eq(options->AlternateBridgeAuthority,
993 old_options->AlternateBridgeAuthority) ||
994 !config_lines_eq(options->AlternateDirAuthority,
995 old_options->AlternateDirAuthority) ||
996 !config_lines_eq(options->AlternateHSAuthority,
997 old_options->AlternateHSAuthority);
999 if (!need_to_update)
1000 return 0; /* all done */
1002 /* Start from a clean slate. */
1003 clear_trusted_dir_servers();
1005 if (!options->DirServers) {
1006 /* then we may want some of the defaults */
1007 authority_type_t type = NO_AUTHORITY;
1008 if (!options->AlternateBridgeAuthority)
1009 type |= BRIDGE_AUTHORITY;
1010 if (!options->AlternateDirAuthority)
1011 type |= V1_AUTHORITY | V2_AUTHORITY | V3_AUTHORITY;
1012 if (!options->AlternateHSAuthority)
1013 type |= HIDSERV_AUTHORITY;
1014 add_default_trusted_dir_authorities(type);
1017 for (cl = options->DirServers; cl; cl = cl->next)
1018 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
1019 return -1;
1020 for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
1021 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
1022 return -1;
1023 for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
1024 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
1025 return -1;
1026 for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
1027 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
1028 return -1;
1029 return 0;
1032 /** Fetch the active option list, and take actions based on it. All of the
1033 * things we do should survive being done repeatedly. If present,
1034 * <b>old_options</b> contains the previous value of the options.
1036 * Return 0 if all goes well, return -1 if things went badly.
1038 static int
1039 options_act_reversible(or_options_t *old_options, char **msg)
1041 smartlist_t *new_listeners = smartlist_create();
1042 smartlist_t *replaced_listeners = smartlist_create();
1043 static int libevent_initialized = 0;
1044 or_options_t *options = get_options();
1045 int running_tor = options->command == CMD_RUN_TOR;
1046 int set_conn_limit = 0;
1047 int r = -1;
1048 int logs_marked = 0;
1050 /* Daemonize _first_, since we only want to open most of this stuff in
1051 * the subprocess. Libevent bases can't be reliably inherited across
1052 * processes. */
1053 if (running_tor && options->RunAsDaemon) {
1054 /* No need to roll back, since you can't change the value. */
1055 start_daemon();
1058 #ifndef HAVE_SYS_UN_H
1059 if (options->ControlSocket) {
1060 *msg = tor_strdup("Unix domain sockets (ControlSocket) not supported"
1061 " on this OS/with this build.");
1062 goto rollback;
1064 #endif
1066 if (running_tor) {
1067 /* We need to set the connection limit before we can open the listeners. */
1068 if (set_max_file_descriptors((unsigned)options->ConnLimit,
1069 &options->_ConnLimit) < 0) {
1070 *msg = tor_strdup("Problem with ConnLimit value. See logs for details.");
1071 goto rollback;
1073 set_conn_limit = 1;
1075 /* Set up libevent. (We need to do this before we can register the
1076 * listeners as listeners.) */
1077 if (running_tor && !libevent_initialized) {
1078 init_libevent();
1079 libevent_initialized = 1;
1082 /* Launch the listeners. (We do this before we setuid, so we can bind to
1083 * ports under 1024.) */
1084 if (retry_all_listeners(replaced_listeners, new_listeners) < 0) {
1085 *msg = tor_strdup("Failed to bind one of the listener ports.");
1086 goto rollback;
1090 #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
1091 /* Open /dev/pf before dropping privileges. */
1092 if (options->TransPort) {
1093 if (get_pf_socket() < 0) {
1094 *msg = tor_strdup("Unable to open /dev/pf for transparent proxy.");
1095 goto rollback;
1098 #endif
1100 /* Setuid/setgid as appropriate */
1101 if (options->User) {
1102 if (switch_id(options->User) != 0) {
1103 /* No need to roll back, since you can't change the value. */
1104 *msg = tor_strdup("Problem with User value. See logs for details.");
1105 goto done;
1109 /* Ensure data directory is private; create if possible. */
1110 if (check_private_dir(options->DataDirectory,
1111 running_tor ? CPD_CREATE : CPD_CHECK)<0) {
1112 char buf[1024];
1113 int tmp = tor_snprintf(buf, sizeof(buf),
1114 "Couldn't access/create private data directory \"%s\"",
1115 options->DataDirectory);
1116 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
1117 goto done;
1118 /* No need to roll back, since you can't change the value. */
1121 if (directory_caches_v2_dir_info(options)) {
1122 size_t len = strlen(options->DataDirectory)+32;
1123 char *fn = tor_malloc(len);
1124 tor_snprintf(fn, len, "%s"PATH_SEPARATOR"cached-status",
1125 options->DataDirectory);
1126 if (check_private_dir(fn, running_tor ? CPD_CREATE : CPD_CHECK) < 0) {
1127 char buf[1024];
1128 int tmp = tor_snprintf(buf, sizeof(buf),
1129 "Couldn't access/create private data directory \"%s\"", fn);
1130 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
1131 tor_free(fn);
1132 goto done;
1134 tor_free(fn);
1137 /* Bail out at this point if we're not going to be a client or server:
1138 * we don't run Tor itself. */
1139 if (!running_tor)
1140 goto commit;
1142 mark_logs_temp(); /* Close current logs once new logs are open. */
1143 logs_marked = 1;
1144 if (options_init_logs(options, 0)<0) { /* Configure the log(s) */
1145 *msg = tor_strdup("Failed to init Log options. See logs for details.");
1146 goto rollback;
1149 commit:
1150 r = 0;
1151 if (logs_marked) {
1152 log_severity_list_t *severity =
1153 tor_malloc_zero(sizeof(log_severity_list_t));
1154 close_temp_logs();
1155 add_callback_log(severity, control_event_logmsg);
1156 control_adjust_event_log_severity();
1157 tor_free(severity);
1159 SMARTLIST_FOREACH(replaced_listeners, connection_t *, conn,
1161 log_notice(LD_NET, "Closing old %s on %s:%d",
1162 conn_type_to_string(conn->type), conn->address, conn->port);
1163 connection_close_immediate(conn);
1164 connection_mark_for_close(conn);
1166 goto done;
1168 rollback:
1169 r = -1;
1170 tor_assert(*msg);
1172 if (logs_marked) {
1173 rollback_log_changes();
1174 control_adjust_event_log_severity();
1177 if (set_conn_limit && old_options)
1178 set_max_file_descriptors((unsigned)old_options->ConnLimit,
1179 &options->_ConnLimit);
1181 SMARTLIST_FOREACH(new_listeners, connection_t *, conn,
1183 log_notice(LD_NET, "Closing partially-constructed listener %s on %s:%d",
1184 conn_type_to_string(conn->type), conn->address, conn->port);
1185 connection_close_immediate(conn);
1186 connection_mark_for_close(conn);
1189 done:
1190 smartlist_free(new_listeners);
1191 smartlist_free(replaced_listeners);
1192 return r;
1195 /** If we need to have a GEOIP ip-to-country map to run with our configured
1196 * options, return 1 and set *<b>reason_out</b> to a description of why. */
1198 options_need_geoip_info(or_options_t *options, const char **reason_out)
1200 int bridge_usage =
1201 options->BridgeRelay && options->BridgeRecordUsageByCountry;
1202 int routerset_usage =
1203 routerset_needs_geoip(options->EntryNodes) ||
1204 routerset_needs_geoip(options->ExitNodes) ||
1205 routerset_needs_geoip(options->ExcludeExitNodes) ||
1206 routerset_needs_geoip(options->ExcludeNodes);
1208 if (routerset_usage && reason_out) {
1209 *reason_out = "We've been configured to use (or avoid) nodes in certain "
1210 "countries, and we need GEOIP information to figure out which ones they "
1211 "are.";
1212 } else if (bridge_usage && reason_out) {
1213 *reason_out = "We've been configured to see which countries can access "
1214 "us as a bridge, and we need GEOIP information to tell which countries "
1215 "clients are in.";
1217 return bridge_usage || routerset_usage;
1220 /** Fetch the active option list, and take actions based on it. All of the
1221 * things we do should survive being done repeatedly. If present,
1222 * <b>old_options</b> contains the previous value of the options.
1224 * Return 0 if all goes well, return -1 if it's time to die.
1226 * Note: We haven't moved all the "act on new configuration" logic
1227 * here yet. Some is still in do_hup() and other places.
1229 static int
1230 options_act(or_options_t *old_options)
1232 config_line_t *cl;
1233 or_options_t *options = get_options();
1234 int running_tor = options->command == CMD_RUN_TOR;
1235 char *msg;
1237 if (running_tor && !have_lockfile()) {
1238 if (try_locking(options, 1) < 0)
1239 return -1;
1242 if (consider_adding_dir_authorities(options, old_options) < 0)
1243 return -1;
1245 if (options->Bridges) {
1246 clear_bridge_list();
1247 for (cl = options->Bridges; cl; cl = cl->next) {
1248 if (parse_bridge_line(cl->value, 0)<0) {
1249 log_warn(LD_BUG,
1250 "Previously validated Bridge line could not be added!");
1251 return -1;
1256 if (running_tor && rend_config_services(options, 0)<0) {
1257 log_warn(LD_BUG,
1258 "Previously validated hidden services line could not be added!");
1259 return -1;
1262 if (running_tor && rend_parse_service_authorization(options, 0) < 0) {
1263 log_warn(LD_BUG, "Previously validated client authorization for "
1264 "hidden services could not be added!");
1265 return -1;
1268 /* Load state */
1269 if (! global_state && running_tor) {
1270 if (or_state_load())
1271 return -1;
1272 rep_hist_load_mtbf_data(time(NULL));
1275 /* Bail out at this point if we're not going to be a client or server:
1276 * we want to not fork, and to log stuff to stderr. */
1277 if (!running_tor)
1278 return 0;
1280 /* Finish backgrounding the process */
1281 if (options->RunAsDaemon) {
1282 /* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
1283 finish_daemon(options->DataDirectory);
1286 /* Write our PID to the PID file. If we do not have write permissions we
1287 * will log a warning */
1288 if (options->PidFile)
1289 write_pidfile(options->PidFile);
1291 /* Register addressmap directives */
1292 config_register_addressmaps(options);
1293 parse_virtual_addr_network(options->VirtualAddrNetwork, 0, &msg);
1295 /* Update address policies. */
1296 if (policies_parse_from_options(options) < 0) {
1297 /* This should be impossible, but let's be sure. */
1298 log_warn(LD_BUG,"Error parsing already-validated policy options.");
1299 return -1;
1302 if (init_cookie_authentication(options->CookieAuthentication) < 0) {
1303 log_warn(LD_CONFIG,"Error creating cookie authentication file.");
1304 return -1;
1307 /* reload keys as needed for rendezvous services. */
1308 if (rend_service_load_keys()<0) {
1309 log_warn(LD_GENERAL,"Error loading rendezvous service keys");
1310 return -1;
1313 /* Set up accounting */
1314 if (accounting_parse_options(options, 0)<0) {
1315 log_warn(LD_CONFIG,"Error in accounting options");
1316 return -1;
1318 if (accounting_is_enabled(options))
1319 configure_accounting(time(NULL));
1321 /* Check for transitions that need action. */
1322 if (old_options) {
1323 if (options->UseEntryGuards && !old_options->UseEntryGuards) {
1324 log_info(LD_CIRC,
1325 "Switching to entry guards; abandoning previous circuits");
1326 circuit_mark_all_unused_circs();
1327 circuit_expire_all_dirty_circs();
1330 if (! bool_eq(options->BridgeRelay, old_options->BridgeRelay)) {
1331 log_info(LD_GENERAL, "Bridge status changed. Forgetting GeoIP stats.");
1332 geoip_remove_old_clients(time(NULL)+(2*60*60));
1335 if (options_transition_affects_workers(old_options, options)) {
1336 log_info(LD_GENERAL,
1337 "Worker-related options changed. Rotating workers.");
1338 if (server_mode(options) && !server_mode(old_options)) {
1339 if (init_keys() < 0) {
1340 log_warn(LD_BUG,"Error initializing keys; exiting");
1341 return -1;
1343 ip_address_changed(0);
1344 if (has_completed_circuit || !any_predicted_circuits(time(NULL)))
1345 inform_testing_reachability();
1347 cpuworkers_rotate();
1348 if (dns_reset())
1349 return -1;
1350 } else {
1351 if (dns_reset())
1352 return -1;
1355 if (options->V3AuthoritativeDir && !old_options->V3AuthoritativeDir)
1356 init_keys();
1359 /* Maybe load geoip file */
1360 if (options->GeoIPFile &&
1361 ((!old_options || !opt_streq(old_options->GeoIPFile, options->GeoIPFile))
1362 || !geoip_is_loaded())) {
1363 /* XXXX Don't use this "<default>" junk; make our filename options
1364 * understand prefixes somehow. -NM */
1365 /* XXXX021 Reload GeoIPFile on SIGHUP. -NM */
1366 char *actual_fname = tor_strdup(options->GeoIPFile);
1367 #ifdef WIN32
1368 if (!strcmp(actual_fname, "<default>")) {
1369 const char *conf_root = get_windows_conf_root();
1370 size_t len = strlen(conf_root)+16;
1371 tor_free(actual_fname);
1372 actual_fname = tor_malloc(len+1);
1373 tor_snprintf(actual_fname, len, "%s\\geoip", conf_root);
1375 #endif
1376 geoip_load_file(actual_fname, options);
1377 tor_free(actual_fname);
1379 #ifdef ENABLE_GEOIP_STATS
1380 /* Check if GeoIP database could be loaded. */
1381 if (!geoip_is_loaded()) {
1382 log_warn(LD_CONFIG, "Configured to measure GeoIP statistics, but no "
1383 "GeoIP database found!");
1384 return -1;
1386 log_notice(LD_CONFIG, "Configured to measure usage by country and "
1387 "write aggregate statistics to disk. Check the geoip-stats file "
1388 "in your data directory once I've been running for 24 hours.");
1389 #endif
1390 #ifdef ENABLE_EXIT_STATS
1391 if (options->ExitPortStatistics)
1392 log_notice(LD_CONFIG, "Configured to measure exit port statistics. "
1393 "Look for the exit-stats file that will first be written to "
1394 "the data directory in 24 hours from now.");
1395 #else
1396 if (options->ExitPortStatistics)
1397 log_warn(LD_CONFIG, "ExitPortStatistics enabled, but Tor was built "
1398 "without port statistics support.");
1399 #endif
1401 #ifdef ENABLE_BUFFER_STATS
1402 if (options->CellStatistics)
1403 log_notice(LD_CONFIG, "Configured to measure cell statistics. Look "
1404 "for the buffer-stats file that will first be written to "
1405 "the data directory in 24 hours from now.");
1406 #else
1407 if (options->CellStatistics)
1408 log_warn(LD_CONFIG, "CellStatistics enabled, but Tor was built "
1409 "without cell statistics support.");
1410 #endif
1412 #ifdef ENABLE_ENTRY_STATS
1413 if (options->EntryStatistics) {
1414 if (should_record_bridge_info(options)) {
1415 /* Don't allow measuring statistics on entry guards when configured
1416 * as bridge. */
1417 log_warn(LD_CONFIG, "Bridges cannot be configured to measure "
1418 "additional GeoIP statistics as entry guards.");
1419 return -1;
1420 } else
1421 log_notice(LD_CONFIG, "Configured to measure entry node "
1422 "statistics. Look for the entry-stats file that will "
1423 "first be written to the data directory in 24 hours "
1424 "from now.");
1426 #else
1427 if (options->EntryStatistics)
1428 log_warn(LD_CONFIG, "EntryStatistics enabled, but Tor was built "
1429 "without entry node statistics support.");
1430 #endif
1431 /* Check if we need to parse and add the EntryNodes config option. */
1432 if (options->EntryNodes &&
1433 (!old_options ||
1434 (!routerset_equal(old_options->EntryNodes,options->EntryNodes))))
1435 entry_nodes_should_be_added();
1437 /* Since our options changed, we might need to regenerate and upload our
1438 * server descriptor.
1440 if (!old_options ||
1441 options_transition_affects_descriptor(old_options, options))
1442 mark_my_descriptor_dirty();
1444 /* We may need to reschedule some directory stuff if our status changed. */
1445 if (old_options) {
1446 if (authdir_mode_v3(options) && !authdir_mode_v3(old_options))
1447 dirvote_recalculate_timing(options, time(NULL));
1448 if (!bool_eq(directory_fetches_dir_info_early(options),
1449 directory_fetches_dir_info_early(old_options)) ||
1450 !bool_eq(directory_fetches_dir_info_later(options),
1451 directory_fetches_dir_info_later(old_options))) {
1452 /* Make sure update_router_have_min_dir_info gets called. */
1453 router_dir_info_changed();
1454 /* We might need to download a new consensus status later or sooner than
1455 * we had expected. */
1456 update_consensus_networkstatus_fetch_time(time(NULL));
1460 /* Load the webpage we're going to serve every time someone asks for '/' on
1461 our DirPort. */
1462 tor_free(global_dirfrontpagecontents);
1463 if (options->DirPortFrontPage) {
1464 global_dirfrontpagecontents =
1465 read_file_to_str(options->DirPortFrontPage, 0, NULL);
1466 if (!global_dirfrontpagecontents) {
1467 log_warn(LD_CONFIG,
1468 "DirPortFrontPage file '%s' not found. Continuing anyway.",
1469 options->DirPortFrontPage);
1473 return 0;
1477 * Functions to parse config options
1480 /** If <b>option</b> is an official abbreviation for a longer option,
1481 * return the longer option. Otherwise return <b>option</b>.
1482 * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
1483 * apply abbreviations that work for the config file and the command line.
1484 * If <b>warn_obsolete</b> is set, warn about deprecated names. */
1485 static const char *
1486 expand_abbrev(config_format_t *fmt, const char *option, int command_line,
1487 int warn_obsolete)
1489 int i;
1490 if (! fmt->abbrevs)
1491 return option;
1492 for (i=0; fmt->abbrevs[i].abbreviated; ++i) {
1493 /* Abbreviations are case insensitive. */
1494 if (!strcasecmp(option,fmt->abbrevs[i].abbreviated) &&
1495 (command_line || !fmt->abbrevs[i].commandline_only)) {
1496 if (warn_obsolete && fmt->abbrevs[i].warn) {
1497 log_warn(LD_CONFIG,
1498 "The configuration option '%s' is deprecated; "
1499 "use '%s' instead.",
1500 fmt->abbrevs[i].abbreviated,
1501 fmt->abbrevs[i].full);
1503 return fmt->abbrevs[i].full;
1506 return option;
1509 /** Helper: Read a list of configuration options from the command line.
1510 * If successful, put them in *<b>result</b> and return 0, and return
1511 * -1 and leave *<b>result</b> alone. */
1512 static int
1513 config_get_commandlines(int argc, char **argv, config_line_t **result)
1515 config_line_t *front = NULL;
1516 config_line_t **new = &front;
1517 char *s;
1518 int i = 1;
1520 while (i < argc) {
1521 if (!strcmp(argv[i],"-f") ||
1522 !strcmp(argv[i],"--hash-password")) {
1523 i += 2; /* command-line option with argument. ignore them. */
1524 continue;
1525 } else if (!strcmp(argv[i],"--list-fingerprint") ||
1526 !strcmp(argv[i],"--verify-config") ||
1527 !strcmp(argv[i],"--ignore-missing-torrc") ||
1528 !strcmp(argv[i],"--quiet") ||
1529 !strcmp(argv[i],"--hush")) {
1530 i += 1; /* command-line option. ignore it. */
1531 continue;
1532 } else if (!strcmp(argv[i],"--nt-service") ||
1533 !strcmp(argv[i],"-nt-service")) {
1534 i += 1;
1535 continue;
1538 if (i == argc-1) {
1539 log_warn(LD_CONFIG,"Command-line option '%s' with no value. Failing.",
1540 argv[i]);
1541 config_free_lines(front);
1542 return -1;
1545 *new = tor_malloc_zero(sizeof(config_line_t));
1546 s = argv[i];
1548 while (*s == '-')
1549 s++;
1551 (*new)->key = tor_strdup(expand_abbrev(&options_format, s, 1, 1));
1552 (*new)->value = tor_strdup(argv[i+1]);
1553 (*new)->next = NULL;
1554 log(LOG_DEBUG, LD_CONFIG, "command line: parsed keyword '%s', value '%s'",
1555 (*new)->key, (*new)->value);
1557 new = &((*new)->next);
1558 i += 2;
1560 *result = front;
1561 return 0;
1564 /** Helper: allocate a new configuration option mapping 'key' to 'val',
1565 * append it to *<b>lst</b>. */
1566 static void
1567 config_line_append(config_line_t **lst,
1568 const char *key,
1569 const char *val)
1571 config_line_t *newline;
1573 newline = tor_malloc(sizeof(config_line_t));
1574 newline->key = tor_strdup(key);
1575 newline->value = tor_strdup(val);
1576 newline->next = NULL;
1577 while (*lst)
1578 lst = &((*lst)->next);
1580 (*lst) = newline;
1583 /** Helper: parse the config string and strdup into key/value
1584 * strings. Set *result to the list, or NULL if parsing the string
1585 * failed. Return 0 on success, -1 on failure. Warn and ignore any
1586 * misformatted lines. */
1588 config_get_lines(const char *string, config_line_t **result)
1590 config_line_t *list = NULL, **next;
1591 char *k, *v;
1593 next = &list;
1594 do {
1595 k = v = NULL;
1596 string = parse_config_line_from_str(string, &k, &v);
1597 if (!string) {
1598 config_free_lines(list);
1599 tor_free(k);
1600 tor_free(v);
1601 return -1;
1603 if (k && v) {
1604 /* This list can get long, so we keep a pointer to the end of it
1605 * rather than using config_line_append over and over and getting
1606 * n^2 performance. */
1607 *next = tor_malloc(sizeof(config_line_t));
1608 (*next)->key = k;
1609 (*next)->value = v;
1610 (*next)->next = NULL;
1611 next = &((*next)->next);
1612 } else {
1613 tor_free(k);
1614 tor_free(v);
1616 } while (*string);
1618 *result = list;
1619 return 0;
1623 * Free all the configuration lines on the linked list <b>front</b>.
1625 void
1626 config_free_lines(config_line_t *front)
1628 config_line_t *tmp;
1630 while (front) {
1631 tmp = front;
1632 front = tmp->next;
1634 tor_free(tmp->key);
1635 tor_free(tmp->value);
1636 tor_free(tmp);
1640 /** Return the description for a given configuration variable, or NULL if no
1641 * description exists. */
1642 static const char *
1643 config_find_description(config_format_t *fmt, const char *name)
1645 int i;
1646 for (i=0; fmt->descriptions[i].name; ++i) {
1647 if (!strcasecmp(name, fmt->descriptions[i].name))
1648 return fmt->descriptions[i].description;
1650 return NULL;
1653 /** If <b>key</b> is a configuration option, return the corresponding
1654 * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
1655 * warn, and return the corresponding config_var_t. Otherwise return NULL.
1657 static config_var_t *
1658 config_find_option(config_format_t *fmt, const char *key)
1660 int i;
1661 size_t keylen = strlen(key);
1662 if (!keylen)
1663 return NULL; /* if they say "--" on the command line, it's not an option */
1664 /* First, check for an exact (case-insensitive) match */
1665 for (i=0; fmt->vars[i].name; ++i) {
1666 if (!strcasecmp(key, fmt->vars[i].name)) {
1667 return &fmt->vars[i];
1670 /* If none, check for an abbreviated match */
1671 for (i=0; fmt->vars[i].name; ++i) {
1672 if (!strncasecmp(key, fmt->vars[i].name, keylen)) {
1673 log_warn(LD_CONFIG, "The abbreviation '%s' is deprecated. "
1674 "Please use '%s' instead",
1675 key, fmt->vars[i].name);
1676 return &fmt->vars[i];
1679 /* Okay, unrecognized option */
1680 return NULL;
1684 * Functions to assign config options.
1687 /** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
1688 * with <b>c</b>-\>value and return 0, or return -1 if bad value.
1690 * Called from config_assign_line() and option_reset().
1692 static int
1693 config_assign_value(config_format_t *fmt, or_options_t *options,
1694 config_line_t *c, char **msg)
1696 int i, r, ok;
1697 char buf[1024];
1698 config_var_t *var;
1699 void *lvalue;
1701 CHECK(fmt, options);
1703 var = config_find_option(fmt, c->key);
1704 tor_assert(var);
1706 lvalue = STRUCT_VAR_P(options, var->var_offset);
1708 switch (var->type) {
1710 case CONFIG_TYPE_UINT:
1711 i = (int)tor_parse_long(c->value, 10, 0, INT_MAX, &ok, NULL);
1712 if (!ok) {
1713 r = tor_snprintf(buf, sizeof(buf),
1714 "Int keyword '%s %s' is malformed or out of bounds.",
1715 c->key, c->value);
1716 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1717 return -1;
1719 *(int *)lvalue = i;
1720 break;
1722 case CONFIG_TYPE_INTERVAL: {
1723 i = config_parse_interval(c->value, &ok);
1724 if (!ok) {
1725 r = tor_snprintf(buf, sizeof(buf),
1726 "Interval '%s %s' is malformed or out of bounds.",
1727 c->key, c->value);
1728 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1729 return -1;
1731 *(int *)lvalue = i;
1732 break;
1735 case CONFIG_TYPE_MEMUNIT: {
1736 uint64_t u64 = config_parse_memunit(c->value, &ok);
1737 if (!ok) {
1738 r = tor_snprintf(buf, sizeof(buf),
1739 "Value '%s %s' is malformed or out of bounds.",
1740 c->key, c->value);
1741 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1742 return -1;
1744 *(uint64_t *)lvalue = u64;
1745 break;
1748 case CONFIG_TYPE_BOOL:
1749 i = (int)tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
1750 if (!ok) {
1751 r = tor_snprintf(buf, sizeof(buf),
1752 "Boolean '%s %s' expects 0 or 1.",
1753 c->key, c->value);
1754 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1755 return -1;
1757 *(int *)lvalue = i;
1758 break;
1760 case CONFIG_TYPE_STRING:
1761 case CONFIG_TYPE_FILENAME:
1762 tor_free(*(char **)lvalue);
1763 *(char **)lvalue = tor_strdup(c->value);
1764 break;
1766 case CONFIG_TYPE_DOUBLE:
1767 *(double *)lvalue = atof(c->value);
1768 break;
1770 case CONFIG_TYPE_ISOTIME:
1771 if (parse_iso_time(c->value, (time_t *)lvalue)) {
1772 r = tor_snprintf(buf, sizeof(buf),
1773 "Invalid time '%s' for keyword '%s'", c->value, c->key);
1774 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1775 return -1;
1777 break;
1779 case CONFIG_TYPE_ROUTERSET:
1780 if (*(routerset_t**)lvalue) {
1781 routerset_free(*(routerset_t**)lvalue);
1783 *(routerset_t**)lvalue = routerset_new();
1784 if (routerset_parse(*(routerset_t**)lvalue, c->value, c->key)<0) {
1785 tor_snprintf(buf, sizeof(buf), "Invalid exit list '%s' for option '%s'",
1786 c->value, c->key);
1787 *msg = tor_strdup(buf);
1788 return -1;
1790 break;
1792 case CONFIG_TYPE_CSV:
1793 if (*(smartlist_t**)lvalue) {
1794 SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
1795 smartlist_clear(*(smartlist_t**)lvalue);
1796 } else {
1797 *(smartlist_t**)lvalue = smartlist_create();
1800 smartlist_split_string(*(smartlist_t**)lvalue, c->value, ",",
1801 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1802 break;
1804 case CONFIG_TYPE_LINELIST:
1805 case CONFIG_TYPE_LINELIST_S:
1806 config_line_append((config_line_t**)lvalue, c->key, c->value);
1807 break;
1808 case CONFIG_TYPE_OBSOLETE:
1809 log_warn(LD_CONFIG, "Skipping obsolete configuration option '%s'", c->key);
1810 break;
1811 case CONFIG_TYPE_LINELIST_V:
1812 r = tor_snprintf(buf, sizeof(buf),
1813 "You may not provide a value for virtual option '%s'", c->key);
1814 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1815 return -1;
1816 default:
1817 tor_assert(0);
1818 break;
1820 return 0;
1823 /** If <b>c</b> is a syntactically valid configuration line, update
1824 * <b>options</b> with its value and return 0. Otherwise return -1 for bad
1825 * key, -2 for bad value.
1827 * If <b>clear_first</b> is set, clear the value first. Then if
1828 * <b>use_defaults</b> is set, set the value to the default.
1830 * Called from config_assign().
1832 static int
1833 config_assign_line(config_format_t *fmt, or_options_t *options,
1834 config_line_t *c, int use_defaults,
1835 int clear_first, char **msg)
1837 config_var_t *var;
1839 CHECK(fmt, options);
1841 var = config_find_option(fmt, c->key);
1842 if (!var) {
1843 if (fmt->extra) {
1844 void *lvalue = STRUCT_VAR_P(options, fmt->extra->var_offset);
1845 log_info(LD_CONFIG,
1846 "Found unrecognized option '%s'; saving it.", c->key);
1847 config_line_append((config_line_t**)lvalue, c->key, c->value);
1848 return 0;
1849 } else {
1850 char buf[1024];
1851 int tmp = tor_snprintf(buf, sizeof(buf),
1852 "Unknown option '%s'. Failing.", c->key);
1853 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
1854 return -1;
1857 /* Put keyword into canonical case. */
1858 if (strcmp(var->name, c->key)) {
1859 tor_free(c->key);
1860 c->key = tor_strdup(var->name);
1863 if (!strlen(c->value)) {
1864 /* reset or clear it, then return */
1865 if (!clear_first) {
1866 if (var->type == CONFIG_TYPE_LINELIST ||
1867 var->type == CONFIG_TYPE_LINELIST_S) {
1868 /* We got an empty linelist from the torrc or command line.
1869 As a special case, call this an error. Warn and ignore. */
1870 log_warn(LD_CONFIG,
1871 "Linelist option '%s' has no value. Skipping.", c->key);
1872 } else { /* not already cleared */
1873 option_reset(fmt, options, var, use_defaults);
1876 return 0;
1879 if (config_assign_value(fmt, options, c, msg) < 0)
1880 return -2;
1881 return 0;
1884 /** Restore the option named <b>key</b> in options to its default value.
1885 * Called from config_assign(). */
1886 static void
1887 config_reset_line(config_format_t *fmt, or_options_t *options,
1888 const char *key, int use_defaults)
1890 config_var_t *var;
1892 CHECK(fmt, options);
1894 var = config_find_option(fmt, key);
1895 if (!var)
1896 return; /* give error on next pass. */
1898 option_reset(fmt, options, var, use_defaults);
1901 /** Return true iff key is a valid configuration option. */
1903 option_is_recognized(const char *key)
1905 config_var_t *var = config_find_option(&options_format, key);
1906 return (var != NULL);
1909 /** Return the canonical name of a configuration option, or NULL
1910 * if no such option exists. */
1911 const char *
1912 option_get_canonical_name(const char *key)
1914 config_var_t *var = config_find_option(&options_format, key);
1915 return var ? var->name : NULL;
1918 /** Return a canonical list of the options assigned for key.
1920 config_line_t *
1921 option_get_assignment(or_options_t *options, const char *key)
1923 return get_assigned_option(&options_format, options, key, 1);
1926 /** Return true iff value needs to be quoted and escaped to be used in
1927 * a configuration file. */
1928 static int
1929 config_value_needs_escape(const char *value)
1931 if (*value == '\"')
1932 return 1;
1933 while (*value) {
1934 switch (*value)
1936 case '\r':
1937 case '\n':
1938 case '#':
1939 /* Note: quotes and backspaces need special handling when we are using
1940 * quotes, not otherwise, so they don't trigger escaping on their
1941 * own. */
1942 return 1;
1943 default:
1944 if (!TOR_ISPRINT(*value))
1945 return 1;
1947 ++value;
1949 return 0;
1952 /** Return a newly allocated deep copy of the lines in <b>inp</b>. */
1953 static config_line_t *
1954 config_lines_dup(const config_line_t *inp)
1956 config_line_t *result = NULL;
1957 config_line_t **next_out = &result;
1958 while (inp) {
1959 *next_out = tor_malloc(sizeof(config_line_t));
1960 (*next_out)->key = tor_strdup(inp->key);
1961 (*next_out)->value = tor_strdup(inp->value);
1962 inp = inp->next;
1963 next_out = &((*next_out)->next);
1965 (*next_out) = NULL;
1966 return result;
1969 /** Return newly allocated line or lines corresponding to <b>key</b> in the
1970 * configuration <b>options</b>. If <b>escape_val</b> is true and a
1971 * value needs to be quoted before it's put in a config file, quote and
1972 * escape that value. Return NULL if no such key exists. */
1973 static config_line_t *
1974 get_assigned_option(config_format_t *fmt, void *options,
1975 const char *key, int escape_val)
1977 config_var_t *var;
1978 const void *value;
1979 char buf[32];
1980 config_line_t *result;
1981 tor_assert(options && key);
1983 CHECK(fmt, options);
1985 var = config_find_option(fmt, key);
1986 if (!var) {
1987 log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key);
1988 return NULL;
1990 value = STRUCT_VAR_P(options, var->var_offset);
1992 result = tor_malloc_zero(sizeof(config_line_t));
1993 result->key = tor_strdup(var->name);
1994 switch (var->type)
1996 case CONFIG_TYPE_STRING:
1997 case CONFIG_TYPE_FILENAME:
1998 if (*(char**)value) {
1999 result->value = tor_strdup(*(char**)value);
2000 } else {
2001 tor_free(result->key);
2002 tor_free(result);
2003 return NULL;
2005 break;
2006 case CONFIG_TYPE_ISOTIME:
2007 if (*(time_t*)value) {
2008 result->value = tor_malloc(ISO_TIME_LEN+1);
2009 format_iso_time(result->value, *(time_t*)value);
2010 } else {
2011 tor_free(result->key);
2012 tor_free(result);
2014 escape_val = 0; /* Can't need escape. */
2015 break;
2016 case CONFIG_TYPE_INTERVAL:
2017 case CONFIG_TYPE_UINT:
2018 /* This means every or_options_t uint or bool element
2019 * needs to be an int. Not, say, a uint16_t or char. */
2020 tor_snprintf(buf, sizeof(buf), "%d", *(int*)value);
2021 result->value = tor_strdup(buf);
2022 escape_val = 0; /* Can't need escape. */
2023 break;
2024 case CONFIG_TYPE_MEMUNIT:
2025 tor_snprintf(buf, sizeof(buf), U64_FORMAT,
2026 U64_PRINTF_ARG(*(uint64_t*)value));
2027 result->value = tor_strdup(buf);
2028 escape_val = 0; /* Can't need escape. */
2029 break;
2030 case CONFIG_TYPE_DOUBLE:
2031 tor_snprintf(buf, sizeof(buf), "%f", *(double*)value);
2032 result->value = tor_strdup(buf);
2033 escape_val = 0; /* Can't need escape. */
2034 break;
2035 case CONFIG_TYPE_BOOL:
2036 result->value = tor_strdup(*(int*)value ? "1" : "0");
2037 escape_val = 0; /* Can't need escape. */
2038 break;
2039 case CONFIG_TYPE_ROUTERSET:
2040 result->value = routerset_to_string(*(routerset_t**)value);
2041 break;
2042 case CONFIG_TYPE_CSV:
2043 if (*(smartlist_t**)value)
2044 result->value =
2045 smartlist_join_strings(*(smartlist_t**)value, ",", 0, NULL);
2046 else
2047 result->value = tor_strdup("");
2048 break;
2049 case CONFIG_TYPE_OBSOLETE:
2050 log_fn(LOG_PROTOCOL_WARN, LD_CONFIG,
2051 "You asked me for the value of an obsolete config option '%s'.",
2052 key);
2053 tor_free(result->key);
2054 tor_free(result);
2055 return NULL;
2056 case CONFIG_TYPE_LINELIST_S:
2057 log_warn(LD_CONFIG,
2058 "Can't return context-sensitive '%s' on its own", key);
2059 tor_free(result->key);
2060 tor_free(result);
2061 return NULL;
2062 case CONFIG_TYPE_LINELIST:
2063 case CONFIG_TYPE_LINELIST_V:
2064 tor_free(result->key);
2065 tor_free(result);
2066 result = config_lines_dup(*(const config_line_t**)value);
2067 break;
2068 default:
2069 tor_free(result->key);
2070 tor_free(result);
2071 log_warn(LD_BUG,"Unknown type %d for known key '%s'",
2072 var->type, key);
2073 return NULL;
2076 if (escape_val) {
2077 config_line_t *line;
2078 for (line = result; line; line = line->next) {
2079 if (line->value && config_value_needs_escape(line->value)) {
2080 char *newval = esc_for_log(line->value);
2081 tor_free(line->value);
2082 line->value = newval;
2087 return result;
2090 /** Iterate through the linked list of requested options <b>list</b>.
2091 * For each item, convert as appropriate and assign to <b>options</b>.
2092 * If an item is unrecognized, set *msg and return -1 immediately,
2093 * else return 0 for success.
2095 * If <b>clear_first</b>, interpret config options as replacing (not
2096 * extending) their previous values. If <b>clear_first</b> is set,
2097 * then <b>use_defaults</b> to decide if you set to defaults after
2098 * clearing, or make the value 0 or NULL.
2100 * Here are the use cases:
2101 * 1. A non-empty AllowInvalid line in your torrc. Appends to current
2102 * if linelist, replaces current if csv.
2103 * 2. An empty AllowInvalid line in your torrc. Should clear it.
2104 * 3. "RESETCONF AllowInvalid" sets it to default.
2105 * 4. "SETCONF AllowInvalid" makes it NULL.
2106 * 5. "SETCONF AllowInvalid=foo" clears it and sets it to "foo".
2108 * Use_defaults Clear_first
2109 * 0 0 "append"
2110 * 1 0 undefined, don't use
2111 * 0 1 "set to null first"
2112 * 1 1 "set to defaults first"
2113 * Return 0 on success, -1 on bad key, -2 on bad value.
2115 * As an additional special case, if a LINELIST config option has
2116 * no value and clear_first is 0, then warn and ignore it.
2120 There are three call cases for config_assign() currently.
2122 Case one: Torrc entry
2123 options_init_from_torrc() calls config_assign(0, 0)
2124 calls config_assign_line(0, 0).
2125 if value is empty, calls option_reset(0) and returns.
2126 calls config_assign_value(), appends.
2128 Case two: setconf
2129 options_trial_assign() calls config_assign(0, 1)
2130 calls config_reset_line(0)
2131 calls option_reset(0)
2132 calls option_clear().
2133 calls config_assign_line(0, 1).
2134 if value is empty, returns.
2135 calls config_assign_value(), appends.
2137 Case three: resetconf
2138 options_trial_assign() calls config_assign(1, 1)
2139 calls config_reset_line(1)
2140 calls option_reset(1)
2141 calls option_clear().
2142 calls config_assign_value(default)
2143 calls config_assign_line(1, 1).
2144 returns.
2146 static int
2147 config_assign(config_format_t *fmt, void *options, config_line_t *list,
2148 int use_defaults, int clear_first, char **msg)
2150 config_line_t *p;
2152 CHECK(fmt, options);
2154 /* pass 1: normalize keys */
2155 for (p = list; p; p = p->next) {
2156 const char *full = expand_abbrev(fmt, p->key, 0, 1);
2157 if (strcmp(full,p->key)) {
2158 tor_free(p->key);
2159 p->key = tor_strdup(full);
2163 /* pass 2: if we're reading from a resetting source, clear all
2164 * mentioned config options, and maybe set to their defaults. */
2165 if (clear_first) {
2166 for (p = list; p; p = p->next)
2167 config_reset_line(fmt, options, p->key, use_defaults);
2170 /* pass 3: assign. */
2171 while (list) {
2172 int r;
2173 if ((r=config_assign_line(fmt, options, list, use_defaults,
2174 clear_first, msg)))
2175 return r;
2176 list = list->next;
2178 return 0;
2181 /** Try assigning <b>list</b> to the global options. You do this by duping
2182 * options, assigning list to the new one, then validating it. If it's
2183 * ok, then throw out the old one and stick with the new one. Else,
2184 * revert to old and return failure. Return SETOPT_OK on success, or
2185 * a setopt_err_t on failure.
2187 * If not success, point *<b>msg</b> to a newly allocated string describing
2188 * what went wrong.
2190 setopt_err_t
2191 options_trial_assign(config_line_t *list, int use_defaults,
2192 int clear_first, char **msg)
2194 int r;
2195 or_options_t *trial_options = options_dup(&options_format, get_options());
2197 if ((r=config_assign(&options_format, trial_options,
2198 list, use_defaults, clear_first, msg)) < 0) {
2199 config_free(&options_format, trial_options);
2200 return r;
2203 if (options_validate(get_options(), trial_options, 1, msg) < 0) {
2204 config_free(&options_format, trial_options);
2205 return SETOPT_ERR_PARSE; /*XXX make this a separate return value. */
2208 if (options_transition_allowed(get_options(), trial_options, msg) < 0) {
2209 config_free(&options_format, trial_options);
2210 return SETOPT_ERR_TRANSITION;
2213 if (set_options(trial_options, msg)<0) {
2214 config_free(&options_format, trial_options);
2215 return SETOPT_ERR_SETTING;
2218 /* we liked it. put it in place. */
2219 return SETOPT_OK;
2222 /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
2223 * Called from option_reset() and config_free(). */
2224 static void
2225 option_clear(config_format_t *fmt, or_options_t *options, config_var_t *var)
2227 void *lvalue = STRUCT_VAR_P(options, var->var_offset);
2228 (void)fmt; /* unused */
2229 switch (var->type) {
2230 case CONFIG_TYPE_STRING:
2231 case CONFIG_TYPE_FILENAME:
2232 tor_free(*(char**)lvalue);
2233 break;
2234 case CONFIG_TYPE_DOUBLE:
2235 *(double*)lvalue = 0.0;
2236 break;
2237 case CONFIG_TYPE_ISOTIME:
2238 *(time_t*)lvalue = 0;
2239 case CONFIG_TYPE_INTERVAL:
2240 case CONFIG_TYPE_UINT:
2241 case CONFIG_TYPE_BOOL:
2242 *(int*)lvalue = 0;
2243 break;
2244 case CONFIG_TYPE_MEMUNIT:
2245 *(uint64_t*)lvalue = 0;
2246 break;
2247 case CONFIG_TYPE_ROUTERSET:
2248 if (*(routerset_t**)lvalue) {
2249 routerset_free(*(routerset_t**)lvalue);
2250 *(routerset_t**)lvalue = NULL;
2252 case CONFIG_TYPE_CSV:
2253 if (*(smartlist_t**)lvalue) {
2254 SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
2255 smartlist_free(*(smartlist_t **)lvalue);
2256 *(smartlist_t **)lvalue = NULL;
2258 break;
2259 case CONFIG_TYPE_LINELIST:
2260 case CONFIG_TYPE_LINELIST_S:
2261 config_free_lines(*(config_line_t **)lvalue);
2262 *(config_line_t **)lvalue = NULL;
2263 break;
2264 case CONFIG_TYPE_LINELIST_V:
2265 /* handled by linelist_s. */
2266 break;
2267 case CONFIG_TYPE_OBSOLETE:
2268 break;
2272 /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
2273 * <b>use_defaults</b>, set it to its default value.
2274 * Called by config_init() and option_reset_line() and option_assign_line(). */
2275 static void
2276 option_reset(config_format_t *fmt, or_options_t *options,
2277 config_var_t *var, int use_defaults)
2279 config_line_t *c;
2280 char *msg = NULL;
2281 CHECK(fmt, options);
2282 option_clear(fmt, options, var); /* clear it first */
2283 if (!use_defaults)
2284 return; /* all done */
2285 if (var->initvalue) {
2286 c = tor_malloc_zero(sizeof(config_line_t));
2287 c->key = tor_strdup(var->name);
2288 c->value = tor_strdup(var->initvalue);
2289 if (config_assign_value(fmt, options, c, &msg) < 0) {
2290 log_warn(LD_BUG, "Failed to assign default: %s", msg);
2291 tor_free(msg); /* if this happens it's a bug */
2293 config_free_lines(c);
2297 /** Print a usage message for tor. */
2298 static void
2299 print_usage(void)
2301 printf(
2302 "Copyright (c) 2001-2004, Roger Dingledine\n"
2303 "Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson\n"
2304 "Copyright (c) 2007-2009, The Tor Project, Inc.\n\n"
2305 "tor -f <torrc> [args]\n"
2306 "See man page for options, or https://www.torproject.org/ for "
2307 "documentation.\n");
2310 /** Print all non-obsolete torrc options. */
2311 static void
2312 list_torrc_options(void)
2314 int i;
2315 smartlist_t *lines = smartlist_create();
2316 for (i = 0; _option_vars[i].name; ++i) {
2317 config_var_t *var = &_option_vars[i];
2318 const char *desc;
2319 if (var->type == CONFIG_TYPE_OBSOLETE ||
2320 var->type == CONFIG_TYPE_LINELIST_V)
2321 continue;
2322 desc = config_find_description(&options_format, var->name);
2323 printf("%s\n", var->name);
2324 if (desc) {
2325 wrap_string(lines, desc, 76, " ", " ");
2326 SMARTLIST_FOREACH(lines, char *, cp, {
2327 printf("%s", cp);
2328 tor_free(cp);
2330 smartlist_clear(lines);
2333 smartlist_free(lines);
2336 /** Last value actually set by resolve_my_address. */
2337 static uint32_t last_resolved_addr = 0;
2339 * Based on <b>options-\>Address</b>, guess our public IP address and put it
2340 * (in host order) into *<b>addr_out</b>. If <b>hostname_out</b> is provided,
2341 * set *<b>hostname_out</b> to a new string holding the hostname we used to
2342 * get the address. Return 0 if all is well, or -1 if we can't find a suitable
2343 * public IP address.
2346 resolve_my_address(int warn_severity, or_options_t *options,
2347 uint32_t *addr_out, char **hostname_out)
2349 struct in_addr in;
2350 struct hostent *rent;
2351 char hostname[256];
2352 int explicit_ip=1;
2353 int explicit_hostname=1;
2354 int from_interface=0;
2355 char tmpbuf[INET_NTOA_BUF_LEN];
2356 const char *address = options->Address;
2357 int notice_severity = warn_severity <= LOG_NOTICE ?
2358 LOG_NOTICE : warn_severity;
2360 tor_assert(addr_out);
2362 if (address && *address) {
2363 strlcpy(hostname, address, sizeof(hostname));
2364 } else { /* then we need to guess our address */
2365 explicit_ip = 0; /* it's implicit */
2366 explicit_hostname = 0; /* it's implicit */
2368 if (gethostname(hostname, sizeof(hostname)) < 0) {
2369 log_fn(warn_severity, LD_NET,"Error obtaining local hostname");
2370 return -1;
2372 log_debug(LD_CONFIG,"Guessed local host name as '%s'",hostname);
2375 /* now we know hostname. resolve it and keep only the IP address */
2377 if (tor_inet_aton(hostname, &in) == 0) {
2378 /* then we have to resolve it */
2379 explicit_ip = 0;
2380 rent = (struct hostent *)gethostbyname(hostname);
2381 if (!rent) {
2382 uint32_t interface_ip;
2384 if (explicit_hostname) {
2385 log_fn(warn_severity, LD_CONFIG,
2386 "Could not resolve local Address '%s'. Failing.", hostname);
2387 return -1;
2389 log_fn(notice_severity, LD_CONFIG,
2390 "Could not resolve guessed local hostname '%s'. "
2391 "Trying something else.", hostname);
2392 if (get_interface_address(warn_severity, &interface_ip)) {
2393 log_fn(warn_severity, LD_CONFIG,
2394 "Could not get local interface IP address. Failing.");
2395 return -1;
2397 from_interface = 1;
2398 in.s_addr = htonl(interface_ip);
2399 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2400 log_fn(notice_severity, LD_CONFIG, "Learned IP address '%s' for "
2401 "local interface. Using that.", tmpbuf);
2402 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
2403 } else {
2404 tor_assert(rent->h_length == 4);
2405 memcpy(&in.s_addr, rent->h_addr, rent->h_length);
2407 if (!explicit_hostname &&
2408 is_internal_IP(ntohl(in.s_addr), 0)) {
2409 uint32_t interface_ip;
2411 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2412 log_fn(notice_severity, LD_CONFIG, "Guessed local hostname '%s' "
2413 "resolves to a private IP address (%s). Trying something "
2414 "else.", hostname, tmpbuf);
2416 if (get_interface_address(warn_severity, &interface_ip)) {
2417 log_fn(warn_severity, LD_CONFIG,
2418 "Could not get local interface IP address. Too bad.");
2419 } else if (is_internal_IP(interface_ip, 0)) {
2420 struct in_addr in2;
2421 in2.s_addr = htonl(interface_ip);
2422 tor_inet_ntoa(&in2,tmpbuf,sizeof(tmpbuf));
2423 log_fn(notice_severity, LD_CONFIG,
2424 "Interface IP address '%s' is a private address too. "
2425 "Ignoring.", tmpbuf);
2426 } else {
2427 from_interface = 1;
2428 in.s_addr = htonl(interface_ip);
2429 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2430 log_fn(notice_severity, LD_CONFIG,
2431 "Learned IP address '%s' for local interface."
2432 " Using that.", tmpbuf);
2433 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
2439 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2440 if (is_internal_IP(ntohl(in.s_addr), 0) &&
2441 options->_PublishServerDescriptor) {
2442 /* make sure we're ok with publishing an internal IP */
2443 if (!options->DirServers && !options->AlternateDirAuthority) {
2444 /* if they are using the default dirservers, disallow internal IPs
2445 * always. */
2446 log_fn(warn_severity, LD_CONFIG,
2447 "Address '%s' resolves to private IP address '%s'. "
2448 "Tor servers that use the default DirServers must have public "
2449 "IP addresses.", hostname, tmpbuf);
2450 return -1;
2452 if (!explicit_ip) {
2453 /* even if they've set their own dirservers, require an explicit IP if
2454 * they're using an internal address. */
2455 log_fn(warn_severity, LD_CONFIG, "Address '%s' resolves to private "
2456 "IP address '%s'. Please set the Address config option to be "
2457 "the IP address you want to use.", hostname, tmpbuf);
2458 return -1;
2462 log_debug(LD_CONFIG, "Resolved Address to '%s'.", tmpbuf);
2463 *addr_out = ntohl(in.s_addr);
2464 if (last_resolved_addr && last_resolved_addr != *addr_out) {
2465 /* Leave this as a notice, regardless of the requested severity,
2466 * at least until dynamic IP address support becomes bulletproof. */
2467 log_notice(LD_NET,
2468 "Your IP address seems to have changed to %s. Updating.",
2469 tmpbuf);
2470 ip_address_changed(0);
2472 if (last_resolved_addr != *addr_out) {
2473 const char *method;
2474 const char *h = hostname;
2475 if (explicit_ip) {
2476 method = "CONFIGURED";
2477 h = NULL;
2478 } else if (explicit_hostname) {
2479 method = "RESOLVED";
2480 } else if (from_interface) {
2481 method = "INTERFACE";
2482 h = NULL;
2483 } else {
2484 method = "GETHOSTNAME";
2486 control_event_server_status(LOG_NOTICE,
2487 "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s %s%s",
2488 tmpbuf, method, h?"HOSTNAME=":"", h);
2490 last_resolved_addr = *addr_out;
2491 if (hostname_out)
2492 *hostname_out = tor_strdup(hostname);
2493 return 0;
2496 /** Return true iff <b>addr</b> is judged to be on the same network as us, or
2497 * on a private network.
2500 is_local_addr(const tor_addr_t *addr)
2502 if (tor_addr_is_internal(addr, 0))
2503 return 1;
2504 /* Check whether ip is on the same /24 as we are. */
2505 if (get_options()->EnforceDistinctSubnets == 0)
2506 return 0;
2507 if (tor_addr_family(addr) == AF_INET) {
2508 /*XXXX022 IP6 what corresponds to an /24? */
2509 uint32_t ip = tor_addr_to_ipv4h(addr);
2511 /* It's possible that this next check will hit before the first time
2512 * resolve_my_address actually succeeds. (For clients, it is likely that
2513 * resolve_my_address will never be called at all). In those cases,
2514 * last_resolved_addr will be 0, and so checking to see whether ip is on
2515 * the same /24 as last_resolved_addr will be the same as checking whether
2516 * it was on net 0, which is already done by is_internal_IP.
2518 if ((last_resolved_addr & 0xffffff00ul) == (ip & 0xffffff00ul))
2519 return 1;
2521 return 0;
2524 /** Called when we don't have a nickname set. Try to guess a good nickname
2525 * based on the hostname, and return it in a newly allocated string. If we
2526 * can't, return NULL and let the caller warn if it wants to. */
2527 static char *
2528 get_default_nickname(void)
2530 static const char * const bad_default_nicknames[] = {
2531 "localhost",
2532 NULL,
2534 char localhostname[256];
2535 char *cp, *out, *outp;
2536 int i;
2538 if (gethostname(localhostname, sizeof(localhostname)) < 0)
2539 return NULL;
2541 /* Put it in lowercase; stop at the first dot. */
2542 if ((cp = strchr(localhostname, '.')))
2543 *cp = '\0';
2544 tor_strlower(localhostname);
2546 /* Strip invalid characters. */
2547 cp = localhostname;
2548 out = outp = tor_malloc(strlen(localhostname) + 1);
2549 while (*cp) {
2550 if (strchr(LEGAL_NICKNAME_CHARACTERS, *cp))
2551 *outp++ = *cp++;
2552 else
2553 cp++;
2555 *outp = '\0';
2557 /* Enforce length. */
2558 if (strlen(out) > MAX_NICKNAME_LEN)
2559 out[MAX_NICKNAME_LEN]='\0';
2561 /* Check for dumb names. */
2562 for (i = 0; bad_default_nicknames[i]; ++i) {
2563 if (!strcmp(out, bad_default_nicknames[i])) {
2564 tor_free(out);
2565 return NULL;
2569 return out;
2572 /** Release storage held by <b>options</b>. */
2573 static void
2574 config_free(config_format_t *fmt, void *options)
2576 int i;
2578 tor_assert(options);
2580 for (i=0; fmt->vars[i].name; ++i)
2581 option_clear(fmt, options, &(fmt->vars[i]));
2582 if (fmt->extra) {
2583 config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->var_offset);
2584 config_free_lines(*linep);
2585 *linep = NULL;
2587 tor_free(options);
2590 /** Return true iff a and b contain identical keys and values in identical
2591 * order. */
2592 static int
2593 config_lines_eq(config_line_t *a, config_line_t *b)
2595 while (a && b) {
2596 if (strcasecmp(a->key, b->key) || strcmp(a->value, b->value))
2597 return 0;
2598 a = a->next;
2599 b = b->next;
2601 if (a || b)
2602 return 0;
2603 return 1;
2606 /** Return true iff the option <b>name</b> has the same value in <b>o1</b>
2607 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
2609 static int
2610 option_is_same(config_format_t *fmt,
2611 or_options_t *o1, or_options_t *o2, const char *name)
2613 config_line_t *c1, *c2;
2614 int r = 1;
2615 CHECK(fmt, o1);
2616 CHECK(fmt, o2);
2618 c1 = get_assigned_option(fmt, o1, name, 0);
2619 c2 = get_assigned_option(fmt, o2, name, 0);
2620 r = config_lines_eq(c1, c2);
2621 config_free_lines(c1);
2622 config_free_lines(c2);
2623 return r;
2626 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
2627 static or_options_t *
2628 options_dup(config_format_t *fmt, or_options_t *old)
2630 or_options_t *newopts;
2631 int i;
2632 config_line_t *line;
2634 newopts = config_alloc(fmt);
2635 for (i=0; fmt->vars[i].name; ++i) {
2636 if (fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2637 continue;
2638 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE)
2639 continue;
2640 line = get_assigned_option(fmt, old, fmt->vars[i].name, 0);
2641 if (line) {
2642 char *msg = NULL;
2643 if (config_assign(fmt, newopts, line, 0, 0, &msg) < 0) {
2644 log_err(LD_BUG, "Config_get_assigned_option() generated "
2645 "something we couldn't config_assign(): %s", msg);
2646 tor_free(msg);
2647 tor_assert(0);
2650 config_free_lines(line);
2652 return newopts;
2655 /** Return a new empty or_options_t. Used for testing. */
2656 or_options_t *
2657 options_new(void)
2659 return config_alloc(&options_format);
2662 /** Set <b>options</b> to hold reasonable defaults for most options.
2663 * Each option defaults to zero. */
2664 void
2665 options_init(or_options_t *options)
2667 config_init(&options_format, options);
2670 /* Check if the port number given in <b>port_option</b> in combination with
2671 * the specified port in <b>listen_options</b> will result in Tor actually
2672 * opening a low port (meaning a port lower than 1024). Return 1 if
2673 * it is, or 0 if it isn't or the concept of a low port isn't applicable for
2674 * the platform we're on. */
2675 static int
2676 is_listening_on_low_port(uint16_t port_option,
2677 const config_line_t *listen_options)
2679 #ifdef MS_WINDOWS
2680 return 0; /* No port is too low for windows. */
2681 #else
2682 const config_line_t *l;
2683 uint16_t p;
2684 if (port_option == 0)
2685 return 0; /* We're not listening */
2686 if (listen_options == NULL)
2687 return (port_option < 1024);
2689 for (l = listen_options; l; l = l->next) {
2690 parse_addr_port(LOG_WARN, l->value, NULL, NULL, &p);
2691 if (p<1024) {
2692 return 1;
2695 return 0;
2696 #endif
2699 /** Set all vars in the configuration object <b>options</b> to their default
2700 * values. */
2701 static void
2702 config_init(config_format_t *fmt, void *options)
2704 int i;
2705 config_var_t *var;
2706 CHECK(fmt, options);
2708 for (i=0; fmt->vars[i].name; ++i) {
2709 var = &fmt->vars[i];
2710 if (!var->initvalue)
2711 continue; /* defaults to NULL or 0 */
2712 option_reset(fmt, options, var, 1);
2716 /** Allocate and return a new string holding the written-out values of the vars
2717 * in 'options'. If 'minimal', do not write out any default-valued vars.
2718 * Else, if comment_defaults, write default values as comments.
2720 static char *
2721 config_dump(config_format_t *fmt, void *options, int minimal,
2722 int comment_defaults)
2724 smartlist_t *elements;
2725 or_options_t *defaults;
2726 config_line_t *line, *assigned;
2727 char *result;
2728 int i;
2729 const char *desc;
2730 char *msg = NULL;
2732 defaults = config_alloc(fmt);
2733 config_init(fmt, defaults);
2735 /* XXX use a 1 here so we don't add a new log line while dumping */
2736 if (fmt->validate_fn(NULL,defaults, 1, &msg) < 0) {
2737 log_err(LD_BUG, "Failed to validate default config.");
2738 tor_free(msg);
2739 tor_assert(0);
2742 elements = smartlist_create();
2743 for (i=0; fmt->vars[i].name; ++i) {
2744 int comment_option = 0;
2745 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE ||
2746 fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2747 continue;
2748 /* Don't save 'hidden' control variables. */
2749 if (!strcmpstart(fmt->vars[i].name, "__"))
2750 continue;
2751 if (minimal && option_is_same(fmt, options, defaults, fmt->vars[i].name))
2752 continue;
2753 else if (comment_defaults &&
2754 option_is_same(fmt, options, defaults, fmt->vars[i].name))
2755 comment_option = 1;
2757 desc = config_find_description(fmt, fmt->vars[i].name);
2758 line = assigned = get_assigned_option(fmt, options, fmt->vars[i].name, 1);
2760 if (line && desc) {
2761 /* Only dump the description if there's something to describe. */
2762 wrap_string(elements, desc, 78, "# ", "# ");
2765 for (; line; line = line->next) {
2766 size_t len = strlen(line->key) + strlen(line->value) + 5;
2767 char *tmp;
2768 tmp = tor_malloc(len);
2769 if (tor_snprintf(tmp, len, "%s%s %s\n",
2770 comment_option ? "# " : "",
2771 line->key, line->value)<0) {
2772 log_err(LD_BUG,"Internal error writing option value");
2773 tor_assert(0);
2775 smartlist_add(elements, tmp);
2777 config_free_lines(assigned);
2780 if (fmt->extra) {
2781 line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->var_offset);
2782 for (; line; line = line->next) {
2783 size_t len = strlen(line->key) + strlen(line->value) + 3;
2784 char *tmp;
2785 tmp = tor_malloc(len);
2786 if (tor_snprintf(tmp, len, "%s %s\n", line->key, line->value)<0) {
2787 log_err(LD_BUG,"Internal error writing option value");
2788 tor_assert(0);
2790 smartlist_add(elements, tmp);
2794 result = smartlist_join_strings(elements, "", 0, NULL);
2795 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2796 smartlist_free(elements);
2797 config_free(fmt, defaults);
2798 return result;
2801 /** Return a string containing a possible configuration file that would give
2802 * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
2803 * include options that are the same as Tor's defaults.
2805 static char *
2806 options_dump(or_options_t *options, int minimal)
2808 return config_dump(&options_format, options, minimal, 0);
2811 /** Return 0 if every element of sl is a string holding a decimal
2812 * representation of a port number, or if sl is NULL.
2813 * Otherwise set *msg and return -1. */
2814 static int
2815 validate_ports_csv(smartlist_t *sl, const char *name, char **msg)
2817 int i;
2818 char buf[1024];
2819 tor_assert(name);
2821 if (!sl)
2822 return 0;
2824 SMARTLIST_FOREACH(sl, const char *, cp,
2826 i = atoi(cp);
2827 if (i < 1 || i > 65535) {
2828 int r = tor_snprintf(buf, sizeof(buf),
2829 "Port '%s' out of range in %s", cp, name);
2830 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2831 return -1;
2834 return 0;
2837 /** If <b>value</b> exceeds ROUTER_MAX_DECLARED_BANDWIDTH, write
2838 * a complaint into *<b>msg</b> using string <b>desc</b>, and return -1.
2839 * Else return 0.
2841 static int
2842 ensure_bandwidth_cap(uint64_t *value, const char *desc, char **msg)
2844 int r;
2845 char buf[1024];
2846 if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
2847 /* This handles an understandable special case where somebody says "2gb"
2848 * whereas our actual maximum is 2gb-1 (INT_MAX) */
2849 --*value;
2851 if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
2852 r = tor_snprintf(buf, sizeof(buf), "%s ("U64_FORMAT") must be at most %d",
2853 desc, U64_PRINTF_ARG(*value),
2854 ROUTER_MAX_DECLARED_BANDWIDTH);
2855 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2856 return -1;
2858 return 0;
2861 /** Parse an authority type from <b>options</b>-\>PublishServerDescriptor
2862 * and write it to <b>options</b>-\>_PublishServerDescriptor. Treat "1"
2863 * as "v2,v3" unless BridgeRelay is 1, in which case treat it as "bridge".
2864 * Treat "0" as "".
2865 * Return 0 on success or -1 if not a recognized authority type (in which
2866 * case the value of _PublishServerDescriptor is undefined). */
2867 static int
2868 compute_publishserverdescriptor(or_options_t *options)
2870 smartlist_t *list = options->PublishServerDescriptor;
2871 authority_type_t *auth = &options->_PublishServerDescriptor;
2872 *auth = NO_AUTHORITY;
2873 if (!list) /* empty list, answer is none */
2874 return 0;
2875 SMARTLIST_FOREACH(list, const char *, string, {
2876 if (!strcasecmp(string, "v1"))
2877 *auth |= V1_AUTHORITY;
2878 else if (!strcmp(string, "1"))
2879 if (options->BridgeRelay)
2880 *auth |= BRIDGE_AUTHORITY;
2881 else
2882 *auth |= V2_AUTHORITY | V3_AUTHORITY;
2883 else if (!strcasecmp(string, "v2"))
2884 *auth |= V2_AUTHORITY;
2885 else if (!strcasecmp(string, "v3"))
2886 *auth |= V3_AUTHORITY;
2887 else if (!strcasecmp(string, "bridge"))
2888 *auth |= BRIDGE_AUTHORITY;
2889 else if (!strcasecmp(string, "hidserv"))
2890 *auth |= HIDSERV_AUTHORITY;
2891 else if (!strcasecmp(string, "") || !strcmp(string, "0"))
2892 /* no authority */;
2893 else
2894 return -1;
2896 return 0;
2899 /** Lowest allowable value for RendPostPeriod; if this is too low, hidden
2900 * services can overload the directory system. */
2901 #define MIN_REND_POST_PERIOD (10*60)
2903 /** Highest allowable value for RendPostPeriod. */
2904 #define MAX_DIR_PERIOD (MIN_ONION_KEY_LIFETIME/2)
2906 /** Lowest allowable value for CircuitBuildTimeout; values too low will
2907 * increase network load because of failing connections being retried, and
2908 * might prevent users from connecting to the network at all. */
2909 #define MIN_CIRCUIT_BUILD_TIMEOUT 30
2911 /** Lowest allowable value for MaxCircuitDirtiness; if this is too low, Tor
2912 * will generate too many circuits and potentially overload the network. */
2913 #define MIN_MAX_CIRCUIT_DIRTINESS 10
2915 /** Return 0 if every setting in <b>options</b> is reasonable, and a
2916 * permissible transition from <b>old_options</b>. Else return -1.
2917 * Should have no side effects, except for normalizing the contents of
2918 * <b>options</b>.
2920 * On error, tor_strdup an error explanation into *<b>msg</b>.
2922 * XXX
2923 * If <b>from_setconf</b>, we were called by the controller, and our
2924 * Log line should stay empty. If it's 0, then give us a default log
2925 * if there are no logs defined.
2927 static int
2928 options_validate(or_options_t *old_options, or_options_t *options,
2929 int from_setconf, char **msg)
2931 int i, r;
2932 config_line_t *cl;
2933 const char *uname = get_uname();
2934 char buf[1024];
2935 #define REJECT(arg) \
2936 STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
2937 #define COMPLAIN(arg) STMT_BEGIN log(LOG_WARN, LD_CONFIG, arg); STMT_END
2939 tor_assert(msg);
2940 *msg = NULL;
2942 if (options->ORPort < 0 || options->ORPort > 65535)
2943 REJECT("ORPort option out of bounds.");
2945 if (server_mode(options) &&
2946 (!strcmpstart(uname, "Windows 95") ||
2947 !strcmpstart(uname, "Windows 98") ||
2948 !strcmpstart(uname, "Windows Me"))) {
2949 log(LOG_WARN, LD_CONFIG, "Tor is running as a server, but you are "
2950 "running %s; this probably won't work. See "
2951 "http://wiki.noreply.org/noreply/TheOnionRouter/TorFAQ#ServerOS "
2952 "for details.", uname);
2955 if (options->ORPort == 0 && options->ORListenAddress != NULL)
2956 REJECT("ORPort must be defined if ORListenAddress is defined.");
2958 if (options->DirPort == 0 && options->DirListenAddress != NULL)
2959 REJECT("DirPort must be defined if DirListenAddress is defined.");
2961 if (options->DNSPort == 0 && options->DNSListenAddress != NULL)
2962 REJECT("DNSPort must be defined if DNSListenAddress is defined.");
2964 if (options->ControlPort == 0 && options->ControlListenAddress != NULL)
2965 REJECT("ControlPort must be defined if ControlListenAddress is defined.");
2967 if (options->TransPort == 0 && options->TransListenAddress != NULL)
2968 REJECT("TransPort must be defined if TransListenAddress is defined.");
2970 if (options->NatdPort == 0 && options->NatdListenAddress != NULL)
2971 REJECT("NatdPort must be defined if NatdListenAddress is defined.");
2973 /* Don't gripe about SocksPort 0 with SocksListenAddress set; a standard
2974 * configuration does this. */
2976 for (i = 0; i < 3; ++i) {
2977 int is_socks = i==0;
2978 int is_trans = i==1;
2979 config_line_t *line, *opt, *old;
2980 const char *tp;
2981 if (is_socks) {
2982 opt = options->SocksListenAddress;
2983 old = old_options ? old_options->SocksListenAddress : NULL;
2984 tp = "SOCKS proxy";
2985 } else if (is_trans) {
2986 opt = options->TransListenAddress;
2987 old = old_options ? old_options->TransListenAddress : NULL;
2988 tp = "transparent proxy";
2989 } else {
2990 opt = options->NatdListenAddress;
2991 old = old_options ? old_options->NatdListenAddress : NULL;
2992 tp = "natd proxy";
2995 for (line = opt; line; line = line->next) {
2996 char *address = NULL;
2997 uint16_t port;
2998 uint32_t addr;
2999 if (parse_addr_port(LOG_WARN, line->value, &address, &addr, &port)<0)
3000 continue; /* We'll warn about this later. */
3001 if (!is_internal_IP(addr, 1) &&
3002 (!old_options || !config_lines_eq(old, opt))) {
3003 log_warn(LD_CONFIG,
3004 "You specified a public address '%s' for a %s. Other "
3005 "people on the Internet might find your computer and use it as "
3006 "an open %s. Please don't allow this unless you have "
3007 "a good reason.", address, tp, tp);
3009 tor_free(address);
3013 if (validate_data_directory(options)<0)
3014 REJECT("Invalid DataDirectory");
3016 if (options->Nickname == NULL) {
3017 if (server_mode(options)) {
3018 if (!(options->Nickname = get_default_nickname())) {
3019 log_notice(LD_CONFIG, "Couldn't pick a nickname based on "
3020 "our hostname; using %s instead.", UNNAMED_ROUTER_NICKNAME);
3021 options->Nickname = tor_strdup(UNNAMED_ROUTER_NICKNAME);
3022 } else {
3023 log_notice(LD_CONFIG, "Choosing default nickname '%s'",
3024 options->Nickname);
3027 } else {
3028 if (!is_legal_nickname(options->Nickname)) {
3029 r = tor_snprintf(buf, sizeof(buf),
3030 "Nickname '%s' is wrong length or contains illegal characters.",
3031 options->Nickname);
3032 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3033 return -1;
3037 if (server_mode(options) && !options->ContactInfo)
3038 log(LOG_NOTICE, LD_CONFIG, "Your ContactInfo config option is not set. "
3039 "Please consider setting it, so we can contact you if your server is "
3040 "misconfigured or something else goes wrong.");
3042 /* Special case on first boot if no Log options are given. */
3043 if (!options->Logs && !options->RunAsDaemon && !from_setconf)
3044 config_line_append(&options->Logs, "Log", "notice stdout");
3046 if (options_init_logs(options, 1)<0) /* Validate the log(s) */
3047 REJECT("Failed to validate Log options. See logs for details.");
3049 if (options->NoPublish) {
3050 log(LOG_WARN, LD_CONFIG,
3051 "NoPublish is obsolete. Use PublishServerDescriptor instead.");
3052 SMARTLIST_FOREACH(options->PublishServerDescriptor, char *, s,
3053 tor_free(s));
3054 smartlist_clear(options->PublishServerDescriptor);
3057 if (authdir_mode(options)) {
3058 /* confirm that our address isn't broken, so we can complain now */
3059 uint32_t tmp;
3060 if (resolve_my_address(LOG_WARN, options, &tmp, NULL) < 0)
3061 REJECT("Failed to resolve/guess local address. See logs for details.");
3064 #ifndef MS_WINDOWS
3065 if (options->RunAsDaemon && torrc_fname && path_is_relative(torrc_fname))
3066 REJECT("Can't use a relative path to torrc when RunAsDaemon is set.");
3067 #endif
3069 if (options->SocksPort < 0 || options->SocksPort > 65535)
3070 REJECT("SocksPort option out of bounds.");
3072 if (options->DNSPort < 0 || options->DNSPort > 65535)
3073 REJECT("DNSPort option out of bounds.");
3075 if (options->TransPort < 0 || options->TransPort > 65535)
3076 REJECT("TransPort option out of bounds.");
3078 if (options->NatdPort < 0 || options->NatdPort > 65535)
3079 REJECT("NatdPort option out of bounds.");
3081 if (options->SocksPort == 0 && options->TransPort == 0 &&
3082 options->NatdPort == 0 && options->ORPort == 0 &&
3083 options->DNSPort == 0 && !options->RendConfigLines)
3084 log(LOG_WARN, LD_CONFIG,
3085 "SocksPort, TransPort, NatdPort, DNSPort, and ORPort are all "
3086 "undefined, and there aren't any hidden services configured. "
3087 "Tor will still run, but probably won't do anything.");
3089 if (options->ControlPort < 0 || options->ControlPort > 65535)
3090 REJECT("ControlPort option out of bounds.");
3092 if (options->DirPort < 0 || options->DirPort > 65535)
3093 REJECT("DirPort option out of bounds.");
3095 #ifndef USE_TRANSPARENT
3096 if (options->TransPort || options->TransListenAddress)
3097 REJECT("TransPort and TransListenAddress are disabled in this build.");
3098 #endif
3100 if (options->AccountingMax &&
3101 (is_listening_on_low_port(options->ORPort, options->ORListenAddress) ||
3102 is_listening_on_low_port(options->DirPort, options->DirListenAddress)))
3104 log(LOG_WARN, LD_CONFIG,
3105 "You have set AccountingMax to use hibernation. You have also "
3106 "chosen a low DirPort or OrPort. This combination can make Tor stop "
3107 "working when it tries to re-attach the port after a period of "
3108 "hibernation. Please choose a different port or turn off "
3109 "hibernation unless you know this combination will work on your "
3110 "platform.");
3113 if (options->ExcludeExitNodes || options->ExcludeNodes) {
3114 options->_ExcludeExitNodesUnion = routerset_new();
3115 routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeExitNodes);
3116 routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeNodes);
3119 if (options->StrictExitNodes &&
3120 (!options->ExitNodes) &&
3121 (!old_options ||
3122 (old_options->StrictExitNodes != options->StrictExitNodes) ||
3123 (!routerset_equal(old_options->ExitNodes,options->ExitNodes))))
3124 COMPLAIN("StrictExitNodes set, but no ExitNodes listed.");
3126 if (options->StrictEntryNodes &&
3127 (!options->EntryNodes) &&
3128 (!old_options ||
3129 (old_options->StrictEntryNodes != options->StrictEntryNodes) ||
3130 (!routerset_equal(old_options->EntryNodes,options->EntryNodes))))
3131 COMPLAIN("StrictEntryNodes set, but no EntryNodes listed.");
3133 if (options->EntryNodes && !routerset_is_list(options->EntryNodes)) {
3134 /* XXXX fix this; see entry_guards_prepend_from_config(). */
3135 REJECT("IPs or countries are not yet supported in EntryNodes.");
3138 if (options->AuthoritativeDir) {
3139 if (!options->ContactInfo && !options->TestingTorNetwork)
3140 REJECT("Authoritative directory servers must set ContactInfo");
3141 if (options->V1AuthoritativeDir && !options->RecommendedVersions)
3142 REJECT("V1 authoritative dir servers must set RecommendedVersions.");
3143 if (!options->RecommendedClientVersions)
3144 options->RecommendedClientVersions =
3145 config_lines_dup(options->RecommendedVersions);
3146 if (!options->RecommendedServerVersions)
3147 options->RecommendedServerVersions =
3148 config_lines_dup(options->RecommendedVersions);
3149 if (options->VersioningAuthoritativeDir &&
3150 (!options->RecommendedClientVersions ||
3151 !options->RecommendedServerVersions))
3152 REJECT("Versioning authoritative dir servers must set "
3153 "Recommended*Versions.");
3154 if (options->UseEntryGuards) {
3155 log_info(LD_CONFIG, "Authoritative directory servers can't set "
3156 "UseEntryGuards. Disabling.");
3157 options->UseEntryGuards = 0;
3159 if (!options->DownloadExtraInfo && authdir_mode_any_main(options)) {
3160 log_info(LD_CONFIG, "Authoritative directories always try to download "
3161 "extra-info documents. Setting DownloadExtraInfo.");
3162 options->DownloadExtraInfo = 1;
3164 if (!(options->BridgeAuthoritativeDir || options->HSAuthoritativeDir ||
3165 options->V1AuthoritativeDir || options->V2AuthoritativeDir ||
3166 options->V3AuthoritativeDir))
3167 REJECT("AuthoritativeDir is set, but none of "
3168 "(Bridge/HS/V1/V2/V3)AuthoritativeDir is set.");
3171 if (options->AuthoritativeDir && !options->DirPort)
3172 REJECT("Running as authoritative directory, but no DirPort set.");
3174 if (options->AuthoritativeDir && !options->ORPort)
3175 REJECT("Running as authoritative directory, but no ORPort set.");
3177 if (options->AuthoritativeDir && options->ClientOnly)
3178 REJECT("Running as authoritative directory, but ClientOnly also set.");
3180 if (options->HSAuthorityRecordStats && !options->HSAuthoritativeDir)
3181 REJECT("HSAuthorityRecordStats is set but we're not running as "
3182 "a hidden service authority.");
3184 if (options->ConnLimit <= 0) {
3185 r = tor_snprintf(buf, sizeof(buf),
3186 "ConnLimit must be greater than 0, but was set to %d",
3187 options->ConnLimit);
3188 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3189 return -1;
3192 if (validate_ports_csv(options->FirewallPorts, "FirewallPorts", msg) < 0)
3193 return -1;
3195 if (validate_ports_csv(options->LongLivedPorts, "LongLivedPorts", msg) < 0)
3196 return -1;
3198 if (validate_ports_csv(options->RejectPlaintextPorts,
3199 "RejectPlaintextPorts", msg) < 0)
3200 return -1;
3202 if (validate_ports_csv(options->WarnPlaintextPorts,
3203 "WarnPlaintextPorts", msg) < 0)
3204 return -1;
3206 if (options->FascistFirewall && !options->ReachableAddresses) {
3207 if (options->FirewallPorts && smartlist_len(options->FirewallPorts)) {
3208 /* We already have firewall ports set, so migrate them to
3209 * ReachableAddresses, which will set ReachableORAddresses and
3210 * ReachableDirAddresses if they aren't set explicitly. */
3211 smartlist_t *instead = smartlist_create();
3212 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3213 new_line->key = tor_strdup("ReachableAddresses");
3214 /* If we're configured with the old format, we need to prepend some
3215 * open ports. */
3216 SMARTLIST_FOREACH(options->FirewallPorts, const char *, portno,
3218 int p = atoi(portno);
3219 char *s;
3220 if (p<0) continue;
3221 s = tor_malloc(16);
3222 tor_snprintf(s, 16, "*:%d", p);
3223 smartlist_add(instead, s);
3225 new_line->value = smartlist_join_strings(instead,",",0,NULL);
3226 /* These have been deprecated since 0.1.1.5-alpha-cvs */
3227 log(LOG_NOTICE, LD_CONFIG,
3228 "Converting FascistFirewall and FirewallPorts "
3229 "config options to new format: \"ReachableAddresses %s\"",
3230 new_line->value);
3231 options->ReachableAddresses = new_line;
3232 SMARTLIST_FOREACH(instead, char *, cp, tor_free(cp));
3233 smartlist_free(instead);
3234 } else {
3235 /* We do not have FirewallPorts set, so add 80 to
3236 * ReachableDirAddresses, and 443 to ReachableORAddresses. */
3237 if (!options->ReachableDirAddresses) {
3238 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3239 new_line->key = tor_strdup("ReachableDirAddresses");
3240 new_line->value = tor_strdup("*:80");
3241 options->ReachableDirAddresses = new_line;
3242 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
3243 "to new format: \"ReachableDirAddresses *:80\"");
3245 if (!options->ReachableORAddresses) {
3246 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3247 new_line->key = tor_strdup("ReachableORAddresses");
3248 new_line->value = tor_strdup("*:443");
3249 options->ReachableORAddresses = new_line;
3250 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
3251 "to new format: \"ReachableORAddresses *:443\"");
3256 for (i=0; i<3; i++) {
3257 config_line_t **linep =
3258 (i==0) ? &options->ReachableAddresses :
3259 (i==1) ? &options->ReachableORAddresses :
3260 &options->ReachableDirAddresses;
3261 if (!*linep)
3262 continue;
3263 /* We need to end with a reject *:*, not an implicit accept *:* */
3264 for (;;) {
3265 if (!strcmp((*linep)->value, "reject *:*")) /* already there */
3266 break;
3267 linep = &((*linep)->next);
3268 if (!*linep) {
3269 *linep = tor_malloc_zero(sizeof(config_line_t));
3270 (*linep)->key = tor_strdup(
3271 (i==0) ? "ReachableAddresses" :
3272 (i==1) ? "ReachableORAddresses" :
3273 "ReachableDirAddresses");
3274 (*linep)->value = tor_strdup("reject *:*");
3275 break;
3280 if ((options->ReachableAddresses ||
3281 options->ReachableORAddresses ||
3282 options->ReachableDirAddresses) &&
3283 server_mode(options))
3284 REJECT("Servers must be able to freely connect to the rest "
3285 "of the Internet, so they must not set Reachable*Addresses "
3286 "or FascistFirewall.");
3288 if (options->UseBridges &&
3289 server_mode(options))
3290 REJECT("Servers must be able to freely connect to the rest "
3291 "of the Internet, so they must not set UseBridges.");
3293 options->_AllowInvalid = 0;
3294 if (options->AllowInvalidNodes) {
3295 SMARTLIST_FOREACH(options->AllowInvalidNodes, const char *, cp, {
3296 if (!strcasecmp(cp, "entry"))
3297 options->_AllowInvalid |= ALLOW_INVALID_ENTRY;
3298 else if (!strcasecmp(cp, "exit"))
3299 options->_AllowInvalid |= ALLOW_INVALID_EXIT;
3300 else if (!strcasecmp(cp, "middle"))
3301 options->_AllowInvalid |= ALLOW_INVALID_MIDDLE;
3302 else if (!strcasecmp(cp, "introduction"))
3303 options->_AllowInvalid |= ALLOW_INVALID_INTRODUCTION;
3304 else if (!strcasecmp(cp, "rendezvous"))
3305 options->_AllowInvalid |= ALLOW_INVALID_RENDEZVOUS;
3306 else {
3307 r = tor_snprintf(buf, sizeof(buf),
3308 "Unrecognized value '%s' in AllowInvalidNodes", cp);
3309 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3310 return -1;
3315 if (compute_publishserverdescriptor(options) < 0) {
3316 r = tor_snprintf(buf, sizeof(buf),
3317 "Unrecognized value in PublishServerDescriptor");
3318 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3319 return -1;
3322 if ((options->BridgeRelay
3323 || options->_PublishServerDescriptor & BRIDGE_AUTHORITY)
3324 && (options->_PublishServerDescriptor
3325 & (V1_AUTHORITY|V2_AUTHORITY|V3_AUTHORITY))) {
3326 REJECT("Bridges are not supposed to publish router descriptors to the "
3327 "directory authorities. Please correct your "
3328 "PublishServerDescriptor line.");
3331 if (options->MinUptimeHidServDirectoryV2 < 0) {
3332 log_warn(LD_CONFIG, "MinUptimeHidServDirectoryV2 option must be at "
3333 "least 0 seconds. Changing to 0.");
3334 options->MinUptimeHidServDirectoryV2 = 0;
3337 if (options->RendPostPeriod < MIN_REND_POST_PERIOD) {
3338 log(LOG_WARN,LD_CONFIG,"RendPostPeriod option is too short; "
3339 "raising to %d seconds.", MIN_REND_POST_PERIOD);
3340 options->RendPostPeriod = MIN_REND_POST_PERIOD;
3343 if (options->RendPostPeriod > MAX_DIR_PERIOD) {
3344 log(LOG_WARN, LD_CONFIG, "RendPostPeriod is too large; clipping to %ds.",
3345 MAX_DIR_PERIOD);
3346 options->RendPostPeriod = MAX_DIR_PERIOD;
3349 if (options->CircuitBuildTimeout < MIN_CIRCUIT_BUILD_TIMEOUT) {
3350 log(LOG_WARN, LD_CONFIG, "CircuitBuildTimeout option is too short; "
3351 "raising to %d seconds.", MIN_CIRCUIT_BUILD_TIMEOUT);
3352 options->CircuitBuildTimeout = MIN_CIRCUIT_BUILD_TIMEOUT;
3355 if (options->MaxCircuitDirtiness < MIN_MAX_CIRCUIT_DIRTINESS) {
3356 log(LOG_WARN, LD_CONFIG, "MaxCircuitDirtiness option is too short; "
3357 "raising to %d seconds.", MIN_MAX_CIRCUIT_DIRTINESS);
3358 options->MaxCircuitDirtiness = MIN_MAX_CIRCUIT_DIRTINESS;
3361 if (options->KeepalivePeriod < 1)
3362 REJECT("KeepalivePeriod option must be positive.");
3364 if (ensure_bandwidth_cap(&options->BandwidthRate,
3365 "BandwidthRate", msg) < 0)
3366 return -1;
3367 if (ensure_bandwidth_cap(&options->BandwidthBurst,
3368 "BandwidthBurst", msg) < 0)
3369 return -1;
3370 if (ensure_bandwidth_cap(&options->MaxAdvertisedBandwidth,
3371 "MaxAdvertisedBandwidth", msg) < 0)
3372 return -1;
3373 if (ensure_bandwidth_cap(&options->RelayBandwidthRate,
3374 "RelayBandwidthRate", msg) < 0)
3375 return -1;
3376 if (ensure_bandwidth_cap(&options->RelayBandwidthBurst,
3377 "RelayBandwidthBurst", msg) < 0)
3378 return -1;
3380 if (server_mode(options)) {
3381 if (options->BandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
3382 r = tor_snprintf(buf, sizeof(buf),
3383 "BandwidthRate is set to %d bytes/second. "
3384 "For servers, it must be at least %d.",
3385 (int)options->BandwidthRate,
3386 ROUTER_REQUIRED_MIN_BANDWIDTH);
3387 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3388 return -1;
3389 } else if (options->MaxAdvertisedBandwidth <
3390 ROUTER_REQUIRED_MIN_BANDWIDTH/2) {
3391 r = tor_snprintf(buf, sizeof(buf),
3392 "MaxAdvertisedBandwidth is set to %d bytes/second. "
3393 "For servers, it must be at least %d.",
3394 (int)options->MaxAdvertisedBandwidth,
3395 ROUTER_REQUIRED_MIN_BANDWIDTH/2);
3396 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3397 return -1;
3399 if (options->RelayBandwidthRate &&
3400 options->RelayBandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
3401 r = tor_snprintf(buf, sizeof(buf),
3402 "RelayBandwidthRate is set to %d bytes/second. "
3403 "For servers, it must be at least %d.",
3404 (int)options->RelayBandwidthRate,
3405 ROUTER_REQUIRED_MIN_BANDWIDTH);
3406 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3407 return -1;
3411 if (options->RelayBandwidthRate && !options->RelayBandwidthBurst)
3412 options->RelayBandwidthBurst = options->RelayBandwidthRate;
3414 if (options->RelayBandwidthRate > options->RelayBandwidthBurst)
3415 REJECT("RelayBandwidthBurst must be at least equal "
3416 "to RelayBandwidthRate.");
3418 if (options->BandwidthRate > options->BandwidthBurst)
3419 REJECT("BandwidthBurst must be at least equal to BandwidthRate.");
3421 /* if they set relaybandwidth* really high but left bandwidth*
3422 * at the default, raise the defaults. */
3423 if (options->RelayBandwidthRate > options->BandwidthRate)
3424 options->BandwidthRate = options->RelayBandwidthRate;
3425 if (options->RelayBandwidthBurst > options->BandwidthBurst)
3426 options->BandwidthBurst = options->RelayBandwidthBurst;
3428 if (accounting_parse_options(options, 1)<0)
3429 REJECT("Failed to parse accounting options. See logs for details.");
3431 if (options->HttpProxy) { /* parse it now */
3432 if (parse_addr_port(LOG_WARN, options->HttpProxy, NULL,
3433 &options->HttpProxyAddr, &options->HttpProxyPort) < 0)
3434 REJECT("HttpProxy failed to parse or resolve. Please fix.");
3435 if (options->HttpProxyPort == 0) { /* give it a default */
3436 options->HttpProxyPort = 80;
3440 if (options->HttpProxyAuthenticator) {
3441 if (strlen(options->HttpProxyAuthenticator) >= 48)
3442 REJECT("HttpProxyAuthenticator is too long (>= 48 chars).");
3445 if (options->HttpsProxy) { /* parse it now */
3446 if (parse_addr_port(LOG_WARN, options->HttpsProxy, NULL,
3447 &options->HttpsProxyAddr, &options->HttpsProxyPort) <0)
3448 REJECT("HttpsProxy failed to parse or resolve. Please fix.");
3449 if (options->HttpsProxyPort == 0) { /* give it a default */
3450 options->HttpsProxyPort = 443;
3454 if (options->HttpsProxyAuthenticator) {
3455 if (strlen(options->HttpsProxyAuthenticator) >= 48)
3456 REJECT("HttpsProxyAuthenticator is too long (>= 48 chars).");
3459 if (options->HashedControlPassword) {
3460 smartlist_t *sl = decode_hashed_passwords(options->HashedControlPassword);
3461 if (!sl) {
3462 REJECT("Bad HashedControlPassword: wrong length or bad encoding");
3463 } else {
3464 SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
3465 smartlist_free(sl);
3469 if (options->HashedControlSessionPassword) {
3470 smartlist_t *sl = decode_hashed_passwords(
3471 options->HashedControlSessionPassword);
3472 if (!sl) {
3473 REJECT("Bad HashedControlSessionPassword: wrong length or bad encoding");
3474 } else {
3475 SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
3476 smartlist_free(sl);
3480 if (options->ControlListenAddress) {
3481 int all_are_local = 1;
3482 config_line_t *ln;
3483 for (ln = options->ControlListenAddress; ln; ln = ln->next) {
3484 if (strcmpstart(ln->value, "127."))
3485 all_are_local = 0;
3487 if (!all_are_local) {
3488 if (!options->HashedControlPassword &&
3489 !options->HashedControlSessionPassword &&
3490 !options->CookieAuthentication) {
3491 log_warn(LD_CONFIG,
3492 "You have a ControlListenAddress set to accept "
3493 "unauthenticated connections from a non-local address. "
3494 "This means that programs not running on your computer "
3495 "can reconfigure your Tor, without even having to guess a "
3496 "password. That's so bad that I'm closing your ControlPort "
3497 "for you. If you need to control your Tor remotely, try "
3498 "enabling authentication and using a tool like stunnel or "
3499 "ssh to encrypt remote access.");
3500 options->ControlPort = 0;
3501 } else {
3502 log_warn(LD_CONFIG, "You have a ControlListenAddress set to accept "
3503 "connections from a non-local address. This means that "
3504 "programs not running on your computer can reconfigure your "
3505 "Tor. That's pretty bad, since the controller "
3506 "protocol isn't encrypted! Maybe you should just listen on "
3507 "127.0.0.1 and use a tool like stunnel or ssh to encrypt "
3508 "remote connections to your control port.");
3513 if (options->ControlPort && !options->HashedControlPassword &&
3514 !options->HashedControlSessionPassword &&
3515 !options->CookieAuthentication) {
3516 log_warn(LD_CONFIG, "ControlPort is open, but no authentication method "
3517 "has been configured. This means that any program on your "
3518 "computer can reconfigure your Tor. That's bad! You should "
3519 "upgrade your Tor controller as soon as possible.");
3522 if (options->UseEntryGuards && ! options->NumEntryGuards)
3523 REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0");
3525 if (check_nickname_list(options->MyFamily, "MyFamily", msg))
3526 return -1;
3527 for (cl = options->NodeFamilies; cl; cl = cl->next) {
3528 if (check_nickname_list(cl->value, "NodeFamily", msg))
3529 return -1;
3532 if (validate_addr_policies(options, msg) < 0)
3533 return -1;
3535 if (validate_dir_authorities(options, old_options) < 0)
3536 REJECT("Directory authority line did not parse. See logs for details.");
3538 if (options->UseBridges && !options->Bridges)
3539 REJECT("If you set UseBridges, you must specify at least one bridge.");
3540 if (options->UseBridges && !options->TunnelDirConns)
3541 REJECT("If you set UseBridges, you must set TunnelDirConns.");
3542 if (options->Bridges) {
3543 for (cl = options->Bridges; cl; cl = cl->next) {
3544 if (parse_bridge_line(cl->value, 1)<0)
3545 REJECT("Bridge line did not parse. See logs for details.");
3549 if (options->ConstrainedSockets) {
3550 /* If the user wants to constrain socket buffer use, make sure the desired
3551 * limit is between MIN|MAX_TCPSOCK_BUFFER in k increments. */
3552 if (options->ConstrainedSockSize < MIN_CONSTRAINED_TCP_BUFFER ||
3553 options->ConstrainedSockSize > MAX_CONSTRAINED_TCP_BUFFER ||
3554 options->ConstrainedSockSize % 1024) {
3555 r = tor_snprintf(buf, sizeof(buf),
3556 "ConstrainedSockSize is invalid. Must be a value between %d and %d "
3557 "in 1024 byte increments.",
3558 MIN_CONSTRAINED_TCP_BUFFER, MAX_CONSTRAINED_TCP_BUFFER);
3559 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3560 return -1;
3562 if (options->DirPort) {
3563 /* Providing cached directory entries while system TCP buffers are scarce
3564 * will exacerbate the socket errors. Suggest that this be disabled. */
3565 COMPLAIN("You have requested constrained socket buffers while also "
3566 "serving directory entries via DirPort. It is strongly "
3567 "suggested that you disable serving directory requests when "
3568 "system TCP buffer resources are scarce.");
3572 if (options->V3AuthVoteDelay + options->V3AuthDistDelay >=
3573 options->V3AuthVotingInterval/2) {
3574 REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than half "
3575 "V3AuthVotingInterval");
3577 if (options->V3AuthVoteDelay < MIN_VOTE_SECONDS)
3578 REJECT("V3AuthVoteDelay is way too low.");
3579 if (options->V3AuthDistDelay < MIN_DIST_SECONDS)
3580 REJECT("V3AuthDistDelay is way too low.");
3582 if (options->V3AuthNIntervalsValid < 2)
3583 REJECT("V3AuthNIntervalsValid must be at least 2.");
3585 if (options->V3AuthVotingInterval < MIN_VOTE_INTERVAL) {
3586 REJECT("V3AuthVotingInterval is insanely low.");
3587 } else if (options->V3AuthVotingInterval > 24*60*60) {
3588 REJECT("V3AuthVotingInterval is insanely high.");
3589 } else if (((24*60*60) % options->V3AuthVotingInterval) != 0) {
3590 COMPLAIN("V3AuthVotingInterval does not divide evenly into 24 hours.");
3593 if (rend_config_services(options, 1) < 0)
3594 REJECT("Failed to configure rendezvous options. See logs for details.");
3596 /* Parse client-side authorization for hidden services. */
3597 if (rend_parse_service_authorization(options, 1) < 0)
3598 REJECT("Failed to configure client authorization for hidden services. "
3599 "See logs for details.");
3601 if (parse_virtual_addr_network(options->VirtualAddrNetwork, 1, NULL)<0)
3602 return -1;
3604 if (options->PreferTunneledDirConns && !options->TunnelDirConns)
3605 REJECT("Must set TunnelDirConns if PreferTunneledDirConns is set.");
3607 if (options->AutomapHostsSuffixes) {
3608 SMARTLIST_FOREACH(options->AutomapHostsSuffixes, char *, suf,
3610 size_t len = strlen(suf);
3611 if (len && suf[len-1] == '.')
3612 suf[len-1] = '\0';
3616 if (options->TestingTorNetwork && !options->DirServers) {
3617 REJECT("TestingTorNetwork may only be configured in combination with "
3618 "a non-default set of DirServers.");
3621 /*XXXX022 checking for defaults manually like this is a bit fragile.*/
3623 /* Keep changes to hard-coded values synchronous to man page and default
3624 * values table. */
3625 if (options->TestingV3AuthInitialVotingInterval != 30*60 &&
3626 !options->TestingTorNetwork) {
3627 REJECT("TestingV3AuthInitialVotingInterval may only be changed in testing "
3628 "Tor networks!");
3629 } else if (options->TestingV3AuthInitialVotingInterval < MIN_VOTE_INTERVAL) {
3630 REJECT("TestingV3AuthInitialVotingInterval is insanely low.");
3631 } else if (((30*60) % options->TestingV3AuthInitialVotingInterval) != 0) {
3632 REJECT("TestingV3AuthInitialVotingInterval does not divide evenly into "
3633 "30 minutes.");
3636 if (options->TestingV3AuthInitialVoteDelay != 5*60 &&
3637 !options->TestingTorNetwork) {
3638 REJECT("TestingV3AuthInitialVoteDelay may only be changed in testing "
3639 "Tor networks!");
3640 } else if (options->TestingV3AuthInitialVoteDelay < MIN_VOTE_SECONDS) {
3641 REJECT("TestingV3AuthInitialVoteDelay is way too low.");
3644 if (options->TestingV3AuthInitialDistDelay != 5*60 &&
3645 !options->TestingTorNetwork) {
3646 REJECT("TestingV3AuthInitialDistDelay may only be changed in testing "
3647 "Tor networks!");
3648 } else if (options->TestingV3AuthInitialDistDelay < MIN_DIST_SECONDS) {
3649 REJECT("TestingV3AuthInitialDistDelay is way too low.");
3652 if (options->TestingV3AuthInitialVoteDelay +
3653 options->TestingV3AuthInitialDistDelay >=
3654 options->TestingV3AuthInitialVotingInterval/2) {
3655 REJECT("TestingV3AuthInitialVoteDelay plus TestingV3AuthInitialDistDelay "
3656 "must be less than half TestingV3AuthInitialVotingInterval");
3659 if (options->TestingAuthDirTimeToLearnReachability != 30*60 &&
3660 !options->TestingTorNetwork) {
3661 REJECT("TestingAuthDirTimeToLearnReachability may only be changed in "
3662 "testing Tor networks!");
3663 } else if (options->TestingAuthDirTimeToLearnReachability < 0) {
3664 REJECT("TestingAuthDirTimeToLearnReachability must be non-negative.");
3665 } else if (options->TestingAuthDirTimeToLearnReachability > 2*60*60) {
3666 COMPLAIN("TestingAuthDirTimeToLearnReachability is insanely high.");
3669 if (options->TestingEstimatedDescriptorPropagationTime != 10*60 &&
3670 !options->TestingTorNetwork) {
3671 REJECT("TestingEstimatedDescriptorPropagationTime may only be changed in "
3672 "testing Tor networks!");
3673 } else if (options->TestingEstimatedDescriptorPropagationTime < 0) {
3674 REJECT("TestingEstimatedDescriptorPropagationTime must be non-negative.");
3675 } else if (options->TestingEstimatedDescriptorPropagationTime > 60*60) {
3676 COMPLAIN("TestingEstimatedDescriptorPropagationTime is insanely high.");
3679 if (options->TestingTorNetwork) {
3680 log_warn(LD_CONFIG, "TestingTorNetwork is set. This will make your node "
3681 "almost unusable in the public Tor network, and is "
3682 "therefore only advised if you are building a "
3683 "testing Tor network!");
3686 if (options->AccelName && !options->HardwareAccel)
3687 options->HardwareAccel = 1;
3688 if (options->AccelDir && !options->AccelName)
3689 REJECT("Can't use hardware crypto accelerator dir without engine name.");
3691 return 0;
3692 #undef REJECT
3693 #undef COMPLAIN
3696 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
3697 * equal strings. */
3698 static int
3699 opt_streq(const char *s1, const char *s2)
3701 if (!s1 && !s2)
3702 return 1;
3703 else if (s1 && s2 && !strcmp(s1,s2))
3704 return 1;
3705 else
3706 return 0;
3709 /** Check if any of the previous options have changed but aren't allowed to. */
3710 static int
3711 options_transition_allowed(or_options_t *old, or_options_t *new_val,
3712 char **msg)
3714 if (!old)
3715 return 0;
3717 if (!opt_streq(old->PidFile, new_val->PidFile)) {
3718 *msg = tor_strdup("PidFile is not allowed to change.");
3719 return -1;
3722 if (old->RunAsDaemon != new_val->RunAsDaemon) {
3723 *msg = tor_strdup("While Tor is running, changing RunAsDaemon "
3724 "is not allowed.");
3725 return -1;
3728 if (strcmp(old->DataDirectory,new_val->DataDirectory)!=0) {
3729 char buf[1024];
3730 int r = tor_snprintf(buf, sizeof(buf),
3731 "While Tor is running, changing DataDirectory "
3732 "(\"%s\"->\"%s\") is not allowed.",
3733 old->DataDirectory, new_val->DataDirectory);
3734 *msg = tor_strdup(r >= 0 ? buf : "internal error");
3735 return -1;
3738 if (!opt_streq(old->User, new_val->User)) {
3739 *msg = tor_strdup("While Tor is running, changing User is not allowed.");
3740 return -1;
3743 if (!opt_streq(old->Group, new_val->Group)) {
3744 *msg = tor_strdup("While Tor is running, changing Group is not allowed.");
3745 return -1;
3748 if ((old->HardwareAccel != new_val->HardwareAccel)
3749 || !opt_streq(old->AccelName, new_val->AccelName)
3750 || !opt_streq(old->AccelDir, new_val->AccelDir)) {
3751 *msg = tor_strdup("While Tor is running, changing OpenSSL hardware "
3752 "acceleration engine is not allowed.");
3753 return -1;
3756 if (old->TestingTorNetwork != new_val->TestingTorNetwork) {
3757 *msg = tor_strdup("While Tor is running, changing TestingTorNetwork "
3758 "is not allowed.");
3759 return -1;
3762 return 0;
3765 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
3766 * will require us to rotate the CPU and DNS workers; else return 0. */
3767 static int
3768 options_transition_affects_workers(or_options_t *old_options,
3769 or_options_t *new_options)
3771 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
3772 old_options->NumCpus != new_options->NumCpus ||
3773 old_options->ORPort != new_options->ORPort ||
3774 old_options->ServerDNSSearchDomains !=
3775 new_options->ServerDNSSearchDomains ||
3776 old_options->SafeLogging != new_options->SafeLogging ||
3777 old_options->ClientOnly != new_options->ClientOnly ||
3778 !config_lines_eq(old_options->Logs, new_options->Logs))
3779 return 1;
3781 /* Check whether log options match. */
3783 /* Nothing that changed matters. */
3784 return 0;
3787 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
3788 * will require us to generate a new descriptor; else return 0. */
3789 static int
3790 options_transition_affects_descriptor(or_options_t *old_options,
3791 or_options_t *new_options)
3793 /* XXX We can be smarter here. If your DirPort isn't being
3794 * published and you just turned it off, no need to republish. If
3795 * you changed your bandwidthrate but maxadvertisedbandwidth still
3796 * trumps, no need to republish. Etc. */
3797 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
3798 !opt_streq(old_options->Nickname,new_options->Nickname) ||
3799 !opt_streq(old_options->Address,new_options->Address) ||
3800 !config_lines_eq(old_options->ExitPolicy,new_options->ExitPolicy) ||
3801 old_options->ExitPolicyRejectPrivate !=
3802 new_options->ExitPolicyRejectPrivate ||
3803 old_options->ORPort != new_options->ORPort ||
3804 old_options->DirPort != new_options->DirPort ||
3805 old_options->ClientOnly != new_options->ClientOnly ||
3806 old_options->NoPublish != new_options->NoPublish ||
3807 old_options->_PublishServerDescriptor !=
3808 new_options->_PublishServerDescriptor ||
3809 old_options->BandwidthRate != new_options->BandwidthRate ||
3810 old_options->BandwidthBurst != new_options->BandwidthBurst ||
3811 old_options->MaxAdvertisedBandwidth !=
3812 new_options->MaxAdvertisedBandwidth ||
3813 !opt_streq(old_options->ContactInfo, new_options->ContactInfo) ||
3814 !opt_streq(old_options->MyFamily, new_options->MyFamily) ||
3815 !opt_streq(old_options->AccountingStart, new_options->AccountingStart) ||
3816 old_options->AccountingMax != new_options->AccountingMax)
3817 return 1;
3819 return 0;
3822 #ifdef MS_WINDOWS
3823 /** Return the directory on windows where we expect to find our application
3824 * data. */
3825 static char *
3826 get_windows_conf_root(void)
3828 static int is_set = 0;
3829 static char path[MAX_PATH+1];
3831 LPITEMIDLIST idl;
3832 IMalloc *m;
3833 HRESULT result;
3835 if (is_set)
3836 return path;
3838 /* Find X:\documents and settings\username\application data\ .
3839 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
3841 #ifdef ENABLE_LOCAL_APPDATA
3842 #define APPDATA_PATH CSIDL_LOCAL_APPDATA
3843 #else
3844 #define APPDATA_PATH CSIDL_APPDATA
3845 #endif
3846 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, APPDATA_PATH, &idl))) {
3847 GetCurrentDirectory(MAX_PATH, path);
3848 is_set = 1;
3849 log_warn(LD_CONFIG,
3850 "I couldn't find your application data folder: are you "
3851 "running an ancient version of Windows 95? Defaulting to \"%s\"",
3852 path);
3853 return path;
3855 /* Convert the path from an "ID List" (whatever that is!) to a path. */
3856 result = SHGetPathFromIDList(idl, path);
3857 /* Now we need to free the */
3858 SHGetMalloc(&m);
3859 if (m) {
3860 m->lpVtbl->Free(m, idl);
3861 m->lpVtbl->Release(m);
3863 if (!SUCCEEDED(result)) {
3864 return NULL;
3866 strlcat(path,"\\tor",MAX_PATH);
3867 is_set = 1;
3868 return path;
3870 #endif
3872 /** Return the default location for our torrc file. */
3873 static const char *
3874 get_default_conf_file(void)
3876 #ifdef MS_WINDOWS
3877 static char path[MAX_PATH+1];
3878 strlcpy(path, get_windows_conf_root(), MAX_PATH);
3879 strlcat(path,"\\torrc",MAX_PATH);
3880 return path;
3881 #else
3882 return (CONFDIR "/torrc");
3883 #endif
3886 /** Verify whether lst is a string containing valid-looking comma-separated
3887 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
3889 static int
3890 check_nickname_list(const char *lst, const char *name, char **msg)
3892 int r = 0;
3893 smartlist_t *sl;
3895 if (!lst)
3896 return 0;
3897 sl = smartlist_create();
3899 smartlist_split_string(sl, lst, ",",
3900 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0);
3902 SMARTLIST_FOREACH(sl, const char *, s,
3904 if (!is_legal_nickname_or_hexdigest(s)) {
3905 char buf[1024];
3906 int tmp = tor_snprintf(buf, sizeof(buf),
3907 "Invalid nickname '%s' in %s line", s, name);
3908 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
3909 r = -1;
3910 break;
3913 SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
3914 smartlist_free(sl);
3915 return r;
3918 /** Learn config file name from command line arguments, or use the default */
3919 static char *
3920 find_torrc_filename(int argc, char **argv,
3921 int *using_default_torrc, int *ignore_missing_torrc)
3923 char *fname=NULL;
3924 int i;
3926 for (i = 1; i < argc; ++i) {
3927 if (i < argc-1 && !strcmp(argv[i],"-f")) {
3928 if (fname) {
3929 log(LOG_WARN, LD_CONFIG, "Duplicate -f options on command line.");
3930 tor_free(fname);
3932 #ifdef MS_WINDOWS
3933 /* XXX one day we might want to extend expand_filename to work
3934 * under Windows as well. */
3935 fname = tor_strdup(argv[i+1]);
3936 #else
3937 fname = expand_filename(argv[i+1]);
3938 #endif
3939 *using_default_torrc = 0;
3940 ++i;
3941 } else if (!strcmp(argv[i],"--ignore-missing-torrc")) {
3942 *ignore_missing_torrc = 1;
3946 if (*using_default_torrc) {
3947 /* didn't find one, try CONFDIR */
3948 const char *dflt = get_default_conf_file();
3949 if (dflt && file_status(dflt) == FN_FILE) {
3950 fname = tor_strdup(dflt);
3951 } else {
3952 #ifndef MS_WINDOWS
3953 char *fn;
3954 fn = expand_filename("~/.torrc");
3955 if (fn && file_status(fn) == FN_FILE) {
3956 fname = fn;
3957 } else {
3958 tor_free(fn);
3959 fname = tor_strdup(dflt);
3961 #else
3962 fname = tor_strdup(dflt);
3963 #endif
3966 return fname;
3969 /** Load torrc from disk, setting torrc_fname if successful */
3970 static char *
3971 load_torrc_from_disk(int argc, char **argv)
3973 char *fname=NULL;
3974 char *cf = NULL;
3975 int using_default_torrc = 1;
3976 int ignore_missing_torrc = 0;
3978 fname = find_torrc_filename(argc, argv,
3979 &using_default_torrc, &ignore_missing_torrc);
3980 tor_assert(fname);
3981 log(LOG_DEBUG, LD_CONFIG, "Opening config file \"%s\"", fname);
3983 tor_free(torrc_fname);
3984 torrc_fname = fname;
3986 /* Open config file */
3987 if (file_status(fname) != FN_FILE ||
3988 !(cf = read_file_to_str(fname,0,NULL))) {
3989 if (using_default_torrc == 1 || ignore_missing_torrc ) {
3990 log(LOG_NOTICE, LD_CONFIG, "Configuration file \"%s\" not present, "
3991 "using reasonable defaults.", fname);
3992 tor_free(fname); /* sets fname to NULL */
3993 torrc_fname = NULL;
3994 cf = tor_strdup("");
3995 } else {
3996 log(LOG_WARN, LD_CONFIG,
3997 "Unable to open configuration file \"%s\".", fname);
3998 goto err;
4002 return cf;
4003 err:
4004 tor_free(fname);
4005 torrc_fname = NULL;
4006 return NULL;
4009 /** Read a configuration file into <b>options</b>, finding the configuration
4010 * file location based on the command line. After loading the file
4011 * call options_init_from_string() to load the config.
4012 * Return 0 if success, -1 if failure. */
4014 options_init_from_torrc(int argc, char **argv)
4016 char *cf=NULL;
4017 int i, retval, command;
4018 static char **backup_argv;
4019 static int backup_argc;
4020 char *command_arg = NULL;
4021 char *errmsg=NULL;
4023 if (argv) { /* first time we're called. save command line args */
4024 backup_argv = argv;
4025 backup_argc = argc;
4026 } else { /* we're reloading. need to clean up old options first. */
4027 argv = backup_argv;
4028 argc = backup_argc;
4030 if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
4031 print_usage();
4032 exit(0);
4034 if (argc > 1 && !strcmp(argv[1], "--list-torrc-options")) {
4035 /* For documenting validating whether we've documented everything. */
4036 list_torrc_options();
4037 exit(0);
4040 if (argc > 1 && (!strcmp(argv[1],"--version"))) {
4041 printf("Tor version %s.\n",get_version());
4042 exit(0);
4044 if (argc > 1 && (!strcmp(argv[1],"--digests"))) {
4045 printf("Tor version %s.\n",get_version());
4046 printf("%s", libor_get_digests());
4047 printf("%s", tor_get_digests());
4048 exit(0);
4051 /* Go through command-line variables */
4052 if (!global_cmdline_options) {
4053 /* Or we could redo the list every time we pass this place.
4054 * It does not really matter */
4055 if (config_get_commandlines(argc, argv, &global_cmdline_options) < 0) {
4056 goto err;
4060 command = CMD_RUN_TOR;
4061 for (i = 1; i < argc; ++i) {
4062 if (!strcmp(argv[i],"--list-fingerprint")) {
4063 command = CMD_LIST_FINGERPRINT;
4064 } else if (!strcmp(argv[i],"--hash-password")) {
4065 command = CMD_HASH_PASSWORD;
4066 command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : "");
4067 ++i;
4068 } else if (!strcmp(argv[i],"--verify-config")) {
4069 command = CMD_VERIFY_CONFIG;
4073 if (command == CMD_HASH_PASSWORD) {
4074 cf = tor_strdup("");
4075 } else {
4076 cf = load_torrc_from_disk(argc, argv);
4077 if (!cf)
4078 goto err;
4081 retval = options_init_from_string(cf, command, command_arg, &errmsg);
4082 tor_free(cf);
4083 if (retval < 0)
4084 goto err;
4086 return 0;
4088 err:
4089 if (errmsg) {
4090 log(LOG_WARN,LD_CONFIG,"%s", errmsg);
4091 tor_free(errmsg);
4093 return -1;
4096 /** Load the options from the configuration in <b>cf</b>, validate
4097 * them for consistency and take actions based on them.
4099 * Return 0 if success, negative on error:
4100 * * -1 for general errors.
4101 * * -2 for failure to parse/validate,
4102 * * -3 for transition not allowed
4103 * * -4 for error while setting the new options
4105 setopt_err_t
4106 options_init_from_string(const char *cf,
4107 int command, const char *command_arg,
4108 char **msg)
4110 or_options_t *oldoptions, *newoptions;
4111 config_line_t *cl;
4112 int retval;
4113 setopt_err_t err = SETOPT_ERR_MISC;
4114 tor_assert(msg);
4116 oldoptions = global_options; /* get_options unfortunately asserts if
4117 this is the first time we run*/
4119 newoptions = tor_malloc_zero(sizeof(or_options_t));
4120 newoptions->_magic = OR_OPTIONS_MAGIC;
4121 options_init(newoptions);
4122 newoptions->command = command;
4123 newoptions->command_arg = command_arg;
4125 /* get config lines, assign them */
4126 retval = config_get_lines(cf, &cl);
4127 if (retval < 0) {
4128 err = SETOPT_ERR_PARSE;
4129 goto err;
4131 retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
4132 config_free_lines(cl);
4133 if (retval < 0) {
4134 err = SETOPT_ERR_PARSE;
4135 goto err;
4138 /* Go through command-line variables too */
4139 retval = config_assign(&options_format, newoptions,
4140 global_cmdline_options, 0, 0, msg);
4141 if (retval < 0) {
4142 err = SETOPT_ERR_PARSE;
4143 goto err;
4146 /* If this is a testing network configuration, change defaults
4147 * for a list of dependent config options, re-initialize newoptions
4148 * with the new defaults, and assign all options to it second time. */
4149 if (newoptions->TestingTorNetwork) {
4150 /* XXXX this is a bit of a kludge. perhaps there's a better way to do
4151 * this? We could, for example, make the parsing algorithm do two passes
4152 * over the configuration. If it finds any "suite" options like
4153 * TestingTorNetwork, it could change the defaults before its second pass.
4154 * Not urgent so long as this seems to work, but at any sign of trouble,
4155 * let's clean it up. -NM */
4157 /* Change defaults. */
4158 int i;
4159 for (i = 0; testing_tor_network_defaults[i].name; ++i) {
4160 config_var_t *new_var = &testing_tor_network_defaults[i];
4161 config_var_t *old_var =
4162 config_find_option(&options_format, new_var->name);
4163 tor_assert(new_var);
4164 tor_assert(old_var);
4165 old_var->initvalue = new_var->initvalue;
4168 /* Clear newoptions and re-initialize them with new defaults. */
4169 config_free(&options_format, newoptions);
4170 newoptions = tor_malloc_zero(sizeof(or_options_t));
4171 newoptions->_magic = OR_OPTIONS_MAGIC;
4172 options_init(newoptions);
4173 newoptions->command = command;
4174 newoptions->command_arg = command_arg;
4176 /* Assign all options a second time. */
4177 retval = config_get_lines(cf, &cl);
4178 if (retval < 0) {
4179 err = SETOPT_ERR_PARSE;
4180 goto err;
4182 retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
4183 config_free_lines(cl);
4184 if (retval < 0) {
4185 err = SETOPT_ERR_PARSE;
4186 goto err;
4188 retval = config_assign(&options_format, newoptions,
4189 global_cmdline_options, 0, 0, msg);
4190 if (retval < 0) {
4191 err = SETOPT_ERR_PARSE;
4192 goto err;
4196 /* Validate newoptions */
4197 if (options_validate(oldoptions, newoptions, 0, msg) < 0) {
4198 err = SETOPT_ERR_PARSE; /*XXX make this a separate return value.*/
4199 goto err;
4202 if (options_transition_allowed(oldoptions, newoptions, msg) < 0) {
4203 err = SETOPT_ERR_TRANSITION;
4204 goto err;
4207 if (set_options(newoptions, msg)) {
4208 err = SETOPT_ERR_SETTING;
4209 goto err; /* frees and replaces old options */
4212 return SETOPT_OK;
4214 err:
4215 config_free(&options_format, newoptions);
4216 if (*msg) {
4217 int len = strlen(*msg)+256;
4218 char *newmsg = tor_malloc(len);
4220 tor_snprintf(newmsg, len, "Failed to parse/validate config: %s", *msg);
4221 tor_free(*msg);
4222 *msg = newmsg;
4224 return err;
4227 /** Return the location for our configuration file.
4229 const char *
4230 get_torrc_fname(void)
4232 if (torrc_fname)
4233 return torrc_fname;
4234 else
4235 return get_default_conf_file();
4238 /** Adjust the address map based on the MapAddress elements in the
4239 * configuration <b>options</b>
4241 static void
4242 config_register_addressmaps(or_options_t *options)
4244 smartlist_t *elts;
4245 config_line_t *opt;
4246 char *from, *to;
4248 addressmap_clear_configured();
4249 elts = smartlist_create();
4250 for (opt = options->AddressMap; opt; opt = opt->next) {
4251 smartlist_split_string(elts, opt->value, NULL,
4252 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
4253 if (smartlist_len(elts) >= 2) {
4254 from = smartlist_get(elts,0);
4255 to = smartlist_get(elts,1);
4256 if (address_is_invalid_destination(to, 1)) {
4257 log_warn(LD_CONFIG,
4258 "Skipping invalid argument '%s' to MapAddress", to);
4259 } else {
4260 addressmap_register(from, tor_strdup(to), 0, ADDRMAPSRC_TORRC);
4261 if (smartlist_len(elts)>2) {
4262 log_warn(LD_CONFIG,"Ignoring extra arguments to MapAddress.");
4265 } else {
4266 log_warn(LD_CONFIG,"MapAddress '%s' has too few arguments. Ignoring.",
4267 opt->value);
4269 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
4270 smartlist_clear(elts);
4272 smartlist_free(elts);
4276 * Initialize the logs based on the configuration file.
4278 static int
4279 options_init_logs(or_options_t *options, int validate_only)
4281 config_line_t *opt;
4282 int ok;
4283 smartlist_t *elts;
4284 int daemon =
4285 #ifdef MS_WINDOWS
4287 #else
4288 options->RunAsDaemon;
4289 #endif
4291 ok = 1;
4292 elts = smartlist_create();
4294 for (opt = options->Logs; opt; opt = opt->next) {
4295 log_severity_list_t *severity;
4296 const char *cfg = opt->value;
4297 severity = tor_malloc_zero(sizeof(log_severity_list_t));
4298 if (parse_log_severity_config(&cfg, severity) < 0) {
4299 log_warn(LD_CONFIG, "Couldn't parse log levels in Log option 'Log %s'",
4300 opt->value);
4301 ok = 0; goto cleanup;
4304 smartlist_split_string(elts, cfg, NULL,
4305 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
4307 if (smartlist_len(elts) == 0)
4308 smartlist_add(elts, tor_strdup("stdout"));
4310 if (smartlist_len(elts) == 1 &&
4311 (!strcasecmp(smartlist_get(elts,0), "stdout") ||
4312 !strcasecmp(smartlist_get(elts,0), "stderr"))) {
4313 int err = smartlist_len(elts) &&
4314 !strcasecmp(smartlist_get(elts,0), "stderr");
4315 if (!validate_only) {
4316 if (daemon) {
4317 log_warn(LD_CONFIG,
4318 "Can't log to %s with RunAsDaemon set; skipping stdout",
4319 err?"stderr":"stdout");
4320 } else {
4321 add_stream_log(severity, err?"<stderr>":"<stdout>",
4322 fileno(err?stderr:stdout));
4325 goto cleanup;
4327 if (smartlist_len(elts) == 1 &&
4328 !strcasecmp(smartlist_get(elts,0), "syslog")) {
4329 #ifdef HAVE_SYSLOG_H
4330 if (!validate_only) {
4331 add_syslog_log(severity);
4333 #else
4334 log_warn(LD_CONFIG, "Syslog is not supported on this system. Sorry.");
4335 #endif
4336 goto cleanup;
4339 if (smartlist_len(elts) == 2 &&
4340 !strcasecmp(smartlist_get(elts,0), "file")) {
4341 if (!validate_only) {
4342 if (add_file_log(severity, smartlist_get(elts, 1)) < 0) {
4343 log_warn(LD_CONFIG, "Couldn't open file for 'Log %s': %s",
4344 opt->value, strerror(errno));
4345 ok = 0;
4348 goto cleanup;
4351 log_warn(LD_CONFIG, "Bad syntax on file Log option 'Log %s'",
4352 opt->value);
4353 ok = 0; goto cleanup;
4355 cleanup:
4356 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
4357 smartlist_clear(elts);
4358 tor_free(severity);
4360 smartlist_free(elts);
4362 return ok?0:-1;
4365 /** Read the contents of a Bridge line from <b>line</b>. Return 0
4366 * if the line is well-formed, and -1 if it isn't. If
4367 * <b>validate_only</b> is 0, and the line is well-formed, then add
4368 * the bridge described in the line to our internal bridge list. */
4369 static int
4370 parse_bridge_line(const char *line, int validate_only)
4372 smartlist_t *items = NULL;
4373 int r;
4374 char *addrport=NULL, *fingerprint=NULL;
4375 tor_addr_t addr;
4376 uint16_t port = 0;
4377 char digest[DIGEST_LEN];
4379 items = smartlist_create();
4380 smartlist_split_string(items, line, NULL,
4381 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
4382 if (smartlist_len(items) < 1) {
4383 log_warn(LD_CONFIG, "Too few arguments to Bridge line.");
4384 goto err;
4386 addrport = smartlist_get(items, 0);
4387 smartlist_del_keeporder(items, 0);
4388 if (tor_addr_port_parse(addrport, &addr, &port)<0) {
4389 log_warn(LD_CONFIG, "Error parsing Bridge address '%s'", addrport);
4390 goto err;
4392 if (!port) {
4393 log_info(LD_CONFIG,
4394 "Bridge address '%s' has no port; using default port 443.",
4395 addrport);
4396 port = 443;
4399 if (smartlist_len(items)) {
4400 fingerprint = smartlist_join_strings(items, "", 0, NULL);
4401 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
4402 log_warn(LD_CONFIG, "Key digest for Bridge is wrong length.");
4403 goto err;
4405 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
4406 log_warn(LD_CONFIG, "Unable to decode Bridge key digest.");
4407 goto err;
4411 if (!validate_only) {
4412 log_debug(LD_DIR, "Bridge at %s:%d (%s)", fmt_addr(&addr),
4413 (int)port,
4414 fingerprint ? fingerprint : "no key listed");
4415 bridge_add_from_config(&addr, port, fingerprint ? digest : NULL);
4418 r = 0;
4419 goto done;
4421 err:
4422 r = -1;
4424 done:
4425 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
4426 smartlist_free(items);
4427 tor_free(addrport);
4428 tor_free(fingerprint);
4429 return r;
4432 /** Read the contents of a DirServer line from <b>line</b>. If
4433 * <b>validate_only</b> is 0, and the line is well-formed, and it
4434 * shares any bits with <b>required_type</b> or <b>required_type</b>
4435 * is 0, then add the dirserver described in the line (minus whatever
4436 * bits it's missing) as a valid authority. Return 0 on success,
4437 * or -1 if the line isn't well-formed or if we can't add it. */
4438 static int
4439 parse_dir_server_line(const char *line, authority_type_t required_type,
4440 int validate_only)
4442 smartlist_t *items = NULL;
4443 int r;
4444 char *addrport=NULL, *address=NULL, *nickname=NULL, *fingerprint=NULL;
4445 uint16_t dir_port = 0, or_port = 0;
4446 char digest[DIGEST_LEN];
4447 char v3_digest[DIGEST_LEN];
4448 authority_type_t type = V2_AUTHORITY;
4449 int is_not_hidserv_authority = 0, is_not_v2_authority = 0;
4451 items = smartlist_create();
4452 smartlist_split_string(items, line, NULL,
4453 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
4454 if (smartlist_len(items) < 1) {
4455 log_warn(LD_CONFIG, "No arguments on DirServer line.");
4456 goto err;
4459 if (is_legal_nickname(smartlist_get(items, 0))) {
4460 nickname = smartlist_get(items, 0);
4461 smartlist_del_keeporder(items, 0);
4464 while (smartlist_len(items)) {
4465 char *flag = smartlist_get(items, 0);
4466 if (TOR_ISDIGIT(flag[0]))
4467 break;
4468 if (!strcasecmp(flag, "v1")) {
4469 type |= (V1_AUTHORITY | HIDSERV_AUTHORITY);
4470 } else if (!strcasecmp(flag, "hs")) {
4471 type |= HIDSERV_AUTHORITY;
4472 } else if (!strcasecmp(flag, "no-hs")) {
4473 is_not_hidserv_authority = 1;
4474 } else if (!strcasecmp(flag, "bridge")) {
4475 type |= BRIDGE_AUTHORITY;
4476 } else if (!strcasecmp(flag, "no-v2")) {
4477 is_not_v2_authority = 1;
4478 } else if (!strcasecmpstart(flag, "orport=")) {
4479 int ok;
4480 char *portstring = flag + strlen("orport=");
4481 or_port = (uint16_t) tor_parse_long(portstring, 10, 1, 65535, &ok, NULL);
4482 if (!ok)
4483 log_warn(LD_CONFIG, "Invalid orport '%s' on DirServer line.",
4484 portstring);
4485 } else if (!strcasecmpstart(flag, "v3ident=")) {
4486 char *idstr = flag + strlen("v3ident=");
4487 if (strlen(idstr) != HEX_DIGEST_LEN ||
4488 base16_decode(v3_digest, DIGEST_LEN, idstr, HEX_DIGEST_LEN)<0) {
4489 log_warn(LD_CONFIG, "Bad v3 identity digest '%s' on DirServer line",
4490 flag);
4491 } else {
4492 type |= V3_AUTHORITY;
4494 } else {
4495 log_warn(LD_CONFIG, "Unrecognized flag '%s' on DirServer line",
4496 flag);
4498 tor_free(flag);
4499 smartlist_del_keeporder(items, 0);
4501 if (is_not_hidserv_authority)
4502 type &= ~HIDSERV_AUTHORITY;
4503 if (is_not_v2_authority)
4504 type &= ~V2_AUTHORITY;
4506 if (smartlist_len(items) < 2) {
4507 log_warn(LD_CONFIG, "Too few arguments to DirServer line.");
4508 goto err;
4510 addrport = smartlist_get(items, 0);
4511 smartlist_del_keeporder(items, 0);
4512 if (parse_addr_port(LOG_WARN, addrport, &address, NULL, &dir_port)<0) {
4513 log_warn(LD_CONFIG, "Error parsing DirServer address '%s'", addrport);
4514 goto err;
4516 if (!dir_port) {
4517 log_warn(LD_CONFIG, "Missing port in DirServer address '%s'",addrport);
4518 goto err;
4521 fingerprint = smartlist_join_strings(items, "", 0, NULL);
4522 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
4523 log_warn(LD_CONFIG, "Key digest for DirServer is wrong length %d.",
4524 (int)strlen(fingerprint));
4525 goto err;
4527 if (!strcmp(fingerprint, "E623F7625FBE0C87820F11EC5F6D5377ED816294")) {
4528 /* a known bad fingerprint. refuse to use it. We can remove this
4529 * clause once Tor 0.1.2.17 is obsolete. */
4530 log_warn(LD_CONFIG, "Dangerous dirserver line. To correct, erase your "
4531 "torrc file (%s), or reinstall Tor and use the default torrc.",
4532 get_torrc_fname());
4533 goto err;
4535 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
4536 log_warn(LD_CONFIG, "Unable to decode DirServer key digest.");
4537 goto err;
4540 if (!validate_only && (!required_type || required_type & type)) {
4541 if (required_type)
4542 type &= required_type; /* pare down what we think of them as an
4543 * authority for. */
4544 log_debug(LD_DIR, "Trusted %d dirserver at %s:%d (%s)", (int)type,
4545 address, (int)dir_port, (char*)smartlist_get(items,0));
4546 if (!add_trusted_dir_server(nickname, address, dir_port, or_port,
4547 digest, v3_digest, type))
4548 goto err;
4551 r = 0;
4552 goto done;
4554 err:
4555 r = -1;
4557 done:
4558 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
4559 smartlist_free(items);
4560 tor_free(addrport);
4561 tor_free(address);
4562 tor_free(nickname);
4563 tor_free(fingerprint);
4564 return r;
4567 /** Adjust the value of options->DataDirectory, or fill it in if it's
4568 * absent. Return 0 on success, -1 on failure. */
4569 static int
4570 normalize_data_directory(or_options_t *options)
4572 #ifdef MS_WINDOWS
4573 char *p;
4574 if (options->DataDirectory)
4575 return 0; /* all set */
4576 p = tor_malloc(MAX_PATH);
4577 strlcpy(p,get_windows_conf_root(),MAX_PATH);
4578 options->DataDirectory = p;
4579 return 0;
4580 #else
4581 const char *d = options->DataDirectory;
4582 if (!d)
4583 d = "~/.tor";
4585 if (strncmp(d,"~/",2) == 0) {
4586 char *fn = expand_filename(d);
4587 if (!fn) {
4588 log_warn(LD_CONFIG,"Failed to expand filename \"%s\".", d);
4589 return -1;
4591 if (!options->DataDirectory && !strcmp(fn,"/.tor")) {
4592 /* If our homedir is /, we probably don't want to use it. */
4593 /* Default to LOCALSTATEDIR/tor which is probably closer to what we
4594 * want. */
4595 log_warn(LD_CONFIG,
4596 "Default DataDirectory is \"~/.tor\". This expands to "
4597 "\"%s\", which is probably not what you want. Using "
4598 "\"%s"PATH_SEPARATOR"tor\" instead", fn, LOCALSTATEDIR);
4599 tor_free(fn);
4600 fn = tor_strdup(LOCALSTATEDIR PATH_SEPARATOR "tor");
4602 tor_free(options->DataDirectory);
4603 options->DataDirectory = fn;
4605 return 0;
4606 #endif
4609 /** Check and normalize the value of options->DataDirectory; return 0 if it
4610 * sane, -1 otherwise. */
4611 static int
4612 validate_data_directory(or_options_t *options)
4614 if (normalize_data_directory(options) < 0)
4615 return -1;
4616 tor_assert(options->DataDirectory);
4617 if (strlen(options->DataDirectory) > (512-128)) {
4618 log_warn(LD_CONFIG, "DataDirectory is too long.");
4619 return -1;
4621 return 0;
4624 /** This string must remain the same forevermore. It is how we
4625 * recognize that the torrc file doesn't need to be backed up. */
4626 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; " \
4627 "if you edit it, comments will not be preserved"
4628 /** This string can change; it tries to give the reader an idea
4629 * that editing this file by hand is not a good plan. */
4630 #define GENERATED_FILE_COMMENT "# The old torrc file was renamed " \
4631 "to torrc.orig.1 or similar, and Tor will ignore it"
4633 /** Save a configuration file for the configuration in <b>options</b>
4634 * into the file <b>fname</b>. If the file already exists, and
4635 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
4636 * replace it. Return 0 on success, -1 on failure. */
4637 static int
4638 write_configuration_file(const char *fname, or_options_t *options)
4640 char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
4641 int rename_old = 0, r;
4642 size_t len;
4644 tor_assert(fname);
4646 switch (file_status(fname)) {
4647 case FN_FILE:
4648 old_val = read_file_to_str(fname, 0, NULL);
4649 if (strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
4650 rename_old = 1;
4652 tor_free(old_val);
4653 break;
4654 case FN_NOENT:
4655 break;
4656 case FN_ERROR:
4657 case FN_DIR:
4658 default:
4659 log_warn(LD_CONFIG,
4660 "Config file \"%s\" is not a file? Failing.", fname);
4661 return -1;
4664 if (!(new_conf = options_dump(options, 1))) {
4665 log_warn(LD_BUG, "Couldn't get configuration string");
4666 goto err;
4669 len = strlen(new_conf)+256;
4670 new_val = tor_malloc(len);
4671 tor_snprintf(new_val, len, "%s\n%s\n\n%s",
4672 GENERATED_FILE_PREFIX, GENERATED_FILE_COMMENT, new_conf);
4674 if (rename_old) {
4675 int i = 1;
4676 size_t fn_tmp_len = strlen(fname)+32;
4677 char *fn_tmp;
4678 tor_assert(fn_tmp_len > strlen(fname)); /*check for overflow*/
4679 fn_tmp = tor_malloc(fn_tmp_len);
4680 while (1) {
4681 if (tor_snprintf(fn_tmp, fn_tmp_len, "%s.orig.%d", fname, i)<0) {
4682 log_warn(LD_BUG, "tor_snprintf failed inexplicably");
4683 tor_free(fn_tmp);
4684 goto err;
4686 if (file_status(fn_tmp) == FN_NOENT)
4687 break;
4688 ++i;
4690 log_notice(LD_CONFIG, "Renaming old configuration file to \"%s\"", fn_tmp);
4691 if (rename(fname, fn_tmp) < 0) {
4692 log_warn(LD_FS,
4693 "Couldn't rename configuration file \"%s\" to \"%s\": %s",
4694 fname, fn_tmp, strerror(errno));
4695 tor_free(fn_tmp);
4696 goto err;
4698 tor_free(fn_tmp);
4701 if (write_str_to_file(fname, new_val, 0) < 0)
4702 goto err;
4704 r = 0;
4705 goto done;
4706 err:
4707 r = -1;
4708 done:
4709 tor_free(new_val);
4710 tor_free(new_conf);
4711 return r;
4715 * Save the current configuration file value to disk. Return 0 on
4716 * success, -1 on failure.
4719 options_save_current(void)
4721 if (torrc_fname) {
4722 /* This fails if we can't write to our configuration file.
4724 * If we try falling back to datadirectory or something, we have a better
4725 * chance of saving the configuration, but a better chance of doing
4726 * something the user never expected. Let's just warn instead. */
4727 return write_configuration_file(torrc_fname, get_options());
4729 return write_configuration_file(get_default_conf_file(), get_options());
4732 /** Mapping from a unit name to a multiplier for converting that unit into a
4733 * base unit. */
4734 struct unit_table_t {
4735 const char *unit;
4736 uint64_t multiplier;
4739 /** Table to map the names of memory units to the number of bytes they
4740 * contain. */
4741 static struct unit_table_t memory_units[] = {
4742 { "", 1 },
4743 { "b", 1<< 0 },
4744 { "byte", 1<< 0 },
4745 { "bytes", 1<< 0 },
4746 { "kb", 1<<10 },
4747 { "kbyte", 1<<10 },
4748 { "kbytes", 1<<10 },
4749 { "kilobyte", 1<<10 },
4750 { "kilobytes", 1<<10 },
4751 { "m", 1<<20 },
4752 { "mb", 1<<20 },
4753 { "mbyte", 1<<20 },
4754 { "mbytes", 1<<20 },
4755 { "megabyte", 1<<20 },
4756 { "megabytes", 1<<20 },
4757 { "gb", 1<<30 },
4758 { "gbyte", 1<<30 },
4759 { "gbytes", 1<<30 },
4760 { "gigabyte", 1<<30 },
4761 { "gigabytes", 1<<30 },
4762 { "tb", U64_LITERAL(1)<<40 },
4763 { "terabyte", U64_LITERAL(1)<<40 },
4764 { "terabytes", U64_LITERAL(1)<<40 },
4765 { NULL, 0 },
4768 /** Table to map the names of time units to the number of seconds they
4769 * contain. */
4770 static struct unit_table_t time_units[] = {
4771 { "", 1 },
4772 { "second", 1 },
4773 { "seconds", 1 },
4774 { "minute", 60 },
4775 { "minutes", 60 },
4776 { "hour", 60*60 },
4777 { "hours", 60*60 },
4778 { "day", 24*60*60 },
4779 { "days", 24*60*60 },
4780 { "week", 7*24*60*60 },
4781 { "weeks", 7*24*60*60 },
4782 { NULL, 0 },
4785 /** Parse a string <b>val</b> containing a number, zero or more
4786 * spaces, and an optional unit string. If the unit appears in the
4787 * table <b>u</b>, then multiply the number by the unit multiplier.
4788 * On success, set *<b>ok</b> to 1 and return this product.
4789 * Otherwise, set *<b>ok</b> to 0.
4791 static uint64_t
4792 config_parse_units(const char *val, struct unit_table_t *u, int *ok)
4794 uint64_t v;
4795 char *cp;
4797 tor_assert(ok);
4799 v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
4800 if (!*ok)
4801 return 0;
4802 if (!cp) {
4803 *ok = 1;
4804 return v;
4806 while (TOR_ISSPACE(*cp))
4807 ++cp;
4808 for ( ;u->unit;++u) {
4809 if (!strcasecmp(u->unit, cp)) {
4810 v *= u->multiplier;
4811 *ok = 1;
4812 return v;
4815 log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
4816 *ok = 0;
4817 return 0;
4820 /** Parse a string in the format "number unit", where unit is a unit of
4821 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
4822 * and return the number of bytes specified. Otherwise, set
4823 * *<b>ok</b> to false and return 0. */
4824 static uint64_t
4825 config_parse_memunit(const char *s, int *ok)
4827 return config_parse_units(s, memory_units, ok);
4830 /** Parse a string in the format "number unit", where unit is a unit of time.
4831 * On success, set *<b>ok</b> to true and return the number of seconds in
4832 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
4834 static int
4835 config_parse_interval(const char *s, int *ok)
4837 uint64_t r;
4838 r = config_parse_units(s, time_units, ok);
4839 if (!ok)
4840 return -1;
4841 if (r > INT_MAX) {
4842 log_warn(LD_CONFIG, "Interval '%s' is too long", s);
4843 *ok = 0;
4844 return -1;
4846 return (int)r;
4850 * Initialize the libevent library.
4852 static void
4853 init_libevent(void)
4855 const char *badness=NULL;
4857 configure_libevent_logging();
4858 /* If the kernel complains that some method (say, epoll) doesn't
4859 * exist, we don't care about it, since libevent will cope.
4861 suppress_libevent_log_msg("Function not implemented");
4863 tor_check_libevent_header_compatibility();
4865 tor_libevent_initialize();
4867 suppress_libevent_log_msg(NULL);
4869 tor_check_libevent_version(tor_libevent_get_method(),
4870 get_options()->ORPort != 0,
4871 &badness);
4872 if (badness) {
4873 const char *v = tor_libevent_get_version_str();
4874 const char *m = tor_libevent_get_method();
4875 control_event_general_status(LOG_WARN,
4876 "BAD_LIBEVENT VERSION=%s METHOD=%s BADNESS=%s RECOVERED=NO",
4877 v, m, badness);
4881 /** Return the persistent state struct for this Tor. */
4882 or_state_t *
4883 get_or_state(void)
4885 tor_assert(global_state);
4886 return global_state;
4889 /** Return a newly allocated string holding a filename relative to the data
4890 * directory. If <b>sub1</b> is present, it is the first path component after
4891 * the data directory. If <b>sub2</b> is also present, it is the second path
4892 * component after the data directory. If <b>suffix</b> is present, it
4893 * is appended to the filename.
4895 * Examples:
4896 * get_datadir_fname2_suffix("a", NULL, NULL) -> $DATADIR/a
4897 * get_datadir_fname2_suffix("a", NULL, ".tmp") -> $DATADIR/a.tmp
4898 * get_datadir_fname2_suffix("a", "b", ".tmp") -> $DATADIR/a/b/.tmp
4899 * get_datadir_fname2_suffix("a", "b", NULL) -> $DATADIR/a/b
4901 * Note: Consider using the get_datadir_fname* macros in or.h.
4903 char *
4904 options_get_datadir_fname2_suffix(or_options_t *options,
4905 const char *sub1, const char *sub2,
4906 const char *suffix)
4908 char *fname = NULL;
4909 size_t len;
4910 tor_assert(options);
4911 tor_assert(options->DataDirectory);
4912 tor_assert(sub1 || !sub2); /* If sub2 is present, sub1 must be present. */
4913 len = strlen(options->DataDirectory);
4914 if (sub1) {
4915 len += strlen(sub1)+1;
4916 if (sub2)
4917 len += strlen(sub2)+1;
4919 if (suffix)
4920 len += strlen(suffix);
4921 len++;
4922 fname = tor_malloc(len);
4923 if (sub1) {
4924 if (sub2) {
4925 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s"PATH_SEPARATOR"%s",
4926 options->DataDirectory, sub1, sub2);
4927 } else {
4928 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s",
4929 options->DataDirectory, sub1);
4931 } else {
4932 strlcpy(fname, options->DataDirectory, len);
4934 if (suffix)
4935 strlcat(fname, suffix, len);
4936 return fname;
4939 /** Return 0 if every setting in <b>state</b> is reasonable, and a
4940 * permissible transition from <b>old_state</b>. Else warn and return -1.
4941 * Should have no side effects, except for normalizing the contents of
4942 * <b>state</b>.
4944 /* XXX from_setconf is here because of bug 238 */
4945 static int
4946 or_state_validate(or_state_t *old_state, or_state_t *state,
4947 int from_setconf, char **msg)
4949 /* We don't use these; only options do. Still, we need to match that
4950 * signature. */
4951 (void) from_setconf;
4952 (void) old_state;
4954 if (entry_guards_parse_state(state, 0, msg)<0)
4955 return -1;
4957 return 0;
4960 /** Replace the current persistent state with <b>new_state</b> */
4961 static void
4962 or_state_set(or_state_t *new_state)
4964 char *err = NULL;
4965 tor_assert(new_state);
4966 if (global_state)
4967 config_free(&state_format, global_state);
4968 global_state = new_state;
4969 if (entry_guards_parse_state(global_state, 1, &err)<0) {
4970 log_warn(LD_GENERAL,"%s",err);
4971 tor_free(err);
4973 if (rep_hist_load_state(global_state, &err)<0) {
4974 log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
4975 tor_free(err);
4979 /** Reload the persistent state from disk, generating a new state as needed.
4980 * Return 0 on success, less than 0 on failure.
4982 static int
4983 or_state_load(void)
4985 or_state_t *new_state = NULL;
4986 char *contents = NULL, *fname;
4987 char *errmsg = NULL;
4988 int r = -1, badstate = 0;
4990 fname = get_datadir_fname("state");
4991 switch (file_status(fname)) {
4992 case FN_FILE:
4993 if (!(contents = read_file_to_str(fname, 0, NULL))) {
4994 log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
4995 goto done;
4997 break;
4998 case FN_NOENT:
4999 break;
5000 case FN_ERROR:
5001 case FN_DIR:
5002 default:
5003 log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
5004 goto done;
5006 new_state = tor_malloc_zero(sizeof(or_state_t));
5007 new_state->_magic = OR_STATE_MAGIC;
5008 config_init(&state_format, new_state);
5009 if (contents) {
5010 config_line_t *lines=NULL;
5011 int assign_retval;
5012 if (config_get_lines(contents, &lines)<0)
5013 goto done;
5014 assign_retval = config_assign(&state_format, new_state,
5015 lines, 0, 0, &errmsg);
5016 config_free_lines(lines);
5017 if (assign_retval<0)
5018 badstate = 1;
5019 if (errmsg) {
5020 log_warn(LD_GENERAL, "%s", errmsg);
5021 tor_free(errmsg);
5025 if (!badstate && or_state_validate(NULL, new_state, 1, &errmsg) < 0)
5026 badstate = 1;
5028 if (errmsg) {
5029 log_warn(LD_GENERAL, "%s", errmsg);
5030 tor_free(errmsg);
5033 if (badstate && !contents) {
5034 log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
5035 " This is a bug in Tor.");
5036 goto done;
5037 } else if (badstate && contents) {
5038 int i;
5039 file_status_t status;
5040 size_t len = strlen(fname)+16;
5041 char *fname2 = tor_malloc(len);
5042 for (i = 0; i < 100; ++i) {
5043 tor_snprintf(fname2, len, "%s.%d", fname, i);
5044 status = file_status(fname2);
5045 if (status == FN_NOENT)
5046 break;
5048 if (i == 100) {
5049 log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
5050 "state files to move aside. Discarding the old state file.",
5051 fname);
5052 unlink(fname);
5053 } else {
5054 log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
5055 "to \"%s\". This could be a bug in Tor; please tell "
5056 "the developers.", fname, fname2);
5057 if (rename(fname, fname2) < 0) {
5058 log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
5059 "OS gave an error of %s", strerror(errno));
5062 tor_free(fname2);
5063 tor_free(contents);
5064 config_free(&state_format, new_state);
5066 new_state = tor_malloc_zero(sizeof(or_state_t));
5067 new_state->_magic = OR_STATE_MAGIC;
5068 config_init(&state_format, new_state);
5069 } else if (contents) {
5070 log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
5071 } else {
5072 log_info(LD_GENERAL, "Initialized state");
5074 or_state_set(new_state);
5075 new_state = NULL;
5076 if (!contents) {
5077 global_state->next_write = 0;
5078 or_state_save(time(NULL));
5080 r = 0;
5082 done:
5083 tor_free(fname);
5084 tor_free(contents);
5085 if (new_state)
5086 config_free(&state_format, new_state);
5088 return r;
5091 /** Write the persistent state to disk. Return 0 for success, <0 on failure. */
5093 or_state_save(time_t now)
5095 char *state, *contents;
5096 char tbuf[ISO_TIME_LEN+1];
5097 size_t len;
5098 char *fname;
5100 tor_assert(global_state);
5102 if (global_state->next_write > now)
5103 return 0;
5105 /* Call everything else that might dirty the state even more, in order
5106 * to avoid redundant writes. */
5107 entry_guards_update_state(global_state);
5108 rep_hist_update_state(global_state);
5109 if (accounting_is_enabled(get_options()))
5110 accounting_run_housekeeping(now);
5112 global_state->LastWritten = time(NULL);
5113 tor_free(global_state->TorVersion);
5114 len = strlen(get_version())+8;
5115 global_state->TorVersion = tor_malloc(len);
5116 tor_snprintf(global_state->TorVersion, len, "Tor %s", get_version());
5118 state = config_dump(&state_format, global_state, 1, 0);
5119 len = strlen(state)+256;
5120 contents = tor_malloc(len);
5121 format_local_iso_time(tbuf, time(NULL));
5122 tor_snprintf(contents, len,
5123 "# Tor state file last generated on %s local time\n"
5124 "# Other times below are in GMT\n"
5125 "# You *do not* need to edit this file.\n\n%s",
5126 tbuf, state);
5127 tor_free(state);
5128 fname = get_datadir_fname("state");
5129 if (write_str_to_file(fname, contents, 0)<0) {
5130 log_warn(LD_FS, "Unable to write state to file \"%s\"", fname);
5131 tor_free(fname);
5132 tor_free(contents);
5133 return -1;
5135 log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
5136 tor_free(fname);
5137 tor_free(contents);
5139 global_state->next_write = TIME_MAX;
5140 return 0;
5143 /** Given a file name check to see whether the file exists but has not been
5144 * modified for a very long time. If so, remove it. */
5145 void
5146 remove_file_if_very_old(const char *fname, time_t now)
5148 #define VERY_OLD_FILE_AGE (28*24*60*60)
5149 struct stat st;
5151 if (stat(fname, &st)==0 && st.st_mtime < now-VERY_OLD_FILE_AGE) {
5152 char buf[ISO_TIME_LEN+1];
5153 format_local_iso_time(buf, st.st_mtime);
5154 log_notice(LD_GENERAL, "Obsolete file %s hasn't been modified since %s. "
5155 "Removing it.", fname, buf);
5156 unlink(fname);
5160 /** Helper to implement GETINFO functions about configuration variables (not
5161 * their values). Given a "config/names" question, set *<b>answer</b> to a
5162 * new string describing the supported configuration variables and their
5163 * types. */
5165 getinfo_helper_config(control_connection_t *conn,
5166 const char *question, char **answer)
5168 (void) conn;
5169 if (!strcmp(question, "config/names")) {
5170 smartlist_t *sl = smartlist_create();
5171 int i;
5172 for (i = 0; _option_vars[i].name; ++i) {
5173 config_var_t *var = &_option_vars[i];
5174 const char *type, *desc;
5175 char *line;
5176 size_t len;
5177 desc = config_find_description(&options_format, var->name);
5178 switch (var->type) {
5179 case CONFIG_TYPE_STRING: type = "String"; break;
5180 case CONFIG_TYPE_FILENAME: type = "Filename"; break;
5181 case CONFIG_TYPE_UINT: type = "Integer"; break;
5182 case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
5183 case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
5184 case CONFIG_TYPE_DOUBLE: type = "Float"; break;
5185 case CONFIG_TYPE_BOOL: type = "Boolean"; break;
5186 case CONFIG_TYPE_ISOTIME: type = "Time"; break;
5187 case CONFIG_TYPE_ROUTERSET: type = "RouterList"; break;
5188 case CONFIG_TYPE_CSV: type = "CommaList"; break;
5189 case CONFIG_TYPE_LINELIST: type = "LineList"; break;
5190 case CONFIG_TYPE_LINELIST_S: type = "Dependant"; break;
5191 case CONFIG_TYPE_LINELIST_V: type = "Virtual"; break;
5192 default:
5193 case CONFIG_TYPE_OBSOLETE:
5194 type = NULL; break;
5196 if (!type)
5197 continue;
5198 len = strlen(var->name)+strlen(type)+16;
5199 if (desc)
5200 len += strlen(desc);
5201 line = tor_malloc(len);
5202 if (desc)
5203 tor_snprintf(line, len, "%s %s %s\n",var->name,type,desc);
5204 else
5205 tor_snprintf(line, len, "%s %s\n",var->name,type);
5206 smartlist_add(sl, line);
5208 *answer = smartlist_join_strings(sl, "", 0, NULL);
5209 SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
5210 smartlist_free(sl);
5212 return 0;