Introduce the DynamicPrimes configuration option.
[tor.git] / src / or / config.c
blob4766b24196142a0138e0ac59e08f84c50f637db3
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-2011, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
7 /**
8 * \file config.c
9 * \brief Code to parse and interpret configuration files.
10 **/
12 #define CONFIG_PRIVATE
14 #include "or.h"
15 #include "circuitbuild.h"
16 #include "circuitlist.h"
17 #include "config.h"
18 #include "connection.h"
19 #include "connection_edge.h"
20 #include "connection_or.h"
21 #include "control.h"
22 #include "cpuworker.h"
23 #include "dirserv.h"
24 #include "dirvote.h"
25 #include "dns.h"
26 #include "geoip.h"
27 #include "hibernate.h"
28 #include "main.h"
29 #include "networkstatus.h"
30 #include "policies.h"
31 #include "relay.h"
32 #include "rendclient.h"
33 #include "rendservice.h"
34 #include "rephist.h"
35 #include "router.h"
36 #include "util.h"
37 #include "routerlist.h"
38 #include "transports.h"
39 #ifdef MS_WINDOWS
40 #include <shlobj.h>
41 #endif
43 #include "procmon.h"
45 /* From main.c */
46 extern int quiet_level;
48 /** Enumeration of types which option values can take */
49 typedef enum config_type_t {
50 CONFIG_TYPE_STRING = 0, /**< An arbitrary string. */
51 CONFIG_TYPE_FILENAME, /**< A filename: some prefixes get expanded. */
52 CONFIG_TYPE_UINT, /**< A non-negative integer less than MAX_INT */
53 CONFIG_TYPE_PORT, /**< A port from 1...65535, 0 for "not set", or
54 * "auto". */
55 CONFIG_TYPE_INTERVAL, /**< A number of seconds, with optional units*/
56 CONFIG_TYPE_MSEC_INTERVAL,/**< A number of milliseconds, with optional
57 * units */
58 CONFIG_TYPE_MEMUNIT, /**< A number of bytes, with optional units*/
59 CONFIG_TYPE_DOUBLE, /**< A floating-point value */
60 CONFIG_TYPE_BOOL, /**< A boolean value, expressed as 0 or 1. */
61 CONFIG_TYPE_AUTOBOOL, /**< A boolean+auto value, expressed 0 for false,
62 * 1 for true, and -1 for auto */
63 CONFIG_TYPE_ISOTIME, /**< An ISO-formatted time relative to GMT. */
64 CONFIG_TYPE_CSV, /**< A list of strings, separated by commas and
65 * optional whitespace. */
66 CONFIG_TYPE_LINELIST, /**< Uninterpreted config lines */
67 CONFIG_TYPE_LINELIST_S, /**< Uninterpreted, context-sensitive config lines,
68 * mixed with other keywords. */
69 CONFIG_TYPE_LINELIST_V, /**< Catch-all "virtual" option to summarize
70 * context-sensitive config lines when fetching.
72 CONFIG_TYPE_ROUTERSET, /**< A list of router names, addrs, and fps,
73 * parsed into a routerset_t. */
74 CONFIG_TYPE_OBSOLETE, /**< Obsolete (ignored) option. */
75 } config_type_t;
77 /** An abbreviation for a configuration option allowed on the command line. */
78 typedef struct config_abbrev_t {
79 const char *abbreviated;
80 const char *full;
81 int commandline_only;
82 int warn;
83 } config_abbrev_t;
85 /* Handy macro for declaring "In the config file or on the command line,
86 * you can abbreviate <b>tok</b>s as <b>tok</b>". */
87 #define PLURAL(tok) { #tok, #tok "s", 0, 0 }
89 /** A list of abbreviations and aliases to map command-line options, obsolete
90 * option names, or alternative option names, to their current values. */
91 static config_abbrev_t _option_abbrevs[] = {
92 PLURAL(ExitNode),
93 PLURAL(EntryNode),
94 PLURAL(ExcludeNode),
95 PLURAL(FirewallPort),
96 PLURAL(LongLivedPort),
97 PLURAL(HiddenServiceNode),
98 PLURAL(HiddenServiceExcludeNode),
99 PLURAL(NumCPU),
100 PLURAL(RendNode),
101 PLURAL(RendExcludeNode),
102 PLURAL(StrictEntryNode),
103 PLURAL(StrictExitNode),
104 PLURAL(StrictNode),
105 { "l", "Log", 1, 0},
106 { "AllowUnverifiedNodes", "AllowInvalidNodes", 0, 0},
107 { "AutomapHostSuffixes", "AutomapHostsSuffixes", 0, 0},
108 { "AutomapHostOnResolve", "AutomapHostsOnResolve", 0, 0},
109 { "BandwidthRateBytes", "BandwidthRate", 0, 0},
110 { "BandwidthBurstBytes", "BandwidthBurst", 0, 0},
111 { "DirFetchPostPeriod", "StatusFetchPeriod", 0, 0},
112 { "MaxConn", "ConnLimit", 0, 1},
113 { "ORBindAddress", "ORListenAddress", 0, 0},
114 { "DirBindAddress", "DirListenAddress", 0, 0},
115 { "SocksBindAddress", "SocksListenAddress", 0, 0},
116 { "UseHelperNodes", "UseEntryGuards", 0, 0},
117 { "NumHelperNodes", "NumEntryGuards", 0, 0},
118 { "UseEntryNodes", "UseEntryGuards", 0, 0},
119 { "NumEntryNodes", "NumEntryGuards", 0, 0},
120 { "ResolvConf", "ServerDNSResolvConfFile", 0, 1},
121 { "SearchDomains", "ServerDNSSearchDomains", 0, 1},
122 { "ServerDNSAllowBrokenResolvConf", "ServerDNSAllowBrokenConfig", 0, 0},
123 { "PreferTunnelledDirConns", "PreferTunneledDirConns", 0, 0},
124 { "BridgeAuthoritativeDirectory", "BridgeAuthoritativeDir", 0, 0},
125 { "HashedControlPassword", "__HashedControlSessionPassword", 1, 0},
126 { "StrictEntryNodes", "StrictNodes", 0, 1},
127 { "StrictExitNodes", "StrictNodes", 0, 1},
128 { NULL, NULL, 0, 0},
131 /** A list of state-file "abbreviations," for compatibility. */
132 static config_abbrev_t _state_abbrevs[] = {
133 { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
134 { "HelperNode", "EntryGuard", 0, 0 },
135 { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
136 { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
137 { "EntryNode", "EntryGuard", 0, 0 },
138 { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
139 { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
140 { NULL, NULL, 0, 0},
142 #undef PLURAL
144 /** A variable allowed in the configuration file or on the command line. */
145 typedef struct config_var_t {
146 const char *name; /**< The full keyword (case insensitive). */
147 config_type_t type; /**< How to interpret the type and turn it into a
148 * value. */
149 off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
150 const char *initvalue; /**< String (or null) describing initial value. */
151 } config_var_t;
153 /** An entry for config_vars: "The option <b>name</b> has type
154 * CONFIG_TYPE_<b>conftype</b>, and corresponds to
155 * or_options_t.<b>member</b>"
157 #define VAR(name,conftype,member,initvalue) \
158 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), \
159 initvalue }
160 /** As VAR, but the option name and member name are the same. */
161 #define V(member,conftype,initvalue) \
162 VAR(#member, conftype, member, initvalue)
163 /** An entry for config_vars: "The option <b>name</b> is obsolete." */
164 #define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
166 /** Array of configuration options. Until we disallow nonstandard
167 * abbreviations, order is significant, since the first matching option will
168 * be chosen first.
170 static config_var_t _option_vars[] = {
171 OBSOLETE("AccountingMaxKB"),
172 V(AccountingMax, MEMUNIT, "0 bytes"),
173 V(AccountingStart, STRING, NULL),
174 V(Address, STRING, NULL),
175 V(AllowDotExit, BOOL, "0"),
176 V(AllowInvalidNodes, CSV, "middle,rendezvous"),
177 V(AllowNonRFC953Hostnames, BOOL, "0"),
178 V(AllowSingleHopCircuits, BOOL, "0"),
179 V(AllowSingleHopExits, BOOL, "0"),
180 V(AlternateBridgeAuthority, LINELIST, NULL),
181 V(AlternateDirAuthority, LINELIST, NULL),
182 V(AlternateHSAuthority, LINELIST, NULL),
183 V(AssumeReachable, BOOL, "0"),
184 V(AuthDirBadDir, LINELIST, NULL),
185 V(AuthDirBadExit, LINELIST, NULL),
186 V(AuthDirInvalid, LINELIST, NULL),
187 V(AuthDirFastGuarantee, MEMUNIT, "100 KB"),
188 V(AuthDirGuardBWGuarantee, MEMUNIT, "250 KB"),
189 V(AuthDirReject, LINELIST, NULL),
190 V(AuthDirRejectUnlisted, BOOL, "0"),
191 V(AuthDirListBadDirs, BOOL, "0"),
192 V(AuthDirListBadExits, BOOL, "0"),
193 V(AuthDirMaxServersPerAddr, UINT, "2"),
194 V(AuthDirMaxServersPerAuthAddr,UINT, "5"),
195 VAR("AuthoritativeDirectory", BOOL, AuthoritativeDir, "0"),
196 V(AutomapHostsOnResolve, BOOL, "0"),
197 V(AutomapHostsSuffixes, CSV, ".onion,.exit"),
198 V(AvoidDiskWrites, BOOL, "0"),
199 V(BandwidthBurst, MEMUNIT, "10 MB"),
200 V(BandwidthRate, MEMUNIT, "5 MB"),
201 V(BridgeAuthoritativeDir, BOOL, "0"),
202 VAR("Bridge", LINELIST, Bridges, NULL),
203 V(BridgePassword, STRING, NULL),
204 V(BridgeRecordUsageByCountry, BOOL, "1"),
205 V(BridgeRelay, BOOL, "0"),
206 V(CellStatistics, BOOL, "0"),
207 V(LearnCircuitBuildTimeout, BOOL, "1"),
208 V(CircuitBuildTimeout, INTERVAL, "0"),
209 V(CircuitIdleTimeout, INTERVAL, "1 hour"),
210 V(CircuitStreamTimeout, INTERVAL, "0"),
211 V(CircuitPriorityHalflife, DOUBLE, "-100.0"), /*negative:'Use default'*/
212 V(ClientDNSRejectInternalAddresses, BOOL,"1"),
213 V(ClientOnly, BOOL, "0"),
214 V(ClientRejectInternalAddresses, BOOL, "1"),
215 V(ClientTransportPlugin, LINELIST, NULL),
216 V(ConsensusParams, STRING, NULL),
217 V(ConnLimit, UINT, "1000"),
218 V(ConnDirectionStatistics, BOOL, "0"),
219 V(ConstrainedSockets, BOOL, "0"),
220 V(ConstrainedSockSize, MEMUNIT, "8192"),
221 V(ContactInfo, STRING, NULL),
222 V(ControlListenAddress, LINELIST, NULL),
223 V(ControlPort, PORT, "0"),
224 V(ControlPortFileGroupReadable,BOOL, "0"),
225 V(ControlPortWriteToFile, FILENAME, NULL),
226 V(ControlSocket, LINELIST, NULL),
227 V(ControlSocketsGroupWritable, BOOL, "0"),
228 V(CookieAuthentication, BOOL, "0"),
229 V(CookieAuthFileGroupReadable, BOOL, "0"),
230 V(CookieAuthFile, STRING, NULL),
231 V(CountPrivateBandwidth, BOOL, "0"),
232 V(DataDirectory, FILENAME, NULL),
233 OBSOLETE("DebugLogFile"),
234 V(DirAllowPrivateAddresses, BOOL, NULL),
235 V(TestingAuthDirTimeToLearnReachability, INTERVAL, "30 minutes"),
236 V(DirListenAddress, LINELIST, NULL),
237 OBSOLETE("DirFetchPeriod"),
238 V(DirPolicy, LINELIST, NULL),
239 V(DirPort, PORT, "0"),
240 V(DirPortFrontPage, FILENAME, NULL),
241 OBSOLETE("DirPostPeriod"),
242 OBSOLETE("DirRecordUsageByCountry"),
243 OBSOLETE("DirRecordUsageGranularity"),
244 OBSOLETE("DirRecordUsageRetainIPs"),
245 OBSOLETE("DirRecordUsageSaveInterval"),
246 V(DirReqStatistics, BOOL, "1"),
247 VAR("DirServer", LINELIST, DirServers, NULL),
248 V(DisableAllSwap, BOOL, "0"),
249 V(DisableIOCP, BOOL, "1"),
250 V(DynamicPrimes, BOOL, "1"),
251 V(DNSPort, LINELIST, NULL),
252 V(DNSListenAddress, LINELIST, NULL),
253 V(DownloadExtraInfo, BOOL, "0"),
254 V(EnforceDistinctSubnets, BOOL, "1"),
255 V(EntryNodes, ROUTERSET, NULL),
256 V(EntryStatistics, BOOL, "0"),
257 V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "10 minutes"),
258 V(ExcludeNodes, ROUTERSET, NULL),
259 V(ExcludeExitNodes, ROUTERSET, NULL),
260 V(ExcludeSingleHopRelays, BOOL, "1"),
261 V(ExitNodes, ROUTERSET, NULL),
262 V(ExitPolicy, LINELIST, NULL),
263 V(ExitPolicyRejectPrivate, BOOL, "1"),
264 V(ExitPortStatistics, BOOL, "0"),
265 V(ExtraInfoStatistics, BOOL, "1"),
267 #if defined (WINCE)
268 V(FallbackNetworkstatusFile, FILENAME, "fallback-consensus"),
269 #else
270 V(FallbackNetworkstatusFile, FILENAME,
271 SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "fallback-consensus"),
272 #endif
273 V(FascistFirewall, BOOL, "0"),
274 V(FirewallPorts, CSV, ""),
275 V(FastFirstHopPK, BOOL, "1"),
276 V(FetchDirInfoEarly, BOOL, "0"),
277 V(FetchDirInfoExtraEarly, BOOL, "0"),
278 V(FetchServerDescriptors, BOOL, "1"),
279 V(FetchHidServDescriptors, BOOL, "1"),
280 V(FetchUselessDescriptors, BOOL, "0"),
281 V(FetchV2Networkstatus, BOOL, "0"),
282 #ifdef WIN32
283 V(GeoIPFile, FILENAME, "<default>"),
284 #else
285 V(GeoIPFile, FILENAME,
286 SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "geoip"),
287 #endif
288 V(GiveGuardFlagTo_CVE_2011_2768_VulnerableRelays,
289 BOOL, "0"),
290 OBSOLETE("Group"),
291 V(HardwareAccel, BOOL, "0"),
292 V(HeartbeatPeriod, INTERVAL, "6 hours"),
293 V(AccelName, STRING, NULL),
294 V(AccelDir, FILENAME, NULL),
295 V(HashedControlPassword, LINELIST, NULL),
296 V(HidServDirectoryV2, BOOL, "1"),
297 VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
298 OBSOLETE("HiddenServiceExcludeNodes"),
299 OBSOLETE("HiddenServiceNodes"),
300 VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
301 VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
302 VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines, NULL),
303 VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL),
304 V(HidServAuth, LINELIST, NULL),
305 V(HSAuthoritativeDir, BOOL, "0"),
306 OBSOLETE("HSAuthorityRecordStats"),
307 V(HTTPProxy, STRING, NULL),
308 V(HTTPProxyAuthenticator, STRING, NULL),
309 V(HTTPSProxy, STRING, NULL),
310 V(HTTPSProxyAuthenticator, STRING, NULL),
311 VAR("ServerTransportPlugin", LINELIST, ServerTransportPlugin, NULL),
312 V(Socks4Proxy, STRING, NULL),
313 V(Socks5Proxy, STRING, NULL),
314 V(Socks5ProxyUsername, STRING, NULL),
315 V(Socks5ProxyPassword, STRING, NULL),
316 OBSOLETE("IgnoreVersion"),
317 V(KeepalivePeriod, INTERVAL, "5 minutes"),
318 VAR("Log", LINELIST, Logs, NULL),
319 V(LogMessageDomains, BOOL, "0"),
320 OBSOLETE("LinkPadding"),
321 OBSOLETE("LogLevel"),
322 OBSOLETE("LogFile"),
323 V(LogTimeGranularity, MSEC_INTERVAL, "1 second"),
324 V(LongLivedPorts, CSV,
325 "21,22,706,1863,5050,5190,5222,5223,6523,6667,6697,8300"),
326 VAR("MapAddress", LINELIST, AddressMap, NULL),
327 V(MaxAdvertisedBandwidth, MEMUNIT, "1 GB"),
328 V(MaxCircuitDirtiness, INTERVAL, "10 minutes"),
329 V(MaxClientCircuitsPending, UINT, "32"),
330 V(MaxOnionsPending, UINT, "100"),
331 OBSOLETE("MonthlyAccountingStart"),
332 V(MyFamily, STRING, NULL),
333 V(NewCircuitPeriod, INTERVAL, "30 seconds"),
334 VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "0"),
335 V(NATDListenAddress, LINELIST, NULL),
336 V(NATDPort, LINELIST, NULL),
337 V(Nickname, STRING, NULL),
338 V(WarnUnsafeSocks, BOOL, "1"),
339 OBSOLETE("NoPublish"),
340 VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
341 V(NumCPUs, UINT, "0"),
342 V(NumEntryGuards, UINT, "3"),
343 V(ORListenAddress, LINELIST, NULL),
344 V(ORPort, PORT, "0"),
345 V(OutboundBindAddress, STRING, NULL),
346 OBSOLETE("PathlenCoinWeight"),
347 V(PerConnBWBurst, MEMUNIT, "0"),
348 V(PerConnBWRate, MEMUNIT, "0"),
349 V(PidFile, STRING, NULL),
350 V(TestingTorNetwork, BOOL, "0"),
351 V(OptimisticData, AUTOBOOL, "auto"),
352 V(PortForwarding, BOOL, "0"),
353 V(PortForwardingHelper, FILENAME, "tor-fw-helper"),
354 V(PreferTunneledDirConns, BOOL, "1"),
355 V(ProtocolWarnings, BOOL, "0"),
356 V(PublishServerDescriptor, CSV, "1"),
357 V(PublishHidServDescriptors, BOOL, "1"),
358 V(ReachableAddresses, LINELIST, NULL),
359 V(ReachableDirAddresses, LINELIST, NULL),
360 V(ReachableORAddresses, LINELIST, NULL),
361 V(RecommendedVersions, LINELIST, NULL),
362 V(RecommendedClientVersions, LINELIST, NULL),
363 V(RecommendedServerVersions, LINELIST, NULL),
364 OBSOLETE("RedirectExit"),
365 V(RefuseUnknownExits, AUTOBOOL, "auto"),
366 V(RejectPlaintextPorts, CSV, ""),
367 V(RelayBandwidthBurst, MEMUNIT, "0"),
368 V(RelayBandwidthRate, MEMUNIT, "0"),
369 OBSOLETE("RendExcludeNodes"),
370 OBSOLETE("RendNodes"),
371 V(RendPostPeriod, INTERVAL, "1 hour"),
372 V(RephistTrackTime, INTERVAL, "24 hours"),
373 OBSOLETE("RouterFile"),
374 V(RunAsDaemon, BOOL, "0"),
375 // V(RunTesting, BOOL, "0"),
376 OBSOLETE("RunTesting"), // currently unused
377 V(SafeLogging, STRING, "1"),
378 V(SafeSocks, BOOL, "0"),
379 V(ServerDNSAllowBrokenConfig, BOOL, "1"),
380 V(ServerDNSAllowNonRFC953Hostnames, BOOL,"0"),
381 V(ServerDNSDetectHijacking, BOOL, "1"),
382 V(ServerDNSRandomizeCase, BOOL, "1"),
383 V(ServerDNSResolvConfFile, STRING, NULL),
384 V(ServerDNSSearchDomains, BOOL, "0"),
385 V(ServerDNSTestAddresses, CSV,
386 "www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"),
387 V(ShutdownWaitLength, INTERVAL, "30 seconds"),
388 V(SocksListenAddress, LINELIST, NULL),
389 V(SocksPolicy, LINELIST, NULL),
390 V(SocksPort, LINELIST, NULL),
391 V(SocksTimeout, INTERVAL, "2 minutes"),
392 OBSOLETE("StatusFetchPeriod"),
393 V(StrictNodes, BOOL, "0"),
394 OBSOLETE("SysLog"),
395 V(TestSocks, BOOL, "0"),
396 OBSOLETE("TestVia"),
397 V(TokenBucketRefillInterval, MSEC_INTERVAL, "100 msec"),
398 V(TrackHostExits, CSV, NULL),
399 V(TrackHostExitsExpire, INTERVAL, "30 minutes"),
400 OBSOLETE("TrafficShaping"),
401 V(TransListenAddress, LINELIST, NULL),
402 V(TransPort, LINELIST, NULL),
403 V(TunnelDirConns, BOOL, "1"),
404 V(UpdateBridgesFromAuthority, BOOL, "0"),
405 V(UseBridges, BOOL, "0"),
406 V(UseEntryGuards, BOOL, "1"),
407 V(UseMicrodescriptors, AUTOBOOL, "auto"),
408 V(User, STRING, NULL),
409 VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
410 VAR("V2AuthoritativeDirectory",BOOL, V2AuthoritativeDir, "0"),
411 VAR("V3AuthoritativeDirectory",BOOL, V3AuthoritativeDir, "0"),
412 V(TestingV3AuthInitialVotingInterval, INTERVAL, "30 minutes"),
413 V(TestingV3AuthInitialVoteDelay, INTERVAL, "5 minutes"),
414 V(TestingV3AuthInitialDistDelay, INTERVAL, "5 minutes"),
415 V(V3AuthVotingInterval, INTERVAL, "1 hour"),
416 V(V3AuthVoteDelay, INTERVAL, "5 minutes"),
417 V(V3AuthDistDelay, INTERVAL, "5 minutes"),
418 V(V3AuthNIntervalsValid, UINT, "3"),
419 V(V3AuthUseLegacyKey, BOOL, "0"),
420 V(V3BandwidthsFile, FILENAME, NULL),
421 VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
422 V(VirtualAddrNetwork, STRING, "127.192.0.0/10"),
423 V(WarnPlaintextPorts, CSV, "23,109,110,143"),
424 V(_UseFilteringSSLBufferevents, BOOL, "0"),
425 VAR("__ReloadTorrcOnSIGHUP", BOOL, ReloadTorrcOnSIGHUP, "1"),
426 VAR("__AllDirActionsPrivate", BOOL, AllDirActionsPrivate, "0"),
427 VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits, "0"),
428 VAR("__LeaveStreamsUnattached",BOOL, LeaveStreamsUnattached, "0"),
429 VAR("__HashedControlSessionPassword", LINELIST, HashedControlSessionPassword,
430 NULL),
431 VAR("__OwningControllerProcess",STRING,OwningControllerProcess, NULL),
432 V(MinUptimeHidServDirectoryV2, INTERVAL, "25 hours"),
433 V(VoteOnHidServDirectoriesV2, BOOL, "1"),
434 V(_UsingTestNetworkDefaults, BOOL, "0"),
436 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
439 /** Override default values with these if the user sets the TestingTorNetwork
440 * option. */
441 static const config_var_t testing_tor_network_defaults[] = {
442 V(ServerDNSAllowBrokenConfig, BOOL, "1"),
443 V(DirAllowPrivateAddresses, BOOL, "1"),
444 V(EnforceDistinctSubnets, BOOL, "0"),
445 V(AssumeReachable, BOOL, "1"),
446 V(AuthDirMaxServersPerAddr, UINT, "0"),
447 V(AuthDirMaxServersPerAuthAddr,UINT, "0"),
448 V(ClientDNSRejectInternalAddresses, BOOL,"0"),
449 V(ClientRejectInternalAddresses, BOOL, "0"),
450 V(CountPrivateBandwidth, BOOL, "1"),
451 V(ExitPolicyRejectPrivate, BOOL, "0"),
452 V(V3AuthVotingInterval, INTERVAL, "5 minutes"),
453 V(V3AuthVoteDelay, INTERVAL, "20 seconds"),
454 V(V3AuthDistDelay, INTERVAL, "20 seconds"),
455 V(TestingV3AuthInitialVotingInterval, INTERVAL, "5 minutes"),
456 V(TestingV3AuthInitialVoteDelay, INTERVAL, "20 seconds"),
457 V(TestingV3AuthInitialDistDelay, INTERVAL, "20 seconds"),
458 V(TestingAuthDirTimeToLearnReachability, INTERVAL, "0 minutes"),
459 V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "0 minutes"),
460 V(MinUptimeHidServDirectoryV2, INTERVAL, "0 minutes"),
461 V(_UsingTestNetworkDefaults, BOOL, "1"),
463 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
465 #undef VAR
467 #define VAR(name,conftype,member,initvalue) \
468 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member), \
469 initvalue }
471 /** Array of "state" variables saved to the ~/.tor/state file. */
472 static config_var_t _state_vars[] = {
473 V(AccountingBytesReadInInterval, MEMUNIT, NULL),
474 V(AccountingBytesWrittenInInterval, MEMUNIT, NULL),
475 V(AccountingExpectedUsage, MEMUNIT, NULL),
476 V(AccountingIntervalStart, ISOTIME, NULL),
477 V(AccountingSecondsActive, INTERVAL, NULL),
478 V(AccountingSecondsToReachSoftLimit,INTERVAL, NULL),
479 V(AccountingSoftLimitHitAt, ISOTIME, NULL),
480 V(AccountingBytesAtSoftLimit, MEMUNIT, NULL),
482 VAR("EntryGuard", LINELIST_S, EntryGuards, NULL),
483 VAR("EntryGuardDownSince", LINELIST_S, EntryGuards, NULL),
484 VAR("EntryGuardUnlistedSince", LINELIST_S, EntryGuards, NULL),
485 VAR("EntryGuardAddedBy", LINELIST_S, EntryGuards, NULL),
486 V(EntryGuards, LINELIST_V, NULL),
488 VAR("TransportProxy", LINELIST_S, TransportProxies, NULL),
489 V(TransportProxies, LINELIST_V, NULL),
491 V(BWHistoryReadEnds, ISOTIME, NULL),
492 V(BWHistoryReadInterval, UINT, "900"),
493 V(BWHistoryReadValues, CSV, ""),
494 V(BWHistoryReadMaxima, CSV, ""),
495 V(BWHistoryWriteEnds, ISOTIME, NULL),
496 V(BWHistoryWriteInterval, UINT, "900"),
497 V(BWHistoryWriteValues, CSV, ""),
498 V(BWHistoryWriteMaxima, CSV, ""),
499 V(BWHistoryDirReadEnds, ISOTIME, NULL),
500 V(BWHistoryDirReadInterval, UINT, "900"),
501 V(BWHistoryDirReadValues, CSV, ""),
502 V(BWHistoryDirReadMaxima, CSV, ""),
503 V(BWHistoryDirWriteEnds, ISOTIME, NULL),
504 V(BWHistoryDirWriteInterval, UINT, "900"),
505 V(BWHistoryDirWriteValues, CSV, ""),
506 V(BWHistoryDirWriteMaxima, CSV, ""),
508 V(TorVersion, STRING, NULL),
510 V(LastRotatedOnionKey, ISOTIME, NULL),
511 V(LastWritten, ISOTIME, NULL),
513 V(TotalBuildTimes, UINT, NULL),
514 V(CircuitBuildAbandonedCount, UINT, "0"),
515 VAR("CircuitBuildTimeBin", LINELIST_S, BuildtimeHistogram, NULL),
516 VAR("BuildtimeHistogram", LINELIST_V, BuildtimeHistogram, NULL),
517 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
520 #undef VAR
521 #undef V
522 #undef OBSOLETE
524 /** Represents an English description of a configuration variable; used when
525 * generating configuration file comments. */
526 typedef struct config_var_description_t {
527 const char *name;
528 const char *description;
529 } config_var_description_t;
531 /** Type of a callback to validate whether a given configuration is
532 * well-formed and consistent. See options_trial_assign() for documentation
533 * of arguments. */
534 typedef int (*validate_fn_t)(void*,void*,int,char**);
536 /** Information on the keys, value types, key-to-struct-member mappings,
537 * variable descriptions, validation functions, and abbreviations for a
538 * configuration or storage format. */
539 typedef struct {
540 size_t size; /**< Size of the struct that everything gets parsed into. */
541 uint32_t magic; /**< Required 'magic value' to make sure we have a struct
542 * of the right type. */
543 off_t magic_offset; /**< Offset of the magic value within the struct. */
544 config_abbrev_t *abbrevs; /**< List of abbreviations that we expand when
545 * parsing this format. */
546 config_var_t *vars; /**< List of variables we recognize, their default
547 * values, and where we stick them in the structure. */
548 validate_fn_t validate_fn; /**< Function to validate config. */
549 /** If present, extra is a LINELIST variable for unrecognized
550 * lines. Otherwise, unrecognized lines are an error. */
551 config_var_t *extra;
552 } config_format_t;
554 /** Macro: assert that <b>cfg</b> has the right magic field for format
555 * <b>fmt</b>. */
556 #define CHECK(fmt, cfg) STMT_BEGIN \
557 tor_assert(fmt && cfg); \
558 tor_assert((fmt)->magic == \
559 *(uint32_t*)STRUCT_VAR_P(cfg,fmt->magic_offset)); \
560 STMT_END
562 #ifdef MS_WINDOWS
563 static char *get_windows_conf_root(void);
564 #endif
565 static void config_line_append(config_line_t **lst,
566 const char *key, const char *val);
567 static void option_clear(const config_format_t *fmt, or_options_t *options,
568 const config_var_t *var);
569 static void option_reset(const config_format_t *fmt, or_options_t *options,
570 const config_var_t *var, int use_defaults);
571 static void config_free(const config_format_t *fmt, void *options);
572 static int config_lines_eq(config_line_t *a, config_line_t *b);
573 static int option_is_same(const config_format_t *fmt,
574 const or_options_t *o1, const or_options_t *o2,
575 const char *name);
576 static or_options_t *options_dup(const config_format_t *fmt,
577 const or_options_t *old);
578 static int options_validate(or_options_t *old_options,
579 or_options_t *options,
580 int from_setconf, char **msg);
581 static int options_act_reversible(const or_options_t *old_options, char **msg);
582 static int options_act(const or_options_t *old_options);
583 static int options_transition_allowed(const or_options_t *old,
584 const or_options_t *new,
585 char **msg);
586 static int options_transition_affects_workers(
587 const or_options_t *old_options, const or_options_t *new_options);
588 static int options_transition_affects_descriptor(
589 const or_options_t *old_options, const or_options_t *new_options);
590 static int check_nickname_list(const char *lst, const char *name, char **msg);
592 static int parse_bridge_line(const char *line, int validate_only);
593 static int parse_client_transport_line(const char *line, int validate_only);
595 static int parse_server_transport_line(const char *line, int validate_only);
596 static int parse_dir_server_line(const char *line,
597 dirinfo_type_t required_type,
598 int validate_only);
599 static void port_cfg_free(port_cfg_t *port);
600 static int parse_client_ports(const or_options_t *options, int validate_only,
601 char **msg_out, int *n_ports_out);
602 static int validate_data_directory(or_options_t *options);
603 static int write_configuration_file(const char *fname,
604 const or_options_t *options);
605 static config_line_t *get_assigned_option(const config_format_t *fmt,
606 const void *options, const char *key,
607 int escape_val);
608 static void config_init(const config_format_t *fmt, void *options);
609 static int or_state_validate(or_state_t *old_options, or_state_t *options,
610 int from_setconf, char **msg);
611 static int or_state_load(void);
612 static int options_init_logs(or_options_t *options, int validate_only);
614 static int is_listening_on_low_port(int port_option,
615 const config_line_t *listen_options);
617 static uint64_t config_parse_memunit(const char *s, int *ok);
618 static int config_parse_msec_interval(const char *s, int *ok);
619 static int config_parse_interval(const char *s, int *ok);
620 static void init_libevent(const or_options_t *options);
621 static int opt_streq(const char *s1, const char *s2);
623 /** Magic value for or_options_t. */
624 #define OR_OPTIONS_MAGIC 9090909
626 /** Configuration format for or_options_t. */
627 static config_format_t options_format = {
628 sizeof(or_options_t),
629 OR_OPTIONS_MAGIC,
630 STRUCT_OFFSET(or_options_t, _magic),
631 _option_abbrevs,
632 _option_vars,
633 (validate_fn_t)options_validate,
634 NULL
637 /** Magic value for or_state_t. */
638 #define OR_STATE_MAGIC 0x57A73f57
640 /** "Extra" variable in the state that receives lines we can't parse. This
641 * lets us preserve options from versions of Tor newer than us. */
642 static config_var_t state_extra_var = {
643 "__extra", CONFIG_TYPE_LINELIST, STRUCT_OFFSET(or_state_t, ExtraLines), NULL
646 /** Configuration format for or_state_t. */
647 static const config_format_t state_format = {
648 sizeof(or_state_t),
649 OR_STATE_MAGIC,
650 STRUCT_OFFSET(or_state_t, _magic),
651 _state_abbrevs,
652 _state_vars,
653 (validate_fn_t)or_state_validate,
654 &state_extra_var,
658 * Functions to read and write the global options pointer.
661 /** Command-line and config-file options. */
662 static or_options_t *global_options = NULL;
663 /** Name of most recently read torrc file. */
664 static char *torrc_fname = NULL;
665 /** Persistent serialized state. */
666 static or_state_t *global_state = NULL;
667 /** Configuration Options set by command line. */
668 static config_line_t *global_cmdline_options = NULL;
669 /** Contents of most recently read DirPortFrontPage file. */
670 static char *global_dirfrontpagecontents = NULL;
671 /** List of port_cfg_t for client-level (SOCKS, DNS, Trans, NATD) ports. */
672 static smartlist_t *configured_client_ports = NULL;
674 /** Return the contents of our frontpage string, or NULL if not configured. */
675 const char *
676 get_dirportfrontpage(void)
678 return global_dirfrontpagecontents;
681 /** Allocate an empty configuration object of a given format type. */
682 static void *
683 config_alloc(const config_format_t *fmt)
685 void *opts = tor_malloc_zero(fmt->size);
686 *(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
687 CHECK(fmt, opts);
688 return opts;
691 /** Return the currently configured options. */
692 or_options_t *
693 get_options_mutable(void)
695 tor_assert(global_options);
696 return global_options;
699 /** Returns the currently configured options */
700 const or_options_t *
701 get_options(void)
703 return get_options_mutable();
706 /** Change the current global options to contain <b>new_val</b> instead of
707 * their current value; take action based on the new value; free the old value
708 * as necessary. Returns 0 on success, -1 on failure.
711 set_options(or_options_t *new_val, char **msg)
713 int i;
714 smartlist_t *elements;
715 config_line_t *line;
716 or_options_t *old_options = global_options;
717 global_options = new_val;
718 /* Note that we pass the *old* options below, for comparison. It
719 * pulls the new options directly out of global_options. */
720 if (options_act_reversible(old_options, msg)<0) {
721 tor_assert(*msg);
722 global_options = old_options;
723 return -1;
725 if (options_act(old_options) < 0) { /* acting on the options failed. die. */
726 log_err(LD_BUG,
727 "Acting on config options left us in a broken state. Dying.");
728 exit(1);
730 /* Issues a CONF_CHANGED event to notify controller of the change. If Tor is
731 * just starting up then the old_options will be undefined. */
732 if (old_options) {
733 elements = smartlist_create();
734 for (i=0; options_format.vars[i].name; ++i) {
735 const config_var_t *var = &options_format.vars[i];
736 const char *var_name = var->name;
737 if (var->type == CONFIG_TYPE_LINELIST_S ||
738 var->type == CONFIG_TYPE_OBSOLETE) {
739 continue;
741 if (!option_is_same(&options_format, new_val, old_options, var_name)) {
742 line = get_assigned_option(&options_format, new_val, var_name, 1);
744 if (line) {
745 for (; line; line = line->next) {
746 smartlist_add(elements, line->key);
747 smartlist_add(elements, line->value);
749 } else {
750 smartlist_add(elements, (char*)options_format.vars[i].name);
751 smartlist_add(elements, NULL);
755 control_event_conf_changed(elements);
756 smartlist_free(elements);
758 config_free(&options_format, old_options);
760 return 0;
763 extern const char tor_git_revision[]; /* from tor_main.c */
765 /** The version of this Tor process, as parsed. */
766 static char *_version = NULL;
768 /** Return the current Tor version. */
769 const char *
770 get_version(void)
772 if (_version == NULL) {
773 if (strlen(tor_git_revision)) {
774 size_t len = strlen(VERSION)+strlen(tor_git_revision)+16;
775 _version = tor_malloc(len);
776 tor_snprintf(_version, len, "%s (git-%s)", VERSION, tor_git_revision);
777 } else {
778 _version = tor_strdup(VERSION);
781 return _version;
784 /** Release additional memory allocated in options
786 static void
787 or_options_free(or_options_t *options)
789 if (!options)
790 return;
792 routerset_free(options->_ExcludeExitNodesUnion);
793 if (options->NodeFamilySets) {
794 SMARTLIST_FOREACH(options->NodeFamilySets, routerset_t *,
795 rs, routerset_free(rs));
796 smartlist_free(options->NodeFamilySets);
798 config_free(&options_format, options);
801 /** Release all memory and resources held by global configuration structures.
803 void
804 config_free_all(void)
806 or_options_free(global_options);
807 global_options = NULL;
809 config_free(&state_format, global_state);
810 global_state = NULL;
812 config_free_lines(global_cmdline_options);
813 global_cmdline_options = NULL;
815 if (configured_client_ports) {
816 SMARTLIST_FOREACH(configured_client_ports,
817 port_cfg_t *, p, tor_free(p));
818 smartlist_free(configured_client_ports);
819 configured_client_ports = NULL;
822 tor_free(torrc_fname);
823 tor_free(_version);
824 tor_free(global_dirfrontpagecontents);
827 /** Make <b>address</b> -- a piece of information related to our operation as
828 * a client -- safe to log according to the settings in options->SafeLogging,
829 * and return it.
831 * (We return "[scrubbed]" if SafeLogging is "1", and address otherwise.)
833 const char *
834 safe_str_client(const char *address)
836 tor_assert(address);
837 if (get_options()->_SafeLogging == SAFELOG_SCRUB_ALL)
838 return "[scrubbed]";
839 else
840 return address;
843 /** Make <b>address</b> -- a piece of information of unspecified sensitivity
844 * -- safe to log according to the settings in options->SafeLogging, and
845 * return it.
847 * (We return "[scrubbed]" if SafeLogging is anything besides "0", and address
848 * otherwise.)
850 const char *
851 safe_str(const char *address)
853 tor_assert(address);
854 if (get_options()->_SafeLogging != SAFELOG_SCRUB_NONE)
855 return "[scrubbed]";
856 else
857 return address;
860 /** Equivalent to escaped(safe_str_client(address)). See reentrancy note on
861 * escaped(): don't use this outside the main thread, or twice in the same
862 * log statement. */
863 const char *
864 escaped_safe_str_client(const char *address)
866 if (get_options()->_SafeLogging == SAFELOG_SCRUB_ALL)
867 return "[scrubbed]";
868 else
869 return escaped(address);
872 /** Equivalent to escaped(safe_str(address)). See reentrancy note on
873 * escaped(): don't use this outside the main thread, or twice in the same
874 * log statement. */
875 const char *
876 escaped_safe_str(const char *address)
878 if (get_options()->_SafeLogging != SAFELOG_SCRUB_NONE)
879 return "[scrubbed]";
880 else
881 return escaped(address);
884 /** Add the default directory authorities directly into the trusted dir list,
885 * but only add them insofar as they share bits with <b>type</b>. */
886 static void
887 add_default_trusted_dir_authorities(dirinfo_type_t type)
889 int i;
890 const char *dirservers[] = {
891 "moria1 orport=9101 no-v2 "
892 "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
893 "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
894 "tor26 v1 orport=443 v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
895 "86.59.21.38:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
896 "dizum orport=443 v3ident=E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58 "
897 "194.109.206.212:80 7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
898 "Tonga orport=443 bridge no-v2 82.94.251.203:80 "
899 "4A0C CD2D DC79 9508 3D73 F5D6 6710 0C8A 5831 F16D",
900 "ides orport=9090 no-v2 v3ident=27B6B5996C426270A5C95488AA5BCEB6BCC86956 "
901 "216.224.124.114:9030 F397 038A DC51 3361 35E7 B80B D99C A384 4360 292B",
902 "gabelmoo orport=443 no-v2 "
903 "v3ident=ED03BB616EB2F60BEC80151114BB25CEF515B226 "
904 "212.112.245.170:80 F204 4413 DAC2 E02E 3D6B CF47 35A1 9BCA 1DE9 7281",
905 "dannenberg orport=443 no-v2 "
906 "v3ident=585769C78764D58426B8B52B6651A5A71137189A "
907 "193.23.244.244:80 7BE6 83E6 5D48 1413 21C5 ED92 F075 C553 64AC 7123",
908 "urras orport=80 no-v2 v3ident=80550987E1D626E3EBA5E5E75A458DE0626D088C "
909 "208.83.223.34:443 0AD3 FA88 4D18 F89E EA2D 89C0 1937 9E0E 7FD9 4417",
910 "maatuska orport=80 no-v2 "
911 "v3ident=49015F787433103580E3B66A1707A00E60F2D15B "
912 "213.115.239.118:443 BD6A 8292 55CB 08E6 6FBE 7D37 4836 3586 E46B 3810",
913 NULL
915 for (i=0; dirservers[i]; i++) {
916 if (parse_dir_server_line(dirservers[i], type, 0)<0) {
917 log_err(LD_BUG, "Couldn't parse internal dirserver line %s",
918 dirservers[i]);
923 /** Look at all the config options for using alternate directory
924 * authorities, and make sure none of them are broken. Also, warn the
925 * user if we changed any dangerous ones.
927 static int
928 validate_dir_authorities(or_options_t *options, or_options_t *old_options)
930 config_line_t *cl;
932 if (options->DirServers &&
933 (options->AlternateDirAuthority || options->AlternateBridgeAuthority ||
934 options->AlternateHSAuthority)) {
935 log_warn(LD_CONFIG,
936 "You cannot set both DirServers and Alternate*Authority.");
937 return -1;
940 /* do we want to complain to the user about being partitionable? */
941 if ((options->DirServers &&
942 (!old_options ||
943 !config_lines_eq(options->DirServers, old_options->DirServers))) ||
944 (options->AlternateDirAuthority &&
945 (!old_options ||
946 !config_lines_eq(options->AlternateDirAuthority,
947 old_options->AlternateDirAuthority)))) {
948 log_warn(LD_CONFIG,
949 "You have used DirServer or AlternateDirAuthority to "
950 "specify alternate directory authorities in "
951 "your configuration. This is potentially dangerous: it can "
952 "make you look different from all other Tor users, and hurt "
953 "your anonymity. Even if you've specified the same "
954 "authorities as Tor uses by default, the defaults could "
955 "change in the future. Be sure you know what you're doing.");
958 /* Now go through the four ways you can configure an alternate
959 * set of directory authorities, and make sure none are broken. */
960 for (cl = options->DirServers; cl; cl = cl->next)
961 if (parse_dir_server_line(cl->value, NO_DIRINFO, 1)<0)
962 return -1;
963 for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
964 if (parse_dir_server_line(cl->value, NO_DIRINFO, 1)<0)
965 return -1;
966 for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
967 if (parse_dir_server_line(cl->value, NO_DIRINFO, 1)<0)
968 return -1;
969 for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
970 if (parse_dir_server_line(cl->value, NO_DIRINFO, 1)<0)
971 return -1;
972 return 0;
975 /** Look at all the config options and assign new dir authorities
976 * as appropriate.
978 static int
979 consider_adding_dir_authorities(const or_options_t *options,
980 const or_options_t *old_options)
982 config_line_t *cl;
983 int need_to_update =
984 !smartlist_len(router_get_trusted_dir_servers()) || !old_options ||
985 !config_lines_eq(options->DirServers, old_options->DirServers) ||
986 !config_lines_eq(options->AlternateBridgeAuthority,
987 old_options->AlternateBridgeAuthority) ||
988 !config_lines_eq(options->AlternateDirAuthority,
989 old_options->AlternateDirAuthority) ||
990 !config_lines_eq(options->AlternateHSAuthority,
991 old_options->AlternateHSAuthority);
993 if (!need_to_update)
994 return 0; /* all done */
996 /* Start from a clean slate. */
997 clear_trusted_dir_servers();
999 if (!options->DirServers) {
1000 /* then we may want some of the defaults */
1001 dirinfo_type_t type = NO_DIRINFO;
1002 if (!options->AlternateBridgeAuthority)
1003 type |= BRIDGE_DIRINFO;
1004 if (!options->AlternateDirAuthority)
1005 type |= V1_DIRINFO | V2_DIRINFO | V3_DIRINFO | EXTRAINFO_DIRINFO |
1006 MICRODESC_DIRINFO;
1007 if (!options->AlternateHSAuthority)
1008 type |= HIDSERV_DIRINFO;
1009 add_default_trusted_dir_authorities(type);
1012 for (cl = options->DirServers; cl; cl = cl->next)
1013 if (parse_dir_server_line(cl->value, NO_DIRINFO, 0)<0)
1014 return -1;
1015 for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
1016 if (parse_dir_server_line(cl->value, NO_DIRINFO, 0)<0)
1017 return -1;
1018 for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
1019 if (parse_dir_server_line(cl->value, NO_DIRINFO, 0)<0)
1020 return -1;
1021 for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
1022 if (parse_dir_server_line(cl->value, NO_DIRINFO, 0)<0)
1023 return -1;
1024 return 0;
1027 /** Fetch the active option list, and take actions based on it. All of the
1028 * things we do should survive being done repeatedly. If present,
1029 * <b>old_options</b> contains the previous value of the options.
1031 * Return 0 if all goes well, return -1 if things went badly.
1033 static int
1034 options_act_reversible(const or_options_t *old_options, char **msg)
1036 smartlist_t *new_listeners = smartlist_create();
1037 smartlist_t *replaced_listeners = smartlist_create();
1038 static int libevent_initialized = 0;
1039 or_options_t *options = get_options_mutable();
1040 int running_tor = options->command == CMD_RUN_TOR;
1041 int set_conn_limit = 0;
1042 int r = -1;
1043 int logs_marked = 0;
1045 /* Daemonize _first_, since we only want to open most of this stuff in
1046 * the subprocess. Libevent bases can't be reliably inherited across
1047 * processes. */
1048 if (running_tor && options->RunAsDaemon) {
1049 /* No need to roll back, since you can't change the value. */
1050 start_daemon();
1053 #ifndef HAVE_SYS_UN_H
1054 if (options->ControlSocket || options->ControlSocketsGroupWritable) {
1055 *msg = tor_strdup("Unix domain sockets (ControlSocket) not supported "
1056 "on this OS/with this build.");
1057 goto rollback;
1059 #else
1060 if (options->ControlSocketsGroupWritable && !options->ControlSocket) {
1061 *msg = tor_strdup("Setting ControlSocketGroupWritable without setting"
1062 "a ControlSocket makes no sense.");
1063 goto rollback;
1065 #endif
1067 if (running_tor) {
1068 int n_client_ports=0;
1069 /* We need to set the connection limit before we can open the listeners. */
1070 if (set_max_file_descriptors((unsigned)options->ConnLimit,
1071 &options->_ConnLimit) < 0) {
1072 *msg = tor_strdup("Problem with ConnLimit value. See logs for details.");
1073 goto rollback;
1075 set_conn_limit = 1;
1077 /* Set up libevent. (We need to do this before we can register the
1078 * listeners as listeners.) */
1079 if (running_tor && !libevent_initialized) {
1080 init_libevent(options);
1081 libevent_initialized = 1;
1084 /* Adjust the client port configuration so we can launch listeners. */
1085 if (parse_client_ports(options, 0, msg, &n_client_ports)) {
1086 if (!*msg)
1087 *msg = tor_strdup("Unexpected problem parsing client port config");
1088 goto rollback;
1091 /* Set the hibernation state appropriately.*/
1092 consider_hibernation(time(NULL));
1094 /* Launch the listeners. (We do this before we setuid, so we can bind to
1095 * ports under 1024.) We don't want to rebind if we're hibernating. */
1096 if (!we_are_hibernating()) {
1097 if (retry_all_listeners(replaced_listeners, new_listeners) < 0) {
1098 *msg = tor_strdup("Failed to bind one of the listener ports.");
1099 goto rollback;
1104 #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
1105 /* Open /dev/pf before dropping privileges. */
1106 if (options->TransPort) {
1107 if (get_pf_socket() < 0) {
1108 *msg = tor_strdup("Unable to open /dev/pf for transparent proxy.");
1109 goto rollback;
1112 #endif
1114 /* Attempt to lock all current and future memory with mlockall() only once */
1115 if (options->DisableAllSwap) {
1116 if (tor_mlockall() == -1) {
1117 *msg = tor_strdup("DisableAllSwap failure. Do you have proper "
1118 "permissions?");
1119 goto done;
1123 /* Setuid/setgid as appropriate */
1124 if (options->User) {
1125 if (switch_id(options->User) != 0) {
1126 /* No need to roll back, since you can't change the value. */
1127 *msg = tor_strdup("Problem with User value. See logs for details.");
1128 goto done;
1132 /* Ensure data directory is private; create if possible. */
1133 if (check_private_dir(options->DataDirectory,
1134 running_tor ? CPD_CREATE : CPD_CHECK,
1135 options->User)<0) {
1136 tor_asprintf(msg,
1137 "Couldn't access/create private data directory \"%s\"",
1138 options->DataDirectory);
1139 goto done;
1140 /* No need to roll back, since you can't change the value. */
1143 /* Write control ports to disk as appropriate */
1144 control_ports_write_to_file();
1146 if (directory_caches_v2_dir_info(options)) {
1147 size_t len = strlen(options->DataDirectory)+32;
1148 char *fn = tor_malloc(len);
1149 tor_snprintf(fn, len, "%s"PATH_SEPARATOR"cached-status",
1150 options->DataDirectory);
1151 if (check_private_dir(fn, running_tor ? CPD_CREATE : CPD_CHECK,
1152 options->User) < 0) {
1153 tor_asprintf(msg,
1154 "Couldn't access/create private data directory \"%s\"", fn);
1155 tor_free(fn);
1156 goto done;
1158 tor_free(fn);
1161 /* Bail out at this point if we're not going to be a client or server:
1162 * we don't run Tor itself. */
1163 if (!running_tor)
1164 goto commit;
1166 mark_logs_temp(); /* Close current logs once new logs are open. */
1167 logs_marked = 1;
1168 if (options_init_logs(options, 0)<0) { /* Configure the log(s) */
1169 *msg = tor_strdup("Failed to init Log options. See logs for details.");
1170 goto rollback;
1173 commit:
1174 r = 0;
1175 if (logs_marked) {
1176 log_severity_list_t *severity =
1177 tor_malloc_zero(sizeof(log_severity_list_t));
1178 close_temp_logs();
1179 add_callback_log(severity, control_event_logmsg);
1180 control_adjust_event_log_severity();
1181 tor_free(severity);
1183 SMARTLIST_FOREACH(replaced_listeners, connection_t *, conn,
1185 log_notice(LD_NET, "Closing old %s on %s:%d",
1186 conn_type_to_string(conn->type), conn->address, conn->port);
1187 connection_close_immediate(conn);
1188 connection_mark_for_close(conn);
1190 goto done;
1192 rollback:
1193 r = -1;
1194 tor_assert(*msg);
1196 if (logs_marked) {
1197 rollback_log_changes();
1198 control_adjust_event_log_severity();
1201 if (set_conn_limit && old_options)
1202 set_max_file_descriptors((unsigned)old_options->ConnLimit,
1203 &options->_ConnLimit);
1205 SMARTLIST_FOREACH(new_listeners, connection_t *, conn,
1207 log_notice(LD_NET, "Closing partially-constructed listener %s on %s:%d",
1208 conn_type_to_string(conn->type), conn->address, conn->port);
1209 connection_close_immediate(conn);
1210 connection_mark_for_close(conn);
1213 done:
1214 smartlist_free(new_listeners);
1215 smartlist_free(replaced_listeners);
1216 return r;
1219 /** If we need to have a GEOIP ip-to-country map to run with our configured
1220 * options, return 1 and set *<b>reason_out</b> to a description of why. */
1222 options_need_geoip_info(const or_options_t *options, const char **reason_out)
1224 int bridge_usage =
1225 options->BridgeRelay && options->BridgeRecordUsageByCountry;
1226 int routerset_usage =
1227 routerset_needs_geoip(options->EntryNodes) ||
1228 routerset_needs_geoip(options->ExitNodes) ||
1229 routerset_needs_geoip(options->ExcludeExitNodes) ||
1230 routerset_needs_geoip(options->ExcludeNodes);
1232 if (routerset_usage && reason_out) {
1233 *reason_out = "We've been configured to use (or avoid) nodes in certain "
1234 "countries, and we need GEOIP information to figure out which ones they "
1235 "are.";
1236 } else if (bridge_usage && reason_out) {
1237 *reason_out = "We've been configured to see which countries can access "
1238 "us as a bridge, and we need GEOIP information to tell which countries "
1239 "clients are in.";
1241 return bridge_usage || routerset_usage;
1244 /** Return the bandwidthrate that we are going to report to the authorities
1245 * based on the config options. */
1246 uint32_t
1247 get_effective_bwrate(const or_options_t *options)
1249 uint64_t bw = options->BandwidthRate;
1250 if (bw > options->MaxAdvertisedBandwidth)
1251 bw = options->MaxAdvertisedBandwidth;
1252 if (options->RelayBandwidthRate > 0 && bw > options->RelayBandwidthRate)
1253 bw = options->RelayBandwidthRate;
1254 /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
1255 return (uint32_t)bw;
1258 /** Return the bandwidthburst that we are going to report to the authorities
1259 * based on the config options. */
1260 uint32_t
1261 get_effective_bwburst(const or_options_t *options)
1263 uint64_t bw = options->BandwidthBurst;
1264 if (options->RelayBandwidthBurst > 0 && bw > options->RelayBandwidthBurst)
1265 bw = options->RelayBandwidthBurst;
1266 /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
1267 return (uint32_t)bw;
1270 /** Fetch the active option list, and take actions based on it. All of the
1271 * things we do should survive being done repeatedly. If present,
1272 * <b>old_options</b> contains the previous value of the options.
1274 * Return 0 if all goes well, return -1 if it's time to die.
1276 * Note: We haven't moved all the "act on new configuration" logic
1277 * here yet. Some is still in do_hup() and other places.
1279 static int
1280 options_act(const or_options_t *old_options)
1282 config_line_t *cl;
1283 or_options_t *options = get_options_mutable();
1284 int running_tor = options->command == CMD_RUN_TOR;
1285 char *msg;
1286 const int transition_affects_workers =
1287 old_options && options_transition_affects_workers(old_options, options);
1289 if (running_tor && !have_lockfile()) {
1290 if (try_locking(options, 1) < 0)
1291 return -1;
1294 if (consider_adding_dir_authorities(options, old_options) < 0)
1295 return -1;
1297 if (options->Bridges) {
1298 mark_bridge_list();
1299 for (cl = options->Bridges; cl; cl = cl->next) {
1300 if (parse_bridge_line(cl->value, 0)<0) {
1301 log_warn(LD_BUG,
1302 "Previously validated Bridge line could not be added!");
1303 return -1;
1306 sweep_bridge_list();
1309 if (running_tor && rend_config_services(options, 0)<0) {
1310 log_warn(LD_BUG,
1311 "Previously validated hidden services line could not be added!");
1312 return -1;
1315 if (running_tor && rend_parse_service_authorization(options, 0) < 0) {
1316 log_warn(LD_BUG, "Previously validated client authorization for "
1317 "hidden services could not be added!");
1318 return -1;
1321 /* Load state */
1322 if (! global_state && running_tor) {
1323 if (or_state_load())
1324 return -1;
1325 rep_hist_load_mtbf_data(time(NULL));
1328 mark_transport_list();
1329 pt_prepare_proxy_list_for_config_read();
1330 if (options->ClientTransportPlugin) {
1331 for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
1332 if (parse_client_transport_line(cl->value, 0)<0) {
1333 log_warn(LD_BUG,
1334 "Previously validated ClientTransportPlugin line "
1335 "could not be added!");
1336 return -1;
1341 if (options->ServerTransportPlugin) {
1342 for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
1343 if (parse_server_transport_line(cl->value, 0)<0) {
1344 log_warn(LD_BUG,
1345 "Previously validated ServerTransportPlugin line "
1346 "could not be added!");
1347 return -1;
1351 sweep_transport_list();
1352 sweep_proxy_list();
1354 /* Bail out at this point if we're not going to be a client or server:
1355 * we want to not fork, and to log stuff to stderr. */
1356 if (!running_tor)
1357 return 0;
1359 /* Finish backgrounding the process */
1360 if (options->RunAsDaemon) {
1361 /* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
1362 finish_daemon(options->DataDirectory);
1365 /* We want to reinit keys as needed before we do much of anything else:
1366 keys are important, and other things can depend on them. */
1367 if (transition_affects_workers ||
1368 (options->V3AuthoritativeDir && (!old_options ||
1369 !old_options->V3AuthoritativeDir))) {
1370 if (init_keys() < 0) {
1371 log_warn(LD_BUG,"Error initializing keys; exiting");
1372 return -1;
1376 /* Write our PID to the PID file. If we do not have write permissions we
1377 * will log a warning */
1378 if (options->PidFile)
1379 write_pidfile(options->PidFile);
1381 /* Register addressmap directives */
1382 config_register_addressmaps(options);
1383 parse_virtual_addr_network(options->VirtualAddrNetwork, 0, &msg);
1385 /* Update address policies. */
1386 if (policies_parse_from_options(options) < 0) {
1387 /* This should be impossible, but let's be sure. */
1388 log_warn(LD_BUG,"Error parsing already-validated policy options.");
1389 return -1;
1392 if (init_cookie_authentication(options->CookieAuthentication) < 0) {
1393 log_warn(LD_CONFIG,"Error creating cookie authentication file.");
1394 return -1;
1397 monitor_owning_controller_process(options->OwningControllerProcess);
1399 /* reload keys as needed for rendezvous services. */
1400 if (rend_service_load_keys()<0) {
1401 log_warn(LD_GENERAL,"Error loading rendezvous service keys");
1402 return -1;
1405 /* Set up accounting */
1406 if (accounting_parse_options(options, 0)<0) {
1407 log_warn(LD_CONFIG,"Error in accounting options");
1408 return -1;
1410 if (accounting_is_enabled(options))
1411 configure_accounting(time(NULL));
1413 #ifdef USE_BUFFEREVENTS
1414 /* If we're using the bufferevents implementation and our rate limits
1415 * changed, we need to tell the rate-limiting system about it. */
1416 if (!old_options ||
1417 old_options->BandwidthRate != options->BandwidthRate ||
1418 old_options->BandwidthBurst != options->BandwidthBurst ||
1419 old_options->RelayBandwidthRate != options->RelayBandwidthRate ||
1420 old_options->RelayBandwidthBurst != options->RelayBandwidthBurst)
1421 connection_bucket_init();
1422 #endif
1424 /* Change the cell EWMA settings */
1425 cell_ewma_set_scale_factor(options, networkstatus_get_latest_consensus());
1427 /* Check for transitions that need action. */
1428 if (old_options) {
1429 int revise_trackexithosts = 0;
1430 int revise_automap_entries = 0;
1431 if ((options->UseEntryGuards && !old_options->UseEntryGuards) ||
1432 options->UseBridges != old_options->UseBridges ||
1433 (options->UseBridges &&
1434 !config_lines_eq(options->Bridges, old_options->Bridges)) ||
1435 !routerset_equal(old_options->ExcludeNodes,options->ExcludeNodes) ||
1436 !routerset_equal(old_options->ExcludeExitNodes,
1437 options->ExcludeExitNodes) ||
1438 !routerset_equal(old_options->EntryNodes, options->EntryNodes) ||
1439 !routerset_equal(old_options->ExitNodes, options->ExitNodes) ||
1440 options->StrictNodes != old_options->StrictNodes) {
1441 log_info(LD_CIRC,
1442 "Changed to using entry guards or bridges, or changed "
1443 "preferred or excluded node lists. "
1444 "Abandoning previous circuits.");
1445 circuit_mark_all_unused_circs();
1446 circuit_expire_all_dirty_circs();
1447 revise_trackexithosts = 1;
1450 if (!smartlist_strings_eq(old_options->TrackHostExits,
1451 options->TrackHostExits))
1452 revise_trackexithosts = 1;
1454 if (revise_trackexithosts)
1455 addressmap_clear_excluded_trackexithosts(options);
1457 if (!options->AutomapHostsOnResolve) {
1458 if (old_options->AutomapHostsOnResolve)
1459 revise_automap_entries = 1;
1460 } else {
1461 if (!smartlist_strings_eq(old_options->AutomapHostsSuffixes,
1462 options->AutomapHostsSuffixes))
1463 revise_automap_entries = 1;
1464 else if (!opt_streq(old_options->VirtualAddrNetwork,
1465 options->VirtualAddrNetwork))
1466 revise_automap_entries = 1;
1469 if (revise_automap_entries)
1470 addressmap_clear_invalid_automaps(options);
1472 /* How long should we delay counting bridge stats after becoming a bridge?
1473 * We use this so we don't count people who used our bridge thinking it is
1474 * a relay. If you change this, don't forget to change the log message
1475 * below. It's 4 hours (the time it takes to stop being used by clients)
1476 * plus some extra time for clock skew. */
1477 #define RELAY_BRIDGE_STATS_DELAY (6 * 60 * 60)
1479 if (! bool_eq(options->BridgeRelay, old_options->BridgeRelay)) {
1480 int was_relay = 0;
1481 if (options->BridgeRelay) {
1482 time_t int_start = time(NULL);
1483 if (old_options->ORPort == options->ORPort) {
1484 int_start += RELAY_BRIDGE_STATS_DELAY;
1485 was_relay = 1;
1487 geoip_bridge_stats_init(int_start);
1488 log_info(LD_CONFIG, "We are acting as a bridge now. Starting new "
1489 "GeoIP stats interval%s.", was_relay ? " in 6 "
1490 "hours from now" : "");
1491 } else {
1492 geoip_bridge_stats_term();
1493 log_info(LD_GENERAL, "We are no longer acting as a bridge. "
1494 "Forgetting GeoIP stats.");
1498 if (transition_affects_workers) {
1499 log_info(LD_GENERAL,
1500 "Worker-related options changed. Rotating workers.");
1502 if (server_mode(options) && !server_mode(old_options)) {
1503 ip_address_changed(0);
1504 if (can_complete_circuit || !any_predicted_circuits(time(NULL)))
1505 inform_testing_reachability();
1507 cpuworkers_rotate();
1508 if (dns_reset())
1509 return -1;
1510 } else {
1511 if (dns_reset())
1512 return -1;
1515 if (options->PerConnBWRate != old_options->PerConnBWRate ||
1516 options->PerConnBWBurst != old_options->PerConnBWBurst)
1517 connection_or_update_token_buckets(get_connection_array(), options);
1520 /* Maybe load geoip file */
1521 if (options->GeoIPFile &&
1522 ((!old_options || !opt_streq(old_options->GeoIPFile, options->GeoIPFile))
1523 || !geoip_is_loaded())) {
1524 /* XXXX Don't use this "<default>" junk; make our filename options
1525 * understand prefixes somehow. -NM */
1526 /* XXXX023 Reload GeoIPFile on SIGHUP. -NM */
1527 char *actual_fname = tor_strdup(options->GeoIPFile);
1528 #ifdef WIN32
1529 if (!strcmp(actual_fname, "<default>")) {
1530 const char *conf_root = get_windows_conf_root();
1531 size_t len = strlen(conf_root)+16;
1532 tor_free(actual_fname);
1533 actual_fname = tor_malloc(len+1);
1534 tor_snprintf(actual_fname, len, "%s\\geoip", conf_root);
1536 #endif
1537 geoip_load_file(actual_fname, options);
1538 tor_free(actual_fname);
1541 if (options->CellStatistics || options->DirReqStatistics ||
1542 options->EntryStatistics || options->ExitPortStatistics ||
1543 options->ConnDirectionStatistics ||
1544 options->BridgeAuthoritativeDir) {
1545 time_t now = time(NULL);
1546 int print_notice = 0;
1548 /* If we aren't acting as a server, we can't collect stats anyway. */
1549 if (!server_mode(options)) {
1550 options->CellStatistics = 0;
1551 options->DirReqStatistics = 0;
1552 options->EntryStatistics = 0;
1553 options->ExitPortStatistics = 0;
1556 if ((!old_options || !old_options->CellStatistics) &&
1557 options->CellStatistics) {
1558 rep_hist_buffer_stats_init(now);
1559 print_notice = 1;
1561 if ((!old_options || !old_options->DirReqStatistics) &&
1562 options->DirReqStatistics) {
1563 if (geoip_is_loaded()) {
1564 geoip_dirreq_stats_init(now);
1565 print_notice = 1;
1566 } else {
1567 options->DirReqStatistics = 0;
1568 /* Don't warn Tor clients, they don't use statistics */
1569 if (options->ORPort)
1570 log_notice(LD_CONFIG, "Configured to measure directory request "
1571 "statistics, but no GeoIP database found. "
1572 "Please specify a GeoIP database using the "
1573 "GeoIPFile option.");
1576 if ((!old_options || !old_options->EntryStatistics) &&
1577 options->EntryStatistics && !should_record_bridge_info(options)) {
1578 if (geoip_is_loaded()) {
1579 geoip_entry_stats_init(now);
1580 print_notice = 1;
1581 } else {
1582 options->EntryStatistics = 0;
1583 log_notice(LD_CONFIG, "Configured to measure entry node "
1584 "statistics, but no GeoIP database found. "
1585 "Please specify a GeoIP database using the "
1586 "GeoIPFile option.");
1589 if ((!old_options || !old_options->ExitPortStatistics) &&
1590 options->ExitPortStatistics) {
1591 rep_hist_exit_stats_init(now);
1592 print_notice = 1;
1594 if ((!old_options || !old_options->ConnDirectionStatistics) &&
1595 options->ConnDirectionStatistics) {
1596 rep_hist_conn_stats_init(now);
1598 if ((!old_options || !old_options->BridgeAuthoritativeDir) &&
1599 options->BridgeAuthoritativeDir) {
1600 rep_hist_desc_stats_init(now);
1601 print_notice = 1;
1603 if (print_notice)
1604 log_notice(LD_CONFIG, "Configured to measure statistics. Look for "
1605 "the *-stats files that will first be written to the "
1606 "data directory in 24 hours from now.");
1609 if (old_options && old_options->CellStatistics &&
1610 !options->CellStatistics)
1611 rep_hist_buffer_stats_term();
1612 if (old_options && old_options->DirReqStatistics &&
1613 !options->DirReqStatistics)
1614 geoip_dirreq_stats_term();
1615 if (old_options && old_options->EntryStatistics &&
1616 !options->EntryStatistics)
1617 geoip_entry_stats_term();
1618 if (old_options && old_options->ExitPortStatistics &&
1619 !options->ExitPortStatistics)
1620 rep_hist_exit_stats_term();
1621 if (old_options && old_options->ConnDirectionStatistics &&
1622 !options->ConnDirectionStatistics)
1623 rep_hist_conn_stats_term();
1624 if (old_options && old_options->BridgeAuthoritativeDir &&
1625 !options->BridgeAuthoritativeDir)
1626 rep_hist_desc_stats_term();
1628 /* Check if we need to parse and add the EntryNodes config option. */
1629 if (options->EntryNodes &&
1630 (!old_options ||
1631 !routerset_equal(old_options->EntryNodes,options->EntryNodes) ||
1632 !routerset_equal(old_options->ExcludeNodes,options->ExcludeNodes)))
1633 entry_nodes_should_be_added();
1635 /* Since our options changed, we might need to regenerate and upload our
1636 * server descriptor.
1638 if (!old_options ||
1639 options_transition_affects_descriptor(old_options, options))
1640 mark_my_descriptor_dirty("config change");
1642 /* We may need to reschedule some directory stuff if our status changed. */
1643 if (old_options) {
1644 if (authdir_mode_v3(options) && !authdir_mode_v3(old_options))
1645 dirvote_recalculate_timing(options, time(NULL));
1646 if (!bool_eq(directory_fetches_dir_info_early(options),
1647 directory_fetches_dir_info_early(old_options)) ||
1648 !bool_eq(directory_fetches_dir_info_later(options),
1649 directory_fetches_dir_info_later(old_options))) {
1650 /* Make sure update_router_have_min_dir_info gets called. */
1651 router_dir_info_changed();
1652 /* We might need to download a new consensus status later or sooner than
1653 * we had expected. */
1654 update_consensus_networkstatus_fetch_time(time(NULL));
1658 /* Load the webpage we're going to serve every time someone asks for '/' on
1659 our DirPort. */
1660 tor_free(global_dirfrontpagecontents);
1661 if (options->DirPortFrontPage) {
1662 global_dirfrontpagecontents =
1663 read_file_to_str(options->DirPortFrontPage, 0, NULL);
1664 if (!global_dirfrontpagecontents) {
1665 log_warn(LD_CONFIG,
1666 "DirPortFrontPage file '%s' not found. Continuing anyway.",
1667 options->DirPortFrontPage);
1671 return 0;
1675 * Functions to parse config options
1678 /** If <b>option</b> is an official abbreviation for a longer option,
1679 * return the longer option. Otherwise return <b>option</b>.
1680 * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
1681 * apply abbreviations that work for the config file and the command line.
1682 * If <b>warn_obsolete</b> is set, warn about deprecated names. */
1683 static const char *
1684 expand_abbrev(const config_format_t *fmt, const char *option, int command_line,
1685 int warn_obsolete)
1687 int i;
1688 if (! fmt->abbrevs)
1689 return option;
1690 for (i=0; fmt->abbrevs[i].abbreviated; ++i) {
1691 /* Abbreviations are case insensitive. */
1692 if (!strcasecmp(option,fmt->abbrevs[i].abbreviated) &&
1693 (command_line || !fmt->abbrevs[i].commandline_only)) {
1694 if (warn_obsolete && fmt->abbrevs[i].warn) {
1695 log_warn(LD_CONFIG,
1696 "The configuration option '%s' is deprecated; "
1697 "use '%s' instead.",
1698 fmt->abbrevs[i].abbreviated,
1699 fmt->abbrevs[i].full);
1701 /* Keep going through the list in case we want to rewrite it more.
1702 * (We could imagine recursing here, but I don't want to get the
1703 * user into an infinite loop if we craft our list wrong.) */
1704 option = fmt->abbrevs[i].full;
1707 return option;
1710 /** Helper: Read a list of configuration options from the command line.
1711 * If successful, put them in *<b>result</b> and return 0, and return
1712 * -1 and leave *<b>result</b> alone. */
1713 static int
1714 config_get_commandlines(int argc, char **argv, config_line_t **result)
1716 config_line_t *front = NULL;
1717 config_line_t **new = &front;
1718 char *s;
1719 int i = 1;
1721 while (i < argc) {
1722 if (!strcmp(argv[i],"-f") ||
1723 !strcmp(argv[i],"--hash-password")) {
1724 i += 2; /* command-line option with argument. ignore them. */
1725 continue;
1726 } else if (!strcmp(argv[i],"--list-fingerprint") ||
1727 !strcmp(argv[i],"--verify-config") ||
1728 !strcmp(argv[i],"--ignore-missing-torrc") ||
1729 !strcmp(argv[i],"--quiet") ||
1730 !strcmp(argv[i],"--hush")) {
1731 i += 1; /* command-line option. ignore it. */
1732 continue;
1733 } else if (!strcmp(argv[i],"--nt-service") ||
1734 !strcmp(argv[i],"-nt-service")) {
1735 i += 1;
1736 continue;
1739 if (i == argc-1) {
1740 log_warn(LD_CONFIG,"Command-line option '%s' with no value. Failing.",
1741 argv[i]);
1742 config_free_lines(front);
1743 return -1;
1746 *new = tor_malloc_zero(sizeof(config_line_t));
1747 s = argv[i];
1749 /* Each keyword may be prefixed with one or two dashes. */
1750 if (*s == '-')
1751 s++;
1752 if (*s == '-')
1753 s++;
1755 (*new)->key = tor_strdup(expand_abbrev(&options_format, s, 1, 1));
1756 (*new)->value = tor_strdup(argv[i+1]);
1757 (*new)->next = NULL;
1758 log(LOG_DEBUG, LD_CONFIG, "command line: parsed keyword '%s', value '%s'",
1759 (*new)->key, (*new)->value);
1761 new = &((*new)->next);
1762 i += 2;
1764 *result = front;
1765 return 0;
1768 /** Helper: allocate a new configuration option mapping 'key' to 'val',
1769 * append it to *<b>lst</b>. */
1770 static void
1771 config_line_append(config_line_t **lst,
1772 const char *key,
1773 const char *val)
1775 config_line_t *newline;
1777 newline = tor_malloc(sizeof(config_line_t));
1778 newline->key = tor_strdup(key);
1779 newline->value = tor_strdup(val);
1780 newline->next = NULL;
1781 while (*lst)
1782 lst = &((*lst)->next);
1784 (*lst) = newline;
1787 /** Helper: parse the config string and strdup into key/value
1788 * strings. Set *result to the list, or NULL if parsing the string
1789 * failed. Return 0 on success, -1 on failure. Warn and ignore any
1790 * misformatted lines. */
1792 config_get_lines(const char *string, config_line_t **result)
1794 config_line_t *list = NULL, **next;
1795 char *k, *v;
1797 next = &list;
1798 do {
1799 k = v = NULL;
1800 string = parse_config_line_from_str(string, &k, &v);
1801 if (!string) {
1802 config_free_lines(list);
1803 tor_free(k);
1804 tor_free(v);
1805 return -1;
1807 if (k && v) {
1808 /* This list can get long, so we keep a pointer to the end of it
1809 * rather than using config_line_append over and over and getting
1810 * n^2 performance. */
1811 *next = tor_malloc(sizeof(config_line_t));
1812 (*next)->key = k;
1813 (*next)->value = v;
1814 (*next)->next = NULL;
1815 next = &((*next)->next);
1816 } else {
1817 tor_free(k);
1818 tor_free(v);
1820 } while (*string);
1822 *result = list;
1823 return 0;
1827 * Free all the configuration lines on the linked list <b>front</b>.
1829 void
1830 config_free_lines(config_line_t *front)
1832 config_line_t *tmp;
1834 while (front) {
1835 tmp = front;
1836 front = tmp->next;
1838 tor_free(tmp->key);
1839 tor_free(tmp->value);
1840 tor_free(tmp);
1844 /** As config_find_option, but return a non-const pointer. */
1845 static config_var_t *
1846 config_find_option_mutable(config_format_t *fmt, const char *key)
1848 int i;
1849 size_t keylen = strlen(key);
1850 if (!keylen)
1851 return NULL; /* if they say "--" on the command line, it's not an option */
1852 /* First, check for an exact (case-insensitive) match */
1853 for (i=0; fmt->vars[i].name; ++i) {
1854 if (!strcasecmp(key, fmt->vars[i].name)) {
1855 return &fmt->vars[i];
1858 /* If none, check for an abbreviated match */
1859 for (i=0; fmt->vars[i].name; ++i) {
1860 if (!strncasecmp(key, fmt->vars[i].name, keylen)) {
1861 log_warn(LD_CONFIG, "The abbreviation '%s' is deprecated. "
1862 "Please use '%s' instead",
1863 key, fmt->vars[i].name);
1864 return &fmt->vars[i];
1867 /* Okay, unrecognized option */
1868 return NULL;
1871 /** If <b>key</b> is a configuration option, return the corresponding const
1872 * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
1873 * warn, and return the corresponding const config_var_t. Otherwise return
1874 * NULL.
1876 static const config_var_t *
1877 config_find_option(const config_format_t *fmt, const char *key)
1879 return config_find_option_mutable((config_format_t*)fmt, key);
1882 /** Return the number of option entries in <b>fmt</b>. */
1883 static int
1884 config_count_options(const config_format_t *fmt)
1886 int i;
1887 for (i=0; fmt->vars[i].name; ++i)
1889 return i;
1893 * Functions to assign config options.
1896 /** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
1897 * with <b>c</b>-\>value and return 0, or return -1 if bad value.
1899 * Called from config_assign_line() and option_reset().
1901 static int
1902 config_assign_value(const config_format_t *fmt, or_options_t *options,
1903 config_line_t *c, char **msg)
1905 int i, ok;
1906 const config_var_t *var;
1907 void *lvalue;
1909 CHECK(fmt, options);
1911 var = config_find_option(fmt, c->key);
1912 tor_assert(var);
1914 lvalue = STRUCT_VAR_P(options, var->var_offset);
1916 switch (var->type) {
1918 case CONFIG_TYPE_PORT:
1919 if (!strcasecmp(c->value, "auto")) {
1920 *(int *)lvalue = CFG_AUTO_PORT;
1921 break;
1923 /* fall through */
1924 case CONFIG_TYPE_UINT:
1925 i = (int)tor_parse_long(c->value, 10, 0,
1926 var->type==CONFIG_TYPE_PORT ? 65535 : INT_MAX,
1927 &ok, NULL);
1928 if (!ok) {
1929 tor_asprintf(msg,
1930 "Int keyword '%s %s' is malformed or out of bounds.",
1931 c->key, c->value);
1932 return -1;
1934 *(int *)lvalue = i;
1935 break;
1937 case CONFIG_TYPE_INTERVAL: {
1938 i = config_parse_interval(c->value, &ok);
1939 if (!ok) {
1940 tor_asprintf(msg,
1941 "Interval '%s %s' is malformed or out of bounds.",
1942 c->key, c->value);
1943 return -1;
1945 *(int *)lvalue = i;
1946 break;
1949 case CONFIG_TYPE_MSEC_INTERVAL: {
1950 i = config_parse_msec_interval(c->value, &ok);
1951 if (!ok) {
1952 tor_asprintf(msg,
1953 "Msec interval '%s %s' is malformed or out of bounds.",
1954 c->key, c->value);
1955 return -1;
1957 *(int *)lvalue = i;
1958 break;
1961 case CONFIG_TYPE_MEMUNIT: {
1962 uint64_t u64 = config_parse_memunit(c->value, &ok);
1963 if (!ok) {
1964 tor_asprintf(msg,
1965 "Value '%s %s' is malformed or out of bounds.",
1966 c->key, c->value);
1967 return -1;
1969 *(uint64_t *)lvalue = u64;
1970 break;
1973 case CONFIG_TYPE_BOOL:
1974 i = (int)tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
1975 if (!ok) {
1976 tor_asprintf(msg,
1977 "Boolean '%s %s' expects 0 or 1.",
1978 c->key, c->value);
1979 return -1;
1981 *(int *)lvalue = i;
1982 break;
1984 case CONFIG_TYPE_AUTOBOOL:
1985 if (!strcmp(c->value, "auto"))
1986 *(int *)lvalue = -1;
1987 else if (!strcmp(c->value, "0"))
1988 *(int *)lvalue = 0;
1989 else if (!strcmp(c->value, "1"))
1990 *(int *)lvalue = 1;
1991 else {
1992 tor_asprintf(msg, "Boolean '%s %s' expects 0, 1, or 'auto'.",
1993 c->key, c->value);
1994 return -1;
1996 break;
1998 case CONFIG_TYPE_STRING:
1999 case CONFIG_TYPE_FILENAME:
2000 tor_free(*(char **)lvalue);
2001 *(char **)lvalue = tor_strdup(c->value);
2002 break;
2004 case CONFIG_TYPE_DOUBLE:
2005 *(double *)lvalue = atof(c->value);
2006 break;
2008 case CONFIG_TYPE_ISOTIME:
2009 if (parse_iso_time(c->value, (time_t *)lvalue)) {
2010 tor_asprintf(msg,
2011 "Invalid time '%s' for keyword '%s'", c->value, c->key);
2012 return -1;
2014 break;
2016 case CONFIG_TYPE_ROUTERSET:
2017 if (*(routerset_t**)lvalue) {
2018 routerset_free(*(routerset_t**)lvalue);
2020 *(routerset_t**)lvalue = routerset_new();
2021 if (routerset_parse(*(routerset_t**)lvalue, c->value, c->key)<0) {
2022 tor_asprintf(msg, "Invalid exit list '%s' for option '%s'",
2023 c->value, c->key);
2024 return -1;
2026 break;
2028 case CONFIG_TYPE_CSV:
2029 if (*(smartlist_t**)lvalue) {
2030 SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
2031 smartlist_clear(*(smartlist_t**)lvalue);
2032 } else {
2033 *(smartlist_t**)lvalue = smartlist_create();
2036 smartlist_split_string(*(smartlist_t**)lvalue, c->value, ",",
2037 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2038 break;
2040 case CONFIG_TYPE_LINELIST:
2041 case CONFIG_TYPE_LINELIST_S:
2042 config_line_append((config_line_t**)lvalue, c->key, c->value);
2043 break;
2044 case CONFIG_TYPE_OBSOLETE:
2045 log_warn(LD_CONFIG, "Skipping obsolete configuration option '%s'", c->key);
2046 break;
2047 case CONFIG_TYPE_LINELIST_V:
2048 tor_asprintf(msg,
2049 "You may not provide a value for virtual option '%s'", c->key);
2050 return -1;
2051 default:
2052 tor_assert(0);
2053 break;
2055 return 0;
2058 /** If <b>c</b> is a syntactically valid configuration line, update
2059 * <b>options</b> with its value and return 0. Otherwise return -1 for bad
2060 * key, -2 for bad value.
2062 * If <b>clear_first</b> is set, clear the value first. Then if
2063 * <b>use_defaults</b> is set, set the value to the default.
2065 * Called from config_assign().
2067 static int
2068 config_assign_line(const config_format_t *fmt, or_options_t *options,
2069 config_line_t *c, int use_defaults,
2070 int clear_first, bitarray_t *options_seen, char **msg)
2072 const config_var_t *var;
2074 CHECK(fmt, options);
2076 var = config_find_option(fmt, c->key);
2077 if (!var) {
2078 if (fmt->extra) {
2079 void *lvalue = STRUCT_VAR_P(options, fmt->extra->var_offset);
2080 log_info(LD_CONFIG,
2081 "Found unrecognized option '%s'; saving it.", c->key);
2082 config_line_append((config_line_t**)lvalue, c->key, c->value);
2083 return 0;
2084 } else {
2085 tor_asprintf(msg,
2086 "Unknown option '%s'. Failing.", c->key);
2087 return -1;
2091 /* Put keyword into canonical case. */
2092 if (strcmp(var->name, c->key)) {
2093 tor_free(c->key);
2094 c->key = tor_strdup(var->name);
2097 if (!strlen(c->value)) {
2098 /* reset or clear it, then return */
2099 if (!clear_first) {
2100 if (var->type == CONFIG_TYPE_LINELIST ||
2101 var->type == CONFIG_TYPE_LINELIST_S) {
2102 /* We got an empty linelist from the torrc or command line.
2103 As a special case, call this an error. Warn and ignore. */
2104 log_warn(LD_CONFIG,
2105 "Linelist option '%s' has no value. Skipping.", c->key);
2106 } else { /* not already cleared */
2107 option_reset(fmt, options, var, use_defaults);
2110 return 0;
2113 if (options_seen && (var->type != CONFIG_TYPE_LINELIST &&
2114 var->type != CONFIG_TYPE_LINELIST_S)) {
2115 /* We're tracking which options we've seen, and this option is not
2116 * supposed to occur more than once. */
2117 int var_index = (int)(var - fmt->vars);
2118 if (bitarray_is_set(options_seen, var_index)) {
2119 log_warn(LD_CONFIG, "Option '%s' used more than once; all but the last "
2120 "value will be ignored.", var->name);
2122 bitarray_set(options_seen, var_index);
2125 if (config_assign_value(fmt, options, c, msg) < 0)
2126 return -2;
2127 return 0;
2130 /** Restore the option named <b>key</b> in options to its default value.
2131 * Called from config_assign(). */
2132 static void
2133 config_reset_line(const config_format_t *fmt, or_options_t *options,
2134 const char *key, int use_defaults)
2136 const config_var_t *var;
2138 CHECK(fmt, options);
2140 var = config_find_option(fmt, key);
2141 if (!var)
2142 return; /* give error on next pass. */
2144 option_reset(fmt, options, var, use_defaults);
2147 /** Return true iff key is a valid configuration option. */
2149 option_is_recognized(const char *key)
2151 const config_var_t *var = config_find_option(&options_format, key);
2152 return (var != NULL);
2155 /** Return the canonical name of a configuration option, or NULL
2156 * if no such option exists. */
2157 const char *
2158 option_get_canonical_name(const char *key)
2160 const config_var_t *var = config_find_option(&options_format, key);
2161 return var ? var->name : NULL;
2164 /** Return a canonical list of the options assigned for key.
2166 config_line_t *
2167 option_get_assignment(const or_options_t *options, const char *key)
2169 return get_assigned_option(&options_format, options, key, 1);
2172 /** Return true iff value needs to be quoted and escaped to be used in
2173 * a configuration file. */
2174 static int
2175 config_value_needs_escape(const char *value)
2177 if (*value == '\"')
2178 return 1;
2179 while (*value) {
2180 switch (*value)
2182 case '\r':
2183 case '\n':
2184 case '#':
2185 /* Note: quotes and backspaces need special handling when we are using
2186 * quotes, not otherwise, so they don't trigger escaping on their
2187 * own. */
2188 return 1;
2189 default:
2190 if (!TOR_ISPRINT(*value))
2191 return 1;
2193 ++value;
2195 return 0;
2198 /** Return a newly allocated deep copy of the lines in <b>inp</b>. */
2199 static config_line_t *
2200 config_lines_dup(const config_line_t *inp)
2202 config_line_t *result = NULL;
2203 config_line_t **next_out = &result;
2204 while (inp) {
2205 *next_out = tor_malloc(sizeof(config_line_t));
2206 (*next_out)->key = tor_strdup(inp->key);
2207 (*next_out)->value = tor_strdup(inp->value);
2208 inp = inp->next;
2209 next_out = &((*next_out)->next);
2211 (*next_out) = NULL;
2212 return result;
2215 /** Return newly allocated line or lines corresponding to <b>key</b> in the
2216 * configuration <b>options</b>. If <b>escape_val</b> is true and a
2217 * value needs to be quoted before it's put in a config file, quote and
2218 * escape that value. Return NULL if no such key exists. */
2219 static config_line_t *
2220 get_assigned_option(const config_format_t *fmt, const void *options,
2221 const char *key, int escape_val)
2223 const config_var_t *var;
2224 const void *value;
2225 config_line_t *result;
2226 tor_assert(options && key);
2228 CHECK(fmt, options);
2230 var = config_find_option(fmt, key);
2231 if (!var) {
2232 log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key);
2233 return NULL;
2235 value = STRUCT_VAR_P(options, var->var_offset);
2237 result = tor_malloc_zero(sizeof(config_line_t));
2238 result->key = tor_strdup(var->name);
2239 switch (var->type)
2241 case CONFIG_TYPE_STRING:
2242 case CONFIG_TYPE_FILENAME:
2243 if (*(char**)value) {
2244 result->value = tor_strdup(*(char**)value);
2245 } else {
2246 tor_free(result->key);
2247 tor_free(result);
2248 return NULL;
2250 break;
2251 case CONFIG_TYPE_ISOTIME:
2252 if (*(time_t*)value) {
2253 result->value = tor_malloc(ISO_TIME_LEN+1);
2254 format_iso_time(result->value, *(time_t*)value);
2255 } else {
2256 tor_free(result->key);
2257 tor_free(result);
2259 escape_val = 0; /* Can't need escape. */
2260 break;
2261 case CONFIG_TYPE_PORT:
2262 if (*(int*)value == CFG_AUTO_PORT) {
2263 result->value = tor_strdup("auto");
2264 escape_val = 0;
2265 break;
2267 /* fall through */
2268 case CONFIG_TYPE_INTERVAL:
2269 case CONFIG_TYPE_MSEC_INTERVAL:
2270 case CONFIG_TYPE_UINT:
2271 /* This means every or_options_t uint or bool element
2272 * needs to be an int. Not, say, a uint16_t or char. */
2273 tor_asprintf(&result->value, "%d", *(int*)value);
2274 escape_val = 0; /* Can't need escape. */
2275 break;
2276 case CONFIG_TYPE_MEMUNIT:
2277 tor_asprintf(&result->value, U64_FORMAT,
2278 U64_PRINTF_ARG(*(uint64_t*)value));
2279 escape_val = 0; /* Can't need escape. */
2280 break;
2281 case CONFIG_TYPE_DOUBLE:
2282 tor_asprintf(&result->value, "%f", *(double*)value);
2283 escape_val = 0; /* Can't need escape. */
2284 break;
2286 case CONFIG_TYPE_AUTOBOOL:
2287 if (*(int*)value == -1) {
2288 result->value = tor_strdup("auto");
2289 escape_val = 0;
2290 break;
2292 /* fall through */
2293 case CONFIG_TYPE_BOOL:
2294 result->value = tor_strdup(*(int*)value ? "1" : "0");
2295 escape_val = 0; /* Can't need escape. */
2296 break;
2297 case CONFIG_TYPE_ROUTERSET:
2298 result->value = routerset_to_string(*(routerset_t**)value);
2299 break;
2300 case CONFIG_TYPE_CSV:
2301 if (*(smartlist_t**)value)
2302 result->value =
2303 smartlist_join_strings(*(smartlist_t**)value, ",", 0, NULL);
2304 else
2305 result->value = tor_strdup("");
2306 break;
2307 case CONFIG_TYPE_OBSOLETE:
2308 log_fn(LOG_PROTOCOL_WARN, LD_CONFIG,
2309 "You asked me for the value of an obsolete config option '%s'.",
2310 key);
2311 tor_free(result->key);
2312 tor_free(result);
2313 return NULL;
2314 case CONFIG_TYPE_LINELIST_S:
2315 log_warn(LD_CONFIG,
2316 "Can't return context-sensitive '%s' on its own", key);
2317 tor_free(result->key);
2318 tor_free(result);
2319 return NULL;
2320 case CONFIG_TYPE_LINELIST:
2321 case CONFIG_TYPE_LINELIST_V:
2322 tor_free(result->key);
2323 tor_free(result);
2324 result = config_lines_dup(*(const config_line_t**)value);
2325 break;
2326 default:
2327 tor_free(result->key);
2328 tor_free(result);
2329 log_warn(LD_BUG,"Unknown type %d for known key '%s'",
2330 var->type, key);
2331 return NULL;
2334 if (escape_val) {
2335 config_line_t *line;
2336 for (line = result; line; line = line->next) {
2337 if (line->value && config_value_needs_escape(line->value)) {
2338 char *newval = esc_for_log(line->value);
2339 tor_free(line->value);
2340 line->value = newval;
2345 return result;
2348 /** Iterate through the linked list of requested options <b>list</b>.
2349 * For each item, convert as appropriate and assign to <b>options</b>.
2350 * If an item is unrecognized, set *msg and return -1 immediately,
2351 * else return 0 for success.
2353 * If <b>clear_first</b>, interpret config options as replacing (not
2354 * extending) their previous values. If <b>clear_first</b> is set,
2355 * then <b>use_defaults</b> to decide if you set to defaults after
2356 * clearing, or make the value 0 or NULL.
2358 * Here are the use cases:
2359 * 1. A non-empty AllowInvalid line in your torrc. Appends to current
2360 * if linelist, replaces current if csv.
2361 * 2. An empty AllowInvalid line in your torrc. Should clear it.
2362 * 3. "RESETCONF AllowInvalid" sets it to default.
2363 * 4. "SETCONF AllowInvalid" makes it NULL.
2364 * 5. "SETCONF AllowInvalid=foo" clears it and sets it to "foo".
2366 * Use_defaults Clear_first
2367 * 0 0 "append"
2368 * 1 0 undefined, don't use
2369 * 0 1 "set to null first"
2370 * 1 1 "set to defaults first"
2371 * Return 0 on success, -1 on bad key, -2 on bad value.
2373 * As an additional special case, if a LINELIST config option has
2374 * no value and clear_first is 0, then warn and ignore it.
2378 There are three call cases for config_assign() currently.
2380 Case one: Torrc entry
2381 options_init_from_torrc() calls config_assign(0, 0)
2382 calls config_assign_line(0, 0).
2383 if value is empty, calls option_reset(0) and returns.
2384 calls config_assign_value(), appends.
2386 Case two: setconf
2387 options_trial_assign() calls config_assign(0, 1)
2388 calls config_reset_line(0)
2389 calls option_reset(0)
2390 calls option_clear().
2391 calls config_assign_line(0, 1).
2392 if value is empty, returns.
2393 calls config_assign_value(), appends.
2395 Case three: resetconf
2396 options_trial_assign() calls config_assign(1, 1)
2397 calls config_reset_line(1)
2398 calls option_reset(1)
2399 calls option_clear().
2400 calls config_assign_value(default)
2401 calls config_assign_line(1, 1).
2402 returns.
2404 static int
2405 config_assign(const config_format_t *fmt, void *options, config_line_t *list,
2406 int use_defaults, int clear_first, char **msg)
2408 config_line_t *p;
2409 bitarray_t *options_seen;
2410 const int n_options = config_count_options(fmt);
2412 CHECK(fmt, options);
2414 /* pass 1: normalize keys */
2415 for (p = list; p; p = p->next) {
2416 const char *full = expand_abbrev(fmt, p->key, 0, 1);
2417 if (strcmp(full,p->key)) {
2418 tor_free(p->key);
2419 p->key = tor_strdup(full);
2423 /* pass 2: if we're reading from a resetting source, clear all
2424 * mentioned config options, and maybe set to their defaults. */
2425 if (clear_first) {
2426 for (p = list; p; p = p->next)
2427 config_reset_line(fmt, options, p->key, use_defaults);
2430 options_seen = bitarray_init_zero(n_options);
2431 /* pass 3: assign. */
2432 while (list) {
2433 int r;
2434 if ((r=config_assign_line(fmt, options, list, use_defaults,
2435 clear_first, options_seen, msg))) {
2436 bitarray_free(options_seen);
2437 return r;
2439 list = list->next;
2441 bitarray_free(options_seen);
2442 return 0;
2445 /** Try assigning <b>list</b> to the global options. You do this by duping
2446 * options, assigning list to the new one, then validating it. If it's
2447 * ok, then throw out the old one and stick with the new one. Else,
2448 * revert to old and return failure. Return SETOPT_OK on success, or
2449 * a setopt_err_t on failure.
2451 * If not success, point *<b>msg</b> to a newly allocated string describing
2452 * what went wrong.
2454 setopt_err_t
2455 options_trial_assign(config_line_t *list, int use_defaults,
2456 int clear_first, char **msg)
2458 int r;
2459 or_options_t *trial_options = options_dup(&options_format, get_options());
2461 if ((r=config_assign(&options_format, trial_options,
2462 list, use_defaults, clear_first, msg)) < 0) {
2463 config_free(&options_format, trial_options);
2464 return r;
2467 if (options_validate(get_options_mutable(), trial_options, 1, msg) < 0) {
2468 config_free(&options_format, trial_options);
2469 return SETOPT_ERR_PARSE; /*XXX make this a separate return value. */
2472 if (options_transition_allowed(get_options(), trial_options, msg) < 0) {
2473 config_free(&options_format, trial_options);
2474 return SETOPT_ERR_TRANSITION;
2477 if (set_options(trial_options, msg)<0) {
2478 config_free(&options_format, trial_options);
2479 return SETOPT_ERR_SETTING;
2482 /* we liked it. put it in place. */
2483 return SETOPT_OK;
2486 /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
2487 * Called from option_reset() and config_free(). */
2488 static void
2489 option_clear(const config_format_t *fmt, or_options_t *options,
2490 const config_var_t *var)
2492 void *lvalue = STRUCT_VAR_P(options, var->var_offset);
2493 (void)fmt; /* unused */
2494 switch (var->type) {
2495 case CONFIG_TYPE_STRING:
2496 case CONFIG_TYPE_FILENAME:
2497 tor_free(*(char**)lvalue);
2498 break;
2499 case CONFIG_TYPE_DOUBLE:
2500 *(double*)lvalue = 0.0;
2501 break;
2502 case CONFIG_TYPE_ISOTIME:
2503 *(time_t*)lvalue = 0;
2504 break;
2505 case CONFIG_TYPE_INTERVAL:
2506 case CONFIG_TYPE_MSEC_INTERVAL:
2507 case CONFIG_TYPE_UINT:
2508 case CONFIG_TYPE_PORT:
2509 case CONFIG_TYPE_BOOL:
2510 *(int*)lvalue = 0;
2511 break;
2512 case CONFIG_TYPE_AUTOBOOL:
2513 *(int*)lvalue = -1;
2514 break;
2515 case CONFIG_TYPE_MEMUNIT:
2516 *(uint64_t*)lvalue = 0;
2517 break;
2518 case CONFIG_TYPE_ROUTERSET:
2519 if (*(routerset_t**)lvalue) {
2520 routerset_free(*(routerset_t**)lvalue);
2521 *(routerset_t**)lvalue = NULL;
2523 break;
2524 case CONFIG_TYPE_CSV:
2525 if (*(smartlist_t**)lvalue) {
2526 SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
2527 smartlist_free(*(smartlist_t **)lvalue);
2528 *(smartlist_t **)lvalue = NULL;
2530 break;
2531 case CONFIG_TYPE_LINELIST:
2532 case CONFIG_TYPE_LINELIST_S:
2533 config_free_lines(*(config_line_t **)lvalue);
2534 *(config_line_t **)lvalue = NULL;
2535 break;
2536 case CONFIG_TYPE_LINELIST_V:
2537 /* handled by linelist_s. */
2538 break;
2539 case CONFIG_TYPE_OBSOLETE:
2540 break;
2544 /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
2545 * <b>use_defaults</b>, set it to its default value.
2546 * Called by config_init() and option_reset_line() and option_assign_line(). */
2547 static void
2548 option_reset(const config_format_t *fmt, or_options_t *options,
2549 const config_var_t *var, int use_defaults)
2551 config_line_t *c;
2552 char *msg = NULL;
2553 CHECK(fmt, options);
2554 option_clear(fmt, options, var); /* clear it first */
2555 if (!use_defaults)
2556 return; /* all done */
2557 if (var->initvalue) {
2558 c = tor_malloc_zero(sizeof(config_line_t));
2559 c->key = tor_strdup(var->name);
2560 c->value = tor_strdup(var->initvalue);
2561 if (config_assign_value(fmt, options, c, &msg) < 0) {
2562 log_warn(LD_BUG, "Failed to assign default: %s", msg);
2563 tor_free(msg); /* if this happens it's a bug */
2565 config_free_lines(c);
2569 /** Print a usage message for tor. */
2570 static void
2571 print_usage(void)
2573 printf(
2574 "Copyright (c) 2001-2004, Roger Dingledine\n"
2575 "Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson\n"
2576 "Copyright (c) 2007-2011, The Tor Project, Inc.\n\n"
2577 "tor -f <torrc> [args]\n"
2578 "See man page for options, or https://www.torproject.org/ for "
2579 "documentation.\n");
2582 /** Print all non-obsolete torrc options. */
2583 static void
2584 list_torrc_options(void)
2586 int i;
2587 smartlist_t *lines = smartlist_create();
2588 for (i = 0; _option_vars[i].name; ++i) {
2589 const config_var_t *var = &_option_vars[i];
2590 if (var->type == CONFIG_TYPE_OBSOLETE ||
2591 var->type == CONFIG_TYPE_LINELIST_V)
2592 continue;
2593 printf("%s\n", var->name);
2595 smartlist_free(lines);
2598 /** Last value actually set by resolve_my_address. */
2599 static uint32_t last_resolved_addr = 0;
2601 * Based on <b>options-\>Address</b>, guess our public IP address and put it
2602 * (in host order) into *<b>addr_out</b>. If <b>hostname_out</b> is provided,
2603 * set *<b>hostname_out</b> to a new string holding the hostname we used to
2604 * get the address. Return 0 if all is well, or -1 if we can't find a suitable
2605 * public IP address.
2608 resolve_my_address(int warn_severity, const or_options_t *options,
2609 uint32_t *addr_out, char **hostname_out)
2611 struct in_addr in;
2612 uint32_t addr; /* host order */
2613 char hostname[256];
2614 int explicit_ip=1;
2615 int explicit_hostname=1;
2616 int from_interface=0;
2617 char *addr_string = NULL;
2618 const char *address = options->Address;
2619 int notice_severity = warn_severity <= LOG_NOTICE ?
2620 LOG_NOTICE : warn_severity;
2622 tor_assert(addr_out);
2624 if (address && *address) {
2625 strlcpy(hostname, address, sizeof(hostname));
2626 } else { /* then we need to guess our address */
2627 explicit_ip = 0; /* it's implicit */
2628 explicit_hostname = 0; /* it's implicit */
2630 if (gethostname(hostname, sizeof(hostname)) < 0) {
2631 log_fn(warn_severity, LD_NET,"Error obtaining local hostname");
2632 return -1;
2634 log_debug(LD_CONFIG,"Guessed local host name as '%s'",hostname);
2637 /* now we know hostname. resolve it and keep only the IP address */
2639 if (tor_inet_aton(hostname, &in) == 0) {
2640 /* then we have to resolve it */
2641 explicit_ip = 0;
2642 if (tor_lookup_hostname(hostname, &addr)) { /* failed to resolve */
2643 uint32_t interface_ip; /* host order */
2645 if (explicit_hostname) {
2646 log_fn(warn_severity, LD_CONFIG,
2647 "Could not resolve local Address '%s'. Failing.", hostname);
2648 return -1;
2650 log_fn(notice_severity, LD_CONFIG,
2651 "Could not resolve guessed local hostname '%s'. "
2652 "Trying something else.", hostname);
2653 if (get_interface_address(warn_severity, &interface_ip)) {
2654 log_fn(warn_severity, LD_CONFIG,
2655 "Could not get local interface IP address. Failing.");
2656 return -1;
2658 from_interface = 1;
2659 addr = interface_ip;
2660 log_fn(notice_severity, LD_CONFIG, "Learned IP address '%s' for "
2661 "local interface. Using that.", fmt_addr32(addr));
2662 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
2663 } else { /* resolved hostname into addr */
2664 if (!explicit_hostname &&
2665 is_internal_IP(addr, 0)) {
2666 uint32_t interface_ip;
2668 log_fn(notice_severity, LD_CONFIG, "Guessed local hostname '%s' "
2669 "resolves to a private IP address (%s). Trying something "
2670 "else.", hostname, fmt_addr32(addr));
2672 if (get_interface_address(warn_severity, &interface_ip)) {
2673 log_fn(warn_severity, LD_CONFIG,
2674 "Could not get local interface IP address. Too bad.");
2675 } else if (is_internal_IP(interface_ip, 0)) {
2676 log_fn(notice_severity, LD_CONFIG,
2677 "Interface IP address '%s' is a private address too. "
2678 "Ignoring.", fmt_addr32(interface_ip));
2679 } else {
2680 from_interface = 1;
2681 addr = interface_ip;
2682 log_fn(notice_severity, LD_CONFIG,
2683 "Learned IP address '%s' for local interface."
2684 " Using that.", fmt_addr32(addr));
2685 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
2689 } else {
2690 addr = ntohl(in.s_addr); /* set addr so that addr_string is not
2691 * illformed */
2694 addr_string = tor_dup_ip(addr);
2695 if (is_internal_IP(addr, 0)) {
2696 /* make sure we're ok with publishing an internal IP */
2697 if (!options->DirServers && !options->AlternateDirAuthority) {
2698 /* if they are using the default dirservers, disallow internal IPs
2699 * always. */
2700 log_fn(warn_severity, LD_CONFIG,
2701 "Address '%s' resolves to private IP address '%s'. "
2702 "Tor servers that use the default DirServers must have public "
2703 "IP addresses.", hostname, addr_string);
2704 tor_free(addr_string);
2705 return -1;
2707 if (!explicit_ip) {
2708 /* even if they've set their own dirservers, require an explicit IP if
2709 * they're using an internal address. */
2710 log_fn(warn_severity, LD_CONFIG, "Address '%s' resolves to private "
2711 "IP address '%s'. Please set the Address config option to be "
2712 "the IP address you want to use.", hostname, addr_string);
2713 tor_free(addr_string);
2714 return -1;
2718 log_debug(LD_CONFIG, "Resolved Address to '%s'.", fmt_addr32(addr));
2719 *addr_out = addr;
2720 if (last_resolved_addr && last_resolved_addr != *addr_out) {
2721 /* Leave this as a notice, regardless of the requested severity,
2722 * at least until dynamic IP address support becomes bulletproof. */
2723 log_notice(LD_NET,
2724 "Your IP address seems to have changed to %s. Updating.",
2725 addr_string);
2726 ip_address_changed(0);
2728 if (last_resolved_addr != *addr_out) {
2729 const char *method;
2730 const char *h = hostname;
2731 if (explicit_ip) {
2732 method = "CONFIGURED";
2733 h = NULL;
2734 } else if (explicit_hostname) {
2735 method = "RESOLVED";
2736 } else if (from_interface) {
2737 method = "INTERFACE";
2738 h = NULL;
2739 } else {
2740 method = "GETHOSTNAME";
2742 control_event_server_status(LOG_NOTICE,
2743 "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s %s%s",
2744 addr_string, method, h?"HOSTNAME=":"", h);
2746 last_resolved_addr = *addr_out;
2747 if (hostname_out)
2748 *hostname_out = tor_strdup(hostname);
2749 tor_free(addr_string);
2750 return 0;
2753 /** Return true iff <b>addr</b> is judged to be on the same network as us, or
2754 * on a private network.
2757 is_local_addr(const tor_addr_t *addr)
2759 if (tor_addr_is_internal(addr, 0))
2760 return 1;
2761 /* Check whether ip is on the same /24 as we are. */
2762 if (get_options()->EnforceDistinctSubnets == 0)
2763 return 0;
2764 if (tor_addr_family(addr) == AF_INET) {
2765 /*XXXX023 IP6 what corresponds to an /24? */
2766 uint32_t ip = tor_addr_to_ipv4h(addr);
2768 /* It's possible that this next check will hit before the first time
2769 * resolve_my_address actually succeeds. (For clients, it is likely that
2770 * resolve_my_address will never be called at all). In those cases,
2771 * last_resolved_addr will be 0, and so checking to see whether ip is on
2772 * the same /24 as last_resolved_addr will be the same as checking whether
2773 * it was on net 0, which is already done by is_internal_IP.
2775 if ((last_resolved_addr & (uint32_t)0xffffff00ul)
2776 == (ip & (uint32_t)0xffffff00ul))
2777 return 1;
2779 return 0;
2782 /** Release storage held by <b>options</b>. */
2783 static void
2784 config_free(const config_format_t *fmt, void *options)
2786 int i;
2788 if (!options)
2789 return;
2791 tor_assert(fmt);
2793 for (i=0; fmt->vars[i].name; ++i)
2794 option_clear(fmt, options, &(fmt->vars[i]));
2795 if (fmt->extra) {
2796 config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->var_offset);
2797 config_free_lines(*linep);
2798 *linep = NULL;
2800 tor_free(options);
2803 /** Return true iff a and b contain identical keys and values in identical
2804 * order. */
2805 static int
2806 config_lines_eq(config_line_t *a, config_line_t *b)
2808 while (a && b) {
2809 if (strcasecmp(a->key, b->key) || strcmp(a->value, b->value))
2810 return 0;
2811 a = a->next;
2812 b = b->next;
2814 if (a || b)
2815 return 0;
2816 return 1;
2819 /** Return true iff the option <b>name</b> has the same value in <b>o1</b>
2820 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
2822 static int
2823 option_is_same(const config_format_t *fmt,
2824 const or_options_t *o1, const or_options_t *o2,
2825 const char *name)
2827 config_line_t *c1, *c2;
2828 int r = 1;
2829 CHECK(fmt, o1);
2830 CHECK(fmt, o2);
2832 c1 = get_assigned_option(fmt, o1, name, 0);
2833 c2 = get_assigned_option(fmt, o2, name, 0);
2834 r = config_lines_eq(c1, c2);
2835 config_free_lines(c1);
2836 config_free_lines(c2);
2837 return r;
2840 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
2841 static or_options_t *
2842 options_dup(const config_format_t *fmt, const or_options_t *old)
2844 or_options_t *newopts;
2845 int i;
2846 config_line_t *line;
2848 newopts = config_alloc(fmt);
2849 for (i=0; fmt->vars[i].name; ++i) {
2850 if (fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2851 continue;
2852 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE)
2853 continue;
2854 line = get_assigned_option(fmt, old, fmt->vars[i].name, 0);
2855 if (line) {
2856 char *msg = NULL;
2857 if (config_assign(fmt, newopts, line, 0, 0, &msg) < 0) {
2858 log_err(LD_BUG, "Config_get_assigned_option() generated "
2859 "something we couldn't config_assign(): %s", msg);
2860 tor_free(msg);
2861 tor_assert(0);
2864 config_free_lines(line);
2866 return newopts;
2869 /** Return a new empty or_options_t. Used for testing. */
2870 or_options_t *
2871 options_new(void)
2873 return config_alloc(&options_format);
2876 /** Set <b>options</b> to hold reasonable defaults for most options.
2877 * Each option defaults to zero. */
2878 void
2879 options_init(or_options_t *options)
2881 config_init(&options_format, options);
2884 /* Check if the port number given in <b>port_option</b> in combination with
2885 * the specified port in <b>listen_options</b> will result in Tor actually
2886 * opening a low port (meaning a port lower than 1024). Return 1 if
2887 * it is, or 0 if it isn't or the concept of a low port isn't applicable for
2888 * the platform we're on. */
2889 static int
2890 is_listening_on_low_port(int port_option,
2891 const config_line_t *listen_options)
2893 #ifdef MS_WINDOWS
2894 (void) port_option;
2895 (void) listen_options;
2896 return 0; /* No port is too low for windows. */
2897 #else
2898 const config_line_t *l;
2899 uint16_t p;
2900 if (port_option == 0)
2901 return 0; /* We're not listening */
2902 if (listen_options == NULL)
2903 return (port_option < 1024);
2905 for (l = listen_options; l; l = l->next) {
2906 addr_port_lookup(LOG_WARN, l->value, NULL, NULL, &p);
2907 if (p<1024) {
2908 return 1;
2911 return 0;
2912 #endif
2915 /** Set all vars in the configuration object <b>options</b> to their default
2916 * values. */
2917 static void
2918 config_init(const config_format_t *fmt, void *options)
2920 int i;
2921 const config_var_t *var;
2922 CHECK(fmt, options);
2924 for (i=0; fmt->vars[i].name; ++i) {
2925 var = &fmt->vars[i];
2926 if (!var->initvalue)
2927 continue; /* defaults to NULL or 0 */
2928 option_reset(fmt, options, var, 1);
2932 /** Allocate and return a new string holding the written-out values of the vars
2933 * in 'options'. If 'minimal', do not write out any default-valued vars.
2934 * Else, if comment_defaults, write default values as comments.
2936 static char *
2937 config_dump(const config_format_t *fmt, const void *options, int minimal,
2938 int comment_defaults)
2940 smartlist_t *elements;
2941 or_options_t *defaults;
2942 config_line_t *line, *assigned;
2943 char *result;
2944 int i;
2945 char *msg = NULL;
2947 defaults = config_alloc(fmt);
2948 config_init(fmt, defaults);
2950 /* XXX use a 1 here so we don't add a new log line while dumping */
2951 if (fmt->validate_fn(NULL,defaults, 1, &msg) < 0) {
2952 log_err(LD_BUG, "Failed to validate default config.");
2953 tor_free(msg);
2954 tor_assert(0);
2957 elements = smartlist_create();
2958 for (i=0; fmt->vars[i].name; ++i) {
2959 int comment_option = 0;
2960 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE ||
2961 fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2962 continue;
2963 /* Don't save 'hidden' control variables. */
2964 if (!strcmpstart(fmt->vars[i].name, "__"))
2965 continue;
2966 if (minimal && option_is_same(fmt, options, defaults, fmt->vars[i].name))
2967 continue;
2968 else if (comment_defaults &&
2969 option_is_same(fmt, options, defaults, fmt->vars[i].name))
2970 comment_option = 1;
2972 line = assigned = get_assigned_option(fmt, options, fmt->vars[i].name, 1);
2974 for (; line; line = line->next) {
2975 char *tmp;
2976 tor_asprintf(&tmp, "%s%s %s\n",
2977 comment_option ? "# " : "",
2978 line->key, line->value);
2979 smartlist_add(elements, tmp);
2981 config_free_lines(assigned);
2984 if (fmt->extra) {
2985 line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->var_offset);
2986 for (; line; line = line->next) {
2987 char *tmp;
2988 tor_asprintf(&tmp, "%s %s\n", line->key, line->value);
2989 smartlist_add(elements, tmp);
2993 result = smartlist_join_strings(elements, "", 0, NULL);
2994 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2995 smartlist_free(elements);
2996 config_free(fmt, defaults);
2997 return result;
3000 /** Return a string containing a possible configuration file that would give
3001 * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
3002 * include options that are the same as Tor's defaults.
3004 char *
3005 options_dump(const or_options_t *options, int minimal)
3007 return config_dump(&options_format, options, minimal, 0);
3010 /** Return 0 if every element of sl is a string holding a decimal
3011 * representation of a port number, or if sl is NULL.
3012 * Otherwise set *msg and return -1. */
3013 static int
3014 validate_ports_csv(smartlist_t *sl, const char *name, char **msg)
3016 int i;
3017 tor_assert(name);
3019 if (!sl)
3020 return 0;
3022 SMARTLIST_FOREACH(sl, const char *, cp,
3024 i = atoi(cp);
3025 if (i < 1 || i > 65535) {
3026 tor_asprintf(msg, "Port '%s' out of range in %s", cp, name);
3027 return -1;
3030 return 0;
3033 /** If <b>value</b> exceeds ROUTER_MAX_DECLARED_BANDWIDTH, write
3034 * a complaint into *<b>msg</b> using string <b>desc</b>, and return -1.
3035 * Else return 0.
3037 static int
3038 ensure_bandwidth_cap(uint64_t *value, const char *desc, char **msg)
3040 if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
3041 /* This handles an understandable special case where somebody says "2gb"
3042 * whereas our actual maximum is 2gb-1 (INT_MAX) */
3043 --*value;
3045 if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
3046 tor_asprintf(msg, "%s ("U64_FORMAT") must be at most %d",
3047 desc, U64_PRINTF_ARG(*value),
3048 ROUTER_MAX_DECLARED_BANDWIDTH);
3049 return -1;
3051 return 0;
3054 /** Parse an authority type from <b>options</b>-\>PublishServerDescriptor
3055 * and write it to <b>options</b>-\>_PublishServerDescriptor. Treat "1"
3056 * as "v2,v3" unless BridgeRelay is 1, in which case treat it as "bridge".
3057 * Treat "0" as "".
3058 * Return 0 on success or -1 if not a recognized authority type (in which
3059 * case the value of _PublishServerDescriptor is undefined). */
3060 static int
3061 compute_publishserverdescriptor(or_options_t *options)
3063 smartlist_t *list = options->PublishServerDescriptor;
3064 dirinfo_type_t *auth = &options->_PublishServerDescriptor;
3065 *auth = NO_DIRINFO;
3066 if (!list) /* empty list, answer is none */
3067 return 0;
3068 SMARTLIST_FOREACH(list, const char *, string, {
3069 if (!strcasecmp(string, "v1"))
3070 *auth |= V1_DIRINFO;
3071 else if (!strcmp(string, "1"))
3072 if (options->BridgeRelay)
3073 *auth |= BRIDGE_DIRINFO;
3074 else
3075 *auth |= V2_DIRINFO | V3_DIRINFO;
3076 else if (!strcasecmp(string, "v2"))
3077 *auth |= V2_DIRINFO;
3078 else if (!strcasecmp(string, "v3"))
3079 *auth |= V3_DIRINFO;
3080 else if (!strcasecmp(string, "bridge"))
3081 *auth |= BRIDGE_DIRINFO;
3082 else if (!strcasecmp(string, "hidserv"))
3083 log_warn(LD_CONFIG,
3084 "PublishServerDescriptor hidserv is invalid. See "
3085 "PublishHidServDescriptors.");
3086 else if (!strcasecmp(string, "") || !strcmp(string, "0"))
3087 /* no authority */;
3088 else
3089 return -1;
3091 return 0;
3094 /** Lowest allowable value for RendPostPeriod; if this is too low, hidden
3095 * services can overload the directory system. */
3096 #define MIN_REND_POST_PERIOD (10*60)
3098 /** Highest allowable value for RendPostPeriod. */
3099 #define MAX_DIR_PERIOD (MIN_ONION_KEY_LIFETIME/2)
3101 /** Lowest allowable value for MaxCircuitDirtiness; if this is too low, Tor
3102 * will generate too many circuits and potentially overload the network. */
3103 #define MIN_MAX_CIRCUIT_DIRTINESS 10
3105 /** Lowest allowable value for CircuitStreamTimeout; if this is too low, Tor
3106 * will generate too many circuits and potentially overload the network. */
3107 #define MIN_CIRCUIT_STREAM_TIMEOUT 10
3109 /** Lowest allowable value for HeartbeatPeriod; if this is too low, we might
3110 * expose more information than we're comfortable with. */
3111 #define MIN_HEARTBEAT_PERIOD (30*60)
3113 /** Return 0 if every setting in <b>options</b> is reasonable, and a
3114 * permissible transition from <b>old_options</b>. Else return -1.
3115 * Should have no side effects, except for normalizing the contents of
3116 * <b>options</b>.
3118 * On error, tor_strdup an error explanation into *<b>msg</b>.
3120 * XXX
3121 * If <b>from_setconf</b>, we were called by the controller, and our
3122 * Log line should stay empty. If it's 0, then give us a default log
3123 * if there are no logs defined.
3125 static int
3126 options_validate(or_options_t *old_options, or_options_t *options,
3127 int from_setconf, char **msg)
3129 int i;
3130 config_line_t *cl;
3131 const char *uname = get_uname();
3132 int n_client_ports=0;
3133 #define REJECT(arg) \
3134 STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
3135 #define COMPLAIN(arg) STMT_BEGIN log(LOG_WARN, LD_CONFIG, arg); STMT_END
3137 tor_assert(msg);
3138 *msg = NULL;
3140 if (server_mode(options) &&
3141 (!strcmpstart(uname, "Windows 95") ||
3142 !strcmpstart(uname, "Windows 98") ||
3143 !strcmpstart(uname, "Windows Me"))) {
3144 log(LOG_WARN, LD_CONFIG, "Tor is running as a server, but you are "
3145 "running %s; this probably won't work. See "
3146 "https://wiki.torproject.org/TheOnionRouter/TorFAQ#ServerOS "
3147 "for details.", uname);
3150 if (options->ORPort == 0 && options->ORListenAddress != NULL)
3151 REJECT("ORPort must be defined if ORListenAddress is defined.");
3153 if (options->DirPort == 0 && options->DirListenAddress != NULL)
3154 REJECT("DirPort must be defined if DirListenAddress is defined.");
3156 if (parse_client_ports(options, 1, msg, &n_client_ports) < 0)
3157 return -1;
3159 if (validate_data_directory(options)<0)
3160 REJECT("Invalid DataDirectory");
3162 if (options->Nickname == NULL) {
3163 if (server_mode(options)) {
3164 options->Nickname = tor_strdup(UNNAMED_ROUTER_NICKNAME);
3166 } else {
3167 if (!is_legal_nickname(options->Nickname)) {
3168 tor_asprintf(msg,
3169 "Nickname '%s' is wrong length or contains illegal characters.",
3170 options->Nickname);
3171 return -1;
3175 if (server_mode(options) && !options->ContactInfo)
3176 log(LOG_NOTICE, LD_CONFIG, "Your ContactInfo config option is not set. "
3177 "Please consider setting it, so we can contact you if your server is "
3178 "misconfigured or something else goes wrong.");
3180 /* Special case on first boot if no Log options are given. */
3181 if (!options->Logs && !options->RunAsDaemon && !from_setconf) {
3182 if (quiet_level == 0)
3183 config_line_append(&options->Logs, "Log", "notice stdout");
3184 else if (quiet_level == 1)
3185 config_line_append(&options->Logs, "Log", "warn stdout");
3188 if (options_init_logs(options, 1)<0) /* Validate the log(s) */
3189 REJECT("Failed to validate Log options. See logs for details.");
3191 if (authdir_mode(options)) {
3192 /* confirm that our address isn't broken, so we can complain now */
3193 uint32_t tmp;
3194 if (resolve_my_address(LOG_WARN, options, &tmp, NULL) < 0)
3195 REJECT("Failed to resolve/guess local address. See logs for details.");
3198 #ifndef MS_WINDOWS
3199 if (options->RunAsDaemon && torrc_fname && path_is_relative(torrc_fname))
3200 REJECT("Can't use a relative path to torrc when RunAsDaemon is set.");
3201 #endif
3203 if (n_client_ports == 0 && options->ORPort == 0 && !options->RendConfigLines)
3204 log(LOG_WARN, LD_CONFIG,
3205 "SocksPort, TransPort, NATDPort, DNSPort, and ORPort are all "
3206 "undefined, and there aren't any hidden services configured. "
3207 "Tor will still run, but probably won't do anything.");
3209 #ifndef USE_TRANSPARENT
3210 if (options->TransPort || options->TransListenAddress)
3211 REJECT("TransPort and TransListenAddress are disabled in this build.");
3212 #endif
3214 if (options->TokenBucketRefillInterval <= 0
3215 || options->TokenBucketRefillInterval > 1000) {
3216 REJECT("TokenBucketRefillInterval must be between 1 and 1000 inclusive.");
3219 if (options->AccountingMax &&
3220 (is_listening_on_low_port(options->ORPort, options->ORListenAddress) ||
3221 is_listening_on_low_port(options->DirPort, options->DirListenAddress)))
3223 log(LOG_WARN, LD_CONFIG,
3224 "You have set AccountingMax to use hibernation. You have also "
3225 "chosen a low DirPort or OrPort. This combination can make Tor stop "
3226 "working when it tries to re-attach the port after a period of "
3227 "hibernation. Please choose a different port or turn off "
3228 "hibernation unless you know this combination will work on your "
3229 "platform.");
3232 if (options->ExcludeExitNodes || options->ExcludeNodes) {
3233 options->_ExcludeExitNodesUnion = routerset_new();
3234 routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeExitNodes);
3235 routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeNodes);
3238 if (options->NodeFamilies) {
3239 options->NodeFamilySets = smartlist_create();
3240 for (cl = options->NodeFamilies; cl; cl = cl->next) {
3241 routerset_t *rs = routerset_new();
3242 if (routerset_parse(rs, cl->value, cl->key) == 0) {
3243 smartlist_add(options->NodeFamilySets, rs);
3244 } else {
3245 routerset_free(rs);
3250 if (options->ExcludeNodes && options->StrictNodes) {
3251 COMPLAIN("You have asked to exclude certain relays from all positions "
3252 "in your circuits. Expect hidden services and other Tor "
3253 "features to be broken in unpredictable ways.");
3256 if (options->AuthoritativeDir) {
3257 if (!options->ContactInfo && !options->TestingTorNetwork)
3258 REJECT("Authoritative directory servers must set ContactInfo");
3259 if (options->V1AuthoritativeDir && !options->RecommendedVersions)
3260 REJECT("V1 authoritative dir servers must set RecommendedVersions.");
3261 if (!options->RecommendedClientVersions)
3262 options->RecommendedClientVersions =
3263 config_lines_dup(options->RecommendedVersions);
3264 if (!options->RecommendedServerVersions)
3265 options->RecommendedServerVersions =
3266 config_lines_dup(options->RecommendedVersions);
3267 if (options->VersioningAuthoritativeDir &&
3268 (!options->RecommendedClientVersions ||
3269 !options->RecommendedServerVersions))
3270 REJECT("Versioning authoritative dir servers must set "
3271 "Recommended*Versions.");
3272 if (options->UseEntryGuards) {
3273 log_info(LD_CONFIG, "Authoritative directory servers can't set "
3274 "UseEntryGuards. Disabling.");
3275 options->UseEntryGuards = 0;
3277 if (!options->DownloadExtraInfo && authdir_mode_any_main(options)) {
3278 log_info(LD_CONFIG, "Authoritative directories always try to download "
3279 "extra-info documents. Setting DownloadExtraInfo.");
3280 options->DownloadExtraInfo = 1;
3282 if (!(options->BridgeAuthoritativeDir || options->HSAuthoritativeDir ||
3283 options->V1AuthoritativeDir || options->V2AuthoritativeDir ||
3284 options->V3AuthoritativeDir))
3285 REJECT("AuthoritativeDir is set, but none of "
3286 "(Bridge/HS/V1/V2/V3)AuthoritativeDir is set.");
3287 /* If we have a v3bandwidthsfile and it's broken, complain on startup */
3288 if (options->V3BandwidthsFile && !old_options) {
3289 dirserv_read_measured_bandwidths(options->V3BandwidthsFile, NULL);
3293 if (options->AuthoritativeDir && !options->DirPort)
3294 REJECT("Running as authoritative directory, but no DirPort set.");
3296 if (options->AuthoritativeDir && !options->ORPort)
3297 REJECT("Running as authoritative directory, but no ORPort set.");
3299 if (options->AuthoritativeDir && options->ClientOnly)
3300 REJECT("Running as authoritative directory, but ClientOnly also set.");
3302 if (options->FetchDirInfoExtraEarly && !options->FetchDirInfoEarly)
3303 REJECT("FetchDirInfoExtraEarly requires that you also set "
3304 "FetchDirInfoEarly");
3306 if (options->HSAuthoritativeDir && proxy_mode(options))
3307 REJECT("Running as authoritative v0 HS directory, but also configured "
3308 "as a client.");
3310 if (options->ConnLimit <= 0) {
3311 tor_asprintf(msg,
3312 "ConnLimit must be greater than 0, but was set to %d",
3313 options->ConnLimit);
3314 return -1;
3317 if (options->MaxClientCircuitsPending <= 0 ||
3318 options->MaxClientCircuitsPending > MAX_MAX_CLIENT_CIRCUITS_PENDING) {
3319 tor_asprintf(msg,
3320 "MaxClientCircuitsPending must be between 1 and %d, but "
3321 "was set to %d", MAX_MAX_CLIENT_CIRCUITS_PENDING,
3322 options->MaxClientCircuitsPending);
3323 return -1;
3326 if (validate_ports_csv(options->FirewallPorts, "FirewallPorts", msg) < 0)
3327 return -1;
3329 if (validate_ports_csv(options->LongLivedPorts, "LongLivedPorts", msg) < 0)
3330 return -1;
3332 if (validate_ports_csv(options->RejectPlaintextPorts,
3333 "RejectPlaintextPorts", msg) < 0)
3334 return -1;
3336 if (validate_ports_csv(options->WarnPlaintextPorts,
3337 "WarnPlaintextPorts", msg) < 0)
3338 return -1;
3340 if (options->FascistFirewall && !options->ReachableAddresses) {
3341 if (options->FirewallPorts && smartlist_len(options->FirewallPorts)) {
3342 /* We already have firewall ports set, so migrate them to
3343 * ReachableAddresses, which will set ReachableORAddresses and
3344 * ReachableDirAddresses if they aren't set explicitly. */
3345 smartlist_t *instead = smartlist_create();
3346 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3347 new_line->key = tor_strdup("ReachableAddresses");
3348 /* If we're configured with the old format, we need to prepend some
3349 * open ports. */
3350 SMARTLIST_FOREACH(options->FirewallPorts, const char *, portno,
3352 int p = atoi(portno);
3353 char *s;
3354 if (p<0) continue;
3355 s = tor_malloc(16);
3356 tor_snprintf(s, 16, "*:%d", p);
3357 smartlist_add(instead, s);
3359 new_line->value = smartlist_join_strings(instead,",",0,NULL);
3360 /* These have been deprecated since 0.1.1.5-alpha-cvs */
3361 log(LOG_NOTICE, LD_CONFIG,
3362 "Converting FascistFirewall and FirewallPorts "
3363 "config options to new format: \"ReachableAddresses %s\"",
3364 new_line->value);
3365 options->ReachableAddresses = new_line;
3366 SMARTLIST_FOREACH(instead, char *, cp, tor_free(cp));
3367 smartlist_free(instead);
3368 } else {
3369 /* We do not have FirewallPorts set, so add 80 to
3370 * ReachableDirAddresses, and 443 to ReachableORAddresses. */
3371 if (!options->ReachableDirAddresses) {
3372 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3373 new_line->key = tor_strdup("ReachableDirAddresses");
3374 new_line->value = tor_strdup("*:80");
3375 options->ReachableDirAddresses = new_line;
3376 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
3377 "to new format: \"ReachableDirAddresses *:80\"");
3379 if (!options->ReachableORAddresses) {
3380 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3381 new_line->key = tor_strdup("ReachableORAddresses");
3382 new_line->value = tor_strdup("*:443");
3383 options->ReachableORAddresses = new_line;
3384 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
3385 "to new format: \"ReachableORAddresses *:443\"");
3390 for (i=0; i<3; i++) {
3391 config_line_t **linep =
3392 (i==0) ? &options->ReachableAddresses :
3393 (i==1) ? &options->ReachableORAddresses :
3394 &options->ReachableDirAddresses;
3395 if (!*linep)
3396 continue;
3397 /* We need to end with a reject *:*, not an implicit accept *:* */
3398 for (;;) {
3399 if (!strcmp((*linep)->value, "reject *:*")) /* already there */
3400 break;
3401 linep = &((*linep)->next);
3402 if (!*linep) {
3403 *linep = tor_malloc_zero(sizeof(config_line_t));
3404 (*linep)->key = tor_strdup(
3405 (i==0) ? "ReachableAddresses" :
3406 (i==1) ? "ReachableORAddresses" :
3407 "ReachableDirAddresses");
3408 (*linep)->value = tor_strdup("reject *:*");
3409 break;
3414 if ((options->ReachableAddresses ||
3415 options->ReachableORAddresses ||
3416 options->ReachableDirAddresses) &&
3417 server_mode(options))
3418 REJECT("Servers must be able to freely connect to the rest "
3419 "of the Internet, so they must not set Reachable*Addresses "
3420 "or FascistFirewall.");
3422 if (options->UseBridges &&
3423 server_mode(options))
3424 REJECT("Servers must be able to freely connect to the rest "
3425 "of the Internet, so they must not set UseBridges.");
3427 /* If both of these are set, we'll end up with funny behavior where we
3428 * demand enough entrynodes be up and running else we won't build
3429 * circuits, yet we never actually use them. */
3430 if (options->UseBridges && options->EntryNodes)
3431 REJECT("You cannot set both UseBridges and EntryNodes.");
3433 options->_AllowInvalid = 0;
3434 if (options->AllowInvalidNodes) {
3435 SMARTLIST_FOREACH(options->AllowInvalidNodes, const char *, cp, {
3436 if (!strcasecmp(cp, "entry"))
3437 options->_AllowInvalid |= ALLOW_INVALID_ENTRY;
3438 else if (!strcasecmp(cp, "exit"))
3439 options->_AllowInvalid |= ALLOW_INVALID_EXIT;
3440 else if (!strcasecmp(cp, "middle"))
3441 options->_AllowInvalid |= ALLOW_INVALID_MIDDLE;
3442 else if (!strcasecmp(cp, "introduction"))
3443 options->_AllowInvalid |= ALLOW_INVALID_INTRODUCTION;
3444 else if (!strcasecmp(cp, "rendezvous"))
3445 options->_AllowInvalid |= ALLOW_INVALID_RENDEZVOUS;
3446 else {
3447 tor_asprintf(msg,
3448 "Unrecognized value '%s' in AllowInvalidNodes", cp);
3449 return -1;
3454 if (!options->SafeLogging ||
3455 !strcasecmp(options->SafeLogging, "0")) {
3456 options->_SafeLogging = SAFELOG_SCRUB_NONE;
3457 } else if (!strcasecmp(options->SafeLogging, "relay")) {
3458 options->_SafeLogging = SAFELOG_SCRUB_RELAY;
3459 } else if (!strcasecmp(options->SafeLogging, "1")) {
3460 options->_SafeLogging = SAFELOG_SCRUB_ALL;
3461 } else {
3462 tor_asprintf(msg,
3463 "Unrecognized value '%s' in SafeLogging",
3464 escaped(options->SafeLogging));
3465 return -1;
3468 if (compute_publishserverdescriptor(options) < 0) {
3469 tor_asprintf(msg, "Unrecognized value in PublishServerDescriptor");
3470 return -1;
3473 if ((options->BridgeRelay
3474 || options->_PublishServerDescriptor & BRIDGE_DIRINFO)
3475 && (options->_PublishServerDescriptor
3476 & (V1_DIRINFO|V2_DIRINFO|V3_DIRINFO))) {
3477 REJECT("Bridges are not supposed to publish router descriptors to the "
3478 "directory authorities. Please correct your "
3479 "PublishServerDescriptor line.");
3482 if (options->BridgeRelay && options->DirPort) {
3483 log_warn(LD_CONFIG, "Can't set a DirPort on a bridge relay; disabling "
3484 "DirPort");
3485 options->DirPort = 0;
3488 if (options->MinUptimeHidServDirectoryV2 < 0) {
3489 log_warn(LD_CONFIG, "MinUptimeHidServDirectoryV2 option must be at "
3490 "least 0 seconds. Changing to 0.");
3491 options->MinUptimeHidServDirectoryV2 = 0;
3494 if (options->RendPostPeriod < MIN_REND_POST_PERIOD) {
3495 log_warn(LD_CONFIG, "RendPostPeriod option is too short; "
3496 "raising to %d seconds.", MIN_REND_POST_PERIOD);
3497 options->RendPostPeriod = MIN_REND_POST_PERIOD;
3500 if (options->RendPostPeriod > MAX_DIR_PERIOD) {
3501 log_warn(LD_CONFIG, "RendPostPeriod is too large; clipping to %ds.",
3502 MAX_DIR_PERIOD);
3503 options->RendPostPeriod = MAX_DIR_PERIOD;
3506 if (options->MaxCircuitDirtiness < MIN_MAX_CIRCUIT_DIRTINESS) {
3507 log_warn(LD_CONFIG, "MaxCircuitDirtiness option is too short; "
3508 "raising to %d seconds.", MIN_MAX_CIRCUIT_DIRTINESS);
3509 options->MaxCircuitDirtiness = MIN_MAX_CIRCUIT_DIRTINESS;
3512 if (options->CircuitStreamTimeout &&
3513 options->CircuitStreamTimeout < MIN_CIRCUIT_STREAM_TIMEOUT) {
3514 log_warn(LD_CONFIG, "CircuitStreamTimeout option is too short; "
3515 "raising to %d seconds.", MIN_CIRCUIT_STREAM_TIMEOUT);
3516 options->CircuitStreamTimeout = MIN_CIRCUIT_STREAM_TIMEOUT;
3519 if (options->HeartbeatPeriod &&
3520 options->HeartbeatPeriod < MIN_HEARTBEAT_PERIOD) {
3521 log_warn(LD_CONFIG, "HeartbeatPeriod option is too short; "
3522 "raising to %d seconds.", MIN_HEARTBEAT_PERIOD);
3523 options->HeartbeatPeriod = MIN_HEARTBEAT_PERIOD;
3526 if (options->KeepalivePeriod < 1)
3527 REJECT("KeepalivePeriod option must be positive.");
3529 if (ensure_bandwidth_cap(&options->BandwidthRate,
3530 "BandwidthRate", msg) < 0)
3531 return -1;
3532 if (ensure_bandwidth_cap(&options->BandwidthBurst,
3533 "BandwidthBurst", msg) < 0)
3534 return -1;
3535 if (ensure_bandwidth_cap(&options->MaxAdvertisedBandwidth,
3536 "MaxAdvertisedBandwidth", msg) < 0)
3537 return -1;
3538 if (ensure_bandwidth_cap(&options->RelayBandwidthRate,
3539 "RelayBandwidthRate", msg) < 0)
3540 return -1;
3541 if (ensure_bandwidth_cap(&options->RelayBandwidthBurst,
3542 "RelayBandwidthBurst", msg) < 0)
3543 return -1;
3544 if (ensure_bandwidth_cap(&options->PerConnBWRate,
3545 "PerConnBWRate", msg) < 0)
3546 return -1;
3547 if (ensure_bandwidth_cap(&options->PerConnBWBurst,
3548 "PerConnBWBurst", msg) < 0)
3549 return -1;
3550 if (ensure_bandwidth_cap(&options->AuthDirFastGuarantee,
3551 "AuthDirFastGuarantee", msg) < 0)
3552 return -1;
3553 if (ensure_bandwidth_cap(&options->AuthDirGuardBWGuarantee,
3554 "AuthDirGuardBWGuarantee", msg) < 0)
3555 return -1;
3557 if (options->RelayBandwidthRate && !options->RelayBandwidthBurst)
3558 options->RelayBandwidthBurst = options->RelayBandwidthRate;
3559 if (options->RelayBandwidthBurst && !options->RelayBandwidthRate)
3560 options->RelayBandwidthRate = options->RelayBandwidthBurst;
3562 if (server_mode(options)) {
3563 if (options->BandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
3564 tor_asprintf(msg,
3565 "BandwidthRate is set to %d bytes/second. "
3566 "For servers, it must be at least %d.",
3567 (int)options->BandwidthRate,
3568 ROUTER_REQUIRED_MIN_BANDWIDTH);
3569 return -1;
3570 } else if (options->MaxAdvertisedBandwidth <
3571 ROUTER_REQUIRED_MIN_BANDWIDTH/2) {
3572 tor_asprintf(msg,
3573 "MaxAdvertisedBandwidth is set to %d bytes/second. "
3574 "For servers, it must be at least %d.",
3575 (int)options->MaxAdvertisedBandwidth,
3576 ROUTER_REQUIRED_MIN_BANDWIDTH/2);
3577 return -1;
3579 if (options->RelayBandwidthRate &&
3580 options->RelayBandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
3581 tor_asprintf(msg,
3582 "RelayBandwidthRate is set to %d bytes/second. "
3583 "For servers, it must be at least %d.",
3584 (int)options->RelayBandwidthRate,
3585 ROUTER_REQUIRED_MIN_BANDWIDTH);
3586 return -1;
3590 if (options->RelayBandwidthRate > options->RelayBandwidthBurst)
3591 REJECT("RelayBandwidthBurst must be at least equal "
3592 "to RelayBandwidthRate.");
3594 if (options->BandwidthRate > options->BandwidthBurst)
3595 REJECT("BandwidthBurst must be at least equal to BandwidthRate.");
3597 /* if they set relaybandwidth* really high but left bandwidth*
3598 * at the default, raise the defaults. */
3599 if (options->RelayBandwidthRate > options->BandwidthRate)
3600 options->BandwidthRate = options->RelayBandwidthRate;
3601 if (options->RelayBandwidthBurst > options->BandwidthBurst)
3602 options->BandwidthBurst = options->RelayBandwidthBurst;
3604 if (accounting_parse_options(options, 1)<0)
3605 REJECT("Failed to parse accounting options. See logs for details.");
3607 if (options->HTTPProxy) { /* parse it now */
3608 if (tor_addr_port_lookup(options->HTTPProxy,
3609 &options->HTTPProxyAddr, &options->HTTPProxyPort) < 0)
3610 REJECT("HTTPProxy failed to parse or resolve. Please fix.");
3611 if (options->HTTPProxyPort == 0) { /* give it a default */
3612 options->HTTPProxyPort = 80;
3616 if (options->HTTPProxyAuthenticator) {
3617 if (strlen(options->HTTPProxyAuthenticator) >= 512)
3618 REJECT("HTTPProxyAuthenticator is too long (>= 512 chars).");
3621 if (options->HTTPSProxy) { /* parse it now */
3622 if (tor_addr_port_lookup(options->HTTPSProxy,
3623 &options->HTTPSProxyAddr, &options->HTTPSProxyPort) <0)
3624 REJECT("HTTPSProxy failed to parse or resolve. Please fix.");
3625 if (options->HTTPSProxyPort == 0) { /* give it a default */
3626 options->HTTPSProxyPort = 443;
3630 if (options->HTTPSProxyAuthenticator) {
3631 if (strlen(options->HTTPSProxyAuthenticator) >= 512)
3632 REJECT("HTTPSProxyAuthenticator is too long (>= 512 chars).");
3635 if (options->Socks4Proxy) { /* parse it now */
3636 if (tor_addr_port_lookup(options->Socks4Proxy,
3637 &options->Socks4ProxyAddr,
3638 &options->Socks4ProxyPort) <0)
3639 REJECT("Socks4Proxy failed to parse or resolve. Please fix.");
3640 if (options->Socks4ProxyPort == 0) { /* give it a default */
3641 options->Socks4ProxyPort = 1080;
3645 if (options->Socks5Proxy) { /* parse it now */
3646 if (tor_addr_port_lookup(options->Socks5Proxy,
3647 &options->Socks5ProxyAddr,
3648 &options->Socks5ProxyPort) <0)
3649 REJECT("Socks5Proxy failed to parse or resolve. Please fix.");
3650 if (options->Socks5ProxyPort == 0) { /* give it a default */
3651 options->Socks5ProxyPort = 1080;
3655 /* Check if more than one proxy type has been enabled. */
3656 if (!!options->Socks4Proxy + !!options->Socks5Proxy +
3657 !!options->HTTPSProxy + !!options->ClientTransportPlugin > 1)
3658 REJECT("You have configured more than one proxy type. "
3659 "(Socks4Proxy|Socks5Proxy|HTTPSProxy|ClientTransportPlugin)");
3661 if (options->Socks5ProxyUsername) {
3662 size_t len;
3664 len = strlen(options->Socks5ProxyUsername);
3665 if (len < 1 || len > 255)
3666 REJECT("Socks5ProxyUsername must be between 1 and 255 characters.");
3668 if (!options->Socks5ProxyPassword)
3669 REJECT("Socks5ProxyPassword must be included with Socks5ProxyUsername.");
3671 len = strlen(options->Socks5ProxyPassword);
3672 if (len < 1 || len > 255)
3673 REJECT("Socks5ProxyPassword must be between 1 and 255 characters.");
3674 } else if (options->Socks5ProxyPassword)
3675 REJECT("Socks5ProxyPassword must be included with Socks5ProxyUsername.");
3677 if (options->HashedControlPassword) {
3678 smartlist_t *sl = decode_hashed_passwords(options->HashedControlPassword);
3679 if (!sl) {
3680 REJECT("Bad HashedControlPassword: wrong length or bad encoding");
3681 } else {
3682 SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
3683 smartlist_free(sl);
3687 if (options->HashedControlSessionPassword) {
3688 smartlist_t *sl = decode_hashed_passwords(
3689 options->HashedControlSessionPassword);
3690 if (!sl) {
3691 REJECT("Bad HashedControlSessionPassword: wrong length or bad encoding");
3692 } else {
3693 SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
3694 smartlist_free(sl);
3698 if (options->OwningControllerProcess) {
3699 const char *validate_pspec_msg = NULL;
3700 if (tor_validate_process_specifier(options->OwningControllerProcess,
3701 &validate_pspec_msg)) {
3702 tor_asprintf(msg, "Bad OwningControllerProcess: %s",
3703 validate_pspec_msg);
3704 return -1;
3708 if (options->ControlListenAddress) {
3709 int all_are_local = 1;
3710 config_line_t *ln;
3711 for (ln = options->ControlListenAddress; ln; ln = ln->next) {
3712 if (strcmpstart(ln->value, "127."))
3713 all_are_local = 0;
3715 if (!all_are_local) {
3716 if (!options->HashedControlPassword &&
3717 !options->HashedControlSessionPassword &&
3718 !options->CookieAuthentication) {
3719 log_warn(LD_CONFIG,
3720 "You have a ControlListenAddress set to accept "
3721 "unauthenticated connections from a non-local address. "
3722 "This means that programs not running on your computer "
3723 "can reconfigure your Tor, without even having to guess a "
3724 "password. That's so bad that I'm closing your ControlPort "
3725 "for you. If you need to control your Tor remotely, try "
3726 "enabling authentication and using a tool like stunnel or "
3727 "ssh to encrypt remote access.");
3728 options->ControlPort = 0;
3729 } else {
3730 log_warn(LD_CONFIG, "You have a ControlListenAddress set to accept "
3731 "connections from a non-local address. This means that "
3732 "programs not running on your computer can reconfigure your "
3733 "Tor. That's pretty bad, since the controller "
3734 "protocol isn't encrypted! Maybe you should just listen on "
3735 "127.0.0.1 and use a tool like stunnel or ssh to encrypt "
3736 "remote connections to your control port.");
3741 if (options->ControlPort && !options->HashedControlPassword &&
3742 !options->HashedControlSessionPassword &&
3743 !options->CookieAuthentication) {
3744 log_warn(LD_CONFIG, "ControlPort is open, but no authentication method "
3745 "has been configured. This means that any program on your "
3746 "computer can reconfigure your Tor. That's bad! You should "
3747 "upgrade your Tor controller as soon as possible.");
3750 if (options->CookieAuthFileGroupReadable && !options->CookieAuthFile) {
3751 log_warn(LD_CONFIG, "CookieAuthFileGroupReadable is set, but will have "
3752 "no effect: you must specify an explicit CookieAuthFile to "
3753 "have it group-readable.");
3756 if (options->UseEntryGuards && ! options->NumEntryGuards)
3757 REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0");
3759 if (check_nickname_list(options->MyFamily, "MyFamily", msg))
3760 return -1;
3761 for (cl = options->NodeFamilies; cl; cl = cl->next) {
3762 routerset_t *rs = routerset_new();
3763 if (routerset_parse(rs, cl->value, cl->key)) {
3764 routerset_free(rs);
3765 return -1;
3767 routerset_free(rs);
3770 if (validate_addr_policies(options, msg) < 0)
3771 return -1;
3773 if (validate_dir_authorities(options, old_options) < 0)
3774 REJECT("Directory authority line did not parse. See logs for details.");
3776 if (options->UseBridges && !options->Bridges)
3777 REJECT("If you set UseBridges, you must specify at least one bridge.");
3778 if (options->UseBridges && !options->TunnelDirConns)
3779 REJECT("If you set UseBridges, you must set TunnelDirConns.");
3781 for (cl = options->Bridges; cl; cl = cl->next) {
3782 if (parse_bridge_line(cl->value, 1)<0)
3783 REJECT("Bridge line did not parse. See logs for details.");
3786 for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
3787 if (parse_client_transport_line(cl->value, 1)<0)
3788 REJECT("Transport line did not parse. See logs for details.");
3791 for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
3792 if (parse_server_transport_line(cl->value, 1)<0)
3793 REJECT("Server transport line did not parse. See logs for details.");
3796 if (options->ConstrainedSockets) {
3797 /* If the user wants to constrain socket buffer use, make sure the desired
3798 * limit is between MIN|MAX_TCPSOCK_BUFFER in k increments. */
3799 if (options->ConstrainedSockSize < MIN_CONSTRAINED_TCP_BUFFER ||
3800 options->ConstrainedSockSize > MAX_CONSTRAINED_TCP_BUFFER ||
3801 options->ConstrainedSockSize % 1024) {
3802 tor_asprintf(msg,
3803 "ConstrainedSockSize is invalid. Must be a value between %d and %d "
3804 "in 1024 byte increments.",
3805 MIN_CONSTRAINED_TCP_BUFFER, MAX_CONSTRAINED_TCP_BUFFER);
3806 return -1;
3808 if (options->DirPort) {
3809 /* Providing cached directory entries while system TCP buffers are scarce
3810 * will exacerbate the socket errors. Suggest that this be disabled. */
3811 COMPLAIN("You have requested constrained socket buffers while also "
3812 "serving directory entries via DirPort. It is strongly "
3813 "suggested that you disable serving directory requests when "
3814 "system TCP buffer resources are scarce.");
3818 if (options->V3AuthVoteDelay + options->V3AuthDistDelay >=
3819 options->V3AuthVotingInterval/2) {
3820 REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than half "
3821 "V3AuthVotingInterval");
3823 if (options->V3AuthVoteDelay < MIN_VOTE_SECONDS)
3824 REJECT("V3AuthVoteDelay is way too low.");
3825 if (options->V3AuthDistDelay < MIN_DIST_SECONDS)
3826 REJECT("V3AuthDistDelay is way too low.");
3828 if (options->V3AuthNIntervalsValid < 2)
3829 REJECT("V3AuthNIntervalsValid must be at least 2.");
3831 if (options->V3AuthVotingInterval < MIN_VOTE_INTERVAL) {
3832 REJECT("V3AuthVotingInterval is insanely low.");
3833 } else if (options->V3AuthVotingInterval > 24*60*60) {
3834 REJECT("V3AuthVotingInterval is insanely high.");
3835 } else if (((24*60*60) % options->V3AuthVotingInterval) != 0) {
3836 COMPLAIN("V3AuthVotingInterval does not divide evenly into 24 hours.");
3839 if (rend_config_services(options, 1) < 0)
3840 REJECT("Failed to configure rendezvous options. See logs for details.");
3842 /* Parse client-side authorization for hidden services. */
3843 if (rend_parse_service_authorization(options, 1) < 0)
3844 REJECT("Failed to configure client authorization for hidden services. "
3845 "See logs for details.");
3847 if (parse_virtual_addr_network(options->VirtualAddrNetwork, 1, NULL)<0)
3848 return -1;
3850 if (options->PreferTunneledDirConns && !options->TunnelDirConns)
3851 REJECT("Must set TunnelDirConns if PreferTunneledDirConns is set.");
3853 if ((options->Socks4Proxy || options->Socks5Proxy) &&
3854 !options->HTTPProxy && !options->PreferTunneledDirConns)
3855 REJECT("When Socks4Proxy or Socks5Proxy is configured, "
3856 "PreferTunneledDirConns and TunnelDirConns must both be "
3857 "set to 1, or HTTPProxy must be configured.");
3859 if (options->AutomapHostsSuffixes) {
3860 SMARTLIST_FOREACH(options->AutomapHostsSuffixes, char *, suf,
3862 size_t len = strlen(suf);
3863 if (len && suf[len-1] == '.')
3864 suf[len-1] = '\0';
3868 if (options->TestingTorNetwork && !options->DirServers) {
3869 REJECT("TestingTorNetwork may only be configured in combination with "
3870 "a non-default set of DirServers.");
3873 if (options->AllowSingleHopExits && !options->DirServers) {
3874 COMPLAIN("You have set AllowSingleHopExits; now your relay will allow "
3875 "others to make one-hop exits. However, since by default most "
3876 "clients avoid relays that set this option, most clients will "
3877 "ignore you.");
3880 /*XXXX023 checking for defaults manually like this is a bit fragile.*/
3882 /* Keep changes to hard-coded values synchronous to man page and default
3883 * values table. */
3884 if (options->TestingV3AuthInitialVotingInterval != 30*60 &&
3885 !options->TestingTorNetwork && !options->_UsingTestNetworkDefaults) {
3886 REJECT("TestingV3AuthInitialVotingInterval may only be changed in testing "
3887 "Tor networks!");
3888 } else if (options->TestingV3AuthInitialVotingInterval < MIN_VOTE_INTERVAL) {
3889 REJECT("TestingV3AuthInitialVotingInterval is insanely low.");
3890 } else if (((30*60) % options->TestingV3AuthInitialVotingInterval) != 0) {
3891 REJECT("TestingV3AuthInitialVotingInterval does not divide evenly into "
3892 "30 minutes.");
3895 if (options->TestingV3AuthInitialVoteDelay != 5*60 &&
3896 !options->TestingTorNetwork && !options->_UsingTestNetworkDefaults) {
3898 REJECT("TestingV3AuthInitialVoteDelay may only be changed in testing "
3899 "Tor networks!");
3900 } else if (options->TestingV3AuthInitialVoteDelay < MIN_VOTE_SECONDS) {
3901 REJECT("TestingV3AuthInitialVoteDelay is way too low.");
3904 if (options->TestingV3AuthInitialDistDelay != 5*60 &&
3905 !options->TestingTorNetwork && !options->_UsingTestNetworkDefaults) {
3906 REJECT("TestingV3AuthInitialDistDelay may only be changed in testing "
3907 "Tor networks!");
3908 } else if (options->TestingV3AuthInitialDistDelay < MIN_DIST_SECONDS) {
3909 REJECT("TestingV3AuthInitialDistDelay is way too low.");
3912 if (options->TestingV3AuthInitialVoteDelay +
3913 options->TestingV3AuthInitialDistDelay >=
3914 options->TestingV3AuthInitialVotingInterval/2) {
3915 REJECT("TestingV3AuthInitialVoteDelay plus TestingV3AuthInitialDistDelay "
3916 "must be less than half TestingV3AuthInitialVotingInterval");
3919 if (options->TestingAuthDirTimeToLearnReachability != 30*60 &&
3920 !options->TestingTorNetwork && !options->_UsingTestNetworkDefaults) {
3921 REJECT("TestingAuthDirTimeToLearnReachability may only be changed in "
3922 "testing Tor networks!");
3923 } else if (options->TestingAuthDirTimeToLearnReachability < 0) {
3924 REJECT("TestingAuthDirTimeToLearnReachability must be non-negative.");
3925 } else if (options->TestingAuthDirTimeToLearnReachability > 2*60*60) {
3926 COMPLAIN("TestingAuthDirTimeToLearnReachability is insanely high.");
3929 if (options->TestingEstimatedDescriptorPropagationTime != 10*60 &&
3930 !options->TestingTorNetwork && !options->_UsingTestNetworkDefaults) {
3931 REJECT("TestingEstimatedDescriptorPropagationTime may only be changed in "
3932 "testing Tor networks!");
3933 } else if (options->TestingEstimatedDescriptorPropagationTime < 0) {
3934 REJECT("TestingEstimatedDescriptorPropagationTime must be non-negative.");
3935 } else if (options->TestingEstimatedDescriptorPropagationTime > 60*60) {
3936 COMPLAIN("TestingEstimatedDescriptorPropagationTime is insanely high.");
3939 if (options->TestingTorNetwork) {
3940 log_warn(LD_CONFIG, "TestingTorNetwork is set. This will make your node "
3941 "almost unusable in the public Tor network, and is "
3942 "therefore only advised if you are building a "
3943 "testing Tor network!");
3946 if (options->AccelName && !options->HardwareAccel)
3947 options->HardwareAccel = 1;
3948 if (options->AccelDir && !options->AccelName)
3949 REJECT("Can't use hardware crypto accelerator dir without engine name.");
3951 if (options->PublishServerDescriptor)
3952 SMARTLIST_FOREACH(options->PublishServerDescriptor, const char *, pubdes, {
3953 if (!strcmp(pubdes, "1") || !strcmp(pubdes, "0"))
3954 if (smartlist_len(options->PublishServerDescriptor) > 1) {
3955 COMPLAIN("You have passed a list of multiple arguments to the "
3956 "PublishServerDescriptor option that includes 0 or 1. "
3957 "0 or 1 should only be used as the sole argument. "
3958 "This configuration will be rejected in a future release.");
3959 break;
3963 if (options->BridgeRelay == 1 && options->ORPort == 0)
3964 REJECT("BridgeRelay is 1, ORPort is 0. This is an invalid combination.");
3966 return 0;
3967 #undef REJECT
3968 #undef COMPLAIN
3971 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
3972 * equal strings. */
3973 static int
3974 opt_streq(const char *s1, const char *s2)
3976 return 0 == strcmp_opt(s1, s2);
3979 /** Check if any of the previous options have changed but aren't allowed to. */
3980 static int
3981 options_transition_allowed(const or_options_t *old,
3982 const or_options_t *new_val,
3983 char **msg)
3985 if (!old)
3986 return 0;
3988 if (!opt_streq(old->PidFile, new_val->PidFile)) {
3989 *msg = tor_strdup("PidFile is not allowed to change.");
3990 return -1;
3993 if (old->RunAsDaemon != new_val->RunAsDaemon) {
3994 *msg = tor_strdup("While Tor is running, changing RunAsDaemon "
3995 "is not allowed.");
3996 return -1;
3999 if (strcmp(old->DataDirectory,new_val->DataDirectory)!=0) {
4000 tor_asprintf(msg,
4001 "While Tor is running, changing DataDirectory "
4002 "(\"%s\"->\"%s\") is not allowed.",
4003 old->DataDirectory, new_val->DataDirectory);
4004 return -1;
4007 if (!opt_streq(old->User, new_val->User)) {
4008 *msg = tor_strdup("While Tor is running, changing User is not allowed.");
4009 return -1;
4012 if ((old->HardwareAccel != new_val->HardwareAccel)
4013 || !opt_streq(old->AccelName, new_val->AccelName)
4014 || !opt_streq(old->AccelDir, new_val->AccelDir)) {
4015 *msg = tor_strdup("While Tor is running, changing OpenSSL hardware "
4016 "acceleration engine is not allowed.");
4017 return -1;
4020 if (old->TestingTorNetwork != new_val->TestingTorNetwork) {
4021 *msg = tor_strdup("While Tor is running, changing TestingTorNetwork "
4022 "is not allowed.");
4023 return -1;
4026 if (old->DisableAllSwap != new_val->DisableAllSwap) {
4027 *msg = tor_strdup("While Tor is running, changing DisableAllSwap "
4028 "is not allowed.");
4029 return -1;
4032 if (old->TokenBucketRefillInterval != new_val->TokenBucketRefillInterval) {
4033 *msg = tor_strdup("While Tor is running, changing TokenBucketRefill"
4034 "Interval is not allowed");
4035 return -1;
4038 if (old->DisableIOCP != new_val->DisableIOCP) {
4039 *msg = tor_strdup("While Tor is running, changing DisableIOCP "
4040 "is not allowed.");
4041 return -1;
4044 return 0;
4047 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
4048 * will require us to rotate the CPU and DNS workers; else return 0. */
4049 static int
4050 options_transition_affects_workers(const or_options_t *old_options,
4051 const or_options_t *new_options)
4053 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
4054 old_options->NumCPUs != new_options->NumCPUs ||
4055 old_options->ORPort != new_options->ORPort ||
4056 old_options->ServerDNSSearchDomains !=
4057 new_options->ServerDNSSearchDomains ||
4058 old_options->_SafeLogging != new_options->_SafeLogging ||
4059 old_options->ClientOnly != new_options->ClientOnly ||
4060 public_server_mode(old_options) != public_server_mode(new_options) ||
4061 !config_lines_eq(old_options->Logs, new_options->Logs) ||
4062 old_options->LogMessageDomains != new_options->LogMessageDomains)
4063 return 1;
4065 /* Check whether log options match. */
4067 /* Nothing that changed matters. */
4068 return 0;
4071 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
4072 * will require us to generate a new descriptor; else return 0. */
4073 static int
4074 options_transition_affects_descriptor(const or_options_t *old_options,
4075 const or_options_t *new_options)
4077 /* XXX We can be smarter here. If your DirPort isn't being
4078 * published and you just turned it off, no need to republish. Etc. */
4079 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
4080 !opt_streq(old_options->Nickname,new_options->Nickname) ||
4081 !opt_streq(old_options->Address,new_options->Address) ||
4082 !config_lines_eq(old_options->ExitPolicy,new_options->ExitPolicy) ||
4083 old_options->ExitPolicyRejectPrivate !=
4084 new_options->ExitPolicyRejectPrivate ||
4085 old_options->ORPort != new_options->ORPort ||
4086 old_options->DirPort != new_options->DirPort ||
4087 old_options->ClientOnly != new_options->ClientOnly ||
4088 old_options->_PublishServerDescriptor !=
4089 new_options->_PublishServerDescriptor ||
4090 get_effective_bwrate(old_options) != get_effective_bwrate(new_options) ||
4091 get_effective_bwburst(old_options) !=
4092 get_effective_bwburst(new_options) ||
4093 !opt_streq(old_options->ContactInfo, new_options->ContactInfo) ||
4094 !opt_streq(old_options->MyFamily, new_options->MyFamily) ||
4095 !opt_streq(old_options->AccountingStart, new_options->AccountingStart) ||
4096 old_options->AccountingMax != new_options->AccountingMax ||
4097 public_server_mode(old_options) != public_server_mode(new_options))
4098 return 1;
4100 return 0;
4103 #ifdef MS_WINDOWS
4104 /** Return the directory on windows where we expect to find our application
4105 * data. */
4106 static char *
4107 get_windows_conf_root(void)
4109 static int is_set = 0;
4110 static char path[MAX_PATH+1];
4111 TCHAR tpath[MAX_PATH] = {0};
4113 LPITEMIDLIST idl;
4114 IMalloc *m;
4115 HRESULT result;
4117 if (is_set)
4118 return path;
4120 /* Find X:\documents and settings\username\application data\ .
4121 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
4123 #ifdef ENABLE_LOCAL_APPDATA
4124 #define APPDATA_PATH CSIDL_LOCAL_APPDATA
4125 #else
4126 #define APPDATA_PATH CSIDL_APPDATA
4127 #endif
4128 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, APPDATA_PATH, &idl))) {
4129 getcwd(path,MAX_PATH);
4130 is_set = 1;
4131 log_warn(LD_CONFIG,
4132 "I couldn't find your application data folder: are you "
4133 "running an ancient version of Windows 95? Defaulting to \"%s\"",
4134 path);
4135 return path;
4137 /* Convert the path from an "ID List" (whatever that is!) to a path. */
4138 result = SHGetPathFromIDList(idl, tpath);
4139 #ifdef UNICODE
4140 wcstombs(path,tpath,MAX_PATH);
4141 #else
4142 strlcpy(path,tpath,sizeof(path));
4143 #endif
4145 /* Now we need to free the memory that the path-idl was stored in. In
4146 * typical Windows fashion, we can't just call 'free()' on it. */
4147 SHGetMalloc(&m);
4148 if (m) {
4149 m->lpVtbl->Free(m, idl);
4150 m->lpVtbl->Release(m);
4152 if (!SUCCEEDED(result)) {
4153 return NULL;
4155 strlcat(path,"\\tor",MAX_PATH);
4156 is_set = 1;
4157 return path;
4159 #endif
4161 /** Return the default location for our torrc file. */
4162 static const char *
4163 get_default_conf_file(void)
4165 #ifdef MS_WINDOWS
4166 static char path[MAX_PATH+1];
4167 strlcpy(path, get_windows_conf_root(), MAX_PATH);
4168 strlcat(path,"\\torrc",MAX_PATH);
4169 return path;
4170 #else
4171 return (CONFDIR "/torrc");
4172 #endif
4175 /** Verify whether lst is a string containing valid-looking comma-separated
4176 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
4178 static int
4179 check_nickname_list(const char *lst, const char *name, char **msg)
4181 int r = 0;
4182 smartlist_t *sl;
4184 if (!lst)
4185 return 0;
4186 sl = smartlist_create();
4188 smartlist_split_string(sl, lst, ",",
4189 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0);
4191 SMARTLIST_FOREACH(sl, const char *, s,
4193 if (!is_legal_nickname_or_hexdigest(s)) {
4194 tor_asprintf(msg, "Invalid nickname '%s' in %s line", s, name);
4195 r = -1;
4196 break;
4199 SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
4200 smartlist_free(sl);
4201 return r;
4204 /** Learn config file name from command line arguments, or use the default */
4205 static char *
4206 find_torrc_filename(int argc, char **argv,
4207 int *using_default_torrc, int *ignore_missing_torrc)
4209 char *fname=NULL;
4210 int i;
4212 for (i = 1; i < argc; ++i) {
4213 if (i < argc-1 && !strcmp(argv[i],"-f")) {
4214 if (fname) {
4215 log(LOG_WARN, LD_CONFIG, "Duplicate -f options on command line.");
4216 tor_free(fname);
4218 fname = expand_filename(argv[i+1]);
4219 *using_default_torrc = 0;
4220 ++i;
4221 } else if (!strcmp(argv[i],"--ignore-missing-torrc")) {
4222 *ignore_missing_torrc = 1;
4226 if (*using_default_torrc) {
4227 /* didn't find one, try CONFDIR */
4228 const char *dflt = get_default_conf_file();
4229 if (dflt && file_status(dflt) == FN_FILE) {
4230 fname = tor_strdup(dflt);
4231 } else {
4232 #ifndef MS_WINDOWS
4233 char *fn;
4234 fn = expand_filename("~/.torrc");
4235 if (fn && file_status(fn) == FN_FILE) {
4236 fname = fn;
4237 } else {
4238 tor_free(fn);
4239 fname = tor_strdup(dflt);
4241 #else
4242 fname = tor_strdup(dflt);
4243 #endif
4246 return fname;
4249 /** Load torrc from disk, setting torrc_fname if successful */
4250 static char *
4251 load_torrc_from_disk(int argc, char **argv)
4253 char *fname=NULL;
4254 char *cf = NULL;
4255 int using_default_torrc = 1;
4256 int ignore_missing_torrc = 0;
4258 fname = find_torrc_filename(argc, argv,
4259 &using_default_torrc, &ignore_missing_torrc);
4260 tor_assert(fname);
4261 log(LOG_DEBUG, LD_CONFIG, "Opening config file \"%s\"", fname);
4263 tor_free(torrc_fname);
4264 torrc_fname = fname;
4266 /* Open config file */
4267 if (file_status(fname) != FN_FILE ||
4268 !(cf = read_file_to_str(fname,0,NULL))) {
4269 if (using_default_torrc == 1 || ignore_missing_torrc ) {
4270 log(LOG_NOTICE, LD_CONFIG, "Configuration file \"%s\" not present, "
4271 "using reasonable defaults.", fname);
4272 tor_free(fname); /* sets fname to NULL */
4273 torrc_fname = NULL;
4274 cf = tor_strdup("");
4275 } else {
4276 log(LOG_WARN, LD_CONFIG,
4277 "Unable to open configuration file \"%s\".", fname);
4278 goto err;
4280 } else {
4281 log(LOG_NOTICE, LD_CONFIG, "Read configuration file \"%s\".", fname);
4284 return cf;
4285 err:
4286 tor_free(fname);
4287 torrc_fname = NULL;
4288 return NULL;
4291 /** Read a configuration file into <b>options</b>, finding the configuration
4292 * file location based on the command line. After loading the file
4293 * call options_init_from_string() to load the config.
4294 * Return 0 if success, -1 if failure. */
4296 options_init_from_torrc(int argc, char **argv)
4298 char *cf=NULL;
4299 int i, retval, command;
4300 static char **backup_argv;
4301 static int backup_argc;
4302 char *command_arg = NULL;
4303 char *errmsg=NULL;
4305 if (argv) { /* first time we're called. save command line args */
4306 backup_argv = argv;
4307 backup_argc = argc;
4308 } else { /* we're reloading. need to clean up old options first. */
4309 argv = backup_argv;
4310 argc = backup_argc;
4312 if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
4313 print_usage();
4314 exit(0);
4316 if (argc > 1 && !strcmp(argv[1], "--list-torrc-options")) {
4317 /* For documenting validating whether we've documented everything. */
4318 list_torrc_options();
4319 exit(0);
4322 if (argc > 1 && (!strcmp(argv[1],"--version"))) {
4323 printf("Tor version %s.\n",get_version());
4324 exit(0);
4326 if (argc > 1 && (!strcmp(argv[1],"--digests"))) {
4327 printf("Tor version %s.\n",get_version());
4328 printf("%s", libor_get_digests());
4329 printf("%s", tor_get_digests());
4330 exit(0);
4333 /* Go through command-line variables */
4334 if (!global_cmdline_options) {
4335 /* Or we could redo the list every time we pass this place.
4336 * It does not really matter */
4337 if (config_get_commandlines(argc, argv, &global_cmdline_options) < 0) {
4338 goto err;
4342 command = CMD_RUN_TOR;
4343 for (i = 1; i < argc; ++i) {
4344 if (!strcmp(argv[i],"--list-fingerprint")) {
4345 command = CMD_LIST_FINGERPRINT;
4346 } else if (!strcmp(argv[i],"--hash-password")) {
4347 command = CMD_HASH_PASSWORD;
4348 command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : "");
4349 ++i;
4350 } else if (!strcmp(argv[i],"--verify-config")) {
4351 command = CMD_VERIFY_CONFIG;
4355 if (command == CMD_HASH_PASSWORD) {
4356 cf = tor_strdup("");
4357 } else {
4358 cf = load_torrc_from_disk(argc, argv);
4359 if (!cf)
4360 goto err;
4363 retval = options_init_from_string(cf, command, command_arg, &errmsg);
4364 tor_free(cf);
4365 if (retval < 0)
4366 goto err;
4368 return 0;
4370 err:
4371 if (errmsg) {
4372 log(LOG_WARN,LD_CONFIG,"%s", errmsg);
4373 tor_free(errmsg);
4375 return -1;
4378 /** Load the options from the configuration in <b>cf</b>, validate
4379 * them for consistency and take actions based on them.
4381 * Return 0 if success, negative on error:
4382 * * -1 for general errors.
4383 * * -2 for failure to parse/validate,
4384 * * -3 for transition not allowed
4385 * * -4 for error while setting the new options
4387 setopt_err_t
4388 options_init_from_string(const char *cf,
4389 int command, const char *command_arg,
4390 char **msg)
4392 or_options_t *oldoptions, *newoptions;
4393 config_line_t *cl;
4394 int retval;
4395 setopt_err_t err = SETOPT_ERR_MISC;
4396 tor_assert(msg);
4398 oldoptions = global_options; /* get_options unfortunately asserts if
4399 this is the first time we run*/
4401 newoptions = tor_malloc_zero(sizeof(or_options_t));
4402 newoptions->_magic = OR_OPTIONS_MAGIC;
4403 options_init(newoptions);
4404 newoptions->command = command;
4405 newoptions->command_arg = command_arg;
4407 /* get config lines, assign them */
4408 retval = config_get_lines(cf, &cl);
4409 if (retval < 0) {
4410 err = SETOPT_ERR_PARSE;
4411 goto err;
4413 retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
4414 config_free_lines(cl);
4415 if (retval < 0) {
4416 err = SETOPT_ERR_PARSE;
4417 goto err;
4420 /* Go through command-line variables too */
4421 retval = config_assign(&options_format, newoptions,
4422 global_cmdline_options, 0, 0, msg);
4423 if (retval < 0) {
4424 err = SETOPT_ERR_PARSE;
4425 goto err;
4428 /* If this is a testing network configuration, change defaults
4429 * for a list of dependent config options, re-initialize newoptions
4430 * with the new defaults, and assign all options to it second time. */
4431 if (newoptions->TestingTorNetwork) {
4432 /* XXXX this is a bit of a kludge. perhaps there's a better way to do
4433 * this? We could, for example, make the parsing algorithm do two passes
4434 * over the configuration. If it finds any "suite" options like
4435 * TestingTorNetwork, it could change the defaults before its second pass.
4436 * Not urgent so long as this seems to work, but at any sign of trouble,
4437 * let's clean it up. -NM */
4439 /* Change defaults. */
4440 int i;
4441 for (i = 0; testing_tor_network_defaults[i].name; ++i) {
4442 const config_var_t *new_var = &testing_tor_network_defaults[i];
4443 config_var_t *old_var =
4444 config_find_option_mutable(&options_format, new_var->name);
4445 tor_assert(new_var);
4446 tor_assert(old_var);
4447 old_var->initvalue = new_var->initvalue;
4450 /* Clear newoptions and re-initialize them with new defaults. */
4451 config_free(&options_format, newoptions);
4452 newoptions = tor_malloc_zero(sizeof(or_options_t));
4453 newoptions->_magic = OR_OPTIONS_MAGIC;
4454 options_init(newoptions);
4455 newoptions->command = command;
4456 newoptions->command_arg = command_arg;
4458 /* Assign all options a second time. */
4459 retval = config_get_lines(cf, &cl);
4460 if (retval < 0) {
4461 err = SETOPT_ERR_PARSE;
4462 goto err;
4464 retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
4465 config_free_lines(cl);
4466 if (retval < 0) {
4467 err = SETOPT_ERR_PARSE;
4468 goto err;
4470 retval = config_assign(&options_format, newoptions,
4471 global_cmdline_options, 0, 0, msg);
4472 if (retval < 0) {
4473 err = SETOPT_ERR_PARSE;
4474 goto err;
4478 /* Validate newoptions */
4479 if (options_validate(oldoptions, newoptions, 0, msg) < 0) {
4480 err = SETOPT_ERR_PARSE; /*XXX make this a separate return value.*/
4481 goto err;
4484 if (options_transition_allowed(oldoptions, newoptions, msg) < 0) {
4485 err = SETOPT_ERR_TRANSITION;
4486 goto err;
4489 if (set_options(newoptions, msg)) {
4490 err = SETOPT_ERR_SETTING;
4491 goto err; /* frees and replaces old options */
4494 return SETOPT_OK;
4496 err:
4497 config_free(&options_format, newoptions);
4498 if (*msg) {
4499 char *old_msg = *msg;
4500 tor_asprintf(msg, "Failed to parse/validate config: %s", old_msg);
4501 tor_free(old_msg);
4503 return err;
4506 /** Return the location for our configuration file.
4508 const char *
4509 get_torrc_fname(void)
4511 if (torrc_fname)
4512 return torrc_fname;
4513 else
4514 return get_default_conf_file();
4517 /** Adjust the address map based on the MapAddress elements in the
4518 * configuration <b>options</b>
4520 void
4521 config_register_addressmaps(const or_options_t *options)
4523 smartlist_t *elts;
4524 config_line_t *opt;
4525 char *from, *to;
4527 addressmap_clear_configured();
4528 elts = smartlist_create();
4529 for (opt = options->AddressMap; opt; opt = opt->next) {
4530 smartlist_split_string(elts, opt->value, NULL,
4531 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
4532 if (smartlist_len(elts) >= 2) {
4533 from = smartlist_get(elts,0);
4534 to = smartlist_get(elts,1);
4535 if (address_is_invalid_destination(to, 1)) {
4536 log_warn(LD_CONFIG,
4537 "Skipping invalid argument '%s' to MapAddress", to);
4538 } else {
4539 addressmap_register(from, tor_strdup(to), 0, ADDRMAPSRC_TORRC);
4540 if (smartlist_len(elts)>2) {
4541 log_warn(LD_CONFIG,"Ignoring extra arguments to MapAddress.");
4544 } else {
4545 log_warn(LD_CONFIG,"MapAddress '%s' has too few arguments. Ignoring.",
4546 opt->value);
4548 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
4549 smartlist_clear(elts);
4551 smartlist_free(elts);
4555 * Initialize the logs based on the configuration file.
4557 static int
4558 options_init_logs(or_options_t *options, int validate_only)
4560 config_line_t *opt;
4561 int ok;
4562 smartlist_t *elts;
4563 int daemon =
4564 #ifdef MS_WINDOWS
4566 #else
4567 options->RunAsDaemon;
4568 #endif
4570 if (options->LogTimeGranularity <= 0) {
4571 log_warn(LD_CONFIG, "Log time granularity '%d' has to be positive.",
4572 options->LogTimeGranularity);
4573 return -1;
4574 } else if (1000 % options->LogTimeGranularity != 0 &&
4575 options->LogTimeGranularity % 1000 != 0) {
4576 int granularity = options->LogTimeGranularity;
4577 if (granularity < 40) {
4578 do granularity++;
4579 while (1000 % granularity != 0);
4580 } else if (granularity < 1000) {
4581 granularity = 1000 / granularity;
4582 while (1000 % granularity != 0)
4583 granularity--;
4584 granularity = 1000 / granularity;
4585 } else {
4586 granularity = 1000 * ((granularity / 1000) + 1);
4588 log_warn(LD_CONFIG, "Log time granularity '%d' has to be either a "
4589 "divisor or a multiple of 1 second. Changing to "
4590 "'%d'.",
4591 options->LogTimeGranularity, granularity);
4592 if (!validate_only)
4593 set_log_time_granularity(granularity);
4594 } else {
4595 if (!validate_only)
4596 set_log_time_granularity(options->LogTimeGranularity);
4599 ok = 1;
4600 elts = smartlist_create();
4602 for (opt = options->Logs; opt; opt = opt->next) {
4603 log_severity_list_t *severity;
4604 const char *cfg = opt->value;
4605 severity = tor_malloc_zero(sizeof(log_severity_list_t));
4606 if (parse_log_severity_config(&cfg, severity) < 0) {
4607 log_warn(LD_CONFIG, "Couldn't parse log levels in Log option 'Log %s'",
4608 opt->value);
4609 ok = 0; goto cleanup;
4612 smartlist_split_string(elts, cfg, NULL,
4613 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
4615 if (smartlist_len(elts) == 0)
4616 smartlist_add(elts, tor_strdup("stdout"));
4618 if (smartlist_len(elts) == 1 &&
4619 (!strcasecmp(smartlist_get(elts,0), "stdout") ||
4620 !strcasecmp(smartlist_get(elts,0), "stderr"))) {
4621 int err = smartlist_len(elts) &&
4622 !strcasecmp(smartlist_get(elts,0), "stderr");
4623 if (!validate_only) {
4624 if (daemon) {
4625 log_warn(LD_CONFIG,
4626 "Can't log to %s with RunAsDaemon set; skipping stdout",
4627 err?"stderr":"stdout");
4628 } else {
4629 add_stream_log(severity, err?"<stderr>":"<stdout>",
4630 fileno(err?stderr:stdout));
4633 goto cleanup;
4635 if (smartlist_len(elts) == 1 &&
4636 !strcasecmp(smartlist_get(elts,0), "syslog")) {
4637 #ifdef HAVE_SYSLOG_H
4638 if (!validate_only) {
4639 add_syslog_log(severity);
4641 #else
4642 log_warn(LD_CONFIG, "Syslog is not supported on this system. Sorry.");
4643 #endif
4644 goto cleanup;
4647 if (smartlist_len(elts) == 2 &&
4648 !strcasecmp(smartlist_get(elts,0), "file")) {
4649 if (!validate_only) {
4650 char *fname = expand_filename(smartlist_get(elts, 1));
4651 if (add_file_log(severity, fname) < 0) {
4652 log_warn(LD_CONFIG, "Couldn't open file for 'Log %s': %s",
4653 opt->value, strerror(errno));
4654 ok = 0;
4656 tor_free(fname);
4658 goto cleanup;
4661 log_warn(LD_CONFIG, "Bad syntax on file Log option 'Log %s'",
4662 opt->value);
4663 ok = 0; goto cleanup;
4665 cleanup:
4666 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
4667 smartlist_clear(elts);
4668 tor_free(severity);
4670 smartlist_free(elts);
4672 if (ok && !validate_only)
4673 logs_set_domain_logging(options->LogMessageDomains);
4675 return ok?0:-1;
4678 /** Read the contents of a Bridge line from <b>line</b>. Return 0
4679 * if the line is well-formed, and -1 if it isn't. If
4680 * <b>validate_only</b> is 0, and the line is well-formed, then add
4681 * the bridge described in the line to our internal bridge list. */
4682 static int
4683 parse_bridge_line(const char *line, int validate_only)
4685 smartlist_t *items = NULL;
4686 int r;
4687 char *addrport=NULL, *fingerprint=NULL;
4688 char *transport_name=NULL;
4689 char *field1=NULL;
4690 tor_addr_t addr;
4691 uint16_t port = 0;
4692 char digest[DIGEST_LEN];
4694 items = smartlist_create();
4695 smartlist_split_string(items, line, NULL,
4696 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
4697 if (smartlist_len(items) < 1) {
4698 log_warn(LD_CONFIG, "Too few arguments to Bridge line.");
4699 goto err;
4702 /* field1 is either a transport name or addrport */
4703 field1 = smartlist_get(items, 0);
4704 smartlist_del_keeporder(items, 0);
4706 if (!(strstr(field1, ".") || strstr(field1, ":"))) {
4707 /* new-style bridge line */
4708 transport_name = field1;
4709 if (smartlist_len(items) < 1) {
4710 log_warn(LD_CONFIG, "Too few items to Bridge line.");
4711 goto err;
4713 addrport = smartlist_get(items, 0);
4714 smartlist_del_keeporder(items, 0);
4715 } else {
4716 addrport = field1;
4719 if (tor_addr_port_lookup(addrport, &addr, &port)<0) {
4720 log_warn(LD_CONFIG, "Error parsing Bridge address '%s'", addrport);
4721 goto err;
4723 if (!port) {
4724 log_info(LD_CONFIG,
4725 "Bridge address '%s' has no port; using default port 443.",
4726 addrport);
4727 port = 443;
4730 if (smartlist_len(items)) {
4731 fingerprint = smartlist_join_strings(items, "", 0, NULL);
4732 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
4733 log_warn(LD_CONFIG, "Key digest for Bridge is wrong length.");
4734 goto err;
4736 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
4737 log_warn(LD_CONFIG, "Unable to decode Bridge key digest.");
4738 goto err;
4742 if (!validate_only) {
4743 log_debug(LD_DIR, "Bridge at %s:%d (transport: %s) (%s)",
4744 fmt_addr(&addr), (int)port,
4745 transport_name ? transport_name : "no transport",
4746 fingerprint ? fingerprint : "no key listed");
4747 bridge_add_from_config(&addr, port,
4748 fingerprint ? digest : NULL, transport_name);
4751 r = 0;
4752 goto done;
4754 err:
4755 r = -1;
4757 done:
4758 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
4759 smartlist_free(items);
4760 tor_free(addrport);
4761 tor_free(transport_name);
4762 tor_free(fingerprint);
4763 return r;
4766 /** Read the contents of a ClientTransportPlugin line from
4767 * <b>line</b>. Return 0 if the line is well-formed, and -1 if it
4768 * isn't.
4770 * If <b>validate_only</b> is 0, and the line is well-formed:
4771 * - If it's an external proxy line, add the transport described in the line to
4772 * our internal transport list.
4773 * - If it's a managed proxy line, launch the managed proxy. */
4774 static int
4775 parse_client_transport_line(const char *line, int validate_only)
4777 smartlist_t *items = NULL;
4778 int r;
4779 char *field2=NULL;
4781 const char *transports=NULL;
4782 smartlist_t *transport_list=NULL;
4783 char *addrport=NULL;
4784 tor_addr_t addr;
4785 uint16_t port = 0;
4786 int socks_ver=PROXY_NONE;
4788 /* managed proxy options */
4789 int is_managed=0;
4790 char **proxy_argv=NULL;
4791 char **tmp=NULL;
4792 int proxy_argc,i;
4794 int line_length;
4796 items = smartlist_create();
4797 smartlist_split_string(items, line, NULL,
4798 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
4800 line_length = smartlist_len(items);
4801 if (line_length < 3) {
4802 log_warn(LD_CONFIG, "Too few arguments on ClientTransportPlugin line.");
4803 goto err;
4806 /* Get the first line element, split it to commas into
4807 transport_list (in case it's multiple transports) and validate
4808 the transport names. */
4809 transports = smartlist_get(items, 0);
4810 transport_list = smartlist_create();
4811 smartlist_split_string(transport_list, transports, ",",
4812 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4813 SMARTLIST_FOREACH_BEGIN(transport_list, const char *, transport_name) {
4814 if (!string_is_C_identifier(transport_name)) {
4815 log_warn(LD_CONFIG, "Transport name is not a C identifier (%s).",
4816 transport_name);
4817 goto err;
4819 } SMARTLIST_FOREACH_END(transport_name);
4821 /* field2 is either a SOCKS version or "exec" */
4822 field2 = smartlist_get(items, 1);
4824 if (!strcmp(field2,"socks4")) {
4825 socks_ver = PROXY_SOCKS4;
4826 } else if (!strcmp(field2,"socks5")) {
4827 socks_ver = PROXY_SOCKS5;
4828 } else if (!strcmp(field2,"exec")) {
4829 is_managed=1;
4830 } else {
4831 log_warn(LD_CONFIG, "Strange ClientTransportPlugin field '%s'.",
4832 field2);
4833 goto err;
4836 if (is_managed) { /* managed */
4837 if (!validate_only) { /* if we are not just validating, use the
4838 rest of the line as the argv of the proxy
4839 to be launched */
4840 proxy_argc = line_length-2;
4841 tor_assert(proxy_argc > 0);
4842 proxy_argv = tor_malloc_zero(sizeof(char*)*(proxy_argc+1));
4843 tmp = proxy_argv;
4844 for (i=0;i<proxy_argc;i++) { /* store arguments */
4845 *tmp++ = smartlist_get(items, 2);
4846 smartlist_del_keeporder(items, 2);
4848 *tmp = NULL; /*terminated with NUL pointer, just like execve() likes it*/
4850 /* kickstart the thing */
4851 pt_kickstart_client_proxy(transport_list, proxy_argv);
4853 } else { /* external */
4854 if (smartlist_len(transport_list) != 1) {
4855 log_warn(LD_CONFIG, "You can't have an external proxy with "
4856 "more than one transports.");
4857 goto err;
4860 addrport = smartlist_get(items, 2);
4862 if (tor_addr_port_lookup(addrport, &addr, &port)<0) {
4863 log_warn(LD_CONFIG, "Error parsing transport "
4864 "address '%s'", addrport);
4865 goto err;
4867 if (!port) {
4868 log_warn(LD_CONFIG,
4869 "Transport address '%s' has no port.", addrport);
4870 goto err;
4873 if (!validate_only) {
4874 transport_add_from_config(&addr, port, smartlist_get(transport_list, 0),
4875 socks_ver);
4877 log_info(LD_DIR, "Transport '%s' found at %s:%d",
4878 transports, fmt_addr(&addr), (int)port);
4882 r = 0;
4883 goto done;
4885 err:
4886 r = -1;
4888 done:
4889 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
4890 smartlist_free(items);
4891 if (transport_list) {
4892 SMARTLIST_FOREACH(transport_list, char*, s, tor_free(s));
4893 smartlist_free(transport_list);
4896 return r;
4899 /** Read the contents of a ServerTransportPlugin line from
4900 * <b>line</b>. Return 0 if the line is well-formed, and -1 if it
4901 * isn't.
4902 * If <b>validate_only</b> is 0, the line is well-formed, and it's a
4903 * managed proxy line, launch the managed proxy. */
4904 static int
4905 parse_server_transport_line(const char *line, int validate_only)
4907 smartlist_t *items = NULL;
4908 int r;
4909 const char *transports=NULL;
4910 smartlist_t *transport_list=NULL;
4911 char *type=NULL;
4912 char *addrport=NULL;
4913 tor_addr_t addr;
4914 uint16_t port = 0;
4916 /* managed proxy options */
4917 int is_managed=0;
4918 char **proxy_argv=NULL;
4919 char **tmp=NULL;
4920 int proxy_argc,i;
4922 int line_length;
4924 items = smartlist_create();
4925 smartlist_split_string(items, line, NULL,
4926 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
4928 line_length = smartlist_len(items);
4929 if (line_length < 3) {
4930 log_warn(LD_CONFIG, "Too few arguments on ServerTransportPlugin line.");
4931 goto err;
4934 /* Get the first line element, split it to commas into
4935 transport_list (in case it's multiple transports) and validate
4936 the transport names. */
4937 transports = smartlist_get(items, 0);
4938 transport_list = smartlist_create();
4939 smartlist_split_string(transport_list, transports, ",",
4940 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
4941 SMARTLIST_FOREACH_BEGIN(transport_list, const char *, transport_name) {
4942 if (!string_is_C_identifier(transport_name)) {
4943 log_warn(LD_CONFIG, "Transport name is not a C identifier (%s).",
4944 transport_name);
4945 goto err;
4947 } SMARTLIST_FOREACH_END(transport_name);
4949 type = smartlist_get(items, 1);
4951 if (!strcmp(type, "exec")) {
4952 is_managed=1;
4953 } else if (!strcmp(type, "proxy")) {
4954 is_managed=0;
4955 } else {
4956 log_warn(LD_CONFIG, "Strange ServerTransportPlugin type '%s'", type);
4957 goto err;
4960 if (is_managed) { /* managed */
4961 if (!validate_only) {
4962 proxy_argc = line_length-2;
4963 tor_assert(proxy_argc > 0);
4964 proxy_argv = tor_malloc_zero(sizeof(char*)*(proxy_argc+1));
4965 tmp = proxy_argv;
4967 for (i=0;i<proxy_argc;i++) { /* store arguments */
4968 *tmp++ = smartlist_get(items, 2);
4969 smartlist_del_keeporder(items, 2);
4971 *tmp = NULL; /*terminated with NUL pointer, just like execve() likes it*/
4973 /* kickstart the thing */
4974 pt_kickstart_server_proxy(transport_list, proxy_argv);
4976 } else { /* external */
4977 if (smartlist_len(transport_list) != 1) {
4978 log_warn(LD_CONFIG, "You can't have an external proxy with "
4979 "more than one transports.");
4980 goto err;
4983 addrport = smartlist_get(items, 2);
4985 if (tor_addr_port_lookup(addrport, &addr, &port)<0) {
4986 log_warn(LD_CONFIG, "Error parsing transport "
4987 "address '%s'", addrport);
4988 goto err;
4990 if (!port) {
4991 log_warn(LD_CONFIG,
4992 "Transport address '%s' has no port.", addrport);
4993 goto err;
4996 if (!validate_only) {
4997 log_info(LD_DIR, "Server transport '%s' at %s:%d.",
4998 transports, fmt_addr(&addr), (int)port);
5002 r = 0;
5003 goto done;
5005 err:
5006 r = -1;
5008 done:
5009 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
5010 smartlist_free(items);
5011 if (transport_list) {
5012 SMARTLIST_FOREACH(transport_list, char*, s, tor_free(s));
5013 smartlist_free(transport_list);
5016 return r;
5019 /** Read the contents of a DirServer line from <b>line</b>. If
5020 * <b>validate_only</b> is 0, and the line is well-formed, and it
5021 * shares any bits with <b>required_type</b> or <b>required_type</b>
5022 * is 0, then add the dirserver described in the line (minus whatever
5023 * bits it's missing) as a valid authority. Return 0 on success,
5024 * or -1 if the line isn't well-formed or if we can't add it. */
5025 static int
5026 parse_dir_server_line(const char *line, dirinfo_type_t required_type,
5027 int validate_only)
5029 smartlist_t *items = NULL;
5030 int r;
5031 char *addrport=NULL, *address=NULL, *nickname=NULL, *fingerprint=NULL;
5032 uint16_t dir_port = 0, or_port = 0;
5033 char digest[DIGEST_LEN];
5034 char v3_digest[DIGEST_LEN];
5035 dirinfo_type_t type = V2_DIRINFO;
5036 int is_not_hidserv_authority = 0, is_not_v2_authority = 0;
5038 items = smartlist_create();
5039 smartlist_split_string(items, line, NULL,
5040 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
5041 if (smartlist_len(items) < 1) {
5042 log_warn(LD_CONFIG, "No arguments on DirServer line.");
5043 goto err;
5046 if (is_legal_nickname(smartlist_get(items, 0))) {
5047 nickname = smartlist_get(items, 0);
5048 smartlist_del_keeporder(items, 0);
5051 while (smartlist_len(items)) {
5052 char *flag = smartlist_get(items, 0);
5053 if (TOR_ISDIGIT(flag[0]))
5054 break;
5055 if (!strcasecmp(flag, "v1")) {
5056 type |= (V1_DIRINFO | HIDSERV_DIRINFO);
5057 } else if (!strcasecmp(flag, "hs")) {
5058 type |= HIDSERV_DIRINFO;
5059 } else if (!strcasecmp(flag, "no-hs")) {
5060 is_not_hidserv_authority = 1;
5061 } else if (!strcasecmp(flag, "bridge")) {
5062 type |= BRIDGE_DIRINFO;
5063 } else if (!strcasecmp(flag, "no-v2")) {
5064 is_not_v2_authority = 1;
5065 } else if (!strcasecmpstart(flag, "orport=")) {
5066 int ok;
5067 char *portstring = flag + strlen("orport=");
5068 or_port = (uint16_t) tor_parse_long(portstring, 10, 1, 65535, &ok, NULL);
5069 if (!ok)
5070 log_warn(LD_CONFIG, "Invalid orport '%s' on DirServer line.",
5071 portstring);
5072 } else if (!strcasecmpstart(flag, "v3ident=")) {
5073 char *idstr = flag + strlen("v3ident=");
5074 if (strlen(idstr) != HEX_DIGEST_LEN ||
5075 base16_decode(v3_digest, DIGEST_LEN, idstr, HEX_DIGEST_LEN)<0) {
5076 log_warn(LD_CONFIG, "Bad v3 identity digest '%s' on DirServer line",
5077 flag);
5078 } else {
5079 type |= V3_DIRINFO|EXTRAINFO_DIRINFO|MICRODESC_DIRINFO;
5081 } else {
5082 log_warn(LD_CONFIG, "Unrecognized flag '%s' on DirServer line",
5083 flag);
5085 tor_free(flag);
5086 smartlist_del_keeporder(items, 0);
5088 if (is_not_hidserv_authority)
5089 type &= ~HIDSERV_DIRINFO;
5090 if (is_not_v2_authority)
5091 type &= ~V2_DIRINFO;
5093 if (smartlist_len(items) < 2) {
5094 log_warn(LD_CONFIG, "Too few arguments to DirServer line.");
5095 goto err;
5097 addrport = smartlist_get(items, 0);
5098 smartlist_del_keeporder(items, 0);
5099 if (addr_port_lookup(LOG_WARN, addrport, &address, NULL, &dir_port)<0) {
5100 log_warn(LD_CONFIG, "Error parsing DirServer address '%s'", addrport);
5101 goto err;
5103 if (!dir_port) {
5104 log_warn(LD_CONFIG, "Missing port in DirServer address '%s'",addrport);
5105 goto err;
5108 fingerprint = smartlist_join_strings(items, "", 0, NULL);
5109 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
5110 log_warn(LD_CONFIG, "Key digest for DirServer is wrong length %d.",
5111 (int)strlen(fingerprint));
5112 goto err;
5114 if (!strcmp(fingerprint, "E623F7625FBE0C87820F11EC5F6D5377ED816294")) {
5115 /* a known bad fingerprint. refuse to use it. We can remove this
5116 * clause once Tor 0.1.2.17 is obsolete. */
5117 log_warn(LD_CONFIG, "Dangerous dirserver line. To correct, erase your "
5118 "torrc file (%s), or reinstall Tor and use the default torrc.",
5119 get_torrc_fname());
5120 goto err;
5122 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
5123 log_warn(LD_CONFIG, "Unable to decode DirServer key digest.");
5124 goto err;
5127 if (!validate_only && (!required_type || required_type & type)) {
5128 if (required_type)
5129 type &= required_type; /* pare down what we think of them as an
5130 * authority for. */
5131 log_debug(LD_DIR, "Trusted %d dirserver at %s:%d (%s)", (int)type,
5132 address, (int)dir_port, (char*)smartlist_get(items,0));
5133 if (!add_trusted_dir_server(nickname, address, dir_port, or_port,
5134 digest, v3_digest, type))
5135 goto err;
5138 r = 0;
5139 goto done;
5141 err:
5142 r = -1;
5144 done:
5145 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
5146 smartlist_free(items);
5147 tor_free(addrport);
5148 tor_free(address);
5149 tor_free(nickname);
5150 tor_free(fingerprint);
5151 return r;
5154 /** Free all storage held in <b>port</b> */
5155 static void
5156 port_cfg_free(port_cfg_t *port)
5158 tor_free(port);
5161 /** Warn for every port in <b>ports</b> that is on a publicly routable
5162 * address. */
5163 static void
5164 warn_nonlocal_client_ports(const smartlist_t *ports, const char *portname)
5166 SMARTLIST_FOREACH_BEGIN(ports, const port_cfg_t *, port) {
5167 if (port->is_unix_addr) {
5168 /* Unix sockets aren't accessible over a network. */
5169 } else if (!tor_addr_is_internal(&port->addr, 1)) {
5170 log_warn(LD_CONFIG, "You specified a public address for %sPort. "
5171 "Other people on the Internet might find your computer and "
5172 "use it as an open proxy. Please don't allow this unless you "
5173 "have a good reason.", portname);
5174 } else if (!tor_addr_is_loopback(&port->addr)) {
5175 log_notice(LD_CONFIG, "You configured a non-loopback address for "
5176 "%sPort. This allows everybody on your local network to use "
5177 "your machine as a proxy. Make sure this is what you wanted.",
5178 portname);
5180 } SMARTLIST_FOREACH_END(port);
5183 #define CL_PORT_NO_OPTIONS (1u<<0)
5184 #define CL_PORT_WARN_NONLOCAL (1u<<1)
5185 #define CL_PORT_ALLOW_EXTRA_LISTENADDR (1u<<2)
5188 * Parse port configuration for a single client port type.
5190 * Read entries of the "FooPort" type from the list <b>ports</b>, and
5191 * entries of the "FooListenAddress" type from the list
5192 * <b>listenaddrs</b>. Two syntaxes are supported: a legacy syntax
5193 * where FooPort is at most a single entry containing a port number and
5194 * where FooListenAddress has any number of address:port combinations;
5195 * and a new syntax where there are no FooListenAddress entries and
5196 * where FooPort can have any number of entries of the format
5197 * "[Address:][Port] IsolationOptions".
5199 * In log messages, describe the port type as <b>portname</b>.
5201 * If no address is specified, default to <b>defaultaddr</b>. If no
5202 * FooPort is given, default to defaultport (if 0, there is no default).
5204 * If CL_PORT_NO_OPTIONS is set in <b>flags</b>, do not allow stream
5205 * isolation options in the FooPort entries.
5207 * If CL_PORT_WARN_NONLOCAL is set in <b>flags</b>, warn if any of the
5208 * ports are not on a local address.
5210 * Unless CL_PORT_ALLOW_EXTRA_LISTENADDR is set in <b>flags</b>, warn
5211 * if FooListenAddress is set but FooPort is 0.
5213 * On success, if <b>out</b> is given, add a new port_cfg_t entry to
5214 * <b>out</b> for every port that the client should listen on. Return 0
5215 * on success, -1 on failure.
5217 static int
5218 parse_client_port_config(smartlist_t *out,
5219 const config_line_t *ports,
5220 const config_line_t *listenaddrs,
5221 const char *portname,
5222 int listener_type,
5223 const char *defaultaddr,
5224 int defaultport,
5225 unsigned flags)
5227 smartlist_t *elts;
5228 int retval = -1;
5229 const unsigned allow_client_options = !(flags & CL_PORT_NO_OPTIONS);
5230 const unsigned warn_nonlocal = flags & CL_PORT_WARN_NONLOCAL;
5231 const unsigned allow_spurious_listenaddr =
5232 flags & CL_PORT_ALLOW_EXTRA_LISTENADDR;
5234 /* FooListenAddress is deprecated; let's make it work like it used to work,
5235 * though. */
5236 if (listenaddrs) {
5237 int mainport = defaultport;
5239 if (ports && ports->next) {
5240 log_warn(LD_CONFIG, "%sListenAddress can't be used when there are "
5241 "multiple %sPort lines", portname, portname);
5242 return -1;
5243 } else if (ports) {
5244 if (!strcmp(ports->value, "auto")) {
5245 mainport = CFG_AUTO_PORT;
5246 } else {
5247 int ok;
5248 mainport = (int)tor_parse_long(ports->value, 10, 0, 65535, &ok, NULL);
5249 if (!ok) {
5250 log_warn(LD_CONFIG, "%sListenAddress can only be used with a single "
5251 "%sPort with value \"auto\" or 1-65535.",
5252 portname, portname);
5253 return -1;
5258 if (mainport == 0) {
5259 if (allow_spurious_listenaddr)
5260 return 1;
5261 log_warn(LD_CONFIG, "%sPort must be defined if %sListenAddress is used",
5262 portname, portname);
5263 return -1;
5266 for (; listenaddrs; listenaddrs = listenaddrs->next) {
5267 tor_addr_t addr;
5268 uint16_t port = 0;
5269 if (tor_addr_port_lookup(listenaddrs->value, &addr, &port) < 0) {
5270 log_warn(LD_CONFIG, "Unable to parse %sListenAddress '%s'",
5271 portname, listenaddrs->value);
5272 return -1;
5274 if (out) {
5275 port_cfg_t *cfg = tor_malloc_zero(sizeof(port_cfg_t));
5276 cfg->type = listener_type;
5277 cfg->port = port ? port : mainport;
5278 tor_addr_copy(&cfg->addr, &addr);
5279 cfg->session_group = SESSION_GROUP_UNSET;
5280 cfg->isolation_flags = ISO_DEFAULT;
5281 smartlist_add(out, cfg);
5285 if (warn_nonlocal && out)
5286 warn_nonlocal_client_ports(out, portname);
5287 return 0;
5288 } /* end if (listenaddrs) */
5290 /* No ListenAddress lines. If there's no FooPort, then maybe make a default
5291 * one. */
5292 if (! ports) {
5293 if (defaultport && out) {
5294 port_cfg_t *cfg = tor_malloc_zero(sizeof(port_cfg_t));
5295 cfg->type = listener_type;
5296 cfg->port = defaultport;
5297 tor_addr_parse(&cfg->addr, defaultaddr);
5298 cfg->session_group = SESSION_GROUP_UNSET;
5299 cfg->isolation_flags = ISO_DEFAULT;
5300 smartlist_add(out, cfg);
5302 return 0;
5305 /* At last we can actually parse the FooPort lines. The syntax is:
5306 * [Addr:](Port|auto) [Options].*/
5307 elts = smartlist_create();
5309 for (; ports; ports = ports->next) {
5310 tor_addr_t addr;
5311 int port;
5312 int sessiongroup = SESSION_GROUP_UNSET;
5313 unsigned isolation = ISO_DEFAULT;
5315 char *addrport;
5316 uint16_t ptmp=0;
5317 int ok;
5319 smartlist_split_string(elts, ports->value, NULL,
5320 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
5321 if (smartlist_len(elts) == 0) {
5322 log_warn(LD_CONFIG, "Invalid %sPort line with no value", portname);
5323 goto err;
5326 if (!allow_client_options && smartlist_len(elts) > 1) {
5327 log_warn(LD_CONFIG, "Too many options on %sPort line", portname);
5328 goto err;
5331 /* Now parse the addr/port value */
5332 addrport = smartlist_get(elts, 0);
5333 if (!strcmp(addrport, "auto")) {
5334 port = CFG_AUTO_PORT;
5335 tor_addr_parse(&addr, defaultaddr);
5336 } else if (!strcasecmpend(addrport, ":auto")) {
5337 char *addrtmp = tor_strndup(addrport, strlen(addrport)-5);
5338 port = CFG_AUTO_PORT;
5339 if (tor_addr_port_lookup(addrtmp, &addr, &ptmp)<0 || ptmp) {
5340 log_warn(LD_CONFIG, "Invalid address '%s' for %sPort",
5341 escaped(addrport), portname);
5342 tor_free(addrtmp);
5343 goto err;
5345 } else {
5346 /* Try parsing integer port before address, because, who knows?
5347 "9050" might be a valid address. */
5348 port = (int) tor_parse_long(addrport, 10, 0, 65535, &ok, NULL);
5349 if (ok) {
5350 tor_addr_parse(&addr, defaultaddr);
5351 } else if (tor_addr_port_lookup(addrport, &addr, &ptmp) == 0) {
5352 if (ptmp == 0) {
5353 log_warn(LD_CONFIG, "%sPort line has address but no port", portname);
5354 goto err;
5356 port = ptmp;
5357 } else {
5358 log_warn(LD_CONFIG, "Couldn't parse address '%s' for %sPort",
5359 escaped(addrport), portname);
5360 goto err;
5364 /* Now parse the rest of the options, if any. */
5365 SMARTLIST_FOREACH_BEGIN(elts, char *, elt) {
5366 int no = 0, isoflag = 0;
5367 const char *elt_orig = elt;
5368 if (elt_sl_idx == 0)
5369 continue; /* Skip addr:port */
5370 if (!strcasecmpstart(elt, "SessionGroup=")) {
5371 int group = (int)tor_parse_long(elt+strlen("SessionGroup="),
5372 10, 0, INT_MAX, &ok, NULL);
5373 if (!ok) {
5374 log_warn(LD_CONFIG, "Invalid %sPort option '%s'",
5375 portname, escaped(elt));
5376 goto err;
5378 if (sessiongroup >= 0) {
5379 log_warn(LD_CONFIG, "Multiple SessionGroup options on %sPort",
5380 portname);
5381 goto err;
5383 sessiongroup = group;
5384 continue;
5387 if (!strcasecmpstart(elt, "No")) {
5388 no = 1;
5389 elt += 2;
5391 if (!strcasecmpend(elt, "s"))
5392 elt[strlen(elt)-1] = '\0'; /* kill plurals. */
5394 if (!strcasecmp(elt, "IsolateDestPort")) {
5395 isoflag = ISO_DESTPORT;
5396 } else if (!strcasecmp(elt, "IsolateDestAddr")) {
5397 isoflag = ISO_DESTADDR;
5398 } else if (!strcasecmp(elt, "IsolateSOCKSAuth")) {
5399 isoflag = ISO_SOCKSAUTH;
5400 } else if (!strcasecmp(elt, "IsolateClientProtocol")) {
5401 isoflag = ISO_CLIENTPROTO;
5402 } else if (!strcasecmp(elt, "IsolateClientAddr")) {
5403 isoflag = ISO_CLIENTADDR;
5404 } else {
5405 log_warn(LD_CONFIG, "Unrecognized %sPort option '%s'",
5406 portname, escaped(elt_orig));
5409 if (no) {
5410 isolation &= ~isoflag;
5411 } else {
5412 isolation |= isoflag;
5414 } SMARTLIST_FOREACH_END(elt);
5416 if (out && port) {
5417 port_cfg_t *cfg = tor_malloc_zero(sizeof(port_cfg_t));
5418 cfg->type = listener_type;
5419 cfg->port = port;
5420 tor_addr_copy(&cfg->addr, &addr);
5421 cfg->session_group = sessiongroup;
5422 cfg->isolation_flags = isolation;
5423 smartlist_add(out, cfg);
5425 SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
5426 smartlist_clear(elts);
5429 if (warn_nonlocal && out)
5430 warn_nonlocal_client_ports(out, portname);
5432 retval = 0;
5433 err:
5434 SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
5435 smartlist_free(elts);
5436 return retval;
5439 /** Parse all client port types (Socks, DNS, Trans, NATD) from
5440 * <b>options</b>. On success, set *<b>n_ports_out</b> to the number of
5441 * ports that are listed and return 0. On failure, set *<b>msg</b> to a
5442 * description of the problem and return -1.
5444 * If <b>validate_only</b> is false, set configured_client_ports to the
5445 * new list of ports parsed from <b>options</b>.
5447 static int
5448 parse_client_ports(const or_options_t *options, int validate_only,
5449 char **msg, int *n_ports_out)
5451 smartlist_t *ports;
5452 int retval = -1;
5454 ports = smartlist_create();
5456 *n_ports_out = 0;
5458 if (parse_client_port_config(ports,
5459 options->SocksPort, options->SocksListenAddress,
5460 "Socks", CONN_TYPE_AP_LISTENER,
5461 "127.0.0.1", 9050,
5462 CL_PORT_WARN_NONLOCAL|CL_PORT_ALLOW_EXTRA_LISTENADDR) < 0) {
5463 *msg = tor_strdup("Invalid SocksPort/SocksListenAddress configuration");
5464 goto err;
5466 if (parse_client_port_config(ports,
5467 options->DNSPort, options->DNSListenAddress,
5468 "DNS", CONN_TYPE_AP_DNS_LISTENER,
5469 "127.0.0.1", 0,
5470 CL_PORT_WARN_NONLOCAL) < 0) {
5471 *msg = tor_strdup("Invalid DNSPort/DNSListenAddress configuration");
5472 goto err;
5474 if (parse_client_port_config(ports,
5475 options->TransPort, options->TransListenAddress,
5476 "Trans", CONN_TYPE_AP_TRANS_LISTENER,
5477 "127.0.0.1", 0,
5478 CL_PORT_WARN_NONLOCAL) < 0) {
5479 *msg = tor_strdup("Invalid TransPort/TransListenAddress configuration");
5480 goto err;
5482 if (parse_client_port_config(ports,
5483 options->NATDPort, options->NATDListenAddress,
5484 "NATD", CONN_TYPE_AP_NATD_LISTENER,
5485 "127.0.0.1", 0,
5486 CL_PORT_WARN_NONLOCAL) < 0) {
5487 *msg = tor_strdup("Invalid NatdPort/NatdListenAddress configuration");
5488 goto err;
5491 *n_ports_out = smartlist_len(ports);
5493 if (!validate_only) {
5494 if (configured_client_ports) {
5495 SMARTLIST_FOREACH(configured_client_ports,
5496 port_cfg_t *, p, port_cfg_free(p));
5497 smartlist_free(configured_client_ports);
5499 configured_client_ports = ports;
5500 ports = NULL; /* prevent free below. */
5503 retval = 0;
5504 err:
5505 if (ports) {
5506 SMARTLIST_FOREACH(ports, port_cfg_t *, p, port_cfg_free(p));
5507 smartlist_free(ports);
5509 return retval;
5512 /** Return a list of port_cfg_t for client ports parsed from the
5513 * options. */
5514 const smartlist_t *
5515 get_configured_client_ports(void)
5517 if (!configured_client_ports)
5518 configured_client_ports = smartlist_create();
5519 return configured_client_ports;
5522 /** Adjust the value of options->DataDirectory, or fill it in if it's
5523 * absent. Return 0 on success, -1 on failure. */
5524 static int
5525 normalize_data_directory(or_options_t *options)
5527 #ifdef MS_WINDOWS
5528 char *p;
5529 if (options->DataDirectory)
5530 return 0; /* all set */
5531 p = tor_malloc(MAX_PATH);
5532 strlcpy(p,get_windows_conf_root(),MAX_PATH);
5533 options->DataDirectory = p;
5534 return 0;
5535 #else
5536 const char *d = options->DataDirectory;
5537 if (!d)
5538 d = "~/.tor";
5540 if (strncmp(d,"~/",2) == 0) {
5541 char *fn = expand_filename(d);
5542 if (!fn) {
5543 log_warn(LD_CONFIG,"Failed to expand filename \"%s\".", d);
5544 return -1;
5546 if (!options->DataDirectory && !strcmp(fn,"/.tor")) {
5547 /* If our homedir is /, we probably don't want to use it. */
5548 /* Default to LOCALSTATEDIR/tor which is probably closer to what we
5549 * want. */
5550 log_warn(LD_CONFIG,
5551 "Default DataDirectory is \"~/.tor\". This expands to "
5552 "\"%s\", which is probably not what you want. Using "
5553 "\"%s"PATH_SEPARATOR"tor\" instead", fn, LOCALSTATEDIR);
5554 tor_free(fn);
5555 fn = tor_strdup(LOCALSTATEDIR PATH_SEPARATOR "tor");
5557 tor_free(options->DataDirectory);
5558 options->DataDirectory = fn;
5560 return 0;
5561 #endif
5564 /** Check and normalize the value of options->DataDirectory; return 0 if it
5565 * is sane, -1 otherwise. */
5566 static int
5567 validate_data_directory(or_options_t *options)
5569 if (normalize_data_directory(options) < 0)
5570 return -1;
5571 tor_assert(options->DataDirectory);
5572 if (strlen(options->DataDirectory) > (512-128)) {
5573 log_warn(LD_CONFIG, "DataDirectory is too long.");
5574 return -1;
5576 return 0;
5579 /** This string must remain the same forevermore. It is how we
5580 * recognize that the torrc file doesn't need to be backed up. */
5581 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; " \
5582 "if you edit it, comments will not be preserved"
5583 /** This string can change; it tries to give the reader an idea
5584 * that editing this file by hand is not a good plan. */
5585 #define GENERATED_FILE_COMMENT "# The old torrc file was renamed " \
5586 "to torrc.orig.1 or similar, and Tor will ignore it"
5588 /** Save a configuration file for the configuration in <b>options</b>
5589 * into the file <b>fname</b>. If the file already exists, and
5590 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
5591 * replace it. Return 0 on success, -1 on failure. */
5592 static int
5593 write_configuration_file(const char *fname, const or_options_t *options)
5595 char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
5596 int rename_old = 0, r;
5598 tor_assert(fname);
5600 switch (file_status(fname)) {
5601 case FN_FILE:
5602 old_val = read_file_to_str(fname, 0, NULL);
5603 if (!old_val || strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
5604 rename_old = 1;
5606 tor_free(old_val);
5607 break;
5608 case FN_NOENT:
5609 break;
5610 case FN_ERROR:
5611 case FN_DIR:
5612 default:
5613 log_warn(LD_CONFIG,
5614 "Config file \"%s\" is not a file? Failing.", fname);
5615 return -1;
5618 if (!(new_conf = options_dump(options, 1))) {
5619 log_warn(LD_BUG, "Couldn't get configuration string");
5620 goto err;
5623 tor_asprintf(&new_val, "%s\n%s\n\n%s",
5624 GENERATED_FILE_PREFIX, GENERATED_FILE_COMMENT, new_conf);
5626 if (rename_old) {
5627 int i = 1;
5628 size_t fn_tmp_len = strlen(fname)+32;
5629 char *fn_tmp;
5630 tor_assert(fn_tmp_len > strlen(fname)); /*check for overflow*/
5631 fn_tmp = tor_malloc(fn_tmp_len);
5632 while (1) {
5633 if (tor_snprintf(fn_tmp, fn_tmp_len, "%s.orig.%d", fname, i)<0) {
5634 log_warn(LD_BUG, "tor_snprintf failed inexplicably");
5635 tor_free(fn_tmp);
5636 goto err;
5638 if (file_status(fn_tmp) == FN_NOENT)
5639 break;
5640 ++i;
5642 log_notice(LD_CONFIG, "Renaming old configuration file to \"%s\"", fn_tmp);
5643 if (rename(fname, fn_tmp) < 0) {
5644 log_warn(LD_FS,
5645 "Couldn't rename configuration file \"%s\" to \"%s\": %s",
5646 fname, fn_tmp, strerror(errno));
5647 tor_free(fn_tmp);
5648 goto err;
5650 tor_free(fn_tmp);
5653 if (write_str_to_file(fname, new_val, 0) < 0)
5654 goto err;
5656 r = 0;
5657 goto done;
5658 err:
5659 r = -1;
5660 done:
5661 tor_free(new_val);
5662 tor_free(new_conf);
5663 return r;
5667 * Save the current configuration file value to disk. Return 0 on
5668 * success, -1 on failure.
5671 options_save_current(void)
5673 /* This fails if we can't write to our configuration file.
5675 * If we try falling back to datadirectory or something, we have a better
5676 * chance of saving the configuration, but a better chance of doing
5677 * something the user never expected. */
5678 return write_configuration_file(get_torrc_fname(), get_options());
5681 /** Mapping from a unit name to a multiplier for converting that unit into a
5682 * base unit. Used by config_parse_unit. */
5683 struct unit_table_t {
5684 const char *unit; /**< The name of the unit */
5685 uint64_t multiplier; /**< How many of the base unit appear in this unit */
5688 /** Table to map the names of memory units to the number of bytes they
5689 * contain. */
5690 static struct unit_table_t memory_units[] = {
5691 { "", 1 },
5692 { "b", 1<< 0 },
5693 { "byte", 1<< 0 },
5694 { "bytes", 1<< 0 },
5695 { "kb", 1<<10 },
5696 { "kbyte", 1<<10 },
5697 { "kbytes", 1<<10 },
5698 { "kilobyte", 1<<10 },
5699 { "kilobytes", 1<<10 },
5700 { "m", 1<<20 },
5701 { "mb", 1<<20 },
5702 { "mbyte", 1<<20 },
5703 { "mbytes", 1<<20 },
5704 { "megabyte", 1<<20 },
5705 { "megabytes", 1<<20 },
5706 { "gb", 1<<30 },
5707 { "gbyte", 1<<30 },
5708 { "gbytes", 1<<30 },
5709 { "gigabyte", 1<<30 },
5710 { "gigabytes", 1<<30 },
5711 { "tb", U64_LITERAL(1)<<40 },
5712 { "terabyte", U64_LITERAL(1)<<40 },
5713 { "terabytes", U64_LITERAL(1)<<40 },
5714 { NULL, 0 },
5717 /** Table to map the names of time units to the number of seconds they
5718 * contain. */
5719 static struct unit_table_t time_units[] = {
5720 { "", 1 },
5721 { "second", 1 },
5722 { "seconds", 1 },
5723 { "minute", 60 },
5724 { "minutes", 60 },
5725 { "hour", 60*60 },
5726 { "hours", 60*60 },
5727 { "day", 24*60*60 },
5728 { "days", 24*60*60 },
5729 { "week", 7*24*60*60 },
5730 { "weeks", 7*24*60*60 },
5731 { NULL, 0 },
5734 /** Table to map the names of time units to the number of milliseconds
5735 * they contain. */
5736 static struct unit_table_t time_msec_units[] = {
5737 { "", 1 },
5738 { "msec", 1 },
5739 { "millisecond", 1 },
5740 { "milliseconds", 1 },
5741 { "second", 1000 },
5742 { "seconds", 1000 },
5743 { "minute", 60*1000 },
5744 { "minutes", 60*1000 },
5745 { "hour", 60*60*1000 },
5746 { "hours", 60*60*1000 },
5747 { "day", 24*60*60*1000 },
5748 { "days", 24*60*60*1000 },
5749 { "week", 7*24*60*60*1000 },
5750 { "weeks", 7*24*60*60*1000 },
5751 { NULL, 0 },
5754 /** Parse a string <b>val</b> containing a number, zero or more
5755 * spaces, and an optional unit string. If the unit appears in the
5756 * table <b>u</b>, then multiply the number by the unit multiplier.
5757 * On success, set *<b>ok</b> to 1 and return this product.
5758 * Otherwise, set *<b>ok</b> to 0.
5760 static uint64_t
5761 config_parse_units(const char *val, struct unit_table_t *u, int *ok)
5763 uint64_t v = 0;
5764 double d = 0;
5765 int use_float = 0;
5766 char *cp;
5768 tor_assert(ok);
5770 v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
5771 if (!*ok || (cp && *cp == '.')) {
5772 d = tor_parse_double(val, 0, UINT64_MAX, ok, &cp);
5773 if (!*ok)
5774 goto done;
5775 use_float = 1;
5778 if (!cp) {
5779 *ok = 1;
5780 v = use_float ? DBL_TO_U64(d) : v;
5781 goto done;
5784 cp = (char*) eat_whitespace(cp);
5786 for ( ;u->unit;++u) {
5787 if (!strcasecmp(u->unit, cp)) {
5788 if (use_float)
5789 v = u->multiplier * d;
5790 else
5791 v *= u->multiplier;
5792 *ok = 1;
5793 goto done;
5796 log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
5797 *ok = 0;
5798 done:
5800 if (*ok)
5801 return v;
5802 else
5803 return 0;
5806 /** Parse a string in the format "number unit", where unit is a unit of
5807 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
5808 * and return the number of bytes specified. Otherwise, set
5809 * *<b>ok</b> to false and return 0. */
5810 static uint64_t
5811 config_parse_memunit(const char *s, int *ok)
5813 uint64_t u = config_parse_units(s, memory_units, ok);
5814 return u;
5817 /** Parse a string in the format "number unit", where unit is a unit of
5818 * time in milliseconds. On success, set *<b>ok</b> to true and return
5819 * the number of milliseconds in the provided interval. Otherwise, set
5820 * *<b>ok</b> to 0 and return -1. */
5821 static int
5822 config_parse_msec_interval(const char *s, int *ok)
5824 uint64_t r;
5825 r = config_parse_units(s, time_msec_units, ok);
5826 if (!ok)
5827 return -1;
5828 if (r > INT_MAX) {
5829 log_warn(LD_CONFIG, "Msec interval '%s' is too long", s);
5830 *ok = 0;
5831 return -1;
5833 return (int)r;
5836 /** Parse a string in the format "number unit", where unit is a unit of time.
5837 * On success, set *<b>ok</b> to true and return the number of seconds in
5838 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
5840 static int
5841 config_parse_interval(const char *s, int *ok)
5843 uint64_t r;
5844 r = config_parse_units(s, time_units, ok);
5845 if (!ok)
5846 return -1;
5847 if (r > INT_MAX) {
5848 log_warn(LD_CONFIG, "Interval '%s' is too long", s);
5849 *ok = 0;
5850 return -1;
5852 return (int)r;
5855 /** Return the number of cpus configured in <b>options</b>. If we are
5856 * told to auto-detect the number of cpus, return the auto-detected number. */
5858 get_num_cpus(const or_options_t *options)
5860 if (options->NumCPUs == 0) {
5861 int n = compute_num_cpus();
5862 return (n >= 1) ? n : 1;
5863 } else {
5864 return options->NumCPUs;
5869 * Initialize the libevent library.
5871 static void
5872 init_libevent(const or_options_t *options)
5874 const char *badness=NULL;
5875 tor_libevent_cfg cfg;
5877 tor_assert(options);
5879 configure_libevent_logging();
5880 /* If the kernel complains that some method (say, epoll) doesn't
5881 * exist, we don't care about it, since libevent will cope.
5883 suppress_libevent_log_msg("Function not implemented");
5885 tor_check_libevent_header_compatibility();
5887 memset(&cfg, 0, sizeof(cfg));
5888 cfg.disable_iocp = options->DisableIOCP;
5889 cfg.num_cpus = get_num_cpus(options);
5890 cfg.msec_per_tick = options->TokenBucketRefillInterval;
5892 tor_libevent_initialize(&cfg);
5894 suppress_libevent_log_msg(NULL);
5896 tor_check_libevent_version(tor_libevent_get_method(),
5897 get_options()->ORPort != 0,
5898 &badness);
5899 if (badness) {
5900 const char *v = tor_libevent_get_version_str();
5901 const char *m = tor_libevent_get_method();
5902 control_event_general_status(LOG_WARN,
5903 "BAD_LIBEVENT VERSION=%s METHOD=%s BADNESS=%s RECOVERED=NO",
5904 v, m, badness);
5908 /** Return the persistent state struct for this Tor. */
5909 or_state_t *
5910 get_or_state(void)
5912 tor_assert(global_state);
5913 return global_state;
5916 /** Return a newly allocated string holding a filename relative to the data
5917 * directory. If <b>sub1</b> is present, it is the first path component after
5918 * the data directory. If <b>sub2</b> is also present, it is the second path
5919 * component after the data directory. If <b>suffix</b> is present, it
5920 * is appended to the filename.
5922 * Examples:
5923 * get_datadir_fname2_suffix("a", NULL, NULL) -> $DATADIR/a
5924 * get_datadir_fname2_suffix("a", NULL, ".tmp") -> $DATADIR/a.tmp
5925 * get_datadir_fname2_suffix("a", "b", ".tmp") -> $DATADIR/a/b/.tmp
5926 * get_datadir_fname2_suffix("a", "b", NULL) -> $DATADIR/a/b
5928 * Note: Consider using the get_datadir_fname* macros in or.h.
5930 char *
5931 options_get_datadir_fname2_suffix(const or_options_t *options,
5932 const char *sub1, const char *sub2,
5933 const char *suffix)
5935 char *fname = NULL;
5936 size_t len;
5937 tor_assert(options);
5938 tor_assert(options->DataDirectory);
5939 tor_assert(sub1 || !sub2); /* If sub2 is present, sub1 must be present. */
5940 len = strlen(options->DataDirectory);
5941 if (sub1) {
5942 len += strlen(sub1)+1;
5943 if (sub2)
5944 len += strlen(sub2)+1;
5946 if (suffix)
5947 len += strlen(suffix);
5948 len++;
5949 fname = tor_malloc(len);
5950 if (sub1) {
5951 if (sub2) {
5952 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s"PATH_SEPARATOR"%s",
5953 options->DataDirectory, sub1, sub2);
5954 } else {
5955 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s",
5956 options->DataDirectory, sub1);
5958 } else {
5959 strlcpy(fname, options->DataDirectory, len);
5961 if (suffix)
5962 strlcat(fname, suffix, len);
5963 return fname;
5966 /** Return true if <b>line</b> is a valid state TransportProxy line.
5967 * Return false otherwise. */
5968 static int
5969 state_transport_line_is_valid(const char *line)
5971 smartlist_t *items = NULL;
5972 char *addrport=NULL;
5973 tor_addr_t addr;
5974 uint16_t port = 0;
5975 int r;
5977 items = smartlist_create();
5978 smartlist_split_string(items, line, NULL,
5979 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
5981 if (smartlist_len(items) != 2) {
5982 log_warn(LD_CONFIG, "state: Not enough arguments in TransportProxy line.");
5983 goto err;
5986 addrport = smartlist_get(items, 1);
5987 if (tor_addr_port_lookup(addrport, &addr, &port) < 0) {
5988 log_warn(LD_CONFIG, "state: Could not parse addrport.");
5989 goto err;
5992 if (!port) {
5993 log_warn(LD_CONFIG, "state: Transport line did not contain port.");
5994 goto err;
5997 r = 1;
5998 goto done;
6000 err:
6001 r = 0;
6003 done:
6004 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
6005 smartlist_free(items);
6006 return r;
6009 /** Return 0 if all TransportProxy lines in <b>state</b> are well
6010 * formed. Otherwise, return -1. */
6011 static int
6012 validate_transports_in_state(or_state_t *state)
6014 int broken = 0;
6015 config_line_t *line;
6017 for (line = state->TransportProxies ; line ; line = line->next) {
6018 tor_assert(!strcmp(line->key, "TransportProxy"));
6019 if (!state_transport_line_is_valid(line->value))
6020 broken = 1;
6023 if (broken)
6024 log_warn(LD_CONFIG, "state: State file seems to be broken.");
6026 return 0;
6029 /** Return 0 if every setting in <b>state</b> is reasonable, and a
6030 * permissible transition from <b>old_state</b>. Else warn and return -1.
6031 * Should have no side effects, except for normalizing the contents of
6032 * <b>state</b>.
6034 /* XXX from_setconf is here because of bug 238 */
6035 static int
6036 or_state_validate(or_state_t *old_state, or_state_t *state,
6037 int from_setconf, char **msg)
6039 /* We don't use these; only options do. Still, we need to match that
6040 * signature. */
6041 (void) from_setconf;
6042 (void) old_state;
6044 if (entry_guards_parse_state(state, 0, msg)<0)
6045 return -1;
6047 if (validate_transports_in_state(state)<0)
6048 return -1;
6050 return 0;
6053 /** Replace the current persistent state with <b>new_state</b> */
6054 static int
6055 or_state_set(or_state_t *new_state)
6057 char *err = NULL;
6058 int ret = 0;
6059 tor_assert(new_state);
6060 config_free(&state_format, global_state);
6061 global_state = new_state;
6062 if (entry_guards_parse_state(global_state, 1, &err)<0) {
6063 log_warn(LD_GENERAL,"%s",err);
6064 tor_free(err);
6065 ret = -1;
6067 if (rep_hist_load_state(global_state, &err)<0) {
6068 log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
6069 tor_free(err);
6070 ret = -1;
6072 if (circuit_build_times_parse_state(&circ_times, global_state) < 0) {
6073 ret = -1;
6075 return ret;
6079 * Save a broken state file to a backup location.
6081 static void
6082 or_state_save_broken(char *fname)
6084 int i;
6085 file_status_t status;
6086 size_t len = strlen(fname)+16;
6087 char *fname2 = tor_malloc(len);
6088 for (i = 0; i < 100; ++i) {
6089 tor_snprintf(fname2, len, "%s.%d", fname, i);
6090 status = file_status(fname2);
6091 if (status == FN_NOENT)
6092 break;
6094 if (i == 100) {
6095 log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
6096 "state files to move aside. Discarding the old state file.",
6097 fname);
6098 unlink(fname);
6099 } else {
6100 log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
6101 "to \"%s\". This could be a bug in Tor; please tell "
6102 "the developers.", fname, fname2);
6103 if (rename(fname, fname2) < 0) {
6104 log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
6105 "OS gave an error of %s", strerror(errno));
6108 tor_free(fname2);
6111 /** Reload the persistent state from disk, generating a new state as needed.
6112 * Return 0 on success, less than 0 on failure.
6114 static int
6115 or_state_load(void)
6117 or_state_t *new_state = NULL;
6118 char *contents = NULL, *fname;
6119 char *errmsg = NULL;
6120 int r = -1, badstate = 0;
6122 fname = get_datadir_fname("state");
6123 switch (file_status(fname)) {
6124 case FN_FILE:
6125 if (!(contents = read_file_to_str(fname, 0, NULL))) {
6126 log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
6127 goto done;
6129 break;
6130 case FN_NOENT:
6131 break;
6132 case FN_ERROR:
6133 case FN_DIR:
6134 default:
6135 log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
6136 goto done;
6138 new_state = tor_malloc_zero(sizeof(or_state_t));
6139 new_state->_magic = OR_STATE_MAGIC;
6140 config_init(&state_format, new_state);
6141 if (contents) {
6142 config_line_t *lines=NULL;
6143 int assign_retval;
6144 if (config_get_lines(contents, &lines)<0)
6145 goto done;
6146 assign_retval = config_assign(&state_format, new_state,
6147 lines, 0, 0, &errmsg);
6148 config_free_lines(lines);
6149 if (assign_retval<0)
6150 badstate = 1;
6151 if (errmsg) {
6152 log_warn(LD_GENERAL, "%s", errmsg);
6153 tor_free(errmsg);
6157 if (!badstate && or_state_validate(NULL, new_state, 1, &errmsg) < 0)
6158 badstate = 1;
6160 if (errmsg) {
6161 log_warn(LD_GENERAL, "%s", errmsg);
6162 tor_free(errmsg);
6165 if (badstate && !contents) {
6166 log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
6167 " This is a bug in Tor.");
6168 goto done;
6169 } else if (badstate && contents) {
6170 or_state_save_broken(fname);
6172 tor_free(contents);
6173 config_free(&state_format, new_state);
6175 new_state = tor_malloc_zero(sizeof(or_state_t));
6176 new_state->_magic = OR_STATE_MAGIC;
6177 config_init(&state_format, new_state);
6178 } else if (contents) {
6179 log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
6180 } else {
6181 log_info(LD_GENERAL, "Initialized state");
6183 if (or_state_set(new_state) == -1) {
6184 or_state_save_broken(fname);
6186 new_state = NULL;
6187 if (!contents) {
6188 global_state->next_write = 0;
6189 or_state_save(time(NULL));
6191 r = 0;
6193 done:
6194 tor_free(fname);
6195 tor_free(contents);
6196 if (new_state)
6197 config_free(&state_format, new_state);
6199 return r;
6202 /** Did the last time we tried to write the state file fail? If so, we
6203 * should consider disabling such features as preemptive circuit generation
6204 * to compute circuit-build-time. */
6205 static int last_state_file_write_failed = 0;
6207 /** Return whether the state file failed to write last time we tried. */
6209 did_last_state_file_write_fail(void)
6211 return last_state_file_write_failed;
6214 /** If writing the state to disk fails, try again after this many seconds. */
6215 #define STATE_WRITE_RETRY_INTERVAL 3600
6217 /** If we're a relay, how often should we checkpoint our state file even
6218 * if nothing else dirties it? This will checkpoint ongoing stats like
6219 * bandwidth used, per-country user stats, etc. */
6220 #define STATE_RELAY_CHECKPOINT_INTERVAL (12*60*60)
6222 /** Write the persistent state to disk. Return 0 for success, <0 on failure. */
6224 or_state_save(time_t now)
6226 char *state, *contents;
6227 char tbuf[ISO_TIME_LEN+1];
6228 char *fname;
6230 tor_assert(global_state);
6232 if (global_state->next_write > now)
6233 return 0;
6235 /* Call everything else that might dirty the state even more, in order
6236 * to avoid redundant writes. */
6237 entry_guards_update_state(global_state);
6238 rep_hist_update_state(global_state);
6239 circuit_build_times_update_state(&circ_times, global_state);
6240 if (accounting_is_enabled(get_options()))
6241 accounting_run_housekeeping(now);
6243 global_state->LastWritten = now;
6245 tor_free(global_state->TorVersion);
6246 tor_asprintf(&global_state->TorVersion, "Tor %s", get_version());
6248 state = config_dump(&state_format, global_state, 1, 0);
6249 format_local_iso_time(tbuf, now);
6250 tor_asprintf(&contents,
6251 "# Tor state file last generated on %s local time\n"
6252 "# Other times below are in GMT\n"
6253 "# You *do not* need to edit this file.\n\n%s",
6254 tbuf, state);
6255 tor_free(state);
6256 fname = get_datadir_fname("state");
6257 if (write_str_to_file(fname, contents, 0)<0) {
6258 log_warn(LD_FS, "Unable to write state to file \"%s\"; "
6259 "will try again later", fname);
6260 last_state_file_write_failed = 1;
6261 tor_free(fname);
6262 tor_free(contents);
6263 /* Try again after STATE_WRITE_RETRY_INTERVAL (or sooner, if the state
6264 * changes sooner). */
6265 global_state->next_write = now + STATE_WRITE_RETRY_INTERVAL;
6266 return -1;
6269 last_state_file_write_failed = 0;
6270 log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
6271 tor_free(fname);
6272 tor_free(contents);
6274 if (server_mode(get_options()))
6275 global_state->next_write = now + STATE_RELAY_CHECKPOINT_INTERVAL;
6276 else
6277 global_state->next_write = TIME_MAX;
6279 return 0;
6282 /** Return the config line for transport <b>transport</b> in the current state.
6283 * Return NULL if there is no config line for <b>transport</b>. */
6284 static config_line_t *
6285 get_transport_in_state_by_name(const char *transport)
6287 or_state_t *or_state = get_or_state();
6288 config_line_t *line;
6289 config_line_t *ret = NULL;
6290 smartlist_t *items = NULL;
6292 for (line = or_state->TransportProxies ; line ; line = line->next) {
6293 tor_assert(!strcmp(line->key, "TransportProxy"));
6295 items = smartlist_create();
6296 smartlist_split_string(items, line->value, NULL,
6297 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
6298 if (smartlist_len(items) != 2) /* broken state */
6299 goto done;
6301 if (!strcmp(smartlist_get(items, 0), transport)) {
6302 ret = line;
6303 goto done;
6306 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
6307 smartlist_free(items);
6308 items = NULL;
6311 done:
6312 if (items) {
6313 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
6314 smartlist_free(items);
6316 return ret;
6319 /** Return string containing the address:port part of the
6320 * TransportProxy <b>line</b> for transport <b>transport</b>.
6321 * If the line is corrupted, return NULL. */
6322 static const char *
6323 get_transport_bindaddr(const char *line, const char *transport)
6325 char *line_tmp = NULL;
6327 if (strlen(line) < strlen(transport) + 2) {
6328 goto broken_state;
6329 } else {
6330 /* line should start with the name of the transport and a space.
6331 (for example, "obfs2 127.0.0.1:47245") */
6332 tor_asprintf(&line_tmp, "%s ", transport);
6333 if (strcmpstart(line, line_tmp))
6334 goto broken_state;
6336 tor_free(line_tmp);
6337 return (line+strlen(transport)+1);
6340 broken_state:
6341 tor_free(line_tmp);
6342 return NULL;
6345 /** Return a static string containing the address:port a proxy
6346 * transport should bind on. */
6347 const char *
6348 get_bindaddr_for_transport(const char *transport)
6350 static const char default_addrport[] = "127.0.0.1:0";
6351 const char *bindaddr = NULL;
6353 config_line_t *line = get_transport_in_state_by_name(transport);
6354 if (!line)
6355 return default_addrport;
6357 bindaddr = get_transport_bindaddr(line->value, transport);
6359 return bindaddr ? bindaddr : default_addrport;
6362 /** Save <b>transport</b> listening on <b>addr</b>:<b>port</b> to
6363 state */
6364 void
6365 save_transport_to_state(const char *transport,
6366 const tor_addr_t *addr, uint16_t port)
6368 or_state_t *state = get_or_state();
6370 char *transport_addrport=NULL;
6372 /** find where to write on the state */
6373 config_line_t **next, *line;
6375 /* see if this transport is already stored in state */
6376 config_line_t *transport_line =
6377 get_transport_in_state_by_name(transport);
6379 if (transport_line) { /* if transport already exists in state... */
6380 const char *prev_bindaddr = /* get its addrport... */
6381 get_transport_bindaddr(transport_line->value, transport);
6382 tor_asprintf(&transport_addrport, "%s:%d", fmt_addr(addr), (int)port);
6384 /* if transport in state has the same address as this one, life is good */
6385 if (!strcmp(prev_bindaddr, transport_addrport)) {
6386 log_info(LD_CONFIG, "Transport seems to have spawned on its usual "
6387 "address:port.");
6388 goto done;
6389 } else { /* if addrport in state is different than the one we got */
6390 log_info(LD_CONFIG, "Transport seems to have spawned on different "
6391 "address:port. Let's update the state file with the new "
6392 "address:port");
6393 tor_free(transport_line->value); /* free the old line */
6394 tor_asprintf(&transport_line->value, "%s %s:%d", transport,
6395 fmt_addr(addr),
6396 (int) port); /* replace old addrport line with new line */
6398 } else { /* never seen this one before; save it in state for next time */
6399 log_info(LD_CONFIG, "It's the first time we see this transport. "
6400 "Let's save its address:port");
6401 next = &state->TransportProxies;
6402 /* find the last TransportProxy line in the state and point 'next'
6403 right after it */
6404 line = state->TransportProxies;
6405 while (line) {
6406 next = &(line->next);
6407 line = line->next;
6410 /* allocate space for the new line and fill it in */
6411 *next = line = tor_malloc_zero(sizeof(config_line_t));
6412 line->key = tor_strdup("TransportProxy");
6413 tor_asprintf(&line->value, "%s %s:%d", transport,
6414 fmt_addr(addr), (int) port);
6416 next = &(line->next);
6419 if (!get_options()->AvoidDiskWrites)
6420 or_state_mark_dirty(state, 0);
6422 done:
6423 tor_free(transport_addrport);
6426 /** Given a file name check to see whether the file exists but has not been
6427 * modified for a very long time. If so, remove it. */
6428 void
6429 remove_file_if_very_old(const char *fname, time_t now)
6431 #define VERY_OLD_FILE_AGE (28*24*60*60)
6432 struct stat st;
6434 if (stat(fname, &st)==0 && st.st_mtime < now-VERY_OLD_FILE_AGE) {
6435 char buf[ISO_TIME_LEN+1];
6436 format_local_iso_time(buf, st.st_mtime);
6437 log_notice(LD_GENERAL, "Obsolete file %s hasn't been modified since %s. "
6438 "Removing it.", fname, buf);
6439 unlink(fname);
6443 /** Helper to implement GETINFO functions about configuration variables (not
6444 * their values). Given a "config/names" question, set *<b>answer</b> to a
6445 * new string describing the supported configuration variables and their
6446 * types. */
6448 getinfo_helper_config(control_connection_t *conn,
6449 const char *question, char **answer,
6450 const char **errmsg)
6452 (void) conn;
6453 (void) errmsg;
6454 if (!strcmp(question, "config/names")) {
6455 smartlist_t *sl = smartlist_create();
6456 int i;
6457 for (i = 0; _option_vars[i].name; ++i) {
6458 const config_var_t *var = &_option_vars[i];
6459 const char *type;
6460 char *line;
6461 switch (var->type) {
6462 case CONFIG_TYPE_STRING: type = "String"; break;
6463 case CONFIG_TYPE_FILENAME: type = "Filename"; break;
6464 case CONFIG_TYPE_UINT: type = "Integer"; break;
6465 case CONFIG_TYPE_PORT: type = "Port"; break;
6466 case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
6467 case CONFIG_TYPE_MSEC_INTERVAL: type = "TimeMsecInterval"; break;
6468 case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
6469 case CONFIG_TYPE_DOUBLE: type = "Float"; break;
6470 case CONFIG_TYPE_BOOL: type = "Boolean"; break;
6471 case CONFIG_TYPE_AUTOBOOL: type = "Boolean+Auto"; break;
6472 case CONFIG_TYPE_ISOTIME: type = "Time"; break;
6473 case CONFIG_TYPE_ROUTERSET: type = "RouterList"; break;
6474 case CONFIG_TYPE_CSV: type = "CommaList"; break;
6475 case CONFIG_TYPE_LINELIST: type = "LineList"; break;
6476 case CONFIG_TYPE_LINELIST_S: type = "Dependant"; break;
6477 case CONFIG_TYPE_LINELIST_V: type = "Virtual"; break;
6478 default:
6479 case CONFIG_TYPE_OBSOLETE:
6480 type = NULL; break;
6482 if (!type)
6483 continue;
6484 tor_asprintf(&line, "%s %s\n",var->name,type);
6485 smartlist_add(sl, line);
6487 *answer = smartlist_join_strings(sl, "", 0, NULL);
6488 SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
6489 smartlist_free(sl);
6491 return 0;