a line that's been sitting in my sandbox for months
[tor.git] / src / or / config.c
blobb6d71ebe232b085f0516c9b4f0785483e4179463
1 /* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2010, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
7 /**
8 * \file config.c
9 * \brief Code to parse and interpret configuration files.
10 **/
12 #define CONFIG_PRIVATE
14 #include "or.h"
15 #ifdef MS_WINDOWS
16 #include <shlobj.h>
17 #endif
19 /** Enumeration of types which option values can take */
20 typedef enum config_type_t {
21 CONFIG_TYPE_STRING = 0, /**< An arbitrary string. */
22 CONFIG_TYPE_FILENAME, /**< A filename: some prefixes get expanded. */
23 CONFIG_TYPE_UINT, /**< A non-negative integer less than MAX_INT */
24 CONFIG_TYPE_INTERVAL, /**< A number of seconds, with optional units*/
25 CONFIG_TYPE_MEMUNIT, /**< A number of bytes, with optional units*/
26 CONFIG_TYPE_DOUBLE, /**< A floating-point value */
27 CONFIG_TYPE_BOOL, /**< A boolean value, expressed as 0 or 1. */
28 CONFIG_TYPE_ISOTIME, /**< An ISO-formatted time relative to GMT. */
29 CONFIG_TYPE_CSV, /**< A list of strings, separated by commas and
30 * optional whitespace. */
31 CONFIG_TYPE_LINELIST, /**< Uninterpreted config lines */
32 CONFIG_TYPE_LINELIST_S, /**< Uninterpreted, context-sensitive config lines,
33 * mixed with other keywords. */
34 CONFIG_TYPE_LINELIST_V, /**< Catch-all "virtual" option to summarize
35 * context-sensitive config lines when fetching.
37 CONFIG_TYPE_ROUTERSET, /**< A list of router names, addrs, and fps,
38 * parsed into a routerset_t. */
39 CONFIG_TYPE_OBSOLETE, /**< Obsolete (ignored) option. */
40 } config_type_t;
42 /** An abbreviation for a configuration option allowed on the command line. */
43 typedef struct config_abbrev_t {
44 const char *abbreviated;
45 const char *full;
46 int commandline_only;
47 int warn;
48 } config_abbrev_t;
50 /* Handy macro for declaring "In the config file or on the command line,
51 * you can abbreviate <b>tok</b>s as <b>tok</b>". */
52 #define PLURAL(tok) { #tok, #tok "s", 0, 0 }
54 /** A list of abbreviations and aliases to map command-line options, obsolete
55 * option names, or alternative option names, to their current values. */
56 static config_abbrev_t _option_abbrevs[] = {
57 PLURAL(ExitNode),
58 PLURAL(EntryNode),
59 PLURAL(ExcludeNode),
60 PLURAL(FirewallPort),
61 PLURAL(LongLivedPort),
62 PLURAL(HiddenServiceNode),
63 PLURAL(HiddenServiceExcludeNode),
64 PLURAL(NumCpu),
65 PLURAL(RendNode),
66 PLURAL(RendExcludeNode),
67 PLURAL(StrictEntryNode),
68 PLURAL(StrictExitNode),
69 PLURAL(StrictNode),
70 { "l", "Log", 1, 0},
71 { "AllowUnverifiedNodes", "AllowInvalidNodes", 0, 0},
72 { "AutomapHostSuffixes", "AutomapHostsSuffixes", 0, 0},
73 { "AutomapHostOnResolve", "AutomapHostsOnResolve", 0, 0},
74 { "BandwidthRateBytes", "BandwidthRate", 0, 0},
75 { "BandwidthBurstBytes", "BandwidthBurst", 0, 0},
76 { "DirFetchPostPeriod", "StatusFetchPeriod", 0, 0},
77 { "MaxConn", "ConnLimit", 0, 1},
78 { "ORBindAddress", "ORListenAddress", 0, 0},
79 { "DirBindAddress", "DirListenAddress", 0, 0},
80 { "SocksBindAddress", "SocksListenAddress", 0, 0},
81 { "UseHelperNodes", "UseEntryGuards", 0, 0},
82 { "NumHelperNodes", "NumEntryGuards", 0, 0},
83 { "UseEntryNodes", "UseEntryGuards", 0, 0},
84 { "NumEntryNodes", "NumEntryGuards", 0, 0},
85 { "ResolvConf", "ServerDNSResolvConfFile", 0, 1},
86 { "SearchDomains", "ServerDNSSearchDomains", 0, 1},
87 { "ServerDNSAllowBrokenResolvConf", "ServerDNSAllowBrokenConfig", 0, 0},
88 { "PreferTunnelledDirConns", "PreferTunneledDirConns", 0, 0},
89 { "BridgeAuthoritativeDirectory", "BridgeAuthoritativeDir", 0, 0},
90 { "HashedControlPassword", "__HashedControlSessionPassword", 1, 0},
91 { "StrictEntryNodes", "StrictNodes", 0, 1},
92 { "StrictExitNodes", "StrictNodes", 0, 1},
93 { NULL, NULL, 0, 0},
96 /** A list of state-file "abbreviations," for compatibility. */
97 static config_abbrev_t _state_abbrevs[] = {
98 { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
99 { "HelperNode", "EntryGuard", 0, 0 },
100 { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
101 { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
102 { "EntryNode", "EntryGuard", 0, 0 },
103 { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
104 { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
105 { NULL, NULL, 0, 0},
107 #undef PLURAL
109 /** A variable allowed in the configuration file or on the command line. */
110 typedef struct config_var_t {
111 const char *name; /**< The full keyword (case insensitive). */
112 config_type_t type; /**< How to interpret the type and turn it into a
113 * value. */
114 off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
115 const char *initvalue; /**< String (or null) describing initial value. */
116 } config_var_t;
118 /** An entry for config_vars: "The option <b>name</b> has type
119 * CONFIG_TYPE_<b>conftype</b>, and corresponds to
120 * or_options_t.<b>member</b>"
122 #define VAR(name,conftype,member,initvalue) \
123 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), \
124 initvalue }
125 /** As VAR, but the option name and member name are the same. */
126 #define V(member,conftype,initvalue) \
127 VAR(#member, conftype, member, initvalue)
128 /** An entry for config_vars: "The option <b>name</b> is obsolete." */
129 #define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
131 /** Array of configuration options. Until we disallow nonstandard
132 * abbreviations, order is significant, since the first matching option will
133 * be chosen first.
135 static config_var_t _option_vars[] = {
136 OBSOLETE("AccountingMaxKB"),
137 V(AccountingMax, MEMUNIT, "0 bytes"),
138 V(AccountingStart, STRING, NULL),
139 V(Address, STRING, NULL),
140 V(AllowDotExit, BOOL, "0"),
141 V(AllowInvalidNodes, CSV, "middle,rendezvous"),
142 V(AllowNonRFC953Hostnames, BOOL, "0"),
143 V(AllowSingleHopCircuits, BOOL, "0"),
144 V(AllowSingleHopExits, BOOL, "0"),
145 V(AlternateBridgeAuthority, LINELIST, NULL),
146 V(AlternateDirAuthority, LINELIST, NULL),
147 V(AlternateHSAuthority, LINELIST, NULL),
148 V(AssumeReachable, BOOL, "0"),
149 V(AuthDirBadDir, LINELIST, NULL),
150 V(AuthDirBadExit, LINELIST, NULL),
151 V(AuthDirInvalid, LINELIST, NULL),
152 V(AuthDirReject, LINELIST, NULL),
153 V(AuthDirRejectUnlisted, BOOL, "0"),
154 V(AuthDirListBadDirs, BOOL, "0"),
155 V(AuthDirListBadExits, BOOL, "0"),
156 V(AuthDirMaxServersPerAddr, UINT, "2"),
157 V(AuthDirMaxServersPerAuthAddr,UINT, "5"),
158 VAR("AuthoritativeDirectory", BOOL, AuthoritativeDir, "0"),
159 V(AutomapHostsOnResolve, BOOL, "0"),
160 V(AutomapHostsSuffixes, CSV, ".onion,.exit"),
161 V(AvoidDiskWrites, BOOL, "0"),
162 V(BandwidthBurst, MEMUNIT, "10 MB"),
163 V(BandwidthRate, MEMUNIT, "5 MB"),
164 V(BridgeAuthoritativeDir, BOOL, "0"),
165 VAR("Bridge", LINELIST, Bridges, NULL),
166 V(BridgePassword, STRING, NULL),
167 V(BridgeRecordUsageByCountry, BOOL, "1"),
168 V(BridgeRelay, BOOL, "0"),
169 V(CellStatistics, BOOL, "0"),
170 V(CircuitBuildTimeout, INTERVAL, "0"),
171 V(CircuitIdleTimeout, INTERVAL, "1 hour"),
172 V(CircuitStreamTimeout, INTERVAL, "0"),
173 V(CircuitPriorityHalflife, DOUBLE, "-100.0"), /*negative:'Use default'*/
174 V(ClientDNSRejectInternalAddresses, BOOL,"1"),
175 V(ClientOnly, BOOL, "0"),
176 V(ConsensusParams, STRING, NULL),
177 V(ConnLimit, UINT, "1000"),
178 V(ConstrainedSockets, BOOL, "0"),
179 V(ConstrainedSockSize, MEMUNIT, "8192"),
180 V(ContactInfo, STRING, NULL),
181 V(ControlListenAddress, LINELIST, NULL),
182 V(ControlPort, UINT, "0"),
183 V(ControlSocket, LINELIST, NULL),
184 V(CookieAuthentication, BOOL, "0"),
185 V(CookieAuthFileGroupReadable, BOOL, "0"),
186 V(CookieAuthFile, STRING, NULL),
187 V(DataDirectory, FILENAME, NULL),
188 OBSOLETE("DebugLogFile"),
189 V(DirAllowPrivateAddresses, BOOL, NULL),
190 V(TestingAuthDirTimeToLearnReachability, INTERVAL, "30 minutes"),
191 V(DirListenAddress, LINELIST, NULL),
192 OBSOLETE("DirFetchPeriod"),
193 V(DirPolicy, LINELIST, NULL),
194 V(DirPort, UINT, "0"),
195 V(DirPortFrontPage, FILENAME, NULL),
196 OBSOLETE("DirPostPeriod"),
197 OBSOLETE("DirRecordUsageByCountry"),
198 OBSOLETE("DirRecordUsageGranularity"),
199 OBSOLETE("DirRecordUsageRetainIPs"),
200 OBSOLETE("DirRecordUsageSaveInterval"),
201 V(DirReqStatistics, BOOL, "0"),
202 VAR("DirServer", LINELIST, DirServers, NULL),
203 V(DisableAllSwap, BOOL, "0"),
204 V(DNSPort, UINT, "0"),
205 V(DNSListenAddress, LINELIST, NULL),
206 V(DownloadExtraInfo, BOOL, "0"),
207 V(EnforceDistinctSubnets, BOOL, "1"),
208 V(EntryNodes, ROUTERSET, NULL),
209 V(EntryStatistics, BOOL, "0"),
210 V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "10 minutes"),
211 V(ExcludeNodes, ROUTERSET, NULL),
212 V(ExcludeExitNodes, ROUTERSET, NULL),
213 V(ExcludeSingleHopRelays, BOOL, "1"),
214 V(ExitNodes, ROUTERSET, NULL),
215 V(ExitPolicy, LINELIST, NULL),
216 V(ExitPolicyRejectPrivate, BOOL, "1"),
217 V(ExitPortStatistics, BOOL, "0"),
218 V(ExtraInfoStatistics, BOOL, "0"),
220 #if defined (WINCE)
221 V(FallbackNetworkstatusFile, FILENAME, "fallback-consensus"),
222 #else
223 V(FallbackNetworkstatusFile, FILENAME,
224 SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "fallback-consensus"),
225 #endif
226 V(FascistFirewall, BOOL, "0"),
227 V(FirewallPorts, CSV, ""),
228 V(FastFirstHopPK, BOOL, "1"),
229 V(FetchDirInfoEarly, BOOL, "0"),
230 V(FetchDirInfoExtraEarly, BOOL, "0"),
231 V(FetchServerDescriptors, BOOL, "1"),
232 V(FetchHidServDescriptors, BOOL, "1"),
233 V(FetchUselessDescriptors, BOOL, "0"),
234 #ifdef WIN32
235 V(GeoIPFile, FILENAME, "<default>"),
236 #else
237 V(GeoIPFile, FILENAME,
238 SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "geoip"),
239 #endif
240 OBSOLETE("Group"),
241 V(HardwareAccel, BOOL, "0"),
242 V(AccelName, STRING, NULL),
243 V(AccelDir, FILENAME, NULL),
244 V(HashedControlPassword, LINELIST, NULL),
245 V(HidServDirectoryV2, BOOL, "1"),
246 VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
247 OBSOLETE("HiddenServiceExcludeNodes"),
248 OBSOLETE("HiddenServiceNodes"),
249 VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
250 VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
251 VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines, NULL),
252 VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL),
253 V(HidServAuth, LINELIST, NULL),
254 V(HSAuthoritativeDir, BOOL, "0"),
255 OBSOLETE("HSAuthorityRecordStats"),
256 V(HttpProxy, STRING, NULL),
257 V(HttpProxyAuthenticator, STRING, NULL),
258 V(HttpsProxy, STRING, NULL),
259 V(HttpsProxyAuthenticator, STRING, NULL),
260 V(Socks4Proxy, STRING, NULL),
261 V(Socks5Proxy, STRING, NULL),
262 V(Socks5ProxyUsername, STRING, NULL),
263 V(Socks5ProxyPassword, STRING, NULL),
264 OBSOLETE("IgnoreVersion"),
265 V(KeepalivePeriod, INTERVAL, "5 minutes"),
266 VAR("Log", LINELIST, Logs, NULL),
267 OBSOLETE("LinkPadding"),
268 OBSOLETE("LogLevel"),
269 OBSOLETE("LogFile"),
270 V(LongLivedPorts, CSV,
271 "21,22,706,1863,5050,5190,5222,5223,6667,6697,8300"),
272 VAR("MapAddress", LINELIST, AddressMap, NULL),
273 V(MaxAdvertisedBandwidth, MEMUNIT, "1 GB"),
274 V(MaxCircuitDirtiness, INTERVAL, "10 minutes"),
275 V(MaxOnionsPending, UINT, "100"),
276 OBSOLETE("MonthlyAccountingStart"),
277 V(MyFamily, STRING, NULL),
278 V(NewCircuitPeriod, INTERVAL, "30 seconds"),
279 VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "0"),
280 V(NatdListenAddress, LINELIST, NULL),
281 V(NatdPort, UINT, "0"),
282 V(Nickname, STRING, NULL),
283 V(WarnUnsafeSocks, BOOL, "1"),
284 V(NoPublish, BOOL, "0"),
285 VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
286 V(NumCpus, UINT, "1"),
287 V(NumEntryGuards, UINT, "3"),
288 V(ORListenAddress, LINELIST, NULL),
289 V(ORPort, UINT, "0"),
290 V(OutboundBindAddress, STRING, NULL),
291 OBSOLETE("PathlenCoinWeight"),
292 V(PerConnBWBurst, MEMUNIT, "0"),
293 V(PerConnBWRate, MEMUNIT, "0"),
294 V(PidFile, STRING, NULL),
295 V(TestingTorNetwork, BOOL, "0"),
296 V(PreferTunneledDirConns, BOOL, "1"),
297 V(ProtocolWarnings, BOOL, "0"),
298 V(PublishServerDescriptor, CSV, "1"),
299 V(PublishHidServDescriptors, BOOL, "1"),
300 V(ReachableAddresses, LINELIST, NULL),
301 V(ReachableDirAddresses, LINELIST, NULL),
302 V(ReachableORAddresses, LINELIST, NULL),
303 V(RecommendedVersions, LINELIST, NULL),
304 V(RecommendedClientVersions, LINELIST, NULL),
305 V(RecommendedServerVersions, LINELIST, NULL),
306 OBSOLETE("RedirectExit"),
307 V(RefuseUnknownExits, BOOL, "0"),
308 V(RejectPlaintextPorts, CSV, ""),
309 V(RelayBandwidthBurst, MEMUNIT, "0"),
310 V(RelayBandwidthRate, MEMUNIT, "0"),
311 OBSOLETE("RendExcludeNodes"),
312 OBSOLETE("RendNodes"),
313 V(RendPostPeriod, INTERVAL, "1 hour"),
314 V(RephistTrackTime, INTERVAL, "24 hours"),
315 OBSOLETE("RouterFile"),
316 V(RunAsDaemon, BOOL, "0"),
317 V(RunTesting, BOOL, "0"),
318 V(SafeLogging, STRING, "1"),
319 V(SafeSocks, BOOL, "0"),
320 V(ServerDNSAllowBrokenConfig, BOOL, "1"),
321 V(ServerDNSAllowNonRFC953Hostnames, BOOL,"0"),
322 V(ServerDNSDetectHijacking, BOOL, "1"),
323 V(ServerDNSRandomizeCase, BOOL, "1"),
324 V(ServerDNSResolvConfFile, STRING, NULL),
325 V(ServerDNSSearchDomains, BOOL, "0"),
326 V(ServerDNSTestAddresses, CSV,
327 "www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"),
328 V(ShutdownWaitLength, INTERVAL, "30 seconds"),
329 V(SocksListenAddress, LINELIST, NULL),
330 V(SocksPolicy, LINELIST, NULL),
331 V(SocksPort, UINT, "9050"),
332 V(SocksTimeout, INTERVAL, "2 minutes"),
333 OBSOLETE("StatusFetchPeriod"),
334 V(StrictNodes, BOOL, "0"),
335 OBSOLETE("SysLog"),
336 V(TestSocks, BOOL, "0"),
337 OBSOLETE("TestVia"),
338 V(TrackHostExits, CSV, NULL),
339 V(TrackHostExitsExpire, INTERVAL, "30 minutes"),
340 OBSOLETE("TrafficShaping"),
341 V(TransListenAddress, LINELIST, NULL),
342 V(TransPort, UINT, "0"),
343 V(TunnelDirConns, BOOL, "1"),
344 V(UpdateBridgesFromAuthority, BOOL, "0"),
345 V(UseBridges, BOOL, "0"),
346 V(UseEntryGuards, BOOL, "1"),
347 V(User, STRING, NULL),
348 VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
349 VAR("V2AuthoritativeDirectory",BOOL, V2AuthoritativeDir, "0"),
350 VAR("V3AuthoritativeDirectory",BOOL, V3AuthoritativeDir, "0"),
351 V(TestingV3AuthInitialVotingInterval, INTERVAL, "30 minutes"),
352 V(TestingV3AuthInitialVoteDelay, INTERVAL, "5 minutes"),
353 V(TestingV3AuthInitialDistDelay, INTERVAL, "5 minutes"),
354 V(V3AuthVotingInterval, INTERVAL, "1 hour"),
355 V(V3AuthVoteDelay, INTERVAL, "5 minutes"),
356 V(V3AuthDistDelay, INTERVAL, "5 minutes"),
357 V(V3AuthNIntervalsValid, UINT, "3"),
358 V(V3AuthUseLegacyKey, BOOL, "0"),
359 V(V3BandwidthsFile, FILENAME, NULL),
360 VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
361 V(VirtualAddrNetwork, STRING, "127.192.0.0/10"),
362 V(WarnPlaintextPorts, CSV, "23,109,110,143"),
363 VAR("__ReloadTorrcOnSIGHUP", BOOL, ReloadTorrcOnSIGHUP, "1"),
364 VAR("__AllDirActionsPrivate", BOOL, AllDirActionsPrivate, "0"),
365 VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits, "0"),
366 VAR("__LeaveStreamsUnattached",BOOL, LeaveStreamsUnattached, "0"),
367 VAR("__HashedControlSessionPassword", LINELIST, HashedControlSessionPassword,
368 NULL),
369 V(MinUptimeHidServDirectoryV2, INTERVAL, "24 hours"),
371 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
374 /** Override default values with these if the user sets the TestingTorNetwork
375 * option. */
376 static config_var_t testing_tor_network_defaults[] = {
377 V(ServerDNSAllowBrokenConfig, BOOL, "1"),
378 V(DirAllowPrivateAddresses, BOOL, "1"),
379 V(EnforceDistinctSubnets, BOOL, "0"),
380 V(AssumeReachable, BOOL, "1"),
381 V(AuthDirMaxServersPerAddr, UINT, "0"),
382 V(AuthDirMaxServersPerAuthAddr,UINT, "0"),
383 V(ClientDNSRejectInternalAddresses, BOOL,"0"),
384 V(ExitPolicyRejectPrivate, BOOL, "0"),
385 V(V3AuthVotingInterval, INTERVAL, "5 minutes"),
386 V(V3AuthVoteDelay, INTERVAL, "20 seconds"),
387 V(V3AuthDistDelay, INTERVAL, "20 seconds"),
388 V(TestingV3AuthInitialVotingInterval, INTERVAL, "5 minutes"),
389 V(TestingV3AuthInitialVoteDelay, INTERVAL, "20 seconds"),
390 V(TestingV3AuthInitialDistDelay, INTERVAL, "20 seconds"),
391 V(TestingAuthDirTimeToLearnReachability, INTERVAL, "0 minutes"),
392 V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "0 minutes"),
393 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
395 #undef VAR
397 #define VAR(name,conftype,member,initvalue) \
398 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member), \
399 initvalue }
401 /** Array of "state" variables saved to the ~/.tor/state file. */
402 static config_var_t _state_vars[] = {
403 V(AccountingBytesReadInInterval, MEMUNIT, NULL),
404 V(AccountingBytesWrittenInInterval, MEMUNIT, NULL),
405 V(AccountingExpectedUsage, MEMUNIT, NULL),
406 V(AccountingIntervalStart, ISOTIME, NULL),
407 V(AccountingSecondsActive, INTERVAL, NULL),
409 VAR("EntryGuard", LINELIST_S, EntryGuards, NULL),
410 VAR("EntryGuardDownSince", LINELIST_S, EntryGuards, NULL),
411 VAR("EntryGuardUnlistedSince", LINELIST_S, EntryGuards, NULL),
412 VAR("EntryGuardAddedBy", LINELIST_S, EntryGuards, NULL),
413 V(EntryGuards, LINELIST_V, NULL),
415 V(BWHistoryReadEnds, ISOTIME, NULL),
416 V(BWHistoryReadInterval, UINT, "900"),
417 V(BWHistoryReadValues, CSV, ""),
418 V(BWHistoryWriteEnds, ISOTIME, NULL),
419 V(BWHistoryWriteInterval, UINT, "900"),
420 V(BWHistoryWriteValues, CSV, ""),
422 V(TorVersion, STRING, NULL),
424 V(LastRotatedOnionKey, ISOTIME, NULL),
425 V(LastWritten, ISOTIME, NULL),
427 V(TotalBuildTimes, UINT, NULL),
428 VAR("CircuitBuildTimeBin", LINELIST_S, BuildtimeHistogram, NULL),
429 VAR("BuildtimeHistogram", LINELIST_V, BuildtimeHistogram, NULL),
431 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
434 #undef VAR
435 #undef V
436 #undef OBSOLETE
438 /** Represents an English description of a configuration variable; used when
439 * generating configuration file comments. */
440 typedef struct config_var_description_t {
441 const char *name;
442 const char *description;
443 } config_var_description_t;
445 /** Type of a callback to validate whether a given configuration is
446 * well-formed and consistent. See options_trial_assign() for documentation
447 * of arguments. */
448 typedef int (*validate_fn_t)(void*,void*,int,char**);
450 /** Information on the keys, value types, key-to-struct-member mappings,
451 * variable descriptions, validation functions, and abbreviations for a
452 * configuration or storage format. */
453 typedef struct {
454 size_t size; /**< Size of the struct that everything gets parsed into. */
455 uint32_t magic; /**< Required 'magic value' to make sure we have a struct
456 * of the right type. */
457 off_t magic_offset; /**< Offset of the magic value within the struct. */
458 config_abbrev_t *abbrevs; /**< List of abbreviations that we expand when
459 * parsing this format. */
460 config_var_t *vars; /**< List of variables we recognize, their default
461 * values, and where we stick them in the structure. */
462 validate_fn_t validate_fn; /**< Function to validate config. */
463 /** If present, extra is a LINELIST variable for unrecognized
464 * lines. Otherwise, unrecognized lines are an error. */
465 config_var_t *extra;
466 } config_format_t;
468 /** Macro: assert that <b>cfg</b> has the right magic field for format
469 * <b>fmt</b>. */
470 #define CHECK(fmt, cfg) STMT_BEGIN \
471 tor_assert(fmt && cfg); \
472 tor_assert((fmt)->magic == \
473 *(uint32_t*)STRUCT_VAR_P(cfg,fmt->magic_offset)); \
474 STMT_END
476 #ifdef MS_WINDOWS
477 static char *get_windows_conf_root(void);
478 #endif
479 static void config_line_append(config_line_t **lst,
480 const char *key, const char *val);
481 static void option_clear(config_format_t *fmt, or_options_t *options,
482 config_var_t *var);
483 static void option_reset(config_format_t *fmt, or_options_t *options,
484 config_var_t *var, int use_defaults);
485 static void config_free(config_format_t *fmt, void *options);
486 static int config_lines_eq(config_line_t *a, config_line_t *b);
487 static int option_is_same(config_format_t *fmt,
488 or_options_t *o1, or_options_t *o2,
489 const char *name);
490 static or_options_t *options_dup(config_format_t *fmt, or_options_t *old);
491 static int options_validate(or_options_t *old_options, or_options_t *options,
492 int from_setconf, char **msg);
493 static int options_act_reversible(or_options_t *old_options, char **msg);
494 static int options_act(or_options_t *old_options);
495 static int options_transition_allowed(or_options_t *old, or_options_t *new,
496 char **msg);
497 static int options_transition_affects_workers(or_options_t *old_options,
498 or_options_t *new_options);
499 static int options_transition_affects_descriptor(or_options_t *old_options,
500 or_options_t *new_options);
501 static int check_nickname_list(const char *lst, const char *name, char **msg);
502 static void config_register_addressmaps(or_options_t *options);
504 static int parse_bridge_line(const char *line, int validate_only);
505 static int parse_dir_server_line(const char *line,
506 authority_type_t required_type,
507 int validate_only);
508 static int validate_data_directory(or_options_t *options);
509 static int write_configuration_file(const char *fname, or_options_t *options);
510 static config_line_t *get_assigned_option(config_format_t *fmt,
511 void *options, const char *key,
512 int escape_val);
513 static void config_init(config_format_t *fmt, void *options);
514 static int or_state_validate(or_state_t *old_options, or_state_t *options,
515 int from_setconf, char **msg);
516 static int or_state_load(void);
517 static int options_init_logs(or_options_t *options, int validate_only);
519 static int is_listening_on_low_port(uint16_t port_option,
520 const config_line_t *listen_options);
522 static uint64_t config_parse_memunit(const char *s, int *ok);
523 static int config_parse_interval(const char *s, int *ok);
524 static void init_libevent(void);
525 static int opt_streq(const char *s1, const char *s2);
527 /** Magic value for or_options_t. */
528 #define OR_OPTIONS_MAGIC 9090909
530 /** Configuration format for or_options_t. */
531 static config_format_t options_format = {
532 sizeof(or_options_t),
533 OR_OPTIONS_MAGIC,
534 STRUCT_OFFSET(or_options_t, _magic),
535 _option_abbrevs,
536 _option_vars,
537 (validate_fn_t)options_validate,
538 NULL
541 /** Magic value for or_state_t. */
542 #define OR_STATE_MAGIC 0x57A73f57
544 /** "Extra" variable in the state that receives lines we can't parse. This
545 * lets us preserve options from versions of Tor newer than us. */
546 static config_var_t state_extra_var = {
547 "__extra", CONFIG_TYPE_LINELIST, STRUCT_OFFSET(or_state_t, ExtraLines), NULL
550 /** Configuration format for or_state_t. */
551 static config_format_t state_format = {
552 sizeof(or_state_t),
553 OR_STATE_MAGIC,
554 STRUCT_OFFSET(or_state_t, _magic),
555 _state_abbrevs,
556 _state_vars,
557 (validate_fn_t)or_state_validate,
558 &state_extra_var,
562 * Functions to read and write the global options pointer.
565 /** Command-line and config-file options. */
566 static or_options_t *global_options = NULL;
567 /** Name of most recently read torrc file. */
568 static char *torrc_fname = NULL;
569 /** Persistent serialized state. */
570 static or_state_t *global_state = NULL;
571 /** Configuration Options set by command line. */
572 static config_line_t *global_cmdline_options = NULL;
573 /** Contents of most recently read DirPortFrontPage file. */
574 static char *global_dirfrontpagecontents = NULL;
576 /** Return the contents of our frontpage string, or NULL if not configured. */
577 const char *
578 get_dirportfrontpage(void)
580 return global_dirfrontpagecontents;
583 /** Allocate an empty configuration object of a given format type. */
584 static void *
585 config_alloc(config_format_t *fmt)
587 void *opts = tor_malloc_zero(fmt->size);
588 *(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
589 CHECK(fmt, opts);
590 return opts;
593 /** Return the currently configured options. */
594 or_options_t *
595 get_options(void)
597 tor_assert(global_options);
598 return global_options;
601 /** Change the current global options to contain <b>new_val</b> instead of
602 * their current value; take action based on the new value; free the old value
603 * as necessary. Returns 0 on success, -1 on failure.
606 set_options(or_options_t *new_val, char **msg)
608 or_options_t *old_options = global_options;
609 global_options = new_val;
610 /* Note that we pass the *old* options below, for comparison. It
611 * pulls the new options directly out of global_options. */
612 if (options_act_reversible(old_options, msg)<0) {
613 tor_assert(*msg);
614 global_options = old_options;
615 return -1;
617 if (options_act(old_options) < 0) { /* acting on the options failed. die. */
618 log_err(LD_BUG,
619 "Acting on config options left us in a broken state. Dying.");
620 exit(1);
623 config_free(&options_format, old_options);
625 return 0;
628 extern const char tor_git_revision[]; /* from tor_main.c */
630 /** The version of this Tor process, as parsed. */
631 static char *_version = NULL;
633 /** Return the current Tor version. */
634 const char *
635 get_version(void)
637 if (_version == NULL) {
638 if (strlen(tor_git_revision)) {
639 size_t len = strlen(VERSION)+strlen(tor_git_revision)+16;
640 _version = tor_malloc(len);
641 tor_snprintf(_version, len, "%s (git-%s)", VERSION, tor_git_revision);
642 } else {
643 _version = tor_strdup(VERSION);
646 return _version;
649 /** Release additional memory allocated in options
651 static void
652 or_options_free(or_options_t *options)
654 if (!options)
655 return;
657 routerset_free(options->_ExcludeExitNodesUnion);
658 config_free(&options_format, options);
661 /** Release all memory and resources held by global configuration structures.
663 void
664 config_free_all(void)
666 or_options_free(global_options);
667 global_options = NULL;
669 config_free(&state_format, global_state);
670 global_state = NULL;
672 config_free_lines(global_cmdline_options);
673 global_cmdline_options = NULL;
675 tor_free(torrc_fname);
676 tor_free(_version);
677 tor_free(global_dirfrontpagecontents);
680 /** Make <b>address</b> -- a piece of information related to our operation as
681 * a client -- safe to log according to the settings in options->SafeLogging,
682 * and return it.
684 * (We return "[scrubbed]" if SafeLogging is "1", and address otherwise.)
686 const char *
687 safe_str_client(const char *address)
689 tor_assert(address);
690 if (get_options()->_SafeLogging == SAFELOG_SCRUB_ALL)
691 return "[scrubbed]";
692 else
693 return address;
696 /** Make <b>address</b> -- a piece of information of unspecified sensitivity
697 * -- safe to log according to the settings in options->SafeLogging, and
698 * return it.
700 * (We return "[scrubbed]" if SafeLogging is anything besides "0", and address
701 * otherwise.)
703 const char *
704 safe_str(const char *address)
706 tor_assert(address);
707 if (get_options()->_SafeLogging != SAFELOG_SCRUB_NONE)
708 return "[scrubbed]";
709 else
710 return address;
713 /** Equivalent to escaped(safe_str_client(address)). See reentrancy note on
714 * escaped(): don't use this outside the main thread, or twice in the same
715 * log statement. */
716 const char *
717 escaped_safe_str_client(const char *address)
719 if (get_options()->_SafeLogging == SAFELOG_SCRUB_ALL)
720 return "[scrubbed]";
721 else
722 return escaped(address);
725 /** Equivalent to escaped(safe_str(address)). See reentrancy note on
726 * escaped(): don't use this outside the main thread, or twice in the same
727 * log statement. */
728 const char *
729 escaped_safe_str(const char *address)
731 if (get_options()->_SafeLogging != SAFELOG_SCRUB_NONE)
732 return "[scrubbed]";
733 else
734 return escaped(address);
737 /** Add the default directory authorities directly into the trusted dir list,
738 * but only add them insofar as they share bits with <b>type</b>. */
739 static void
740 add_default_trusted_dir_authorities(authority_type_t type)
742 int i;
743 const char *dirservers[] = {
744 "moria1 orport=9101 no-v2 "
745 "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
746 "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
747 "tor26 v1 orport=443 v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
748 "86.59.21.38:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
749 "dizum orport=443 v3ident=E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58 "
750 "194.109.206.212:80 7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
751 "Tonga orport=443 bridge no-v2 82.94.251.203:80 "
752 "4A0C CD2D DC79 9508 3D73 F5D6 6710 0C8A 5831 F16D",
753 "ides orport=9090 no-v2 v3ident=27B6B5996C426270A5C95488AA5BCEB6BCC86956 "
754 "216.224.124.114:9030 F397 038A DC51 3361 35E7 B80B D99C A384 4360 292B",
755 "gabelmoo orport=8080 no-v2 "
756 "v3ident=ED03BB616EB2F60BEC80151114BB25CEF515B226 "
757 "80.190.246.100:8180 F204 4413 DAC2 E02E 3D6B CF47 35A1 9BCA 1DE9 7281",
758 "dannenberg orport=443 no-v2 "
759 "v3ident=585769C78764D58426B8B52B6651A5A71137189A "
760 "193.23.244.244:80 7BE6 83E6 5D48 1413 21C5 ED92 F075 C553 64AC 7123",
761 "urras orport=80 no-v2 v3ident=80550987E1D626E3EBA5E5E75A458DE0626D088C "
762 "208.83.223.34:443 0AD3 FA88 4D18 F89E EA2D 89C0 1937 9E0E 7FD9 4417",
763 "maatuska orport=80 no-v2 "
764 "v3ident=49015F787433103580E3B66A1707A00E60F2D15B "
765 "213.115.239.118:443 BD6A 8292 55CB 08E6 6FBE 7D37 4836 3586 E46B 3810",
766 NULL
768 for (i=0; dirservers[i]; i++) {
769 if (parse_dir_server_line(dirservers[i], type, 0)<0) {
770 log_err(LD_BUG, "Couldn't parse internal dirserver line %s",
771 dirservers[i]);
776 /** Look at all the config options for using alternate directory
777 * authorities, and make sure none of them are broken. Also, warn the
778 * user if we changed any dangerous ones.
780 static int
781 validate_dir_authorities(or_options_t *options, or_options_t *old_options)
783 config_line_t *cl;
785 if (options->DirServers &&
786 (options->AlternateDirAuthority || options->AlternateBridgeAuthority ||
787 options->AlternateHSAuthority)) {
788 log_warn(LD_CONFIG,
789 "You cannot set both DirServers and Alternate*Authority.");
790 return -1;
793 /* do we want to complain to the user about being partitionable? */
794 if ((options->DirServers &&
795 (!old_options ||
796 !config_lines_eq(options->DirServers, old_options->DirServers))) ||
797 (options->AlternateDirAuthority &&
798 (!old_options ||
799 !config_lines_eq(options->AlternateDirAuthority,
800 old_options->AlternateDirAuthority)))) {
801 log_warn(LD_CONFIG,
802 "You have used DirServer or AlternateDirAuthority to "
803 "specify alternate directory authorities in "
804 "your configuration. This is potentially dangerous: it can "
805 "make you look different from all other Tor users, and hurt "
806 "your anonymity. Even if you've specified the same "
807 "authorities as Tor uses by default, the defaults could "
808 "change in the future. Be sure you know what you're doing.");
811 /* Now go through the four ways you can configure an alternate
812 * set of directory authorities, and make sure none are broken. */
813 for (cl = options->DirServers; cl; cl = cl->next)
814 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
815 return -1;
816 for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
817 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
818 return -1;
819 for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
820 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
821 return -1;
822 for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
823 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
824 return -1;
825 return 0;
828 /** Look at all the config options and assign new dir authorities
829 * as appropriate.
831 static int
832 consider_adding_dir_authorities(or_options_t *options,
833 or_options_t *old_options)
835 config_line_t *cl;
836 int need_to_update =
837 !smartlist_len(router_get_trusted_dir_servers()) || !old_options ||
838 !config_lines_eq(options->DirServers, old_options->DirServers) ||
839 !config_lines_eq(options->AlternateBridgeAuthority,
840 old_options->AlternateBridgeAuthority) ||
841 !config_lines_eq(options->AlternateDirAuthority,
842 old_options->AlternateDirAuthority) ||
843 !config_lines_eq(options->AlternateHSAuthority,
844 old_options->AlternateHSAuthority);
846 if (!need_to_update)
847 return 0; /* all done */
849 /* Start from a clean slate. */
850 clear_trusted_dir_servers();
852 if (!options->DirServers) {
853 /* then we may want some of the defaults */
854 authority_type_t type = NO_AUTHORITY;
855 if (!options->AlternateBridgeAuthority)
856 type |= BRIDGE_AUTHORITY;
857 if (!options->AlternateDirAuthority)
858 type |= V1_AUTHORITY | V2_AUTHORITY | V3_AUTHORITY;
859 if (!options->AlternateHSAuthority)
860 type |= HIDSERV_AUTHORITY;
861 add_default_trusted_dir_authorities(type);
864 for (cl = options->DirServers; cl; cl = cl->next)
865 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
866 return -1;
867 for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
868 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
869 return -1;
870 for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
871 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
872 return -1;
873 for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
874 if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
875 return -1;
876 return 0;
879 /** Fetch the active option list, and take actions based on it. All of the
880 * things we do should survive being done repeatedly. If present,
881 * <b>old_options</b> contains the previous value of the options.
883 * Return 0 if all goes well, return -1 if things went badly.
885 static int
886 options_act_reversible(or_options_t *old_options, char **msg)
888 smartlist_t *new_listeners = smartlist_create();
889 smartlist_t *replaced_listeners = smartlist_create();
890 static int libevent_initialized = 0;
891 or_options_t *options = get_options();
892 int running_tor = options->command == CMD_RUN_TOR;
893 int set_conn_limit = 0;
894 int r = -1;
895 int logs_marked = 0;
897 /* Daemonize _first_, since we only want to open most of this stuff in
898 * the subprocess. Libevent bases can't be reliably inherited across
899 * processes. */
900 if (running_tor && options->RunAsDaemon) {
901 /* No need to roll back, since you can't change the value. */
902 start_daemon();
905 #ifndef HAVE_SYS_UN_H
906 if (options->ControlSocket) {
907 *msg = tor_strdup("Unix domain sockets (ControlSocket) not supported"
908 " on this OS/with this build.");
909 goto rollback;
911 #endif
913 if (running_tor) {
914 /* We need to set the connection limit before we can open the listeners. */
915 if (set_max_file_descriptors((unsigned)options->ConnLimit,
916 &options->_ConnLimit) < 0) {
917 *msg = tor_strdup("Problem with ConnLimit value. See logs for details.");
918 goto rollback;
920 set_conn_limit = 1;
922 /* Set up libevent. (We need to do this before we can register the
923 * listeners as listeners.) */
924 if (running_tor && !libevent_initialized) {
925 init_libevent();
926 libevent_initialized = 1;
929 /* Launch the listeners. (We do this before we setuid, so we can bind to
930 * ports under 1024.) */
931 if (retry_all_listeners(replaced_listeners, new_listeners) < 0) {
932 *msg = tor_strdup("Failed to bind one of the listener ports.");
933 goto rollback;
937 #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
938 /* Open /dev/pf before dropping privileges. */
939 if (options->TransPort) {
940 if (get_pf_socket() < 0) {
941 *msg = tor_strdup("Unable to open /dev/pf for transparent proxy.");
942 goto rollback;
945 #endif
947 /* Attempt to lock all current and future memory with mlockall() only once */
948 if (options->DisableAllSwap) {
949 if (tor_mlockall() == -1) {
950 *msg = tor_strdup("DisableAllSwap failure. Do you have proper "
951 "permissions?");
952 goto done;
956 /* Setuid/setgid as appropriate */
957 if (options->User) {
958 if (switch_id(options->User) != 0) {
959 /* No need to roll back, since you can't change the value. */
960 *msg = tor_strdup("Problem with User value. See logs for details.");
961 goto done;
965 /* Ensure data directory is private; create if possible. */
966 if (check_private_dir(options->DataDirectory,
967 running_tor ? CPD_CREATE : CPD_CHECK)<0) {
968 tor_asprintf(msg,
969 "Couldn't access/create private data directory \"%s\"",
970 options->DataDirectory);
971 goto done;
972 /* No need to roll back, since you can't change the value. */
975 if (directory_caches_v2_dir_info(options)) {
976 size_t len = strlen(options->DataDirectory)+32;
977 char *fn = tor_malloc(len);
978 tor_snprintf(fn, len, "%s"PATH_SEPARATOR"cached-status",
979 options->DataDirectory);
980 if (check_private_dir(fn, running_tor ? CPD_CREATE : CPD_CHECK) < 0) {
981 tor_asprintf(msg,
982 "Couldn't access/create private data directory \"%s\"", fn);
983 tor_free(fn);
984 goto done;
986 tor_free(fn);
989 /* Bail out at this point if we're not going to be a client or server:
990 * we don't run Tor itself. */
991 if (!running_tor)
992 goto commit;
994 mark_logs_temp(); /* Close current logs once new logs are open. */
995 logs_marked = 1;
996 if (options_init_logs(options, 0)<0) { /* Configure the log(s) */
997 *msg = tor_strdup("Failed to init Log options. See logs for details.");
998 goto rollback;
1001 commit:
1002 r = 0;
1003 if (logs_marked) {
1004 log_severity_list_t *severity =
1005 tor_malloc_zero(sizeof(log_severity_list_t));
1006 close_temp_logs();
1007 add_callback_log(severity, control_event_logmsg);
1008 control_adjust_event_log_severity();
1009 tor_free(severity);
1011 SMARTLIST_FOREACH(replaced_listeners, connection_t *, conn,
1013 log_notice(LD_NET, "Closing old %s on %s:%d",
1014 conn_type_to_string(conn->type), conn->address, conn->port);
1015 connection_close_immediate(conn);
1016 connection_mark_for_close(conn);
1018 goto done;
1020 rollback:
1021 r = -1;
1022 tor_assert(*msg);
1024 if (logs_marked) {
1025 rollback_log_changes();
1026 control_adjust_event_log_severity();
1029 if (set_conn_limit && old_options)
1030 set_max_file_descriptors((unsigned)old_options->ConnLimit,
1031 &options->_ConnLimit);
1033 SMARTLIST_FOREACH(new_listeners, connection_t *, conn,
1035 log_notice(LD_NET, "Closing partially-constructed listener %s on %s:%d",
1036 conn_type_to_string(conn->type), conn->address, conn->port);
1037 connection_close_immediate(conn);
1038 connection_mark_for_close(conn);
1041 done:
1042 smartlist_free(new_listeners);
1043 smartlist_free(replaced_listeners);
1044 return r;
1047 /** If we need to have a GEOIP ip-to-country map to run with our configured
1048 * options, return 1 and set *<b>reason_out</b> to a description of why. */
1050 options_need_geoip_info(or_options_t *options, const char **reason_out)
1052 int bridge_usage =
1053 options->BridgeRelay && options->BridgeRecordUsageByCountry;
1054 int routerset_usage =
1055 routerset_needs_geoip(options->EntryNodes) ||
1056 routerset_needs_geoip(options->ExitNodes) ||
1057 routerset_needs_geoip(options->ExcludeExitNodes) ||
1058 routerset_needs_geoip(options->ExcludeNodes);
1060 if (routerset_usage && reason_out) {
1061 *reason_out = "We've been configured to use (or avoid) nodes in certain "
1062 "countries, and we need GEOIP information to figure out which ones they "
1063 "are.";
1064 } else if (bridge_usage && reason_out) {
1065 *reason_out = "We've been configured to see which countries can access "
1066 "us as a bridge, and we need GEOIP information to tell which countries "
1067 "clients are in.";
1069 return bridge_usage || routerset_usage;
1072 /** Return the bandwidthrate that we are going to report to the authorities
1073 * based on the config options. */
1074 uint32_t
1075 get_effective_bwrate(or_options_t *options)
1077 uint64_t bw = options->BandwidthRate;
1078 if (bw > options->MaxAdvertisedBandwidth)
1079 bw = options->MaxAdvertisedBandwidth;
1080 if (options->RelayBandwidthRate > 0 && bw > options->RelayBandwidthRate)
1081 bw = options->RelayBandwidthRate;
1082 /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
1083 return (uint32_t)bw;
1086 /** Return the bandwidthburst that we are going to report to the authorities
1087 * based on the config options. */
1088 uint32_t
1089 get_effective_bwburst(or_options_t *options)
1091 uint64_t bw = options->BandwidthBurst;
1092 if (options->RelayBandwidthBurst > 0 && bw > options->RelayBandwidthBurst)
1093 bw = options->RelayBandwidthBurst;
1094 /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
1095 return (uint32_t)bw;
1098 /** Fetch the active option list, and take actions based on it. All of the
1099 * things we do should survive being done repeatedly. If present,
1100 * <b>old_options</b> contains the previous value of the options.
1102 * Return 0 if all goes well, return -1 if it's time to die.
1104 * Note: We haven't moved all the "act on new configuration" logic
1105 * here yet. Some is still in do_hup() and other places.
1107 static int
1108 options_act(or_options_t *old_options)
1110 config_line_t *cl;
1111 or_options_t *options = get_options();
1112 int running_tor = options->command == CMD_RUN_TOR;
1113 char *msg;
1115 if (running_tor && !have_lockfile()) {
1116 if (try_locking(options, 1) < 0)
1117 return -1;
1120 if (consider_adding_dir_authorities(options, old_options) < 0)
1121 return -1;
1123 if (options->Bridges) {
1124 clear_bridge_list();
1125 for (cl = options->Bridges; cl; cl = cl->next) {
1126 if (parse_bridge_line(cl->value, 0)<0) {
1127 log_warn(LD_BUG,
1128 "Previously validated Bridge line could not be added!");
1129 return -1;
1134 if (running_tor && rend_config_services(options, 0)<0) {
1135 log_warn(LD_BUG,
1136 "Previously validated hidden services line could not be added!");
1137 return -1;
1140 if (running_tor && rend_parse_service_authorization(options, 0) < 0) {
1141 log_warn(LD_BUG, "Previously validated client authorization for "
1142 "hidden services could not be added!");
1143 return -1;
1146 /* Load state */
1147 if (! global_state && running_tor) {
1148 if (or_state_load())
1149 return -1;
1150 rep_hist_load_mtbf_data(time(NULL));
1153 /* Bail out at this point if we're not going to be a client or server:
1154 * we want to not fork, and to log stuff to stderr. */
1155 if (!running_tor)
1156 return 0;
1158 /* Finish backgrounding the process */
1159 if (options->RunAsDaemon) {
1160 /* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
1161 finish_daemon(options->DataDirectory);
1164 /* Write our PID to the PID file. If we do not have write permissions we
1165 * will log a warning */
1166 if (options->PidFile)
1167 write_pidfile(options->PidFile);
1169 /* Register addressmap directives */
1170 config_register_addressmaps(options);
1171 parse_virtual_addr_network(options->VirtualAddrNetwork, 0, &msg);
1173 /* Update address policies. */
1174 if (policies_parse_from_options(options) < 0) {
1175 /* This should be impossible, but let's be sure. */
1176 log_warn(LD_BUG,"Error parsing already-validated policy options.");
1177 return -1;
1180 if (init_cookie_authentication(options->CookieAuthentication) < 0) {
1181 log_warn(LD_CONFIG,"Error creating cookie authentication file.");
1182 return -1;
1185 /* reload keys as needed for rendezvous services. */
1186 if (rend_service_load_keys()<0) {
1187 log_warn(LD_GENERAL,"Error loading rendezvous service keys");
1188 return -1;
1191 /* Set up accounting */
1192 if (accounting_parse_options(options, 0)<0) {
1193 log_warn(LD_CONFIG,"Error in accounting options");
1194 return -1;
1196 if (accounting_is_enabled(options))
1197 configure_accounting(time(NULL));
1199 /* Change the cell EWMA settings */
1200 cell_ewma_set_scale_factor(options, networkstatus_get_latest_consensus());
1202 /* Check for transitions that need action. */
1203 if (old_options) {
1205 if ((options->UseEntryGuards && !old_options->UseEntryGuards) ||
1206 (options->ExcludeNodes &&
1207 !routerset_equal(old_options->ExcludeNodes,options->ExcludeNodes)) ||
1208 (options->ExcludeExitNodes &&
1209 !routerset_equal(old_options->ExcludeExitNodes,
1210 options->ExcludeExitNodes)) ||
1211 (options->EntryNodes &&
1212 !routerset_equal(old_options->EntryNodes, options->EntryNodes)) ||
1213 (options->ExitNodes &&
1214 !routerset_equal(old_options->ExitNodes, options->ExitNodes)) ||
1215 options->StrictNodes != old_options->StrictNodes) {
1216 log_info(LD_CIRC,
1217 "Changed to using entry guards, or changed preferred or "
1218 "excluded node lists. Abandoning previous circuits.");
1219 circuit_mark_all_unused_circs();
1220 circuit_expire_all_dirty_circs();
1223 if (! bool_eq(options->BridgeRelay, old_options->BridgeRelay)) {
1224 log_info(LD_GENERAL, "Bridge status changed. Forgetting GeoIP stats.");
1225 geoip_remove_old_clients(time(NULL)+(2*60*60));
1228 if (options_transition_affects_workers(old_options, options)) {
1229 log_info(LD_GENERAL,
1230 "Worker-related options changed. Rotating workers.");
1231 if (server_mode(options) && !server_mode(old_options)) {
1232 if (init_keys() < 0) {
1233 log_warn(LD_BUG,"Error initializing keys; exiting");
1234 return -1;
1236 ip_address_changed(0);
1237 if (has_completed_circuit || !any_predicted_circuits(time(NULL)))
1238 inform_testing_reachability();
1240 cpuworkers_rotate();
1241 if (dns_reset())
1242 return -1;
1243 } else {
1244 if (dns_reset())
1245 return -1;
1248 if (options->V3AuthoritativeDir && !old_options->V3AuthoritativeDir)
1249 init_keys();
1252 /* Maybe load geoip file */
1253 if (options->GeoIPFile &&
1254 ((!old_options || !opt_streq(old_options->GeoIPFile, options->GeoIPFile))
1255 || !geoip_is_loaded())) {
1256 /* XXXX Don't use this "<default>" junk; make our filename options
1257 * understand prefixes somehow. -NM */
1258 /* XXXX021 Reload GeoIPFile on SIGHUP. -NM */
1259 char *actual_fname = tor_strdup(options->GeoIPFile);
1260 #ifdef WIN32
1261 if (!strcmp(actual_fname, "<default>")) {
1262 const char *conf_root = get_windows_conf_root();
1263 size_t len = strlen(conf_root)+16;
1264 tor_free(actual_fname);
1265 actual_fname = tor_malloc(len+1);
1266 tor_snprintf(actual_fname, len, "%s\\geoip", conf_root);
1268 #endif
1269 geoip_load_file(actual_fname, options);
1270 tor_free(actual_fname);
1273 if (options->DirReqStatistics && !geoip_is_loaded()) {
1274 /* Check if GeoIP database could be loaded. */
1275 log_warn(LD_CONFIG, "Configured to measure directory request "
1276 "statistics, but no GeoIP database found!");
1277 return -1;
1280 if (options->EntryStatistics) {
1281 if (should_record_bridge_info(options)) {
1282 /* Don't allow measuring statistics on entry guards when configured
1283 * as bridge. */
1284 log_warn(LD_CONFIG, "Bridges cannot be configured to measure "
1285 "additional GeoIP statistics as entry guards.");
1286 return -1;
1287 } else if (!geoip_is_loaded()) {
1288 /* Check if GeoIP database could be loaded. */
1289 log_warn(LD_CONFIG, "Configured to measure entry node statistics, "
1290 "but no GeoIP database found!");
1291 return -1;
1295 /* Check if we need to parse and add the EntryNodes config option. */
1296 if (options->EntryNodes &&
1297 (!old_options ||
1298 (!routerset_equal(old_options->EntryNodes,options->EntryNodes))))
1299 entry_nodes_should_be_added();
1301 /* Since our options changed, we might need to regenerate and upload our
1302 * server descriptor.
1304 if (!old_options ||
1305 options_transition_affects_descriptor(old_options, options))
1306 mark_my_descriptor_dirty();
1308 /* We may need to reschedule some directory stuff if our status changed. */
1309 if (old_options) {
1310 if (authdir_mode_v3(options) && !authdir_mode_v3(old_options))
1311 dirvote_recalculate_timing(options, time(NULL));
1312 if (!bool_eq(directory_fetches_dir_info_early(options),
1313 directory_fetches_dir_info_early(old_options)) ||
1314 !bool_eq(directory_fetches_dir_info_later(options),
1315 directory_fetches_dir_info_later(old_options))) {
1316 /* Make sure update_router_have_min_dir_info gets called. */
1317 router_dir_info_changed();
1318 /* We might need to download a new consensus status later or sooner than
1319 * we had expected. */
1320 update_consensus_networkstatus_fetch_time(time(NULL));
1324 /* Load the webpage we're going to serve every time someone asks for '/' on
1325 our DirPort. */
1326 tor_free(global_dirfrontpagecontents);
1327 if (options->DirPortFrontPage) {
1328 global_dirfrontpagecontents =
1329 read_file_to_str(options->DirPortFrontPage, 0, NULL);
1330 if (!global_dirfrontpagecontents) {
1331 log_warn(LD_CONFIG,
1332 "DirPortFrontPage file '%s' not found. Continuing anyway.",
1333 options->DirPortFrontPage);
1337 return 0;
1341 * Functions to parse config options
1344 /** If <b>option</b> is an official abbreviation for a longer option,
1345 * return the longer option. Otherwise return <b>option</b>.
1346 * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
1347 * apply abbreviations that work for the config file and the command line.
1348 * If <b>warn_obsolete</b> is set, warn about deprecated names. */
1349 static const char *
1350 expand_abbrev(config_format_t *fmt, const char *option, int command_line,
1351 int warn_obsolete)
1353 int i;
1354 if (! fmt->abbrevs)
1355 return option;
1356 for (i=0; fmt->abbrevs[i].abbreviated; ++i) {
1357 /* Abbreviations are case insensitive. */
1358 if (!strcasecmp(option,fmt->abbrevs[i].abbreviated) &&
1359 (command_line || !fmt->abbrevs[i].commandline_only)) {
1360 if (warn_obsolete && fmt->abbrevs[i].warn) {
1361 log_warn(LD_CONFIG,
1362 "The configuration option '%s' is deprecated; "
1363 "use '%s' instead.",
1364 fmt->abbrevs[i].abbreviated,
1365 fmt->abbrevs[i].full);
1367 /* Keep going through the list in case we want to rewrite it more.
1368 * (We could imagine recursing here, but I don't want to get the
1369 * user into an infinite loop if we craft our list wrong.) */
1370 option = fmt->abbrevs[i].full;
1373 return option;
1376 /** Helper: Read a list of configuration options from the command line.
1377 * If successful, put them in *<b>result</b> and return 0, and return
1378 * -1 and leave *<b>result</b> alone. */
1379 static int
1380 config_get_commandlines(int argc, char **argv, config_line_t **result)
1382 config_line_t *front = NULL;
1383 config_line_t **new = &front;
1384 char *s;
1385 int i = 1;
1387 while (i < argc) {
1388 if (!strcmp(argv[i],"-f") ||
1389 !strcmp(argv[i],"--hash-password")) {
1390 i += 2; /* command-line option with argument. ignore them. */
1391 continue;
1392 } else if (!strcmp(argv[i],"--list-fingerprint") ||
1393 !strcmp(argv[i],"--verify-config") ||
1394 !strcmp(argv[i],"--ignore-missing-torrc") ||
1395 !strcmp(argv[i],"--quiet") ||
1396 !strcmp(argv[i],"--hush")) {
1397 i += 1; /* command-line option. ignore it. */
1398 continue;
1399 } else if (!strcmp(argv[i],"--nt-service") ||
1400 !strcmp(argv[i],"-nt-service")) {
1401 i += 1;
1402 continue;
1405 if (i == argc-1) {
1406 log_warn(LD_CONFIG,"Command-line option '%s' with no value. Failing.",
1407 argv[i]);
1408 config_free_lines(front);
1409 return -1;
1412 *new = tor_malloc_zero(sizeof(config_line_t));
1413 s = argv[i];
1415 /* Each keyword may be prefixed with one or two dashes. */
1416 if (*s == '-')
1417 s++;
1418 if (*s == '-')
1419 s++;
1421 (*new)->key = tor_strdup(expand_abbrev(&options_format, s, 1, 1));
1422 (*new)->value = tor_strdup(argv[i+1]);
1423 (*new)->next = NULL;
1424 log(LOG_DEBUG, LD_CONFIG, "command line: parsed keyword '%s', value '%s'",
1425 (*new)->key, (*new)->value);
1427 new = &((*new)->next);
1428 i += 2;
1430 *result = front;
1431 return 0;
1434 /** Helper: allocate a new configuration option mapping 'key' to 'val',
1435 * append it to *<b>lst</b>. */
1436 static void
1437 config_line_append(config_line_t **lst,
1438 const char *key,
1439 const char *val)
1441 config_line_t *newline;
1443 newline = tor_malloc(sizeof(config_line_t));
1444 newline->key = tor_strdup(key);
1445 newline->value = tor_strdup(val);
1446 newline->next = NULL;
1447 while (*lst)
1448 lst = &((*lst)->next);
1450 (*lst) = newline;
1453 /** Helper: parse the config string and strdup into key/value
1454 * strings. Set *result to the list, or NULL if parsing the string
1455 * failed. Return 0 on success, -1 on failure. Warn and ignore any
1456 * misformatted lines. */
1458 config_get_lines(const char *string, config_line_t **result)
1460 config_line_t *list = NULL, **next;
1461 char *k, *v;
1463 next = &list;
1464 do {
1465 k = v = NULL;
1466 string = parse_config_line_from_str(string, &k, &v);
1467 if (!string) {
1468 config_free_lines(list);
1469 tor_free(k);
1470 tor_free(v);
1471 return -1;
1473 if (k && v) {
1474 /* This list can get long, so we keep a pointer to the end of it
1475 * rather than using config_line_append over and over and getting
1476 * n^2 performance. */
1477 *next = tor_malloc(sizeof(config_line_t));
1478 (*next)->key = k;
1479 (*next)->value = v;
1480 (*next)->next = NULL;
1481 next = &((*next)->next);
1482 } else {
1483 tor_free(k);
1484 tor_free(v);
1486 } while (*string);
1488 *result = list;
1489 return 0;
1493 * Free all the configuration lines on the linked list <b>front</b>.
1495 void
1496 config_free_lines(config_line_t *front)
1498 config_line_t *tmp;
1500 while (front) {
1501 tmp = front;
1502 front = tmp->next;
1504 tor_free(tmp->key);
1505 tor_free(tmp->value);
1506 tor_free(tmp);
1510 /** If <b>key</b> is a configuration option, return the corresponding
1511 * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
1512 * warn, and return the corresponding config_var_t. Otherwise return NULL.
1514 static config_var_t *
1515 config_find_option(config_format_t *fmt, const char *key)
1517 int i;
1518 size_t keylen = strlen(key);
1519 if (!keylen)
1520 return NULL; /* if they say "--" on the command line, it's not an option */
1521 /* First, check for an exact (case-insensitive) match */
1522 for (i=0; fmt->vars[i].name; ++i) {
1523 if (!strcasecmp(key, fmt->vars[i].name)) {
1524 return &fmt->vars[i];
1527 /* If none, check for an abbreviated match */
1528 for (i=0; fmt->vars[i].name; ++i) {
1529 if (!strncasecmp(key, fmt->vars[i].name, keylen)) {
1530 log_warn(LD_CONFIG, "The abbreviation '%s' is deprecated. "
1531 "Please use '%s' instead",
1532 key, fmt->vars[i].name);
1533 return &fmt->vars[i];
1536 /* Okay, unrecognized option */
1537 return NULL;
1541 * Functions to assign config options.
1544 /** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
1545 * with <b>c</b>-\>value and return 0, or return -1 if bad value.
1547 * Called from config_assign_line() and option_reset().
1549 static int
1550 config_assign_value(config_format_t *fmt, or_options_t *options,
1551 config_line_t *c, char **msg)
1553 int i, ok;
1554 config_var_t *var;
1555 void *lvalue;
1557 CHECK(fmt, options);
1559 var = config_find_option(fmt, c->key);
1560 tor_assert(var);
1562 lvalue = STRUCT_VAR_P(options, var->var_offset);
1564 switch (var->type) {
1566 case CONFIG_TYPE_UINT:
1567 i = (int)tor_parse_long(c->value, 10, 0, INT_MAX, &ok, NULL);
1568 if (!ok) {
1569 tor_asprintf(msg,
1570 "Int keyword '%s %s' is malformed or out of bounds.",
1571 c->key, c->value);
1572 return -1;
1574 *(int *)lvalue = i;
1575 break;
1577 case CONFIG_TYPE_INTERVAL: {
1578 i = config_parse_interval(c->value, &ok);
1579 if (!ok) {
1580 tor_asprintf(msg,
1581 "Interval '%s %s' is malformed or out of bounds.",
1582 c->key, c->value);
1583 return -1;
1585 *(int *)lvalue = i;
1586 break;
1589 case CONFIG_TYPE_MEMUNIT: {
1590 uint64_t u64 = config_parse_memunit(c->value, &ok);
1591 if (!ok) {
1592 tor_asprintf(msg,
1593 "Value '%s %s' is malformed or out of bounds.",
1594 c->key, c->value);
1595 return -1;
1597 *(uint64_t *)lvalue = u64;
1598 break;
1601 case CONFIG_TYPE_BOOL:
1602 i = (int)tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
1603 if (!ok) {
1604 tor_asprintf(msg,
1605 "Boolean '%s %s' expects 0 or 1.",
1606 c->key, c->value);
1607 return -1;
1609 *(int *)lvalue = i;
1610 break;
1612 case CONFIG_TYPE_STRING:
1613 case CONFIG_TYPE_FILENAME:
1614 tor_free(*(char **)lvalue);
1615 *(char **)lvalue = tor_strdup(c->value);
1616 break;
1618 case CONFIG_TYPE_DOUBLE:
1619 *(double *)lvalue = atof(c->value);
1620 break;
1622 case CONFIG_TYPE_ISOTIME:
1623 if (parse_iso_time(c->value, (time_t *)lvalue)) {
1624 tor_asprintf(msg,
1625 "Invalid time '%s' for keyword '%s'", c->value, c->key);
1626 return -1;
1628 break;
1630 case CONFIG_TYPE_ROUTERSET:
1631 if (*(routerset_t**)lvalue) {
1632 routerset_free(*(routerset_t**)lvalue);
1634 *(routerset_t**)lvalue = routerset_new();
1635 if (routerset_parse(*(routerset_t**)lvalue, c->value, c->key)<0) {
1636 tor_asprintf(msg, "Invalid exit list '%s' for option '%s'",
1637 c->value, c->key);
1638 return -1;
1640 break;
1642 case CONFIG_TYPE_CSV:
1643 if (*(smartlist_t**)lvalue) {
1644 SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
1645 smartlist_clear(*(smartlist_t**)lvalue);
1646 } else {
1647 *(smartlist_t**)lvalue = smartlist_create();
1650 smartlist_split_string(*(smartlist_t**)lvalue, c->value, ",",
1651 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1652 break;
1654 case CONFIG_TYPE_LINELIST:
1655 case CONFIG_TYPE_LINELIST_S:
1656 config_line_append((config_line_t**)lvalue, c->key, c->value);
1657 break;
1658 case CONFIG_TYPE_OBSOLETE:
1659 log_warn(LD_CONFIG, "Skipping obsolete configuration option '%s'", c->key);
1660 break;
1661 case CONFIG_TYPE_LINELIST_V:
1662 tor_asprintf(msg,
1663 "You may not provide a value for virtual option '%s'", c->key);
1664 return -1;
1665 default:
1666 tor_assert(0);
1667 break;
1669 return 0;
1672 /** If <b>c</b> is a syntactically valid configuration line, update
1673 * <b>options</b> with its value and return 0. Otherwise return -1 for bad
1674 * key, -2 for bad value.
1676 * If <b>clear_first</b> is set, clear the value first. Then if
1677 * <b>use_defaults</b> is set, set the value to the default.
1679 * Called from config_assign().
1681 static int
1682 config_assign_line(config_format_t *fmt, or_options_t *options,
1683 config_line_t *c, int use_defaults,
1684 int clear_first, char **msg)
1686 config_var_t *var;
1688 CHECK(fmt, options);
1690 var = config_find_option(fmt, c->key);
1691 if (!var) {
1692 if (fmt->extra) {
1693 void *lvalue = STRUCT_VAR_P(options, fmt->extra->var_offset);
1694 log_info(LD_CONFIG,
1695 "Found unrecognized option '%s'; saving it.", c->key);
1696 config_line_append((config_line_t**)lvalue, c->key, c->value);
1697 return 0;
1698 } else {
1699 tor_asprintf(msg,
1700 "Unknown option '%s'. Failing.", c->key);
1701 return -1;
1704 /* Put keyword into canonical case. */
1705 if (strcmp(var->name, c->key)) {
1706 tor_free(c->key);
1707 c->key = tor_strdup(var->name);
1710 if (!strlen(c->value)) {
1711 /* reset or clear it, then return */
1712 if (!clear_first) {
1713 if (var->type == CONFIG_TYPE_LINELIST ||
1714 var->type == CONFIG_TYPE_LINELIST_S) {
1715 /* We got an empty linelist from the torrc or command line.
1716 As a special case, call this an error. Warn and ignore. */
1717 log_warn(LD_CONFIG,
1718 "Linelist option '%s' has no value. Skipping.", c->key);
1719 } else { /* not already cleared */
1720 option_reset(fmt, options, var, use_defaults);
1723 return 0;
1726 if (config_assign_value(fmt, options, c, msg) < 0)
1727 return -2;
1728 return 0;
1731 /** Restore the option named <b>key</b> in options to its default value.
1732 * Called from config_assign(). */
1733 static void
1734 config_reset_line(config_format_t *fmt, or_options_t *options,
1735 const char *key, int use_defaults)
1737 config_var_t *var;
1739 CHECK(fmt, options);
1741 var = config_find_option(fmt, key);
1742 if (!var)
1743 return; /* give error on next pass. */
1745 option_reset(fmt, options, var, use_defaults);
1748 /** Return true iff key is a valid configuration option. */
1750 option_is_recognized(const char *key)
1752 config_var_t *var = config_find_option(&options_format, key);
1753 return (var != NULL);
1756 /** Return the canonical name of a configuration option, or NULL
1757 * if no such option exists. */
1758 const char *
1759 option_get_canonical_name(const char *key)
1761 config_var_t *var = config_find_option(&options_format, key);
1762 return var ? var->name : NULL;
1765 /** Return a canonical list of the options assigned for key.
1767 config_line_t *
1768 option_get_assignment(or_options_t *options, const char *key)
1770 return get_assigned_option(&options_format, options, key, 1);
1773 /** Return true iff value needs to be quoted and escaped to be used in
1774 * a configuration file. */
1775 static int
1776 config_value_needs_escape(const char *value)
1778 if (*value == '\"')
1779 return 1;
1780 while (*value) {
1781 switch (*value)
1783 case '\r':
1784 case '\n':
1785 case '#':
1786 /* Note: quotes and backspaces need special handling when we are using
1787 * quotes, not otherwise, so they don't trigger escaping on their
1788 * own. */
1789 return 1;
1790 default:
1791 if (!TOR_ISPRINT(*value))
1792 return 1;
1794 ++value;
1796 return 0;
1799 /** Return a newly allocated deep copy of the lines in <b>inp</b>. */
1800 static config_line_t *
1801 config_lines_dup(const config_line_t *inp)
1803 config_line_t *result = NULL;
1804 config_line_t **next_out = &result;
1805 while (inp) {
1806 *next_out = tor_malloc(sizeof(config_line_t));
1807 (*next_out)->key = tor_strdup(inp->key);
1808 (*next_out)->value = tor_strdup(inp->value);
1809 inp = inp->next;
1810 next_out = &((*next_out)->next);
1812 (*next_out) = NULL;
1813 return result;
1816 /** Return newly allocated line or lines corresponding to <b>key</b> in the
1817 * configuration <b>options</b>. If <b>escape_val</b> is true and a
1818 * value needs to be quoted before it's put in a config file, quote and
1819 * escape that value. Return NULL if no such key exists. */
1820 static config_line_t *
1821 get_assigned_option(config_format_t *fmt, void *options,
1822 const char *key, int escape_val)
1824 config_var_t *var;
1825 const void *value;
1826 config_line_t *result;
1827 tor_assert(options && key);
1829 CHECK(fmt, options);
1831 var = config_find_option(fmt, key);
1832 if (!var) {
1833 log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key);
1834 return NULL;
1836 value = STRUCT_VAR_P(options, var->var_offset);
1838 result = tor_malloc_zero(sizeof(config_line_t));
1839 result->key = tor_strdup(var->name);
1840 switch (var->type)
1842 case CONFIG_TYPE_STRING:
1843 case CONFIG_TYPE_FILENAME:
1844 if (*(char**)value) {
1845 result->value = tor_strdup(*(char**)value);
1846 } else {
1847 tor_free(result->key);
1848 tor_free(result);
1849 return NULL;
1851 break;
1852 case CONFIG_TYPE_ISOTIME:
1853 if (*(time_t*)value) {
1854 result->value = tor_malloc(ISO_TIME_LEN+1);
1855 format_iso_time(result->value, *(time_t*)value);
1856 } else {
1857 tor_free(result->key);
1858 tor_free(result);
1860 escape_val = 0; /* Can't need escape. */
1861 break;
1862 case CONFIG_TYPE_INTERVAL:
1863 case CONFIG_TYPE_UINT:
1864 /* This means every or_options_t uint or bool element
1865 * needs to be an int. Not, say, a uint16_t or char. */
1866 tor_asprintf(&result->value, "%d", *(int*)value);
1867 escape_val = 0; /* Can't need escape. */
1868 break;
1869 case CONFIG_TYPE_MEMUNIT:
1870 tor_asprintf(&result->value, U64_FORMAT,
1871 U64_PRINTF_ARG(*(uint64_t*)value));
1872 escape_val = 0; /* Can't need escape. */
1873 break;
1874 case CONFIG_TYPE_DOUBLE:
1875 tor_asprintf(&result->value, "%f", *(double*)value);
1876 escape_val = 0; /* Can't need escape. */
1877 break;
1878 case CONFIG_TYPE_BOOL:
1879 result->value = tor_strdup(*(int*)value ? "1" : "0");
1880 escape_val = 0; /* Can't need escape. */
1881 break;
1882 case CONFIG_TYPE_ROUTERSET:
1883 result->value = routerset_to_string(*(routerset_t**)value);
1884 break;
1885 case CONFIG_TYPE_CSV:
1886 if (*(smartlist_t**)value)
1887 result->value =
1888 smartlist_join_strings(*(smartlist_t**)value, ",", 0, NULL);
1889 else
1890 result->value = tor_strdup("");
1891 break;
1892 case CONFIG_TYPE_OBSOLETE:
1893 log_fn(LOG_PROTOCOL_WARN, LD_CONFIG,
1894 "You asked me for the value of an obsolete config option '%s'.",
1895 key);
1896 tor_free(result->key);
1897 tor_free(result);
1898 return NULL;
1899 case CONFIG_TYPE_LINELIST_S:
1900 log_warn(LD_CONFIG,
1901 "Can't return context-sensitive '%s' on its own", key);
1902 tor_free(result->key);
1903 tor_free(result);
1904 return NULL;
1905 case CONFIG_TYPE_LINELIST:
1906 case CONFIG_TYPE_LINELIST_V:
1907 tor_free(result->key);
1908 tor_free(result);
1909 result = config_lines_dup(*(const config_line_t**)value);
1910 break;
1911 default:
1912 tor_free(result->key);
1913 tor_free(result);
1914 log_warn(LD_BUG,"Unknown type %d for known key '%s'",
1915 var->type, key);
1916 return NULL;
1919 if (escape_val) {
1920 config_line_t *line;
1921 for (line = result; line; line = line->next) {
1922 if (line->value && config_value_needs_escape(line->value)) {
1923 char *newval = esc_for_log(line->value);
1924 tor_free(line->value);
1925 line->value = newval;
1930 return result;
1933 /** Iterate through the linked list of requested options <b>list</b>.
1934 * For each item, convert as appropriate and assign to <b>options</b>.
1935 * If an item is unrecognized, set *msg and return -1 immediately,
1936 * else return 0 for success.
1938 * If <b>clear_first</b>, interpret config options as replacing (not
1939 * extending) their previous values. If <b>clear_first</b> is set,
1940 * then <b>use_defaults</b> to decide if you set to defaults after
1941 * clearing, or make the value 0 or NULL.
1943 * Here are the use cases:
1944 * 1. A non-empty AllowInvalid line in your torrc. Appends to current
1945 * if linelist, replaces current if csv.
1946 * 2. An empty AllowInvalid line in your torrc. Should clear it.
1947 * 3. "RESETCONF AllowInvalid" sets it to default.
1948 * 4. "SETCONF AllowInvalid" makes it NULL.
1949 * 5. "SETCONF AllowInvalid=foo" clears it and sets it to "foo".
1951 * Use_defaults Clear_first
1952 * 0 0 "append"
1953 * 1 0 undefined, don't use
1954 * 0 1 "set to null first"
1955 * 1 1 "set to defaults first"
1956 * Return 0 on success, -1 on bad key, -2 on bad value.
1958 * As an additional special case, if a LINELIST config option has
1959 * no value and clear_first is 0, then warn and ignore it.
1963 There are three call cases for config_assign() currently.
1965 Case one: Torrc entry
1966 options_init_from_torrc() calls config_assign(0, 0)
1967 calls config_assign_line(0, 0).
1968 if value is empty, calls option_reset(0) and returns.
1969 calls config_assign_value(), appends.
1971 Case two: setconf
1972 options_trial_assign() calls config_assign(0, 1)
1973 calls config_reset_line(0)
1974 calls option_reset(0)
1975 calls option_clear().
1976 calls config_assign_line(0, 1).
1977 if value is empty, returns.
1978 calls config_assign_value(), appends.
1980 Case three: resetconf
1981 options_trial_assign() calls config_assign(1, 1)
1982 calls config_reset_line(1)
1983 calls option_reset(1)
1984 calls option_clear().
1985 calls config_assign_value(default)
1986 calls config_assign_line(1, 1).
1987 returns.
1989 static int
1990 config_assign(config_format_t *fmt, void *options, config_line_t *list,
1991 int use_defaults, int clear_first, char **msg)
1993 config_line_t *p;
1995 CHECK(fmt, options);
1997 /* pass 1: normalize keys */
1998 for (p = list; p; p = p->next) {
1999 const char *full = expand_abbrev(fmt, p->key, 0, 1);
2000 if (strcmp(full,p->key)) {
2001 tor_free(p->key);
2002 p->key = tor_strdup(full);
2006 /* pass 2: if we're reading from a resetting source, clear all
2007 * mentioned config options, and maybe set to their defaults. */
2008 if (clear_first) {
2009 for (p = list; p; p = p->next)
2010 config_reset_line(fmt, options, p->key, use_defaults);
2013 /* pass 3: assign. */
2014 while (list) {
2015 int r;
2016 if ((r=config_assign_line(fmt, options, list, use_defaults,
2017 clear_first, msg)))
2018 return r;
2019 list = list->next;
2021 return 0;
2024 /** Try assigning <b>list</b> to the global options. You do this by duping
2025 * options, assigning list to the new one, then validating it. If it's
2026 * ok, then throw out the old one and stick with the new one. Else,
2027 * revert to old and return failure. Return SETOPT_OK on success, or
2028 * a setopt_err_t on failure.
2030 * If not success, point *<b>msg</b> to a newly allocated string describing
2031 * what went wrong.
2033 setopt_err_t
2034 options_trial_assign(config_line_t *list, int use_defaults,
2035 int clear_first, char **msg)
2037 int r;
2038 or_options_t *trial_options = options_dup(&options_format, get_options());
2040 if ((r=config_assign(&options_format, trial_options,
2041 list, use_defaults, clear_first, msg)) < 0) {
2042 config_free(&options_format, trial_options);
2043 return r;
2046 if (options_validate(get_options(), trial_options, 1, msg) < 0) {
2047 config_free(&options_format, trial_options);
2048 return SETOPT_ERR_PARSE; /*XXX make this a separate return value. */
2051 if (options_transition_allowed(get_options(), trial_options, msg) < 0) {
2052 config_free(&options_format, trial_options);
2053 return SETOPT_ERR_TRANSITION;
2056 if (set_options(trial_options, msg)<0) {
2057 config_free(&options_format, trial_options);
2058 return SETOPT_ERR_SETTING;
2061 /* we liked it. put it in place. */
2062 return SETOPT_OK;
2065 /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
2066 * Called from option_reset() and config_free(). */
2067 static void
2068 option_clear(config_format_t *fmt, or_options_t *options, config_var_t *var)
2070 void *lvalue = STRUCT_VAR_P(options, var->var_offset);
2071 (void)fmt; /* unused */
2072 switch (var->type) {
2073 case CONFIG_TYPE_STRING:
2074 case CONFIG_TYPE_FILENAME:
2075 tor_free(*(char**)lvalue);
2076 break;
2077 case CONFIG_TYPE_DOUBLE:
2078 *(double*)lvalue = 0.0;
2079 break;
2080 case CONFIG_TYPE_ISOTIME:
2081 *(time_t*)lvalue = 0;
2082 break;
2083 case CONFIG_TYPE_INTERVAL:
2084 case CONFIG_TYPE_UINT:
2085 case CONFIG_TYPE_BOOL:
2086 *(int*)lvalue = 0;
2087 break;
2088 case CONFIG_TYPE_MEMUNIT:
2089 *(uint64_t*)lvalue = 0;
2090 break;
2091 case CONFIG_TYPE_ROUTERSET:
2092 if (*(routerset_t**)lvalue) {
2093 routerset_free(*(routerset_t**)lvalue);
2094 *(routerset_t**)lvalue = NULL;
2096 break;
2097 case CONFIG_TYPE_CSV:
2098 if (*(smartlist_t**)lvalue) {
2099 SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
2100 smartlist_free(*(smartlist_t **)lvalue);
2101 *(smartlist_t **)lvalue = NULL;
2103 break;
2104 case CONFIG_TYPE_LINELIST:
2105 case CONFIG_TYPE_LINELIST_S:
2106 config_free_lines(*(config_line_t **)lvalue);
2107 *(config_line_t **)lvalue = NULL;
2108 break;
2109 case CONFIG_TYPE_LINELIST_V:
2110 /* handled by linelist_s. */
2111 break;
2112 case CONFIG_TYPE_OBSOLETE:
2113 break;
2117 /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
2118 * <b>use_defaults</b>, set it to its default value.
2119 * Called by config_init() and option_reset_line() and option_assign_line(). */
2120 static void
2121 option_reset(config_format_t *fmt, or_options_t *options,
2122 config_var_t *var, int use_defaults)
2124 config_line_t *c;
2125 char *msg = NULL;
2126 CHECK(fmt, options);
2127 option_clear(fmt, options, var); /* clear it first */
2128 if (!use_defaults)
2129 return; /* all done */
2130 if (var->initvalue) {
2131 c = tor_malloc_zero(sizeof(config_line_t));
2132 c->key = tor_strdup(var->name);
2133 c->value = tor_strdup(var->initvalue);
2134 if (config_assign_value(fmt, options, c, &msg) < 0) {
2135 log_warn(LD_BUG, "Failed to assign default: %s", msg);
2136 tor_free(msg); /* if this happens it's a bug */
2138 config_free_lines(c);
2142 /** Print a usage message for tor. */
2143 static void
2144 print_usage(void)
2146 printf(
2147 "Copyright (c) 2001-2004, Roger Dingledine\n"
2148 "Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson\n"
2149 "Copyright (c) 2007-2010, The Tor Project, Inc.\n\n"
2150 "tor -f <torrc> [args]\n"
2151 "See man page for options, or https://www.torproject.org/ for "
2152 "documentation.\n");
2155 /** Print all non-obsolete torrc options. */
2156 static void
2157 list_torrc_options(void)
2159 int i;
2160 smartlist_t *lines = smartlist_create();
2161 for (i = 0; _option_vars[i].name; ++i) {
2162 config_var_t *var = &_option_vars[i];
2163 if (var->type == CONFIG_TYPE_OBSOLETE ||
2164 var->type == CONFIG_TYPE_LINELIST_V)
2165 continue;
2166 printf("%s\n", var->name);
2168 smartlist_free(lines);
2171 /** Last value actually set by resolve_my_address. */
2172 static uint32_t last_resolved_addr = 0;
2174 * Based on <b>options-\>Address</b>, guess our public IP address and put it
2175 * (in host order) into *<b>addr_out</b>. If <b>hostname_out</b> is provided,
2176 * set *<b>hostname_out</b> to a new string holding the hostname we used to
2177 * get the address. Return 0 if all is well, or -1 if we can't find a suitable
2178 * public IP address.
2181 resolve_my_address(int warn_severity, or_options_t *options,
2182 uint32_t *addr_out, char **hostname_out)
2184 struct in_addr in;
2185 uint32_t addr; /* host order */
2186 char hostname[256];
2187 int explicit_ip=1;
2188 int explicit_hostname=1;
2189 int from_interface=0;
2190 char tmpbuf[INET_NTOA_BUF_LEN];
2191 const char *address = options->Address;
2192 int notice_severity = warn_severity <= LOG_NOTICE ?
2193 LOG_NOTICE : warn_severity;
2195 tor_assert(addr_out);
2197 if (address && *address) {
2198 strlcpy(hostname, address, sizeof(hostname));
2199 } else { /* then we need to guess our address */
2200 explicit_ip = 0; /* it's implicit */
2201 explicit_hostname = 0; /* it's implicit */
2203 if (gethostname(hostname, sizeof(hostname)) < 0) {
2204 log_fn(warn_severity, LD_NET,"Error obtaining local hostname");
2205 return -1;
2207 log_debug(LD_CONFIG,"Guessed local host name as '%s'",hostname);
2210 /* now we know hostname. resolve it and keep only the IP address */
2212 if (tor_inet_aton(hostname, &in) == 0) {
2213 /* then we have to resolve it */
2214 explicit_ip = 0;
2215 if (tor_lookup_hostname(hostname, &addr)) { /* failed to resolve */
2216 uint32_t interface_ip; /* host order */
2218 if (explicit_hostname) {
2219 log_fn(warn_severity, LD_CONFIG,
2220 "Could not resolve local Address '%s'. Failing.", hostname);
2221 return -1;
2223 log_fn(notice_severity, LD_CONFIG,
2224 "Could not resolve guessed local hostname '%s'. "
2225 "Trying something else.", hostname);
2226 if (get_interface_address(warn_severity, &interface_ip)) {
2227 log_fn(warn_severity, LD_CONFIG,
2228 "Could not get local interface IP address. Failing.");
2229 return -1;
2231 from_interface = 1;
2232 in.s_addr = htonl(interface_ip);
2233 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2234 log_fn(notice_severity, LD_CONFIG, "Learned IP address '%s' for "
2235 "local interface. Using that.", tmpbuf);
2236 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
2237 } else { /* resolved hostname into addr */
2238 in.s_addr = htonl(addr);
2240 if (!explicit_hostname &&
2241 is_internal_IP(ntohl(in.s_addr), 0)) {
2242 uint32_t interface_ip;
2244 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2245 log_fn(notice_severity, LD_CONFIG, "Guessed local hostname '%s' "
2246 "resolves to a private IP address (%s). Trying something "
2247 "else.", hostname, tmpbuf);
2249 if (get_interface_address(warn_severity, &interface_ip)) {
2250 log_fn(warn_severity, LD_CONFIG,
2251 "Could not get local interface IP address. Too bad.");
2252 } else if (is_internal_IP(interface_ip, 0)) {
2253 struct in_addr in2;
2254 in2.s_addr = htonl(interface_ip);
2255 tor_inet_ntoa(&in2,tmpbuf,sizeof(tmpbuf));
2256 log_fn(notice_severity, LD_CONFIG,
2257 "Interface IP address '%s' is a private address too. "
2258 "Ignoring.", tmpbuf);
2259 } else {
2260 from_interface = 1;
2261 in.s_addr = htonl(interface_ip);
2262 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2263 log_fn(notice_severity, LD_CONFIG,
2264 "Learned IP address '%s' for local interface."
2265 " Using that.", tmpbuf);
2266 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
2272 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
2273 if (is_internal_IP(ntohl(in.s_addr), 0) &&
2274 options->_PublishServerDescriptor) {
2275 /* make sure we're ok with publishing an internal IP */
2276 if (!options->DirServers && !options->AlternateDirAuthority) {
2277 /* if they are using the default dirservers, disallow internal IPs
2278 * always. */
2279 log_fn(warn_severity, LD_CONFIG,
2280 "Address '%s' resolves to private IP address '%s'. "
2281 "Tor servers that use the default DirServers must have public "
2282 "IP addresses.", hostname, tmpbuf);
2283 return -1;
2285 if (!explicit_ip) {
2286 /* even if they've set their own dirservers, require an explicit IP if
2287 * they're using an internal address. */
2288 log_fn(warn_severity, LD_CONFIG, "Address '%s' resolves to private "
2289 "IP address '%s'. Please set the Address config option to be "
2290 "the IP address you want to use.", hostname, tmpbuf);
2291 return -1;
2295 log_debug(LD_CONFIG, "Resolved Address to '%s'.", tmpbuf);
2296 *addr_out = ntohl(in.s_addr);
2297 if (last_resolved_addr && last_resolved_addr != *addr_out) {
2298 /* Leave this as a notice, regardless of the requested severity,
2299 * at least until dynamic IP address support becomes bulletproof. */
2300 log_notice(LD_NET,
2301 "Your IP address seems to have changed to %s. Updating.",
2302 tmpbuf);
2303 ip_address_changed(0);
2305 if (last_resolved_addr != *addr_out) {
2306 const char *method;
2307 const char *h = hostname;
2308 if (explicit_ip) {
2309 method = "CONFIGURED";
2310 h = NULL;
2311 } else if (explicit_hostname) {
2312 method = "RESOLVED";
2313 } else if (from_interface) {
2314 method = "INTERFACE";
2315 h = NULL;
2316 } else {
2317 method = "GETHOSTNAME";
2319 control_event_server_status(LOG_NOTICE,
2320 "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s %s%s",
2321 tmpbuf, method, h?"HOSTNAME=":"", h);
2323 last_resolved_addr = *addr_out;
2324 if (hostname_out)
2325 *hostname_out = tor_strdup(hostname);
2326 return 0;
2329 /** Return true iff <b>addr</b> is judged to be on the same network as us, or
2330 * on a private network.
2333 is_local_addr(const tor_addr_t *addr)
2335 if (tor_addr_is_internal(addr, 0))
2336 return 1;
2337 /* Check whether ip is on the same /24 as we are. */
2338 if (get_options()->EnforceDistinctSubnets == 0)
2339 return 0;
2340 if (tor_addr_family(addr) == AF_INET) {
2341 /*XXXX022 IP6 what corresponds to an /24? */
2342 uint32_t ip = tor_addr_to_ipv4h(addr);
2344 /* It's possible that this next check will hit before the first time
2345 * resolve_my_address actually succeeds. (For clients, it is likely that
2346 * resolve_my_address will never be called at all). In those cases,
2347 * last_resolved_addr will be 0, and so checking to see whether ip is on
2348 * the same /24 as last_resolved_addr will be the same as checking whether
2349 * it was on net 0, which is already done by is_internal_IP.
2351 if ((last_resolved_addr & (uint32_t)0xffffff00ul)
2352 == (ip & (uint32_t)0xffffff00ul))
2353 return 1;
2355 return 0;
2358 /** Called when we don't have a nickname set. Try to guess a good nickname
2359 * based on the hostname, and return it in a newly allocated string. If we
2360 * can't, return NULL and let the caller warn if it wants to. */
2361 static char *
2362 get_default_nickname(void)
2364 static const char * const bad_default_nicknames[] = {
2365 "localhost",
2366 NULL,
2368 char localhostname[256];
2369 char *cp, *out, *outp;
2370 int i;
2372 if (gethostname(localhostname, sizeof(localhostname)) < 0)
2373 return NULL;
2375 /* Put it in lowercase; stop at the first dot. */
2376 if ((cp = strchr(localhostname, '.')))
2377 *cp = '\0';
2378 tor_strlower(localhostname);
2380 /* Strip invalid characters. */
2381 cp = localhostname;
2382 out = outp = tor_malloc(strlen(localhostname) + 1);
2383 while (*cp) {
2384 if (strchr(LEGAL_NICKNAME_CHARACTERS, *cp))
2385 *outp++ = *cp++;
2386 else
2387 cp++;
2389 *outp = '\0';
2391 /* Enforce length. */
2392 if (strlen(out) > MAX_NICKNAME_LEN)
2393 out[MAX_NICKNAME_LEN]='\0';
2395 /* Check for dumb names. */
2396 for (i = 0; bad_default_nicknames[i]; ++i) {
2397 if (!strcmp(out, bad_default_nicknames[i])) {
2398 tor_free(out);
2399 return NULL;
2403 return out;
2406 /** Release storage held by <b>options</b>. */
2407 static void
2408 config_free(config_format_t *fmt, void *options)
2410 int i;
2412 if (!options)
2413 return;
2415 tor_assert(fmt);
2417 for (i=0; fmt->vars[i].name; ++i)
2418 option_clear(fmt, options, &(fmt->vars[i]));
2419 if (fmt->extra) {
2420 config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->var_offset);
2421 config_free_lines(*linep);
2422 *linep = NULL;
2424 tor_free(options);
2427 /** Return true iff a and b contain identical keys and values in identical
2428 * order. */
2429 static int
2430 config_lines_eq(config_line_t *a, config_line_t *b)
2432 while (a && b) {
2433 if (strcasecmp(a->key, b->key) || strcmp(a->value, b->value))
2434 return 0;
2435 a = a->next;
2436 b = b->next;
2438 if (a || b)
2439 return 0;
2440 return 1;
2443 /** Return true iff the option <b>name</b> has the same value in <b>o1</b>
2444 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
2446 static int
2447 option_is_same(config_format_t *fmt,
2448 or_options_t *o1, or_options_t *o2, const char *name)
2450 config_line_t *c1, *c2;
2451 int r = 1;
2452 CHECK(fmt, o1);
2453 CHECK(fmt, o2);
2455 c1 = get_assigned_option(fmt, o1, name, 0);
2456 c2 = get_assigned_option(fmt, o2, name, 0);
2457 r = config_lines_eq(c1, c2);
2458 config_free_lines(c1);
2459 config_free_lines(c2);
2460 return r;
2463 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
2464 static or_options_t *
2465 options_dup(config_format_t *fmt, or_options_t *old)
2467 or_options_t *newopts;
2468 int i;
2469 config_line_t *line;
2471 newopts = config_alloc(fmt);
2472 for (i=0; fmt->vars[i].name; ++i) {
2473 if (fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2474 continue;
2475 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE)
2476 continue;
2477 line = get_assigned_option(fmt, old, fmt->vars[i].name, 0);
2478 if (line) {
2479 char *msg = NULL;
2480 if (config_assign(fmt, newopts, line, 0, 0, &msg) < 0) {
2481 log_err(LD_BUG, "Config_get_assigned_option() generated "
2482 "something we couldn't config_assign(): %s", msg);
2483 tor_free(msg);
2484 tor_assert(0);
2487 config_free_lines(line);
2489 return newopts;
2492 /** Return a new empty or_options_t. Used for testing. */
2493 or_options_t *
2494 options_new(void)
2496 return config_alloc(&options_format);
2499 /** Set <b>options</b> to hold reasonable defaults for most options.
2500 * Each option defaults to zero. */
2501 void
2502 options_init(or_options_t *options)
2504 config_init(&options_format, options);
2507 /* Check if the port number given in <b>port_option</b> in combination with
2508 * the specified port in <b>listen_options</b> will result in Tor actually
2509 * opening a low port (meaning a port lower than 1024). Return 1 if
2510 * it is, or 0 if it isn't or the concept of a low port isn't applicable for
2511 * the platform we're on. */
2512 static int
2513 is_listening_on_low_port(uint16_t port_option,
2514 const config_line_t *listen_options)
2516 #ifdef MS_WINDOWS
2517 (void) port_option;
2518 (void) listen_options;
2519 return 0; /* No port is too low for windows. */
2520 #else
2521 const config_line_t *l;
2522 uint16_t p;
2523 if (port_option == 0)
2524 return 0; /* We're not listening */
2525 if (listen_options == NULL)
2526 return (port_option < 1024);
2528 for (l = listen_options; l; l = l->next) {
2529 parse_addr_port(LOG_WARN, l->value, NULL, NULL, &p);
2530 if (p<1024) {
2531 return 1;
2534 return 0;
2535 #endif
2538 /** Set all vars in the configuration object <b>options</b> to their default
2539 * values. */
2540 static void
2541 config_init(config_format_t *fmt, void *options)
2543 int i;
2544 config_var_t *var;
2545 CHECK(fmt, options);
2547 for (i=0; fmt->vars[i].name; ++i) {
2548 var = &fmt->vars[i];
2549 if (!var->initvalue)
2550 continue; /* defaults to NULL or 0 */
2551 option_reset(fmt, options, var, 1);
2555 /** Allocate and return a new string holding the written-out values of the vars
2556 * in 'options'. If 'minimal', do not write out any default-valued vars.
2557 * Else, if comment_defaults, write default values as comments.
2559 static char *
2560 config_dump(config_format_t *fmt, void *options, int minimal,
2561 int comment_defaults)
2563 smartlist_t *elements;
2564 or_options_t *defaults;
2565 config_line_t *line, *assigned;
2566 char *result;
2567 int i;
2568 char *msg = NULL;
2570 defaults = config_alloc(fmt);
2571 config_init(fmt, defaults);
2573 /* XXX use a 1 here so we don't add a new log line while dumping */
2574 if (fmt->validate_fn(NULL,defaults, 1, &msg) < 0) {
2575 log_err(LD_BUG, "Failed to validate default config.");
2576 tor_free(msg);
2577 tor_assert(0);
2580 elements = smartlist_create();
2581 for (i=0; fmt->vars[i].name; ++i) {
2582 int comment_option = 0;
2583 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE ||
2584 fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2585 continue;
2586 /* Don't save 'hidden' control variables. */
2587 if (!strcmpstart(fmt->vars[i].name, "__"))
2588 continue;
2589 if (minimal && option_is_same(fmt, options, defaults, fmt->vars[i].name))
2590 continue;
2591 else if (comment_defaults &&
2592 option_is_same(fmt, options, defaults, fmt->vars[i].name))
2593 comment_option = 1;
2595 line = assigned = get_assigned_option(fmt, options, fmt->vars[i].name, 1);
2597 for (; line; line = line->next) {
2598 char *tmp;
2599 tor_asprintf(&tmp, "%s%s %s\n",
2600 comment_option ? "# " : "",
2601 line->key, line->value);
2602 smartlist_add(elements, tmp);
2604 config_free_lines(assigned);
2607 if (fmt->extra) {
2608 line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->var_offset);
2609 for (; line; line = line->next) {
2610 char *tmp;
2611 tor_asprintf(&tmp, "%s %s\n", line->key, line->value);
2612 smartlist_add(elements, tmp);
2616 result = smartlist_join_strings(elements, "", 0, NULL);
2617 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2618 smartlist_free(elements);
2619 config_free(fmt, defaults);
2620 return result;
2623 /** Return a string containing a possible configuration file that would give
2624 * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
2625 * include options that are the same as Tor's defaults.
2627 char *
2628 options_dump(or_options_t *options, int minimal)
2630 return config_dump(&options_format, options, minimal, 0);
2633 /** Return 0 if every element of sl is a string holding a decimal
2634 * representation of a port number, or if sl is NULL.
2635 * Otherwise set *msg and return -1. */
2636 static int
2637 validate_ports_csv(smartlist_t *sl, const char *name, char **msg)
2639 int i;
2640 tor_assert(name);
2642 if (!sl)
2643 return 0;
2645 SMARTLIST_FOREACH(sl, const char *, cp,
2647 i = atoi(cp);
2648 if (i < 1 || i > 65535) {
2649 tor_asprintf(msg, "Port '%s' out of range in %s", cp, name);
2650 return -1;
2653 return 0;
2656 /** If <b>value</b> exceeds ROUTER_MAX_DECLARED_BANDWIDTH, write
2657 * a complaint into *<b>msg</b> using string <b>desc</b>, and return -1.
2658 * Else return 0.
2660 static int
2661 ensure_bandwidth_cap(uint64_t *value, const char *desc, char **msg)
2663 if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
2664 /* This handles an understandable special case where somebody says "2gb"
2665 * whereas our actual maximum is 2gb-1 (INT_MAX) */
2666 --*value;
2668 if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
2669 tor_asprintf(msg, "%s ("U64_FORMAT") must be at most %d",
2670 desc, U64_PRINTF_ARG(*value),
2671 ROUTER_MAX_DECLARED_BANDWIDTH);
2672 return -1;
2674 return 0;
2677 /** Parse an authority type from <b>options</b>-\>PublishServerDescriptor
2678 * and write it to <b>options</b>-\>_PublishServerDescriptor. Treat "1"
2679 * as "v2,v3" unless BridgeRelay is 1, in which case treat it as "bridge".
2680 * Treat "0" as "".
2681 * Return 0 on success or -1 if not a recognized authority type (in which
2682 * case the value of _PublishServerDescriptor is undefined). */
2683 static int
2684 compute_publishserverdescriptor(or_options_t *options)
2686 smartlist_t *list = options->PublishServerDescriptor;
2687 authority_type_t *auth = &options->_PublishServerDescriptor;
2688 *auth = NO_AUTHORITY;
2689 if (!list) /* empty list, answer is none */
2690 return 0;
2691 SMARTLIST_FOREACH(list, const char *, string, {
2692 if (!strcasecmp(string, "v1"))
2693 *auth |= V1_AUTHORITY;
2694 else if (!strcmp(string, "1"))
2695 if (options->BridgeRelay)
2696 *auth |= BRIDGE_AUTHORITY;
2697 else
2698 *auth |= V2_AUTHORITY | V3_AUTHORITY;
2699 else if (!strcasecmp(string, "v2"))
2700 *auth |= V2_AUTHORITY;
2701 else if (!strcasecmp(string, "v3"))
2702 *auth |= V3_AUTHORITY;
2703 else if (!strcasecmp(string, "bridge"))
2704 *auth |= BRIDGE_AUTHORITY;
2705 else if (!strcasecmp(string, "hidserv"))
2706 *auth |= HIDSERV_AUTHORITY;
2707 else if (!strcasecmp(string, "") || !strcmp(string, "0"))
2708 /* no authority */;
2709 else
2710 return -1;
2712 return 0;
2715 /** Lowest allowable value for RendPostPeriod; if this is too low, hidden
2716 * services can overload the directory system. */
2717 #define MIN_REND_POST_PERIOD (10*60)
2719 /** Highest allowable value for RendPostPeriod. */
2720 #define MAX_DIR_PERIOD (MIN_ONION_KEY_LIFETIME/2)
2722 /** Lowest allowable value for MaxCircuitDirtiness; if this is too low, Tor
2723 * will generate too many circuits and potentially overload the network. */
2724 #define MIN_MAX_CIRCUIT_DIRTINESS 10
2726 /** Lowest allowable value for CircuitStreamTimeout; if this is too low, Tor
2727 * will generate too many circuits and potentially overload the network. */
2728 #define MIN_CIRCUIT_STREAM_TIMEOUT 10
2730 /** Return 0 if every setting in <b>options</b> is reasonable, and a
2731 * permissible transition from <b>old_options</b>. Else return -1.
2732 * Should have no side effects, except for normalizing the contents of
2733 * <b>options</b>.
2735 * On error, tor_strdup an error explanation into *<b>msg</b>.
2737 * XXX
2738 * If <b>from_setconf</b>, we were called by the controller, and our
2739 * Log line should stay empty. If it's 0, then give us a default log
2740 * if there are no logs defined.
2742 static int
2743 options_validate(or_options_t *old_options, or_options_t *options,
2744 int from_setconf, char **msg)
2746 int i;
2747 config_line_t *cl;
2748 const char *uname = get_uname();
2749 #define REJECT(arg) \
2750 STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
2751 #define COMPLAIN(arg) STMT_BEGIN log(LOG_WARN, LD_CONFIG, arg); STMT_END
2753 tor_assert(msg);
2754 *msg = NULL;
2756 if (options->ORPort < 0 || options->ORPort > 65535)
2757 REJECT("ORPort option out of bounds.");
2759 if (server_mode(options) &&
2760 (!strcmpstart(uname, "Windows 95") ||
2761 !strcmpstart(uname, "Windows 98") ||
2762 !strcmpstart(uname, "Windows Me"))) {
2763 log(LOG_WARN, LD_CONFIG, "Tor is running as a server, but you are "
2764 "running %s; this probably won't work. See "
2765 "https://wiki.torproject.org/TheOnionRouter/TorFAQ#ServerOS "
2766 "for details.", uname);
2769 if (options->ORPort == 0 && options->ORListenAddress != NULL)
2770 REJECT("ORPort must be defined if ORListenAddress is defined.");
2772 if (options->DirPort == 0 && options->DirListenAddress != NULL)
2773 REJECT("DirPort must be defined if DirListenAddress is defined.");
2775 if (options->DNSPort == 0 && options->DNSListenAddress != NULL)
2776 REJECT("DNSPort must be defined if DNSListenAddress is defined.");
2778 if (options->ControlPort == 0 && options->ControlListenAddress != NULL)
2779 REJECT("ControlPort must be defined if ControlListenAddress is defined.");
2781 if (options->TransPort == 0 && options->TransListenAddress != NULL)
2782 REJECT("TransPort must be defined if TransListenAddress is defined.");
2784 if (options->NatdPort == 0 && options->NatdListenAddress != NULL)
2785 REJECT("NatdPort must be defined if NatdListenAddress is defined.");
2787 /* Don't gripe about SocksPort 0 with SocksListenAddress set; a standard
2788 * configuration does this. */
2790 for (i = 0; i < 3; ++i) {
2791 int is_socks = i==0;
2792 int is_trans = i==1;
2793 config_line_t *line, *opt, *old;
2794 const char *tp;
2795 if (is_socks) {
2796 opt = options->SocksListenAddress;
2797 old = old_options ? old_options->SocksListenAddress : NULL;
2798 tp = "SOCKS proxy";
2799 } else if (is_trans) {
2800 opt = options->TransListenAddress;
2801 old = old_options ? old_options->TransListenAddress : NULL;
2802 tp = "transparent proxy";
2803 } else {
2804 opt = options->NatdListenAddress;
2805 old = old_options ? old_options->NatdListenAddress : NULL;
2806 tp = "natd proxy";
2809 for (line = opt; line; line = line->next) {
2810 char *address = NULL;
2811 uint16_t port;
2812 uint32_t addr;
2813 if (parse_addr_port(LOG_WARN, line->value, &address, &addr, &port)<0)
2814 continue; /* We'll warn about this later. */
2815 if (!is_internal_IP(addr, 1) &&
2816 (!old_options || !config_lines_eq(old, opt))) {
2817 log_warn(LD_CONFIG,
2818 "You specified a public address '%s' for a %s. Other "
2819 "people on the Internet might find your computer and use it as "
2820 "an open %s. Please don't allow this unless you have "
2821 "a good reason.", address, tp, tp);
2823 tor_free(address);
2827 if (validate_data_directory(options)<0)
2828 REJECT("Invalid DataDirectory");
2830 if (options->Nickname == NULL) {
2831 if (server_mode(options)) {
2832 if (!(options->Nickname = get_default_nickname())) {
2833 log_notice(LD_CONFIG, "Couldn't pick a nickname based on "
2834 "our hostname; using %s instead.", UNNAMED_ROUTER_NICKNAME);
2835 options->Nickname = tor_strdup(UNNAMED_ROUTER_NICKNAME);
2836 } else {
2837 log_notice(LD_CONFIG, "Choosing default nickname '%s'",
2838 options->Nickname);
2841 } else {
2842 if (!is_legal_nickname(options->Nickname)) {
2843 tor_asprintf(msg,
2844 "Nickname '%s' is wrong length or contains illegal characters.",
2845 options->Nickname);
2846 return -1;
2850 if (server_mode(options) && !options->ContactInfo)
2851 log(LOG_NOTICE, LD_CONFIG, "Your ContactInfo config option is not set. "
2852 "Please consider setting it, so we can contact you if your server is "
2853 "misconfigured or something else goes wrong.");
2855 /* Special case on first boot if no Log options are given. */
2856 if (!options->Logs && !options->RunAsDaemon && !from_setconf)
2857 config_line_append(&options->Logs, "Log", "notice stdout");
2859 if (options_init_logs(options, 1)<0) /* Validate the log(s) */
2860 REJECT("Failed to validate Log options. See logs for details.");
2862 if (options->NoPublish) {
2863 log(LOG_WARN, LD_CONFIG,
2864 "NoPublish is obsolete. Use PublishServerDescriptor instead.");
2865 SMARTLIST_FOREACH(options->PublishServerDescriptor, char *, s,
2866 tor_free(s));
2867 smartlist_clear(options->PublishServerDescriptor);
2870 if (authdir_mode(options)) {
2871 /* confirm that our address isn't broken, so we can complain now */
2872 uint32_t tmp;
2873 if (resolve_my_address(LOG_WARN, options, &tmp, NULL) < 0)
2874 REJECT("Failed to resolve/guess local address. See logs for details.");
2877 #ifndef MS_WINDOWS
2878 if (options->RunAsDaemon && torrc_fname && path_is_relative(torrc_fname))
2879 REJECT("Can't use a relative path to torrc when RunAsDaemon is set.");
2880 #endif
2882 if (options->SocksPort < 0 || options->SocksPort > 65535)
2883 REJECT("SocksPort option out of bounds.");
2885 if (options->DNSPort < 0 || options->DNSPort > 65535)
2886 REJECT("DNSPort option out of bounds.");
2888 if (options->TransPort < 0 || options->TransPort > 65535)
2889 REJECT("TransPort option out of bounds.");
2891 if (options->NatdPort < 0 || options->NatdPort > 65535)
2892 REJECT("NatdPort option out of bounds.");
2894 if (options->SocksPort == 0 && options->TransPort == 0 &&
2895 options->NatdPort == 0 && options->ORPort == 0 &&
2896 options->DNSPort == 0 && !options->RendConfigLines)
2897 log(LOG_WARN, LD_CONFIG,
2898 "SocksPort, TransPort, NatdPort, DNSPort, and ORPort are all "
2899 "undefined, and there aren't any hidden services configured. "
2900 "Tor will still run, but probably won't do anything.");
2902 if (options->ControlPort < 0 || options->ControlPort > 65535)
2903 REJECT("ControlPort option out of bounds.");
2905 if (options->DirPort < 0 || options->DirPort > 65535)
2906 REJECT("DirPort option out of bounds.");
2908 #ifndef USE_TRANSPARENT
2909 if (options->TransPort || options->TransListenAddress)
2910 REJECT("TransPort and TransListenAddress are disabled in this build.");
2911 #endif
2913 if (options->AccountingMax &&
2914 (is_listening_on_low_port(options->ORPort, options->ORListenAddress) ||
2915 is_listening_on_low_port(options->DirPort, options->DirListenAddress)))
2917 log(LOG_WARN, LD_CONFIG,
2918 "You have set AccountingMax to use hibernation. You have also "
2919 "chosen a low DirPort or OrPort. This combination can make Tor stop "
2920 "working when it tries to re-attach the port after a period of "
2921 "hibernation. Please choose a different port or turn off "
2922 "hibernation unless you know this combination will work on your "
2923 "platform.");
2926 if (options->ExcludeExitNodes || options->ExcludeNodes) {
2927 options->_ExcludeExitNodesUnion = routerset_new();
2928 routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeExitNodes);
2929 routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeNodes);
2932 if (options->ExcludeNodes && options->StrictNodes) {
2933 COMPLAIN("You have asked to exclude certain relays from all positions "
2934 "in your circuits. Expect hidden services and other Tor "
2935 "features to be broken in unpredictable ways.");
2938 if (options->EntryNodes && !routerset_is_list(options->EntryNodes)) {
2939 /* XXXX fix this; see entry_guards_prepend_from_config(). */
2940 REJECT("IPs or countries are not yet supported in EntryNodes.");
2943 if (options->AuthoritativeDir) {
2944 if (!options->ContactInfo && !options->TestingTorNetwork)
2945 REJECT("Authoritative directory servers must set ContactInfo");
2946 if (options->V1AuthoritativeDir && !options->RecommendedVersions)
2947 REJECT("V1 authoritative dir servers must set RecommendedVersions.");
2948 if (!options->RecommendedClientVersions)
2949 options->RecommendedClientVersions =
2950 config_lines_dup(options->RecommendedVersions);
2951 if (!options->RecommendedServerVersions)
2952 options->RecommendedServerVersions =
2953 config_lines_dup(options->RecommendedVersions);
2954 if (options->VersioningAuthoritativeDir &&
2955 (!options->RecommendedClientVersions ||
2956 !options->RecommendedServerVersions))
2957 REJECT("Versioning authoritative dir servers must set "
2958 "Recommended*Versions.");
2959 if (options->UseEntryGuards) {
2960 log_info(LD_CONFIG, "Authoritative directory servers can't set "
2961 "UseEntryGuards. Disabling.");
2962 options->UseEntryGuards = 0;
2964 if (!options->DownloadExtraInfo && authdir_mode_any_main(options)) {
2965 log_info(LD_CONFIG, "Authoritative directories always try to download "
2966 "extra-info documents. Setting DownloadExtraInfo.");
2967 options->DownloadExtraInfo = 1;
2969 if (!(options->BridgeAuthoritativeDir || options->HSAuthoritativeDir ||
2970 options->V1AuthoritativeDir || options->V2AuthoritativeDir ||
2971 options->V3AuthoritativeDir))
2972 REJECT("AuthoritativeDir is set, but none of "
2973 "(Bridge/HS/V1/V2/V3)AuthoritativeDir is set.");
2974 /* If we have a v3bandwidthsfile and it's broken, complain on startup */
2975 if (options->V3BandwidthsFile && !old_options) {
2976 dirserv_read_measured_bandwidths(options->V3BandwidthsFile, NULL);
2980 if (options->AuthoritativeDir && !options->DirPort)
2981 REJECT("Running as authoritative directory, but no DirPort set.");
2983 if (options->AuthoritativeDir && !options->ORPort)
2984 REJECT("Running as authoritative directory, but no ORPort set.");
2986 if (options->AuthoritativeDir && options->ClientOnly)
2987 REJECT("Running as authoritative directory, but ClientOnly also set.");
2989 if (options->FetchDirInfoExtraEarly && !options->FetchDirInfoEarly)
2990 REJECT("FetchDirInfoExtraEarly requires that you also set "
2991 "FetchDirInfoEarly");
2993 if (options->ConnLimit <= 0) {
2994 tor_asprintf(msg,
2995 "ConnLimit must be greater than 0, but was set to %d",
2996 options->ConnLimit);
2997 return -1;
3000 if (validate_ports_csv(options->FirewallPorts, "FirewallPorts", msg) < 0)
3001 return -1;
3003 if (validate_ports_csv(options->LongLivedPorts, "LongLivedPorts", msg) < 0)
3004 return -1;
3006 if (validate_ports_csv(options->RejectPlaintextPorts,
3007 "RejectPlaintextPorts", msg) < 0)
3008 return -1;
3010 if (validate_ports_csv(options->WarnPlaintextPorts,
3011 "WarnPlaintextPorts", msg) < 0)
3012 return -1;
3014 if (options->FascistFirewall && !options->ReachableAddresses) {
3015 if (options->FirewallPorts && smartlist_len(options->FirewallPorts)) {
3016 /* We already have firewall ports set, so migrate them to
3017 * ReachableAddresses, which will set ReachableORAddresses and
3018 * ReachableDirAddresses if they aren't set explicitly. */
3019 smartlist_t *instead = smartlist_create();
3020 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3021 new_line->key = tor_strdup("ReachableAddresses");
3022 /* If we're configured with the old format, we need to prepend some
3023 * open ports. */
3024 SMARTLIST_FOREACH(options->FirewallPorts, const char *, portno,
3026 int p = atoi(portno);
3027 char *s;
3028 if (p<0) continue;
3029 s = tor_malloc(16);
3030 tor_snprintf(s, 16, "*:%d", p);
3031 smartlist_add(instead, s);
3033 new_line->value = smartlist_join_strings(instead,",",0,NULL);
3034 /* These have been deprecated since 0.1.1.5-alpha-cvs */
3035 log(LOG_NOTICE, LD_CONFIG,
3036 "Converting FascistFirewall and FirewallPorts "
3037 "config options to new format: \"ReachableAddresses %s\"",
3038 new_line->value);
3039 options->ReachableAddresses = new_line;
3040 SMARTLIST_FOREACH(instead, char *, cp, tor_free(cp));
3041 smartlist_free(instead);
3042 } else {
3043 /* We do not have FirewallPorts set, so add 80 to
3044 * ReachableDirAddresses, and 443 to ReachableORAddresses. */
3045 if (!options->ReachableDirAddresses) {
3046 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3047 new_line->key = tor_strdup("ReachableDirAddresses");
3048 new_line->value = tor_strdup("*:80");
3049 options->ReachableDirAddresses = new_line;
3050 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
3051 "to new format: \"ReachableDirAddresses *:80\"");
3053 if (!options->ReachableORAddresses) {
3054 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3055 new_line->key = tor_strdup("ReachableORAddresses");
3056 new_line->value = tor_strdup("*:443");
3057 options->ReachableORAddresses = new_line;
3058 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
3059 "to new format: \"ReachableORAddresses *:443\"");
3064 for (i=0; i<3; i++) {
3065 config_line_t **linep =
3066 (i==0) ? &options->ReachableAddresses :
3067 (i==1) ? &options->ReachableORAddresses :
3068 &options->ReachableDirAddresses;
3069 if (!*linep)
3070 continue;
3071 /* We need to end with a reject *:*, not an implicit accept *:* */
3072 for (;;) {
3073 if (!strcmp((*linep)->value, "reject *:*")) /* already there */
3074 break;
3075 linep = &((*linep)->next);
3076 if (!*linep) {
3077 *linep = tor_malloc_zero(sizeof(config_line_t));
3078 (*linep)->key = tor_strdup(
3079 (i==0) ? "ReachableAddresses" :
3080 (i==1) ? "ReachableORAddresses" :
3081 "ReachableDirAddresses");
3082 (*linep)->value = tor_strdup("reject *:*");
3083 break;
3088 if ((options->ReachableAddresses ||
3089 options->ReachableORAddresses ||
3090 options->ReachableDirAddresses) &&
3091 server_mode(options))
3092 REJECT("Servers must be able to freely connect to the rest "
3093 "of the Internet, so they must not set Reachable*Addresses "
3094 "or FascistFirewall.");
3096 if (options->UseBridges &&
3097 server_mode(options))
3098 REJECT("Servers must be able to freely connect to the rest "
3099 "of the Internet, so they must not set UseBridges.");
3101 options->_AllowInvalid = 0;
3102 if (options->AllowInvalidNodes) {
3103 SMARTLIST_FOREACH(options->AllowInvalidNodes, const char *, cp, {
3104 if (!strcasecmp(cp, "entry"))
3105 options->_AllowInvalid |= ALLOW_INVALID_ENTRY;
3106 else if (!strcasecmp(cp, "exit"))
3107 options->_AllowInvalid |= ALLOW_INVALID_EXIT;
3108 else if (!strcasecmp(cp, "middle"))
3109 options->_AllowInvalid |= ALLOW_INVALID_MIDDLE;
3110 else if (!strcasecmp(cp, "introduction"))
3111 options->_AllowInvalid |= ALLOW_INVALID_INTRODUCTION;
3112 else if (!strcasecmp(cp, "rendezvous"))
3113 options->_AllowInvalid |= ALLOW_INVALID_RENDEZVOUS;
3114 else {
3115 tor_asprintf(msg,
3116 "Unrecognized value '%s' in AllowInvalidNodes", cp);
3117 return -1;
3122 if (!options->SafeLogging ||
3123 !strcasecmp(options->SafeLogging, "0")) {
3124 options->_SafeLogging = SAFELOG_SCRUB_NONE;
3125 } else if (!strcasecmp(options->SafeLogging, "relay")) {
3126 options->_SafeLogging = SAFELOG_SCRUB_RELAY;
3127 } else if (!strcasecmp(options->SafeLogging, "1")) {
3128 options->_SafeLogging = SAFELOG_SCRUB_ALL;
3129 } else {
3130 tor_asprintf(msg,
3131 "Unrecognized value '%s' in SafeLogging",
3132 escaped(options->SafeLogging));
3133 return -1;
3136 if (compute_publishserverdescriptor(options) < 0) {
3137 tor_asprintf(msg, "Unrecognized value in PublishServerDescriptor");
3138 return -1;
3141 if ((options->BridgeRelay
3142 || options->_PublishServerDescriptor & BRIDGE_AUTHORITY)
3143 && (options->_PublishServerDescriptor
3144 & (V1_AUTHORITY|V2_AUTHORITY|V3_AUTHORITY))) {
3145 REJECT("Bridges are not supposed to publish router descriptors to the "
3146 "directory authorities. Please correct your "
3147 "PublishServerDescriptor line.");
3150 if (options->MinUptimeHidServDirectoryV2 < 0) {
3151 log_warn(LD_CONFIG, "MinUptimeHidServDirectoryV2 option must be at "
3152 "least 0 seconds. Changing to 0.");
3153 options->MinUptimeHidServDirectoryV2 = 0;
3156 if (options->RendPostPeriod < MIN_REND_POST_PERIOD) {
3157 log_warn(LD_CONFIG, "RendPostPeriod option is too short; "
3158 "raising to %d seconds.", MIN_REND_POST_PERIOD);
3159 options->RendPostPeriod = MIN_REND_POST_PERIOD;
3162 if (options->RendPostPeriod > MAX_DIR_PERIOD) {
3163 log_warn(LD_CONFIG, "RendPostPeriod is too large; clipping to %ds.",
3164 MAX_DIR_PERIOD);
3165 options->RendPostPeriod = MAX_DIR_PERIOD;
3168 if (options->MaxCircuitDirtiness < MIN_MAX_CIRCUIT_DIRTINESS) {
3169 log_warn(LD_CONFIG, "MaxCircuitDirtiness option is too short; "
3170 "raising to %d seconds.", MIN_MAX_CIRCUIT_DIRTINESS);
3171 options->MaxCircuitDirtiness = MIN_MAX_CIRCUIT_DIRTINESS;
3174 if (options->CircuitStreamTimeout &&
3175 options->CircuitStreamTimeout < MIN_CIRCUIT_STREAM_TIMEOUT) {
3176 log_warn(LD_CONFIG, "CircuitStreamTimeout option is too short; "
3177 "raising to %d seconds.", MIN_CIRCUIT_STREAM_TIMEOUT);
3178 options->CircuitStreamTimeout = MIN_CIRCUIT_STREAM_TIMEOUT;
3181 if (options->KeepalivePeriod < 1)
3182 REJECT("KeepalivePeriod option must be positive.");
3184 if (ensure_bandwidth_cap(&options->BandwidthRate,
3185 "BandwidthRate", msg) < 0)
3186 return -1;
3187 if (ensure_bandwidth_cap(&options->BandwidthBurst,
3188 "BandwidthBurst", msg) < 0)
3189 return -1;
3190 if (ensure_bandwidth_cap(&options->MaxAdvertisedBandwidth,
3191 "MaxAdvertisedBandwidth", msg) < 0)
3192 return -1;
3193 if (ensure_bandwidth_cap(&options->RelayBandwidthRate,
3194 "RelayBandwidthRate", msg) < 0)
3195 return -1;
3196 if (ensure_bandwidth_cap(&options->RelayBandwidthBurst,
3197 "RelayBandwidthBurst", msg) < 0)
3198 return -1;
3199 if (ensure_bandwidth_cap(&options->PerConnBWRate,
3200 "PerConnBWRate", msg) < 0)
3201 return -1;
3202 if (ensure_bandwidth_cap(&options->PerConnBWBurst,
3203 "PerConnBWBurst", msg) < 0)
3204 return -1;
3206 if (server_mode(options)) {
3207 if (options->BandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
3208 tor_asprintf(msg,
3209 "BandwidthRate is set to %d bytes/second. "
3210 "For servers, it must be at least %d.",
3211 (int)options->BandwidthRate,
3212 ROUTER_REQUIRED_MIN_BANDWIDTH);
3213 return -1;
3214 } else if (options->MaxAdvertisedBandwidth <
3215 ROUTER_REQUIRED_MIN_BANDWIDTH/2) {
3216 tor_asprintf(msg,
3217 "MaxAdvertisedBandwidth is set to %d bytes/second. "
3218 "For servers, it must be at least %d.",
3219 (int)options->MaxAdvertisedBandwidth,
3220 ROUTER_REQUIRED_MIN_BANDWIDTH/2);
3221 return -1;
3223 if (options->RelayBandwidthRate &&
3224 options->RelayBandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
3225 tor_asprintf(msg,
3226 "RelayBandwidthRate is set to %d bytes/second. "
3227 "For servers, it must be at least %d.",
3228 (int)options->RelayBandwidthRate,
3229 ROUTER_REQUIRED_MIN_BANDWIDTH);
3230 return -1;
3234 if (options->RelayBandwidthRate && !options->RelayBandwidthBurst)
3235 options->RelayBandwidthBurst = options->RelayBandwidthRate;
3237 if (options->RelayBandwidthRate > options->RelayBandwidthBurst)
3238 REJECT("RelayBandwidthBurst must be at least equal "
3239 "to RelayBandwidthRate.");
3241 if (options->BandwidthRate > options->BandwidthBurst)
3242 REJECT("BandwidthBurst must be at least equal to BandwidthRate.");
3244 /* if they set relaybandwidth* really high but left bandwidth*
3245 * at the default, raise the defaults. */
3246 if (options->RelayBandwidthRate > options->BandwidthRate)
3247 options->BandwidthRate = options->RelayBandwidthRate;
3248 if (options->RelayBandwidthBurst > options->BandwidthBurst)
3249 options->BandwidthBurst = options->RelayBandwidthBurst;
3251 if (accounting_parse_options(options, 1)<0)
3252 REJECT("Failed to parse accounting options. See logs for details.");
3254 if (options->HttpProxy) { /* parse it now */
3255 if (tor_addr_port_parse(options->HttpProxy,
3256 &options->HttpProxyAddr, &options->HttpProxyPort) < 0)
3257 REJECT("HttpProxy failed to parse or resolve. Please fix.");
3258 if (options->HttpProxyPort == 0) { /* give it a default */
3259 options->HttpProxyPort = 80;
3263 if (options->HttpProxyAuthenticator) {
3264 if (strlen(options->HttpProxyAuthenticator) >= 48)
3265 REJECT("HttpProxyAuthenticator is too long (>= 48 chars).");
3268 if (options->HttpsProxy) { /* parse it now */
3269 if (tor_addr_port_parse(options->HttpsProxy,
3270 &options->HttpsProxyAddr, &options->HttpsProxyPort) <0)
3271 REJECT("HttpsProxy failed to parse or resolve. Please fix.");
3272 if (options->HttpsProxyPort == 0) { /* give it a default */
3273 options->HttpsProxyPort = 443;
3277 if (options->HttpsProxyAuthenticator) {
3278 if (strlen(options->HttpsProxyAuthenticator) >= 48)
3279 REJECT("HttpsProxyAuthenticator is too long (>= 48 chars).");
3282 if (options->Socks4Proxy) { /* parse it now */
3283 if (tor_addr_port_parse(options->Socks4Proxy,
3284 &options->Socks4ProxyAddr,
3285 &options->Socks4ProxyPort) <0)
3286 REJECT("Socks4Proxy failed to parse or resolve. Please fix.");
3287 if (options->Socks4ProxyPort == 0) { /* give it a default */
3288 options->Socks4ProxyPort = 1080;
3292 if (options->Socks5Proxy) { /* parse it now */
3293 if (tor_addr_port_parse(options->Socks5Proxy,
3294 &options->Socks5ProxyAddr,
3295 &options->Socks5ProxyPort) <0)
3296 REJECT("Socks5Proxy failed to parse or resolve. Please fix.");
3297 if (options->Socks5ProxyPort == 0) { /* give it a default */
3298 options->Socks5ProxyPort = 1080;
3302 if (options->Socks4Proxy && options->Socks5Proxy)
3303 REJECT("You cannot specify both Socks4Proxy and SOCKS5Proxy");
3305 if (options->Socks5ProxyUsername) {
3306 size_t len;
3308 len = strlen(options->Socks5ProxyUsername);
3309 if (len < 1 || len > 255)
3310 REJECT("Socks5ProxyUsername must be between 1 and 255 characters.");
3312 if (!options->Socks5ProxyPassword)
3313 REJECT("Socks5ProxyPassword must be included with Socks5ProxyUsername.");
3315 len = strlen(options->Socks5ProxyPassword);
3316 if (len < 1 || len > 255)
3317 REJECT("Socks5ProxyPassword must be between 1 and 255 characters.");
3318 } else if (options->Socks5ProxyPassword)
3319 REJECT("Socks5ProxyPassword must be included with Socks5ProxyUsername.");
3321 if (options->HashedControlPassword) {
3322 smartlist_t *sl = decode_hashed_passwords(options->HashedControlPassword);
3323 if (!sl) {
3324 REJECT("Bad HashedControlPassword: wrong length or bad encoding");
3325 } else {
3326 SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
3327 smartlist_free(sl);
3331 if (options->HashedControlSessionPassword) {
3332 smartlist_t *sl = decode_hashed_passwords(
3333 options->HashedControlSessionPassword);
3334 if (!sl) {
3335 REJECT("Bad HashedControlSessionPassword: wrong length or bad encoding");
3336 } else {
3337 SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
3338 smartlist_free(sl);
3342 if (options->ControlListenAddress) {
3343 int all_are_local = 1;
3344 config_line_t *ln;
3345 for (ln = options->ControlListenAddress; ln; ln = ln->next) {
3346 if (strcmpstart(ln->value, "127."))
3347 all_are_local = 0;
3349 if (!all_are_local) {
3350 if (!options->HashedControlPassword &&
3351 !options->HashedControlSessionPassword &&
3352 !options->CookieAuthentication) {
3353 log_warn(LD_CONFIG,
3354 "You have a ControlListenAddress set to accept "
3355 "unauthenticated connections from a non-local address. "
3356 "This means that programs not running on your computer "
3357 "can reconfigure your Tor, without even having to guess a "
3358 "password. That's so bad that I'm closing your ControlPort "
3359 "for you. If you need to control your Tor remotely, try "
3360 "enabling authentication and using a tool like stunnel or "
3361 "ssh to encrypt remote access.");
3362 options->ControlPort = 0;
3363 } else {
3364 log_warn(LD_CONFIG, "You have a ControlListenAddress set to accept "
3365 "connections from a non-local address. This means that "
3366 "programs not running on your computer can reconfigure your "
3367 "Tor. That's pretty bad, since the controller "
3368 "protocol isn't encrypted! Maybe you should just listen on "
3369 "127.0.0.1 and use a tool like stunnel or ssh to encrypt "
3370 "remote connections to your control port.");
3375 if (options->ControlPort && !options->HashedControlPassword &&
3376 !options->HashedControlSessionPassword &&
3377 !options->CookieAuthentication) {
3378 log_warn(LD_CONFIG, "ControlPort is open, but no authentication method "
3379 "has been configured. This means that any program on your "
3380 "computer can reconfigure your Tor. That's bad! You should "
3381 "upgrade your Tor controller as soon as possible.");
3384 if (options->UseEntryGuards && ! options->NumEntryGuards)
3385 REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0");
3387 if (check_nickname_list(options->MyFamily, "MyFamily", msg))
3388 return -1;
3389 for (cl = options->NodeFamilies; cl; cl = cl->next) {
3390 if (check_nickname_list(cl->value, "NodeFamily", msg))
3391 return -1;
3394 if (validate_addr_policies(options, msg) < 0)
3395 return -1;
3397 if (validate_dir_authorities(options, old_options) < 0)
3398 REJECT("Directory authority line did not parse. See logs for details.");
3400 if (options->UseBridges && !options->Bridges)
3401 REJECT("If you set UseBridges, you must specify at least one bridge.");
3402 if (options->UseBridges && !options->TunnelDirConns)
3403 REJECT("If you set UseBridges, you must set TunnelDirConns.");
3404 if (options->Bridges) {
3405 for (cl = options->Bridges; cl; cl = cl->next) {
3406 if (parse_bridge_line(cl->value, 1)<0)
3407 REJECT("Bridge line did not parse. See logs for details.");
3411 if (options->ConstrainedSockets) {
3412 /* If the user wants to constrain socket buffer use, make sure the desired
3413 * limit is between MIN|MAX_TCPSOCK_BUFFER in k increments. */
3414 if (options->ConstrainedSockSize < MIN_CONSTRAINED_TCP_BUFFER ||
3415 options->ConstrainedSockSize > MAX_CONSTRAINED_TCP_BUFFER ||
3416 options->ConstrainedSockSize % 1024) {
3417 tor_asprintf(msg,
3418 "ConstrainedSockSize is invalid. Must be a value between %d and %d "
3419 "in 1024 byte increments.",
3420 MIN_CONSTRAINED_TCP_BUFFER, MAX_CONSTRAINED_TCP_BUFFER);
3421 return -1;
3423 if (options->DirPort) {
3424 /* Providing cached directory entries while system TCP buffers are scarce
3425 * will exacerbate the socket errors. Suggest that this be disabled. */
3426 COMPLAIN("You have requested constrained socket buffers while also "
3427 "serving directory entries via DirPort. It is strongly "
3428 "suggested that you disable serving directory requests when "
3429 "system TCP buffer resources are scarce.");
3433 if (options->V3AuthVoteDelay + options->V3AuthDistDelay >=
3434 options->V3AuthVotingInterval/2) {
3435 REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than half "
3436 "V3AuthVotingInterval");
3438 if (options->V3AuthVoteDelay < MIN_VOTE_SECONDS)
3439 REJECT("V3AuthVoteDelay is way too low.");
3440 if (options->V3AuthDistDelay < MIN_DIST_SECONDS)
3441 REJECT("V3AuthDistDelay is way too low.");
3443 if (options->V3AuthNIntervalsValid < 2)
3444 REJECT("V3AuthNIntervalsValid must be at least 2.");
3446 if (options->V3AuthVotingInterval < MIN_VOTE_INTERVAL) {
3447 REJECT("V3AuthVotingInterval is insanely low.");
3448 } else if (options->V3AuthVotingInterval > 24*60*60) {
3449 REJECT("V3AuthVotingInterval is insanely high.");
3450 } else if (((24*60*60) % options->V3AuthVotingInterval) != 0) {
3451 COMPLAIN("V3AuthVotingInterval does not divide evenly into 24 hours.");
3454 if (rend_config_services(options, 1) < 0)
3455 REJECT("Failed to configure rendezvous options. See logs for details.");
3457 /* Parse client-side authorization for hidden services. */
3458 if (rend_parse_service_authorization(options, 1) < 0)
3459 REJECT("Failed to configure client authorization for hidden services. "
3460 "See logs for details.");
3462 if (parse_virtual_addr_network(options->VirtualAddrNetwork, 1, NULL)<0)
3463 return -1;
3465 if (options->PreferTunneledDirConns && !options->TunnelDirConns)
3466 REJECT("Must set TunnelDirConns if PreferTunneledDirConns is set.");
3468 if ((options->Socks4Proxy || options->Socks5Proxy) &&
3469 !options->HttpProxy && !options->PreferTunneledDirConns)
3470 REJECT("When Socks4Proxy or Socks5Proxy is configured, "
3471 "PreferTunneledDirConns and TunnelDirConns must both be "
3472 "set to 1, or HttpProxy must be configured.");
3474 if (options->AutomapHostsSuffixes) {
3475 SMARTLIST_FOREACH(options->AutomapHostsSuffixes, char *, suf,
3477 size_t len = strlen(suf);
3478 if (len && suf[len-1] == '.')
3479 suf[len-1] = '\0';
3483 if (options->TestingTorNetwork && !options->DirServers) {
3484 REJECT("TestingTorNetwork may only be configured in combination with "
3485 "a non-default set of DirServers.");
3488 /*XXXX022 checking for defaults manually like this is a bit fragile.*/
3490 /* Keep changes to hard-coded values synchronous to man page and default
3491 * values table. */
3492 if (options->TestingV3AuthInitialVotingInterval != 30*60 &&
3493 !options->TestingTorNetwork) {
3494 REJECT("TestingV3AuthInitialVotingInterval may only be changed in testing "
3495 "Tor networks!");
3496 } else if (options->TestingV3AuthInitialVotingInterval < MIN_VOTE_INTERVAL) {
3497 REJECT("TestingV3AuthInitialVotingInterval is insanely low.");
3498 } else if (((30*60) % options->TestingV3AuthInitialVotingInterval) != 0) {
3499 REJECT("TestingV3AuthInitialVotingInterval does not divide evenly into "
3500 "30 minutes.");
3503 if (options->TestingV3AuthInitialVoteDelay != 5*60 &&
3504 !options->TestingTorNetwork) {
3505 REJECT("TestingV3AuthInitialVoteDelay may only be changed in testing "
3506 "Tor networks!");
3507 } else if (options->TestingV3AuthInitialVoteDelay < MIN_VOTE_SECONDS) {
3508 REJECT("TestingV3AuthInitialVoteDelay is way too low.");
3511 if (options->TestingV3AuthInitialDistDelay != 5*60 &&
3512 !options->TestingTorNetwork) {
3513 REJECT("TestingV3AuthInitialDistDelay may only be changed in testing "
3514 "Tor networks!");
3515 } else if (options->TestingV3AuthInitialDistDelay < MIN_DIST_SECONDS) {
3516 REJECT("TestingV3AuthInitialDistDelay is way too low.");
3519 if (options->TestingV3AuthInitialVoteDelay +
3520 options->TestingV3AuthInitialDistDelay >=
3521 options->TestingV3AuthInitialVotingInterval/2) {
3522 REJECT("TestingV3AuthInitialVoteDelay plus TestingV3AuthInitialDistDelay "
3523 "must be less than half TestingV3AuthInitialVotingInterval");
3526 if (options->TestingAuthDirTimeToLearnReachability != 30*60 &&
3527 !options->TestingTorNetwork) {
3528 REJECT("TestingAuthDirTimeToLearnReachability may only be changed in "
3529 "testing Tor networks!");
3530 } else if (options->TestingAuthDirTimeToLearnReachability < 0) {
3531 REJECT("TestingAuthDirTimeToLearnReachability must be non-negative.");
3532 } else if (options->TestingAuthDirTimeToLearnReachability > 2*60*60) {
3533 COMPLAIN("TestingAuthDirTimeToLearnReachability is insanely high.");
3536 if (options->TestingEstimatedDescriptorPropagationTime != 10*60 &&
3537 !options->TestingTorNetwork) {
3538 REJECT("TestingEstimatedDescriptorPropagationTime may only be changed in "
3539 "testing Tor networks!");
3540 } else if (options->TestingEstimatedDescriptorPropagationTime < 0) {
3541 REJECT("TestingEstimatedDescriptorPropagationTime must be non-negative.");
3542 } else if (options->TestingEstimatedDescriptorPropagationTime > 60*60) {
3543 COMPLAIN("TestingEstimatedDescriptorPropagationTime is insanely high.");
3546 if (options->TestingTorNetwork) {
3547 log_warn(LD_CONFIG, "TestingTorNetwork is set. This will make your node "
3548 "almost unusable in the public Tor network, and is "
3549 "therefore only advised if you are building a "
3550 "testing Tor network!");
3553 if (options->AccelName && !options->HardwareAccel)
3554 options->HardwareAccel = 1;
3555 if (options->AccelDir && !options->AccelName)
3556 REJECT("Can't use hardware crypto accelerator dir without engine name.");
3558 return 0;
3559 #undef REJECT
3560 #undef COMPLAIN
3563 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
3564 * equal strings. */
3565 static int
3566 opt_streq(const char *s1, const char *s2)
3568 if (!s1 && !s2)
3569 return 1;
3570 else if (s1 && s2 && !strcmp(s1,s2))
3571 return 1;
3572 else
3573 return 0;
3576 /** Check if any of the previous options have changed but aren't allowed to. */
3577 static int
3578 options_transition_allowed(or_options_t *old, or_options_t *new_val,
3579 char **msg)
3581 if (!old)
3582 return 0;
3584 if (!opt_streq(old->PidFile, new_val->PidFile)) {
3585 *msg = tor_strdup("PidFile is not allowed to change.");
3586 return -1;
3589 if (old->RunAsDaemon != new_val->RunAsDaemon) {
3590 *msg = tor_strdup("While Tor is running, changing RunAsDaemon "
3591 "is not allowed.");
3592 return -1;
3595 if (strcmp(old->DataDirectory,new_val->DataDirectory)!=0) {
3596 tor_asprintf(msg,
3597 "While Tor is running, changing DataDirectory "
3598 "(\"%s\"->\"%s\") is not allowed.",
3599 old->DataDirectory, new_val->DataDirectory);
3600 return -1;
3603 if (!opt_streq(old->User, new_val->User)) {
3604 *msg = tor_strdup("While Tor is running, changing User is not allowed.");
3605 return -1;
3608 if (!opt_streq(old->Group, new_val->Group)) {
3609 *msg = tor_strdup("While Tor is running, changing Group is not allowed.");
3610 return -1;
3613 if ((old->HardwareAccel != new_val->HardwareAccel)
3614 || !opt_streq(old->AccelName, new_val->AccelName)
3615 || !opt_streq(old->AccelDir, new_val->AccelDir)) {
3616 *msg = tor_strdup("While Tor is running, changing OpenSSL hardware "
3617 "acceleration engine is not allowed.");
3618 return -1;
3621 if (old->TestingTorNetwork != new_val->TestingTorNetwork) {
3622 *msg = tor_strdup("While Tor is running, changing TestingTorNetwork "
3623 "is not allowed.");
3624 return -1;
3627 if (old->CellStatistics != new_val->CellStatistics ||
3628 old->DirReqStatistics != new_val->DirReqStatistics ||
3629 old->EntryStatistics != new_val->EntryStatistics ||
3630 old->ExitPortStatistics != new_val->ExitPortStatistics) {
3631 *msg = tor_strdup("While Tor is running, changing either "
3632 "CellStatistics, DirReqStatistics, EntryStatistics, "
3633 "or ExitPortStatistics is not allowed.");
3634 return -1;
3637 if (old->DisableAllSwap != new_val->DisableAllSwap) {
3638 *msg = tor_strdup("While Tor is running, changing DisableAllSwap "
3639 "is not allowed.");
3640 return -1;
3643 return 0;
3646 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
3647 * will require us to rotate the CPU and DNS workers; else return 0. */
3648 static int
3649 options_transition_affects_workers(or_options_t *old_options,
3650 or_options_t *new_options)
3652 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
3653 old_options->NumCpus != new_options->NumCpus ||
3654 old_options->ORPort != new_options->ORPort ||
3655 old_options->ServerDNSSearchDomains !=
3656 new_options->ServerDNSSearchDomains ||
3657 old_options->SafeLogging != new_options->SafeLogging ||
3658 old_options->ClientOnly != new_options->ClientOnly ||
3659 !config_lines_eq(old_options->Logs, new_options->Logs))
3660 return 1;
3662 /* Check whether log options match. */
3664 /* Nothing that changed matters. */
3665 return 0;
3668 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
3669 * will require us to generate a new descriptor; else return 0. */
3670 static int
3671 options_transition_affects_descriptor(or_options_t *old_options,
3672 or_options_t *new_options)
3674 /* XXX We can be smarter here. If your DirPort isn't being
3675 * published and you just turned it off, no need to republish. Etc. */
3676 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
3677 !opt_streq(old_options->Nickname,new_options->Nickname) ||
3678 !opt_streq(old_options->Address,new_options->Address) ||
3679 !config_lines_eq(old_options->ExitPolicy,new_options->ExitPolicy) ||
3680 old_options->ExitPolicyRejectPrivate !=
3681 new_options->ExitPolicyRejectPrivate ||
3682 old_options->ORPort != new_options->ORPort ||
3683 old_options->DirPort != new_options->DirPort ||
3684 old_options->ClientOnly != new_options->ClientOnly ||
3685 old_options->NoPublish != new_options->NoPublish ||
3686 old_options->_PublishServerDescriptor !=
3687 new_options->_PublishServerDescriptor ||
3688 get_effective_bwrate(old_options) != get_effective_bwrate(new_options) ||
3689 get_effective_bwburst(old_options) !=
3690 get_effective_bwburst(new_options) ||
3691 !opt_streq(old_options->ContactInfo, new_options->ContactInfo) ||
3692 !opt_streq(old_options->MyFamily, new_options->MyFamily) ||
3693 !opt_streq(old_options->AccountingStart, new_options->AccountingStart) ||
3694 old_options->AccountingMax != new_options->AccountingMax)
3695 return 1;
3697 return 0;
3700 #ifdef MS_WINDOWS
3701 /** Return the directory on windows where we expect to find our application
3702 * data. */
3703 static char *
3704 get_windows_conf_root(void)
3706 static int is_set = 0;
3707 static char path[MAX_PATH+1];
3708 WCHAR wpath[MAX_PATH] = {0};
3710 LPITEMIDLIST idl;
3711 IMalloc *m;
3712 HRESULT result;
3714 if (is_set)
3715 return path;
3717 /* Find X:\documents and settings\username\application data\ .
3718 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
3720 #ifdef ENABLE_LOCAL_APPDATA
3721 #define APPDATA_PATH CSIDL_LOCAL_APPDATA
3722 #else
3723 #define APPDATA_PATH CSIDL_APPDATA
3724 #endif
3725 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, APPDATA_PATH, &idl))) {
3726 getcwd(path,MAX_PATH);
3727 is_set = 1;
3728 log_warn(LD_CONFIG,
3729 "I couldn't find your application data folder: are you "
3730 "running an ancient version of Windows 95? Defaulting to \"%s\"",
3731 path);
3732 return path;
3734 /* Convert the path from an "ID List" (whatever that is!) to a path. */
3735 result = SHGetPathFromIDListW(idl, wpath);
3736 wcstombs(path,wpath,MAX_PATH);
3738 /* Now we need to free the ... XXX free the what? */
3739 SHGetMalloc(&m);
3740 if (m) {
3741 m->lpVtbl->Free(m, idl);
3742 m->lpVtbl->Release(m);
3744 if (!SUCCEEDED(result)) {
3745 return NULL;
3747 strlcat(path,"\\tor",MAX_PATH);
3748 is_set = 1;
3749 return path;
3751 #endif
3753 /** Return the default location for our torrc file. */
3754 static const char *
3755 get_default_conf_file(void)
3757 #ifdef MS_WINDOWS
3758 static char path[MAX_PATH+1];
3759 strlcpy(path, get_windows_conf_root(), MAX_PATH);
3760 strlcat(path,"\\torrc",MAX_PATH);
3761 return path;
3762 #else
3763 return (CONFDIR "/torrc");
3764 #endif
3767 /** Verify whether lst is a string containing valid-looking comma-separated
3768 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
3770 static int
3771 check_nickname_list(const char *lst, const char *name, char **msg)
3773 int r = 0;
3774 smartlist_t *sl;
3776 if (!lst)
3777 return 0;
3778 sl = smartlist_create();
3780 smartlist_split_string(sl, lst, ",",
3781 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0);
3783 SMARTLIST_FOREACH(sl, const char *, s,
3785 if (!is_legal_nickname_or_hexdigest(s)) {
3786 tor_asprintf(msg, "Invalid nickname '%s' in %s line", s, name);
3787 r = -1;
3788 break;
3791 SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
3792 smartlist_free(sl);
3793 return r;
3796 /** Learn config file name from command line arguments, or use the default */
3797 static char *
3798 find_torrc_filename(int argc, char **argv,
3799 int *using_default_torrc, int *ignore_missing_torrc)
3801 char *fname=NULL;
3802 int i;
3804 for (i = 1; i < argc; ++i) {
3805 if (i < argc-1 && !strcmp(argv[i],"-f")) {
3806 if (fname) {
3807 log(LOG_WARN, LD_CONFIG, "Duplicate -f options on command line.");
3808 tor_free(fname);
3810 fname = expand_filename(argv[i+1]);
3811 *using_default_torrc = 0;
3812 ++i;
3813 } else if (!strcmp(argv[i],"--ignore-missing-torrc")) {
3814 *ignore_missing_torrc = 1;
3818 if (*using_default_torrc) {
3819 /* didn't find one, try CONFDIR */
3820 const char *dflt = get_default_conf_file();
3821 if (dflt && file_status(dflt) == FN_FILE) {
3822 fname = tor_strdup(dflt);
3823 } else {
3824 #ifndef MS_WINDOWS
3825 char *fn;
3826 fn = expand_filename("~/.torrc");
3827 if (fn && file_status(fn) == FN_FILE) {
3828 fname = fn;
3829 } else {
3830 tor_free(fn);
3831 fname = tor_strdup(dflt);
3833 #else
3834 fname = tor_strdup(dflt);
3835 #endif
3838 return fname;
3841 /** Load torrc from disk, setting torrc_fname if successful */
3842 static char *
3843 load_torrc_from_disk(int argc, char **argv)
3845 char *fname=NULL;
3846 char *cf = NULL;
3847 int using_default_torrc = 1;
3848 int ignore_missing_torrc = 0;
3850 fname = find_torrc_filename(argc, argv,
3851 &using_default_torrc, &ignore_missing_torrc);
3852 tor_assert(fname);
3853 log(LOG_DEBUG, LD_CONFIG, "Opening config file \"%s\"", fname);
3855 tor_free(torrc_fname);
3856 torrc_fname = fname;
3858 /* Open config file */
3859 if (file_status(fname) != FN_FILE ||
3860 !(cf = read_file_to_str(fname,0,NULL))) {
3861 if (using_default_torrc == 1 || ignore_missing_torrc ) {
3862 log(LOG_NOTICE, LD_CONFIG, "Configuration file \"%s\" not present, "
3863 "using reasonable defaults.", fname);
3864 tor_free(fname); /* sets fname to NULL */
3865 torrc_fname = NULL;
3866 cf = tor_strdup("");
3867 } else {
3868 log(LOG_WARN, LD_CONFIG,
3869 "Unable to open configuration file \"%s\".", fname);
3870 goto err;
3874 return cf;
3875 err:
3876 tor_free(fname);
3877 torrc_fname = NULL;
3878 return NULL;
3881 /** Read a configuration file into <b>options</b>, finding the configuration
3882 * file location based on the command line. After loading the file
3883 * call options_init_from_string() to load the config.
3884 * Return 0 if success, -1 if failure. */
3886 options_init_from_torrc(int argc, char **argv)
3888 char *cf=NULL;
3889 int i, retval, command;
3890 static char **backup_argv;
3891 static int backup_argc;
3892 char *command_arg = NULL;
3893 char *errmsg=NULL;
3895 if (argv) { /* first time we're called. save command line args */
3896 backup_argv = argv;
3897 backup_argc = argc;
3898 } else { /* we're reloading. need to clean up old options first. */
3899 argv = backup_argv;
3900 argc = backup_argc;
3902 if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
3903 print_usage();
3904 exit(0);
3906 if (argc > 1 && !strcmp(argv[1], "--list-torrc-options")) {
3907 /* For documenting validating whether we've documented everything. */
3908 list_torrc_options();
3909 exit(0);
3912 if (argc > 1 && (!strcmp(argv[1],"--version"))) {
3913 printf("Tor version %s.\n",get_version());
3914 exit(0);
3916 if (argc > 1 && (!strcmp(argv[1],"--digests"))) {
3917 printf("Tor version %s.\n",get_version());
3918 printf("%s", libor_get_digests());
3919 printf("%s", tor_get_digests());
3920 exit(0);
3923 /* Go through command-line variables */
3924 if (!global_cmdline_options) {
3925 /* Or we could redo the list every time we pass this place.
3926 * It does not really matter */
3927 if (config_get_commandlines(argc, argv, &global_cmdline_options) < 0) {
3928 goto err;
3932 command = CMD_RUN_TOR;
3933 for (i = 1; i < argc; ++i) {
3934 if (!strcmp(argv[i],"--list-fingerprint")) {
3935 command = CMD_LIST_FINGERPRINT;
3936 } else if (!strcmp(argv[i],"--hash-password")) {
3937 command = CMD_HASH_PASSWORD;
3938 command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : "");
3939 ++i;
3940 } else if (!strcmp(argv[i],"--verify-config")) {
3941 command = CMD_VERIFY_CONFIG;
3945 if (command == CMD_HASH_PASSWORD) {
3946 cf = tor_strdup("");
3947 } else {
3948 cf = load_torrc_from_disk(argc, argv);
3949 if (!cf)
3950 goto err;
3953 retval = options_init_from_string(cf, command, command_arg, &errmsg);
3954 tor_free(cf);
3955 if (retval < 0)
3956 goto err;
3958 return 0;
3960 err:
3961 if (errmsg) {
3962 log(LOG_WARN,LD_CONFIG,"%s", errmsg);
3963 tor_free(errmsg);
3965 return -1;
3968 /** Load the options from the configuration in <b>cf</b>, validate
3969 * them for consistency and take actions based on them.
3971 * Return 0 if success, negative on error:
3972 * * -1 for general errors.
3973 * * -2 for failure to parse/validate,
3974 * * -3 for transition not allowed
3975 * * -4 for error while setting the new options
3977 setopt_err_t
3978 options_init_from_string(const char *cf,
3979 int command, const char *command_arg,
3980 char **msg)
3982 or_options_t *oldoptions, *newoptions;
3983 config_line_t *cl;
3984 int retval;
3985 setopt_err_t err = SETOPT_ERR_MISC;
3986 tor_assert(msg);
3988 oldoptions = global_options; /* get_options unfortunately asserts if
3989 this is the first time we run*/
3991 newoptions = tor_malloc_zero(sizeof(or_options_t));
3992 newoptions->_magic = OR_OPTIONS_MAGIC;
3993 options_init(newoptions);
3994 newoptions->command = command;
3995 newoptions->command_arg = command_arg;
3997 /* get config lines, assign them */
3998 retval = config_get_lines(cf, &cl);
3999 if (retval < 0) {
4000 err = SETOPT_ERR_PARSE;
4001 goto err;
4003 retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
4004 config_free_lines(cl);
4005 if (retval < 0) {
4006 err = SETOPT_ERR_PARSE;
4007 goto err;
4010 /* Go through command-line variables too */
4011 retval = config_assign(&options_format, newoptions,
4012 global_cmdline_options, 0, 0, msg);
4013 if (retval < 0) {
4014 err = SETOPT_ERR_PARSE;
4015 goto err;
4018 /* If this is a testing network configuration, change defaults
4019 * for a list of dependent config options, re-initialize newoptions
4020 * with the new defaults, and assign all options to it second time. */
4021 if (newoptions->TestingTorNetwork) {
4022 /* XXXX this is a bit of a kludge. perhaps there's a better way to do
4023 * this? We could, for example, make the parsing algorithm do two passes
4024 * over the configuration. If it finds any "suite" options like
4025 * TestingTorNetwork, it could change the defaults before its second pass.
4026 * Not urgent so long as this seems to work, but at any sign of trouble,
4027 * let's clean it up. -NM */
4029 /* Change defaults. */
4030 int i;
4031 for (i = 0; testing_tor_network_defaults[i].name; ++i) {
4032 config_var_t *new_var = &testing_tor_network_defaults[i];
4033 config_var_t *old_var =
4034 config_find_option(&options_format, new_var->name);
4035 tor_assert(new_var);
4036 tor_assert(old_var);
4037 old_var->initvalue = new_var->initvalue;
4040 /* Clear newoptions and re-initialize them with new defaults. */
4041 config_free(&options_format, newoptions);
4042 newoptions = tor_malloc_zero(sizeof(or_options_t));
4043 newoptions->_magic = OR_OPTIONS_MAGIC;
4044 options_init(newoptions);
4045 newoptions->command = command;
4046 newoptions->command_arg = command_arg;
4048 /* Assign all options a second time. */
4049 retval = config_get_lines(cf, &cl);
4050 if (retval < 0) {
4051 err = SETOPT_ERR_PARSE;
4052 goto err;
4054 retval = config_assign(&options_format, newoptions, cl, 0, 0, msg);
4055 config_free_lines(cl);
4056 if (retval < 0) {
4057 err = SETOPT_ERR_PARSE;
4058 goto err;
4060 retval = config_assign(&options_format, newoptions,
4061 global_cmdline_options, 0, 0, msg);
4062 if (retval < 0) {
4063 err = SETOPT_ERR_PARSE;
4064 goto err;
4068 /* Validate newoptions */
4069 if (options_validate(oldoptions, newoptions, 0, msg) < 0) {
4070 err = SETOPT_ERR_PARSE; /*XXX make this a separate return value.*/
4071 goto err;
4074 if (options_transition_allowed(oldoptions, newoptions, msg) < 0) {
4075 err = SETOPT_ERR_TRANSITION;
4076 goto err;
4079 if (set_options(newoptions, msg)) {
4080 err = SETOPT_ERR_SETTING;
4081 goto err; /* frees and replaces old options */
4084 return SETOPT_OK;
4086 err:
4087 config_free(&options_format, newoptions);
4088 if (*msg) {
4089 char *old_msg = *msg;
4090 tor_asprintf(msg, "Failed to parse/validate config: %s", old_msg);
4091 tor_free(old_msg);
4093 return err;
4096 /** Return the location for our configuration file.
4098 const char *
4099 get_torrc_fname(void)
4101 if (torrc_fname)
4102 return torrc_fname;
4103 else
4104 return get_default_conf_file();
4107 /** Adjust the address map based on the MapAddress elements in the
4108 * configuration <b>options</b>
4110 static void
4111 config_register_addressmaps(or_options_t *options)
4113 smartlist_t *elts;
4114 config_line_t *opt;
4115 char *from, *to;
4117 addressmap_clear_configured();
4118 elts = smartlist_create();
4119 for (opt = options->AddressMap; opt; opt = opt->next) {
4120 smartlist_split_string(elts, opt->value, NULL,
4121 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
4122 if (smartlist_len(elts) >= 2) {
4123 from = smartlist_get(elts,0);
4124 to = smartlist_get(elts,1);
4125 if (address_is_invalid_destination(to, 1)) {
4126 log_warn(LD_CONFIG,
4127 "Skipping invalid argument '%s' to MapAddress", to);
4128 } else {
4129 addressmap_register(from, tor_strdup(to), 0, ADDRMAPSRC_TORRC);
4130 if (smartlist_len(elts)>2) {
4131 log_warn(LD_CONFIG,"Ignoring extra arguments to MapAddress.");
4134 } else {
4135 log_warn(LD_CONFIG,"MapAddress '%s' has too few arguments. Ignoring.",
4136 opt->value);
4138 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
4139 smartlist_clear(elts);
4141 smartlist_free(elts);
4145 * Initialize the logs based on the configuration file.
4147 static int
4148 options_init_logs(or_options_t *options, int validate_only)
4150 config_line_t *opt;
4151 int ok;
4152 smartlist_t *elts;
4153 int daemon =
4154 #ifdef MS_WINDOWS
4156 #else
4157 options->RunAsDaemon;
4158 #endif
4160 ok = 1;
4161 elts = smartlist_create();
4163 for (opt = options->Logs; opt; opt = opt->next) {
4164 log_severity_list_t *severity;
4165 const char *cfg = opt->value;
4166 severity = tor_malloc_zero(sizeof(log_severity_list_t));
4167 if (parse_log_severity_config(&cfg, severity) < 0) {
4168 log_warn(LD_CONFIG, "Couldn't parse log levels in Log option 'Log %s'",
4169 opt->value);
4170 ok = 0; goto cleanup;
4173 smartlist_split_string(elts, cfg, NULL,
4174 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
4176 if (smartlist_len(elts) == 0)
4177 smartlist_add(elts, tor_strdup("stdout"));
4179 if (smartlist_len(elts) == 1 &&
4180 (!strcasecmp(smartlist_get(elts,0), "stdout") ||
4181 !strcasecmp(smartlist_get(elts,0), "stderr"))) {
4182 int err = smartlist_len(elts) &&
4183 !strcasecmp(smartlist_get(elts,0), "stderr");
4184 if (!validate_only) {
4185 if (daemon) {
4186 log_warn(LD_CONFIG,
4187 "Can't log to %s with RunAsDaemon set; skipping stdout",
4188 err?"stderr":"stdout");
4189 } else {
4190 add_stream_log(severity, err?"<stderr>":"<stdout>",
4191 fileno(err?stderr:stdout));
4194 goto cleanup;
4196 if (smartlist_len(elts) == 1 &&
4197 !strcasecmp(smartlist_get(elts,0), "syslog")) {
4198 #ifdef HAVE_SYSLOG_H
4199 if (!validate_only) {
4200 add_syslog_log(severity);
4202 #else
4203 log_warn(LD_CONFIG, "Syslog is not supported on this system. Sorry.");
4204 #endif
4205 goto cleanup;
4208 if (smartlist_len(elts) == 2 &&
4209 !strcasecmp(smartlist_get(elts,0), "file")) {
4210 if (!validate_only) {
4211 if (add_file_log(severity, smartlist_get(elts, 1)) < 0) {
4212 log_warn(LD_CONFIG, "Couldn't open file for 'Log %s': %s",
4213 opt->value, strerror(errno));
4214 ok = 0;
4217 goto cleanup;
4220 log_warn(LD_CONFIG, "Bad syntax on file Log option 'Log %s'",
4221 opt->value);
4222 ok = 0; goto cleanup;
4224 cleanup:
4225 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
4226 smartlist_clear(elts);
4227 tor_free(severity);
4229 smartlist_free(elts);
4231 return ok?0:-1;
4234 /** Read the contents of a Bridge line from <b>line</b>. Return 0
4235 * if the line is well-formed, and -1 if it isn't. If
4236 * <b>validate_only</b> is 0, and the line is well-formed, then add
4237 * the bridge described in the line to our internal bridge list. */
4238 static int
4239 parse_bridge_line(const char *line, int validate_only)
4241 smartlist_t *items = NULL;
4242 int r;
4243 char *addrport=NULL, *fingerprint=NULL;
4244 tor_addr_t addr;
4245 uint16_t port = 0;
4246 char digest[DIGEST_LEN];
4248 items = smartlist_create();
4249 smartlist_split_string(items, line, NULL,
4250 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
4251 if (smartlist_len(items) < 1) {
4252 log_warn(LD_CONFIG, "Too few arguments to Bridge line.");
4253 goto err;
4255 addrport = smartlist_get(items, 0);
4256 smartlist_del_keeporder(items, 0);
4257 if (tor_addr_port_parse(addrport, &addr, &port)<0) {
4258 log_warn(LD_CONFIG, "Error parsing Bridge address '%s'", addrport);
4259 goto err;
4261 if (!port) {
4262 log_info(LD_CONFIG,
4263 "Bridge address '%s' has no port; using default port 443.",
4264 addrport);
4265 port = 443;
4268 if (smartlist_len(items)) {
4269 fingerprint = smartlist_join_strings(items, "", 0, NULL);
4270 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
4271 log_warn(LD_CONFIG, "Key digest for Bridge is wrong length.");
4272 goto err;
4274 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
4275 log_warn(LD_CONFIG, "Unable to decode Bridge key digest.");
4276 goto err;
4280 if (!validate_only) {
4281 log_debug(LD_DIR, "Bridge at %s:%d (%s)", fmt_addr(&addr),
4282 (int)port,
4283 fingerprint ? fingerprint : "no key listed");
4284 bridge_add_from_config(&addr, port, fingerprint ? digest : NULL);
4287 r = 0;
4288 goto done;
4290 err:
4291 r = -1;
4293 done:
4294 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
4295 smartlist_free(items);
4296 tor_free(addrport);
4297 tor_free(fingerprint);
4298 return r;
4301 /** Read the contents of a DirServer line from <b>line</b>. If
4302 * <b>validate_only</b> is 0, and the line is well-formed, and it
4303 * shares any bits with <b>required_type</b> or <b>required_type</b>
4304 * is 0, then add the dirserver described in the line (minus whatever
4305 * bits it's missing) as a valid authority. Return 0 on success,
4306 * or -1 if the line isn't well-formed or if we can't add it. */
4307 static int
4308 parse_dir_server_line(const char *line, authority_type_t required_type,
4309 int validate_only)
4311 smartlist_t *items = NULL;
4312 int r;
4313 char *addrport=NULL, *address=NULL, *nickname=NULL, *fingerprint=NULL;
4314 uint16_t dir_port = 0, or_port = 0;
4315 char digest[DIGEST_LEN];
4316 char v3_digest[DIGEST_LEN];
4317 authority_type_t type = V2_AUTHORITY;
4318 int is_not_hidserv_authority = 0, is_not_v2_authority = 0;
4320 items = smartlist_create();
4321 smartlist_split_string(items, line, NULL,
4322 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
4323 if (smartlist_len(items) < 1) {
4324 log_warn(LD_CONFIG, "No arguments on DirServer line.");
4325 goto err;
4328 if (is_legal_nickname(smartlist_get(items, 0))) {
4329 nickname = smartlist_get(items, 0);
4330 smartlist_del_keeporder(items, 0);
4333 while (smartlist_len(items)) {
4334 char *flag = smartlist_get(items, 0);
4335 if (TOR_ISDIGIT(flag[0]))
4336 break;
4337 if (!strcasecmp(flag, "v1")) {
4338 type |= (V1_AUTHORITY | HIDSERV_AUTHORITY);
4339 } else if (!strcasecmp(flag, "hs")) {
4340 type |= HIDSERV_AUTHORITY;
4341 } else if (!strcasecmp(flag, "no-hs")) {
4342 is_not_hidserv_authority = 1;
4343 } else if (!strcasecmp(flag, "bridge")) {
4344 type |= BRIDGE_AUTHORITY;
4345 } else if (!strcasecmp(flag, "no-v2")) {
4346 is_not_v2_authority = 1;
4347 } else if (!strcasecmpstart(flag, "orport=")) {
4348 int ok;
4349 char *portstring = flag + strlen("orport=");
4350 or_port = (uint16_t) tor_parse_long(portstring, 10, 1, 65535, &ok, NULL);
4351 if (!ok)
4352 log_warn(LD_CONFIG, "Invalid orport '%s' on DirServer line.",
4353 portstring);
4354 } else if (!strcasecmpstart(flag, "v3ident=")) {
4355 char *idstr = flag + strlen("v3ident=");
4356 if (strlen(idstr) != HEX_DIGEST_LEN ||
4357 base16_decode(v3_digest, DIGEST_LEN, idstr, HEX_DIGEST_LEN)<0) {
4358 log_warn(LD_CONFIG, "Bad v3 identity digest '%s' on DirServer line",
4359 flag);
4360 } else {
4361 type |= V3_AUTHORITY;
4363 } else {
4364 log_warn(LD_CONFIG, "Unrecognized flag '%s' on DirServer line",
4365 flag);
4367 tor_free(flag);
4368 smartlist_del_keeporder(items, 0);
4370 if (is_not_hidserv_authority)
4371 type &= ~HIDSERV_AUTHORITY;
4372 if (is_not_v2_authority)
4373 type &= ~V2_AUTHORITY;
4375 if (smartlist_len(items) < 2) {
4376 log_warn(LD_CONFIG, "Too few arguments to DirServer line.");
4377 goto err;
4379 addrport = smartlist_get(items, 0);
4380 smartlist_del_keeporder(items, 0);
4381 if (parse_addr_port(LOG_WARN, addrport, &address, NULL, &dir_port)<0) {
4382 log_warn(LD_CONFIG, "Error parsing DirServer address '%s'", addrport);
4383 goto err;
4385 if (!dir_port) {
4386 log_warn(LD_CONFIG, "Missing port in DirServer address '%s'",addrport);
4387 goto err;
4390 fingerprint = smartlist_join_strings(items, "", 0, NULL);
4391 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
4392 log_warn(LD_CONFIG, "Key digest for DirServer is wrong length %d.",
4393 (int)strlen(fingerprint));
4394 goto err;
4396 if (!strcmp(fingerprint, "E623F7625FBE0C87820F11EC5F6D5377ED816294")) {
4397 /* a known bad fingerprint. refuse to use it. We can remove this
4398 * clause once Tor 0.1.2.17 is obsolete. */
4399 log_warn(LD_CONFIG, "Dangerous dirserver line. To correct, erase your "
4400 "torrc file (%s), or reinstall Tor and use the default torrc.",
4401 get_torrc_fname());
4402 goto err;
4404 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
4405 log_warn(LD_CONFIG, "Unable to decode DirServer key digest.");
4406 goto err;
4409 if (!validate_only && (!required_type || required_type & type)) {
4410 if (required_type)
4411 type &= required_type; /* pare down what we think of them as an
4412 * authority for. */
4413 log_debug(LD_DIR, "Trusted %d dirserver at %s:%d (%s)", (int)type,
4414 address, (int)dir_port, (char*)smartlist_get(items,0));
4415 if (!add_trusted_dir_server(nickname, address, dir_port, or_port,
4416 digest, v3_digest, type))
4417 goto err;
4420 r = 0;
4421 goto done;
4423 err:
4424 r = -1;
4426 done:
4427 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
4428 smartlist_free(items);
4429 tor_free(addrport);
4430 tor_free(address);
4431 tor_free(nickname);
4432 tor_free(fingerprint);
4433 return r;
4436 /** Adjust the value of options->DataDirectory, or fill it in if it's
4437 * absent. Return 0 on success, -1 on failure. */
4438 static int
4439 normalize_data_directory(or_options_t *options)
4441 #ifdef MS_WINDOWS
4442 char *p;
4443 if (options->DataDirectory)
4444 return 0; /* all set */
4445 p = tor_malloc(MAX_PATH);
4446 strlcpy(p,get_windows_conf_root(),MAX_PATH);
4447 options->DataDirectory = p;
4448 return 0;
4449 #else
4450 const char *d = options->DataDirectory;
4451 if (!d)
4452 d = "~/.tor";
4454 if (strncmp(d,"~/",2) == 0) {
4455 char *fn = expand_filename(d);
4456 if (!fn) {
4457 log_warn(LD_CONFIG,"Failed to expand filename \"%s\".", d);
4458 return -1;
4460 if (!options->DataDirectory && !strcmp(fn,"/.tor")) {
4461 /* If our homedir is /, we probably don't want to use it. */
4462 /* Default to LOCALSTATEDIR/tor which is probably closer to what we
4463 * want. */
4464 log_warn(LD_CONFIG,
4465 "Default DataDirectory is \"~/.tor\". This expands to "
4466 "\"%s\", which is probably not what you want. Using "
4467 "\"%s"PATH_SEPARATOR"tor\" instead", fn, LOCALSTATEDIR);
4468 tor_free(fn);
4469 fn = tor_strdup(LOCALSTATEDIR PATH_SEPARATOR "tor");
4471 tor_free(options->DataDirectory);
4472 options->DataDirectory = fn;
4474 return 0;
4475 #endif
4478 /** Check and normalize the value of options->DataDirectory; return 0 if it
4479 * is sane, -1 otherwise. */
4480 static int
4481 validate_data_directory(or_options_t *options)
4483 if (normalize_data_directory(options) < 0)
4484 return -1;
4485 tor_assert(options->DataDirectory);
4486 if (strlen(options->DataDirectory) > (512-128)) {
4487 log_warn(LD_CONFIG, "DataDirectory is too long.");
4488 return -1;
4490 return 0;
4493 /** This string must remain the same forevermore. It is how we
4494 * recognize that the torrc file doesn't need to be backed up. */
4495 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; " \
4496 "if you edit it, comments will not be preserved"
4497 /** This string can change; it tries to give the reader an idea
4498 * that editing this file by hand is not a good plan. */
4499 #define GENERATED_FILE_COMMENT "# The old torrc file was renamed " \
4500 "to torrc.orig.1 or similar, and Tor will ignore it"
4502 /** Save a configuration file for the configuration in <b>options</b>
4503 * into the file <b>fname</b>. If the file already exists, and
4504 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
4505 * replace it. Return 0 on success, -1 on failure. */
4506 static int
4507 write_configuration_file(const char *fname, or_options_t *options)
4509 char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
4510 int rename_old = 0, r;
4512 tor_assert(fname);
4514 switch (file_status(fname)) {
4515 case FN_FILE:
4516 old_val = read_file_to_str(fname, 0, NULL);
4517 if (strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
4518 rename_old = 1;
4520 tor_free(old_val);
4521 break;
4522 case FN_NOENT:
4523 break;
4524 case FN_ERROR:
4525 case FN_DIR:
4526 default:
4527 log_warn(LD_CONFIG,
4528 "Config file \"%s\" is not a file? Failing.", fname);
4529 return -1;
4532 if (!(new_conf = options_dump(options, 1))) {
4533 log_warn(LD_BUG, "Couldn't get configuration string");
4534 goto err;
4537 tor_asprintf(&new_val, "%s\n%s\n\n%s",
4538 GENERATED_FILE_PREFIX, GENERATED_FILE_COMMENT, new_conf);
4540 if (rename_old) {
4541 int i = 1;
4542 size_t fn_tmp_len = strlen(fname)+32;
4543 char *fn_tmp;
4544 tor_assert(fn_tmp_len > strlen(fname)); /*check for overflow*/
4545 fn_tmp = tor_malloc(fn_tmp_len);
4546 while (1) {
4547 if (tor_snprintf(fn_tmp, fn_tmp_len, "%s.orig.%d", fname, i)<0) {
4548 log_warn(LD_BUG, "tor_snprintf failed inexplicably");
4549 tor_free(fn_tmp);
4550 goto err;
4552 if (file_status(fn_tmp) == FN_NOENT)
4553 break;
4554 ++i;
4556 log_notice(LD_CONFIG, "Renaming old configuration file to \"%s\"", fn_tmp);
4557 if (rename(fname, fn_tmp) < 0) {
4558 log_warn(LD_FS,
4559 "Couldn't rename configuration file \"%s\" to \"%s\": %s",
4560 fname, fn_tmp, strerror(errno));
4561 tor_free(fn_tmp);
4562 goto err;
4564 tor_free(fn_tmp);
4567 if (write_str_to_file(fname, new_val, 0) < 0)
4568 goto err;
4570 r = 0;
4571 goto done;
4572 err:
4573 r = -1;
4574 done:
4575 tor_free(new_val);
4576 tor_free(new_conf);
4577 return r;
4581 * Save the current configuration file value to disk. Return 0 on
4582 * success, -1 on failure.
4585 options_save_current(void)
4587 /* This fails if we can't write to our configuration file.
4589 * If we try falling back to datadirectory or something, we have a better
4590 * chance of saving the configuration, but a better chance of doing
4591 * something the user never expected. */
4592 return write_configuration_file(get_torrc_fname(), get_options());
4595 /** Mapping from a unit name to a multiplier for converting that unit into a
4596 * base unit. */
4597 struct unit_table_t {
4598 const char *unit;
4599 uint64_t multiplier;
4602 /** Table to map the names of memory units to the number of bytes they
4603 * contain. */
4604 static struct unit_table_t memory_units[] = {
4605 { "", 1 },
4606 { "b", 1<< 0 },
4607 { "byte", 1<< 0 },
4608 { "bytes", 1<< 0 },
4609 { "kb", 1<<10 },
4610 { "kbyte", 1<<10 },
4611 { "kbytes", 1<<10 },
4612 { "kilobyte", 1<<10 },
4613 { "kilobytes", 1<<10 },
4614 { "m", 1<<20 },
4615 { "mb", 1<<20 },
4616 { "mbyte", 1<<20 },
4617 { "mbytes", 1<<20 },
4618 { "megabyte", 1<<20 },
4619 { "megabytes", 1<<20 },
4620 { "gb", 1<<30 },
4621 { "gbyte", 1<<30 },
4622 { "gbytes", 1<<30 },
4623 { "gigabyte", 1<<30 },
4624 { "gigabytes", 1<<30 },
4625 { "tb", U64_LITERAL(1)<<40 },
4626 { "terabyte", U64_LITERAL(1)<<40 },
4627 { "terabytes", U64_LITERAL(1)<<40 },
4628 { NULL, 0 },
4631 /** Table to map the names of time units to the number of seconds they
4632 * contain. */
4633 static struct unit_table_t time_units[] = {
4634 { "", 1 },
4635 { "second", 1 },
4636 { "seconds", 1 },
4637 { "minute", 60 },
4638 { "minutes", 60 },
4639 { "hour", 60*60 },
4640 { "hours", 60*60 },
4641 { "day", 24*60*60 },
4642 { "days", 24*60*60 },
4643 { "week", 7*24*60*60 },
4644 { "weeks", 7*24*60*60 },
4645 { NULL, 0 },
4648 /** Parse a string <b>val</b> containing a number, zero or more
4649 * spaces, and an optional unit string. If the unit appears in the
4650 * table <b>u</b>, then multiply the number by the unit multiplier.
4651 * On success, set *<b>ok</b> to 1 and return this product.
4652 * Otherwise, set *<b>ok</b> to 0.
4654 static uint64_t
4655 config_parse_units(const char *val, struct unit_table_t *u, int *ok)
4657 uint64_t v = 0;
4658 double d = 0;
4659 int use_float = 0;
4660 char *cp;
4662 tor_assert(ok);
4664 v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
4665 if (!*ok || (cp && *cp == '.')) {
4666 d = tor_parse_double(val, 0, UINT64_MAX, ok, &cp);
4667 if (!*ok)
4668 goto done;
4669 use_float = 1;
4672 if (!cp) {
4673 *ok = 1;
4674 v = use_float ? DBL_TO_U64(d) : v;
4675 goto done;
4678 cp = (char*) eat_whitespace(cp);
4680 for ( ;u->unit;++u) {
4681 if (!strcasecmp(u->unit, cp)) {
4682 if (use_float)
4683 v = u->multiplier * d;
4684 else
4685 v *= u->multiplier;
4686 *ok = 1;
4687 goto done;
4690 log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
4691 *ok = 0;
4692 done:
4694 if (*ok)
4695 return v;
4696 else
4697 return 0;
4700 /** Parse a string in the format "number unit", where unit is a unit of
4701 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
4702 * and return the number of bytes specified. Otherwise, set
4703 * *<b>ok</b> to false and return 0. */
4704 static uint64_t
4705 config_parse_memunit(const char *s, int *ok)
4707 uint64_t u = config_parse_units(s, memory_units, ok);
4708 return u;
4711 /** Parse a string in the format "number unit", where unit is a unit of time.
4712 * On success, set *<b>ok</b> to true and return the number of seconds in
4713 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
4715 static int
4716 config_parse_interval(const char *s, int *ok)
4718 uint64_t r;
4719 r = config_parse_units(s, time_units, ok);
4720 if (!ok)
4721 return -1;
4722 if (r > INT_MAX) {
4723 log_warn(LD_CONFIG, "Interval '%s' is too long", s);
4724 *ok = 0;
4725 return -1;
4727 return (int)r;
4731 * Initialize the libevent library.
4733 static void
4734 init_libevent(void)
4736 const char *badness=NULL;
4738 configure_libevent_logging();
4739 /* If the kernel complains that some method (say, epoll) doesn't
4740 * exist, we don't care about it, since libevent will cope.
4742 suppress_libevent_log_msg("Function not implemented");
4744 tor_check_libevent_header_compatibility();
4746 tor_libevent_initialize();
4748 suppress_libevent_log_msg(NULL);
4750 tor_check_libevent_version(tor_libevent_get_method(),
4751 get_options()->ORPort != 0,
4752 &badness);
4753 if (badness) {
4754 const char *v = tor_libevent_get_version_str();
4755 const char *m = tor_libevent_get_method();
4756 control_event_general_status(LOG_WARN,
4757 "BAD_LIBEVENT VERSION=%s METHOD=%s BADNESS=%s RECOVERED=NO",
4758 v, m, badness);
4762 /** Return the persistent state struct for this Tor. */
4763 or_state_t *
4764 get_or_state(void)
4766 tor_assert(global_state);
4767 return global_state;
4770 /** Return a newly allocated string holding a filename relative to the data
4771 * directory. If <b>sub1</b> is present, it is the first path component after
4772 * the data directory. If <b>sub2</b> is also present, it is the second path
4773 * component after the data directory. If <b>suffix</b> is present, it
4774 * is appended to the filename.
4776 * Examples:
4777 * get_datadir_fname2_suffix("a", NULL, NULL) -> $DATADIR/a
4778 * get_datadir_fname2_suffix("a", NULL, ".tmp") -> $DATADIR/a.tmp
4779 * get_datadir_fname2_suffix("a", "b", ".tmp") -> $DATADIR/a/b/.tmp
4780 * get_datadir_fname2_suffix("a", "b", NULL) -> $DATADIR/a/b
4782 * Note: Consider using the get_datadir_fname* macros in or.h.
4784 char *
4785 options_get_datadir_fname2_suffix(or_options_t *options,
4786 const char *sub1, const char *sub2,
4787 const char *suffix)
4789 char *fname = NULL;
4790 size_t len;
4791 tor_assert(options);
4792 tor_assert(options->DataDirectory);
4793 tor_assert(sub1 || !sub2); /* If sub2 is present, sub1 must be present. */
4794 len = strlen(options->DataDirectory);
4795 if (sub1) {
4796 len += strlen(sub1)+1;
4797 if (sub2)
4798 len += strlen(sub2)+1;
4800 if (suffix)
4801 len += strlen(suffix);
4802 len++;
4803 fname = tor_malloc(len);
4804 if (sub1) {
4805 if (sub2) {
4806 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s"PATH_SEPARATOR"%s",
4807 options->DataDirectory, sub1, sub2);
4808 } else {
4809 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s",
4810 options->DataDirectory, sub1);
4812 } else {
4813 strlcpy(fname, options->DataDirectory, len);
4815 if (suffix)
4816 strlcat(fname, suffix, len);
4817 return fname;
4820 /** Return 0 if every setting in <b>state</b> is reasonable, and a
4821 * permissible transition from <b>old_state</b>. Else warn and return -1.
4822 * Should have no side effects, except for normalizing the contents of
4823 * <b>state</b>.
4825 /* XXX from_setconf is here because of bug 238 */
4826 static int
4827 or_state_validate(or_state_t *old_state, or_state_t *state,
4828 int from_setconf, char **msg)
4830 /* We don't use these; only options do. Still, we need to match that
4831 * signature. */
4832 (void) from_setconf;
4833 (void) old_state;
4835 if (entry_guards_parse_state(state, 0, msg)<0)
4836 return -1;
4838 return 0;
4841 /** Replace the current persistent state with <b>new_state</b> */
4842 static void
4843 or_state_set(or_state_t *new_state)
4845 char *err = NULL;
4846 tor_assert(new_state);
4847 config_free(&state_format, global_state);
4848 global_state = new_state;
4849 if (entry_guards_parse_state(global_state, 1, &err)<0) {
4850 log_warn(LD_GENERAL,"%s",err);
4851 tor_free(err);
4853 if (rep_hist_load_state(global_state, &err)<0) {
4854 log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
4855 tor_free(err);
4857 if (circuit_build_times_parse_state(&circ_times, global_state, &err) < 0) {
4858 log_warn(LD_GENERAL,"%s",err);
4859 tor_free(err);
4863 /** Reload the persistent state from disk, generating a new state as needed.
4864 * Return 0 on success, less than 0 on failure.
4866 static int
4867 or_state_load(void)
4869 or_state_t *new_state = NULL;
4870 char *contents = NULL, *fname;
4871 char *errmsg = NULL;
4872 int r = -1, badstate = 0;
4874 fname = get_datadir_fname("state");
4875 switch (file_status(fname)) {
4876 case FN_FILE:
4877 if (!(contents = read_file_to_str(fname, 0, NULL))) {
4878 log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
4879 goto done;
4881 break;
4882 case FN_NOENT:
4883 break;
4884 case FN_ERROR:
4885 case FN_DIR:
4886 default:
4887 log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
4888 goto done;
4890 new_state = tor_malloc_zero(sizeof(or_state_t));
4891 new_state->_magic = OR_STATE_MAGIC;
4892 config_init(&state_format, new_state);
4893 if (contents) {
4894 config_line_t *lines=NULL;
4895 int assign_retval;
4896 if (config_get_lines(contents, &lines)<0)
4897 goto done;
4898 assign_retval = config_assign(&state_format, new_state,
4899 lines, 0, 0, &errmsg);
4900 config_free_lines(lines);
4901 if (assign_retval<0)
4902 badstate = 1;
4903 if (errmsg) {
4904 log_warn(LD_GENERAL, "%s", errmsg);
4905 tor_free(errmsg);
4909 if (!badstate && or_state_validate(NULL, new_state, 1, &errmsg) < 0)
4910 badstate = 1;
4912 if (errmsg) {
4913 log_warn(LD_GENERAL, "%s", errmsg);
4914 tor_free(errmsg);
4917 if (badstate && !contents) {
4918 log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
4919 " This is a bug in Tor.");
4920 goto done;
4921 } else if (badstate && contents) {
4922 int i;
4923 file_status_t status;
4924 size_t len = strlen(fname)+16;
4925 char *fname2 = tor_malloc(len);
4926 for (i = 0; i < 100; ++i) {
4927 tor_snprintf(fname2, len, "%s.%d", fname, i);
4928 status = file_status(fname2);
4929 if (status == FN_NOENT)
4930 break;
4932 if (i == 100) {
4933 log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
4934 "state files to move aside. Discarding the old state file.",
4935 fname);
4936 unlink(fname);
4937 } else {
4938 log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
4939 "to \"%s\". This could be a bug in Tor; please tell "
4940 "the developers.", fname, fname2);
4941 if (rename(fname, fname2) < 0) {
4942 log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
4943 "OS gave an error of %s", strerror(errno));
4946 tor_free(fname2);
4947 tor_free(contents);
4948 config_free(&state_format, new_state);
4950 new_state = tor_malloc_zero(sizeof(or_state_t));
4951 new_state->_magic = OR_STATE_MAGIC;
4952 config_init(&state_format, new_state);
4953 } else if (contents) {
4954 log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
4955 } else {
4956 log_info(LD_GENERAL, "Initialized state");
4958 or_state_set(new_state);
4959 new_state = NULL;
4960 if (!contents) {
4961 global_state->next_write = 0;
4962 or_state_save(time(NULL));
4964 r = 0;
4966 done:
4967 tor_free(fname);
4968 tor_free(contents);
4969 if (new_state)
4970 config_free(&state_format, new_state);
4972 return r;
4975 /** Write the persistent state to disk. Return 0 for success, <0 on failure. */
4977 or_state_save(time_t now)
4979 char *state, *contents;
4980 char tbuf[ISO_TIME_LEN+1];
4981 char *fname;
4983 tor_assert(global_state);
4985 if (global_state->next_write > now)
4986 return 0;
4988 /* Call everything else that might dirty the state even more, in order
4989 * to avoid redundant writes. */
4990 entry_guards_update_state(global_state);
4991 rep_hist_update_state(global_state);
4992 circuit_build_times_update_state(&circ_times, global_state);
4993 if (accounting_is_enabled(get_options()))
4994 accounting_run_housekeeping(now);
4996 global_state->LastWritten = time(NULL);
4997 tor_free(global_state->TorVersion);
4998 tor_asprintf(&global_state->TorVersion, "Tor %s", get_version());
5000 state = config_dump(&state_format, global_state, 1, 0);
5001 format_local_iso_time(tbuf, time(NULL));
5002 tor_asprintf(&contents,
5003 "# Tor state file last generated on %s local time\n"
5004 "# Other times below are in GMT\n"
5005 "# You *do not* need to edit this file.\n\n%s",
5006 tbuf, state);
5007 tor_free(state);
5008 fname = get_datadir_fname("state");
5009 if (write_str_to_file(fname, contents, 0)<0) {
5010 log_warn(LD_FS, "Unable to write state to file \"%s\"", fname);
5011 tor_free(fname);
5012 tor_free(contents);
5013 return -1;
5015 log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
5016 tor_free(fname);
5017 tor_free(contents);
5019 global_state->next_write = TIME_MAX;
5020 return 0;
5023 /** Given a file name check to see whether the file exists but has not been
5024 * modified for a very long time. If so, remove it. */
5025 void
5026 remove_file_if_very_old(const char *fname, time_t now)
5028 #define VERY_OLD_FILE_AGE (28*24*60*60)
5029 struct stat st;
5031 if (stat(fname, &st)==0 && st.st_mtime < now-VERY_OLD_FILE_AGE) {
5032 char buf[ISO_TIME_LEN+1];
5033 format_local_iso_time(buf, st.st_mtime);
5034 log_notice(LD_GENERAL, "Obsolete file %s hasn't been modified since %s. "
5035 "Removing it.", fname, buf);
5036 unlink(fname);
5040 /** Helper to implement GETINFO functions about configuration variables (not
5041 * their values). Given a "config/names" question, set *<b>answer</b> to a
5042 * new string describing the supported configuration variables and their
5043 * types. */
5045 getinfo_helper_config(control_connection_t *conn,
5046 const char *question, char **answer)
5048 (void) conn;
5049 if (!strcmp(question, "config/names")) {
5050 smartlist_t *sl = smartlist_create();
5051 int i;
5052 for (i = 0; _option_vars[i].name; ++i) {
5053 config_var_t *var = &_option_vars[i];
5054 const char *type;
5055 char *line;
5056 switch (var->type) {
5057 case CONFIG_TYPE_STRING: type = "String"; break;
5058 case CONFIG_TYPE_FILENAME: type = "Filename"; break;
5059 case CONFIG_TYPE_UINT: type = "Integer"; break;
5060 case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
5061 case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
5062 case CONFIG_TYPE_DOUBLE: type = "Float"; break;
5063 case CONFIG_TYPE_BOOL: type = "Boolean"; break;
5064 case CONFIG_TYPE_ISOTIME: type = "Time"; break;
5065 case CONFIG_TYPE_ROUTERSET: type = "RouterList"; break;
5066 case CONFIG_TYPE_CSV: type = "CommaList"; break;
5067 case CONFIG_TYPE_LINELIST: type = "LineList"; break;
5068 case CONFIG_TYPE_LINELIST_S: type = "Dependant"; break;
5069 case CONFIG_TYPE_LINELIST_V: type = "Virtual"; break;
5070 default:
5071 case CONFIG_TYPE_OBSOLETE:
5072 type = NULL; break;
5074 if (!type)
5075 continue;
5076 tor_asprintf(&line, "%s %s\n",var->name,type);
5077 smartlist_add(sl, line);
5079 *answer = smartlist_join_strings(sl, "", 0, NULL);
5080 SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
5081 smartlist_free(sl);
5083 return 0;