More work towards making bridge users able to connect via bridges:
[tor.git] / src / or / config.c
blob844e802b97dbccd26d1af4b881e94e39078809f5
1 /* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2007, Roger Dingledine, Nick Mathewson. */
4 /* See LICENSE for licensing information */
5 /* $Id$ */
6 const char config_c_id[] = \
7 "$Id$";
9 /**
10 * \file config.c
11 * \brief Code to parse and interpret configuration files.
12 **/
14 #define CONFIG_PRIVATE
16 #include "or.h"
17 #ifdef MS_WINDOWS
18 #include <shlobj.h>
19 #endif
20 #include "../common/aes.h"
22 /** Enumeration of types which option values can take */
23 typedef enum config_type_t {
24 CONFIG_TYPE_STRING = 0, /**< An arbitrary string. */
25 CONFIG_TYPE_UINT, /**< A non-negative integer less than MAX_INT */
26 CONFIG_TYPE_INTERVAL, /**< A number of seconds, with optional units*/
27 CONFIG_TYPE_MEMUNIT, /**< A number of bytes, with optional units*/
28 CONFIG_TYPE_DOUBLE, /**< A floating-point value */
29 CONFIG_TYPE_BOOL, /**< A boolean value, expressed as 0 or 1. */
30 CONFIG_TYPE_ISOTIME, /**< An ISO-formated time relative to GMT. */
31 CONFIG_TYPE_CSV, /**< A list of strings, separated by commas and
32 * optional whitespace. */
33 CONFIG_TYPE_LINELIST, /**< Uninterpreted config lines */
34 CONFIG_TYPE_LINELIST_S, /**< Uninterpreted, context-sensitive config lines,
35 * mixed with other keywords. */
36 CONFIG_TYPE_LINELIST_V, /**< Catch-all "virtual" option to summarize
37 * context-sensitive config lines when fetching.
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 command-line abbreviations. */
55 static config_abbrev_t _option_abbrevs[] = {
56 PLURAL(ExitNode),
57 PLURAL(EntryNode),
58 PLURAL(ExcludeNode),
59 PLURAL(FirewallPort),
60 PLURAL(LongLivedPort),
61 PLURAL(HiddenServiceNode),
62 PLURAL(HiddenServiceExcludeNode),
63 PLURAL(NumCpu),
64 PLURAL(RendNode),
65 PLURAL(RendExcludeNode),
66 PLURAL(StrictEntryNode),
67 PLURAL(StrictExitNode),
68 { "l", "Log", 1, 0},
69 { "AllowUnverifiedNodes", "AllowInvalidNodes", 0, 0},
70 { "AutomapHostSuffixes", "AutomapHostsSuffixes", 0, 0},
71 { "AutomapHostOnResolve", "AutomapHostsOnResolve", 0, 0},
72 { "BandwidthRateBytes", "BandwidthRate", 0, 0},
73 { "BandwidthBurstBytes", "BandwidthBurst", 0, 0},
74 { "DirFetchPostPeriod", "StatusFetchPeriod", 0, 0},
75 { "MaxConn", "ConnLimit", 0, 1},
76 { "ORBindAddress", "ORListenAddress", 0, 0},
77 { "DirBindAddress", "DirListenAddress", 0, 0},
78 { "SocksBindAddress", "SocksListenAddress", 0, 0},
79 { "UseHelperNodes", "UseEntryGuards", 0, 0},
80 { "NumHelperNodes", "NumEntryGuards", 0, 0},
81 { "UseEntryNodes", "UseEntryGuards", 0, 0},
82 { "NumEntryNodes", "NumEntryGuards", 0, 0},
83 { "ResolvConf", "ServerDNSResolvConfFile", 0, 1},
84 { "SearchDomains", "ServerDNSSearchDomains", 0, 1},
85 { NULL, NULL, 0, 0},
87 /* A list of state-file abbreviations, for compatibility. */
88 static config_abbrev_t _state_abbrevs[] = {
89 { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
90 { "HelperNode", "EntryGuard", 0, 0 },
91 { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
92 { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
93 { "EntryNode", "EntryGuard", 0, 0 },
94 { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
95 { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
96 { NULL, NULL, 0, 0},
98 #undef PLURAL
100 /** A variable allowed in the configuration file or on the command line. */
101 typedef struct config_var_t {
102 const char *name; /**< The full keyword (case insensitive). */
103 config_type_t type; /**< How to interpret the type and turn it into a
104 * value. */
105 off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
106 const char *initvalue; /**< String (or null) describing initial value. */
107 } config_var_t;
109 /** An entry for config_vars: "The option <b>name</b> has type
110 * CONFIG_TYPE_<b>conftype</b>, and corresponds to
111 * or_options_t.<b>member</b>"
113 #define VAR(name,conftype,member,initvalue) \
114 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), \
115 initvalue }
116 /** An entry for config_vars: "The option <b>name</b> is obsolete." */
117 #define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
119 /** Array of configuration options. Until we disallow nonstandard
120 * abbreviations, order is significant, since the first matching option will
121 * be chosen first.
123 static config_var_t _option_vars[] = {
124 OBSOLETE("AccountingMaxKB"),
125 VAR("AccountingMax", MEMUNIT, AccountingMax, "0 bytes"),
126 VAR("AccountingStart", STRING, AccountingStart, NULL),
127 VAR("Address", STRING, Address, NULL),
128 VAR("AllowInvalidNodes", CSV, AllowInvalidNodes,
129 "middle,rendezvous"),
130 VAR("AllowNonRFC953Hostnames", BOOL, AllowNonRFC953Hostnames, "0"),
131 VAR("AssumeReachable", BOOL, AssumeReachable, "0"),
132 VAR("AuthDirBadExit", LINELIST, AuthDirBadExit, NULL),
133 VAR("AuthDirInvalid", LINELIST, AuthDirInvalid, NULL),
134 VAR("AuthDirReject", LINELIST, AuthDirReject, NULL),
135 VAR("AuthDirRejectUnlisted",BOOL, AuthDirRejectUnlisted,"0"),
136 VAR("AuthDirListBadExits", BOOL, AuthDirListBadExits, "0"),
137 VAR("AuthoritativeDirectory",BOOL, AuthoritativeDir, "0"),
138 VAR("AutomapHostsOnResolve",BOOL, AutomapHostsOnResolve,"0"),
139 VAR("AutomapHostsSuffixes",CSV, AutomapHostsSuffixes, ".onion,.exit"),
140 VAR("AvoidDiskWrites", BOOL, AvoidDiskWrites, "0"),
141 VAR("BandwidthBurst", MEMUNIT, BandwidthBurst, "6 MB"),
142 VAR("BandwidthRate", MEMUNIT, BandwidthRate, "3 MB"),
143 VAR("BridgeAuthoritativeDir", BOOL, BridgeAuthoritativeDir, "0"),
144 VAR("Bridge", LINELIST, Bridges, NULL),
145 VAR("CircuitBuildTimeout", INTERVAL, CircuitBuildTimeout, "1 minute"),
146 VAR("CircuitIdleTimeout", INTERVAL, CircuitIdleTimeout, "1 hour"),
147 VAR("ClientOnly", BOOL, ClientOnly, "0"),
148 VAR("ConnLimit", UINT, ConnLimit, "1000"),
149 VAR("ContactInfo", STRING, ContactInfo, NULL),
150 VAR("ControlListenAddress",LINELIST, ControlListenAddress, NULL),
151 VAR("ControlPort", UINT, ControlPort, "0"),
152 VAR("ControlSocket", LINELIST, ControlSocket, NULL),
153 VAR("CookieAuthentication",BOOL, CookieAuthentication, "0"),
154 VAR("DataDirectory", STRING, DataDirectory, NULL),
155 OBSOLETE("DebugLogFile"),
156 VAR("DirAllowPrivateAddresses",BOOL, DirAllowPrivateAddresses, NULL),
157 VAR("DirListenAddress", LINELIST, DirListenAddress, NULL),
158 OBSOLETE("DirFetchPeriod"),
159 VAR("DirPolicy", LINELIST, DirPolicy, NULL),
160 VAR("DirPort", UINT, DirPort, "0"),
161 OBSOLETE("DirPostPeriod"),
162 VAR("DirServer", LINELIST, DirServers, NULL),
163 VAR("DNSPort", UINT, DNSPort, "0"),
164 VAR("DNSListenAddress", LINELIST, DNSListenAddress, NULL),
165 VAR("DownloadExtraInfo", BOOL, DownloadExtraInfo, "0"),
166 VAR("EnforceDistinctSubnets", BOOL, EnforceDistinctSubnets,"1"),
167 VAR("EntryNodes", STRING, EntryNodes, NULL),
168 VAR("ExcludeNodes", STRING, ExcludeNodes, NULL),
169 VAR("ExitNodes", STRING, ExitNodes, NULL),
170 VAR("ExitPolicy", LINELIST, ExitPolicy, NULL),
171 VAR("ExitPolicyRejectPrivate", BOOL, ExitPolicyRejectPrivate, "1"),
172 VAR("FascistFirewall", BOOL, FascistFirewall, "0"),
173 VAR("FirewallPorts", CSV, FirewallPorts, ""),
174 VAR("FastFirstHopPK", BOOL, FastFirstHopPK, "1"),
175 VAR("FetchServerDescriptors",BOOL, FetchServerDescriptors,"1"),
176 VAR("FetchHidServDescriptors",BOOL, FetchHidServDescriptors, "1"),
177 VAR("FetchUselessDescriptors",BOOL, FetchUselessDescriptors, "0"),
178 VAR("Group", STRING, Group, NULL),
179 VAR("HardwareAccel", BOOL, HardwareAccel, "0"),
180 VAR("HashedControlPassword",STRING, HashedControlPassword, NULL),
181 VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
182 VAR("HiddenServiceExcludeNodes", LINELIST_S, RendConfigLines, NULL),
183 VAR("HiddenServiceNodes", LINELIST_S, RendConfigLines, NULL),
184 VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
185 VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
186 VAR("HSAuthoritativeDir", BOOL, HSAuthoritativeDir, "0"),
187 VAR("HSAuthorityRecordStats",BOOL, HSAuthorityRecordStats,"0"),
188 VAR("HttpProxy", STRING, HttpProxy, NULL),
189 VAR("HttpProxyAuthenticator",STRING, HttpProxyAuthenticator,NULL),
190 VAR("HttpsProxy", STRING, HttpsProxy, NULL),
191 VAR("HttpsProxyAuthenticator",STRING,HttpsProxyAuthenticator,NULL),
192 OBSOLETE("IgnoreVersion"),
193 VAR("KeepalivePeriod", INTERVAL, KeepalivePeriod, "5 minutes"),
194 VAR("Log", LINELIST, Logs, NULL),
195 OBSOLETE("LinkPadding"),
196 OBSOLETE("LogLevel"),
197 OBSOLETE("LogFile"),
198 VAR("LongLivedPorts", CSV, LongLivedPorts,
199 "21,22,706,1863,5050,5190,5222,5223,6667,6697,8300"),
200 VAR("MapAddress", LINELIST, AddressMap, NULL),
201 VAR("MaxAdvertisedBandwidth",MEMUNIT,MaxAdvertisedBandwidth,"1 GB"),
202 VAR("MaxCircuitDirtiness", INTERVAL, MaxCircuitDirtiness, "10 minutes"),
203 VAR("MaxOnionsPending", UINT, MaxOnionsPending, "100"),
204 OBSOLETE("MonthlyAccountingStart"),
205 VAR("MyFamily", STRING, MyFamily, NULL),
206 VAR("NewCircuitPeriod", INTERVAL, NewCircuitPeriod, "30 seconds"),
207 VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "0"),
208 VAR("NatdListenAddress", LINELIST, NatdListenAddress, NULL),
209 VAR("NatdPort", UINT, NatdPort, "0"),
210 VAR("Nickname", STRING, Nickname, NULL),
211 VAR("NoPublish", BOOL, NoPublish, "0"),
212 VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
213 VAR("NumCpus", UINT, NumCpus, "1"),
214 VAR("NumEntryGuards", UINT, NumEntryGuards, "3"),
215 VAR("ORListenAddress", LINELIST, ORListenAddress, NULL),
216 VAR("ORPort", UINT, ORPort, "0"),
217 VAR("OutboundBindAddress", STRING, OutboundBindAddress, NULL),
218 OBSOLETE("PathlenCoinWeight"),
219 VAR("PidFile", STRING, PidFile, NULL),
220 VAR("PreferTunneledDirConns", BOOL, PreferTunneledDirConns, "0"),
221 VAR("ProtocolWarnings", BOOL, ProtocolWarnings, "0"),
222 VAR("PublishServerDescriptor", CSV, PublishServerDescriptor,"v1,v2"),
223 VAR("PublishHidServDescriptors",BOOL,PublishHidServDescriptors, "1"),
224 VAR("ReachableAddresses", LINELIST, ReachableAddresses, NULL),
225 VAR("ReachableDirAddresses",LINELIST,ReachableDirAddresses,NULL),
226 VAR("ReachableORAddresses",LINELIST, ReachableORAddresses, NULL),
227 VAR("RecommendedVersions", LINELIST, RecommendedVersions, NULL),
228 VAR("RecommendedClientVersions", LINELIST, RecommendedClientVersions, NULL),
229 VAR("RecommendedServerVersions", LINELIST, RecommendedServerVersions, NULL),
230 VAR("RedirectExit", LINELIST, RedirectExit, NULL),
231 VAR("RelayBandwidthBurst", MEMUNIT, RelayBandwidthBurst, "0"),
232 VAR("RelayBandwidthRate", MEMUNIT, RelayBandwidthRate, "0"),
233 VAR("RendExcludeNodes", STRING, RendExcludeNodes, NULL),
234 VAR("RendNodes", STRING, RendNodes, NULL),
235 VAR("RendPostPeriod", INTERVAL, RendPostPeriod, "1 hour"),
236 VAR("RephistTrackTime", INTERVAL, RephistTrackTime, "24 hours"),
237 OBSOLETE("RouterFile"),
238 VAR("RunAsDaemon", BOOL, RunAsDaemon, "0"),
239 VAR("RunTesting", BOOL, RunTesting, "0"),
240 VAR("SafeLogging", BOOL, SafeLogging, "1"),
241 VAR("SafeSocks", BOOL, SafeSocks, "0"),
242 VAR("ServerDNSAllowNonRFC953Hostnames",
243 BOOL, ServerDNSAllowNonRFC953Hostnames, "0"),
244 VAR("ServerDNSDetectHijacking",BOOL, ServerDNSDetectHijacking,"1"),
245 VAR("ServerDNSResolvConfFile", STRING, ServerDNSResolvConfFile, NULL),
246 VAR("ServerDNSSearchDomains", BOOL, ServerDNSSearchDomains, "0"),
247 VAR("ServerDNSTestAddresses", CSV, ServerDNSTestAddresses,
248 "www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"),
249 VAR("ShutdownWaitLength", INTERVAL, ShutdownWaitLength, "30 seconds"),
250 VAR("SocksListenAddress", LINELIST, SocksListenAddress, NULL),
251 VAR("SocksPolicy", LINELIST, SocksPolicy, NULL),
252 VAR("SocksPort", UINT, SocksPort, "9050"),
253 VAR("SocksTimeout", INTERVAL, SocksTimeout, "2 minutes"),
254 OBSOLETE("StatusFetchPeriod"),
255 VAR("StrictEntryNodes", BOOL, StrictEntryNodes, "0"),
256 VAR("StrictExitNodes", BOOL, StrictExitNodes, "0"),
257 OBSOLETE("SysLog"),
258 VAR("TestSocks", BOOL, TestSocks, "0"),
259 VAR("TestVia", STRING, TestVia, NULL),
260 VAR("TrackHostExits", CSV, TrackHostExits, NULL),
261 VAR("TrackHostExitsExpire",INTERVAL, TrackHostExitsExpire, "30 minutes"),
262 OBSOLETE("TrafficShaping"),
263 VAR("TransListenAddress", LINELIST, TransListenAddress, NULL),
264 VAR("TransPort", UINT, TransPort, "0"),
265 VAR("TunnelDirConns", BOOL, TunnelDirConns, "0"),
266 VAR("UpdateBridgesFromAuthority",BOOL,UpdateBridgesFromAuthority,"0"),
267 VAR("UseBridges", BOOL, UseBridges, "0"),
268 VAR("UseEntryGuards", BOOL, UseEntryGuards, "1"),
269 VAR("User", STRING, User, NULL),
270 VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
271 VAR("V2AuthoritativeDirectory",BOOL, V2AuthoritativeDir, "0"),
272 VAR("V3AuthoritativeDirectory",BOOL, V3AuthoritativeDir, "0"),
273 VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
274 VAR("VirtualAddrNetwork", STRING, VirtualAddrNetwork, "127.192.0.0/10"),
275 VAR("__AllDirActionsPrivate",BOOL, AllDirActionsPrivate, "0"),
276 VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits,"0"),
277 VAR("__LeaveStreamsUnattached", BOOL,LeaveStreamsUnattached, "0"),
279 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
281 #undef VAR
283 #define VAR(name,conftype,member,initvalue) \
284 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member), \
285 initvalue }
286 static config_var_t _state_vars[] = {
287 VAR("AccountingBytesReadInInterval", MEMUNIT,
288 AccountingBytesReadInInterval, NULL),
289 VAR("AccountingBytesWrittenInInterval", MEMUNIT,
290 AccountingBytesWrittenInInterval, NULL),
291 VAR("AccountingExpectedUsage", MEMUNIT, AccountingExpectedUsage, NULL),
292 VAR("AccountingIntervalStart", ISOTIME, AccountingIntervalStart, NULL),
293 VAR("AccountingSecondsActive", INTERVAL, AccountingSecondsActive, NULL),
294 VAR("EntryGuard", LINELIST_S, EntryGuards, NULL),
295 VAR("EntryGuardDownSince", LINELIST_S, EntryGuards, NULL),
296 VAR("EntryGuardUnlistedSince", LINELIST_S, EntryGuards, NULL),
297 VAR("EntryGuards", LINELIST_V, EntryGuards, NULL),
299 VAR("BWHistoryReadEnds", ISOTIME, BWHistoryReadEnds, NULL),
300 VAR("BWHistoryReadInterval", UINT, BWHistoryReadInterval, "900"),
301 VAR("BWHistoryReadValues", CSV, BWHistoryReadValues, ""),
302 VAR("BWHistoryWriteEnds", ISOTIME, BWHistoryWriteEnds, NULL),
303 VAR("BWHistoryWriteInterval", UINT, BWHistoryWriteInterval, "900"),
304 VAR("BWHistoryWriteValues", CSV, BWHistoryWriteValues, ""),
306 VAR("TorVersion", STRING, TorVersion, NULL),
308 VAR("LastRotatedOnionKey", ISOTIME, LastRotatedOnionKey, NULL),
309 VAR("LastWritten", ISOTIME, LastWritten, NULL),
311 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
314 #undef VAR
315 #undef OBSOLETE
317 /** Represents an English description of a configuration variable; used when
318 * generating configuration file comments. */
319 typedef struct config_var_description_t {
320 const char *name;
321 const char *description;
322 } config_var_description_t;
324 static config_var_description_t options_description[] = {
325 /* ==== general options */
326 { "AvoidDiskWrites", "If non-zero, try to write to disk less frequently than"
327 " we would otherwise." },
328 { "BandwidthRate", "A token bucket limits the average incoming bandwidth on "
329 "this node to the specified number of bytes per second." },
330 { "BandwidthBurst", "Limit the maximum token buffer size (also known as "
331 "burst) to the given number of bytes." },
332 { "ConnLimit", "Maximum number of simultaneous sockets allowed." },
333 /* ControlListenAddress */
334 { "ControlPort", "If set, Tor will accept connections from the same machine "
335 "(localhost only) on this port, and allow those connections to control "
336 "the Tor process using the Tor Control Protocol (described in"
337 "control-spec.txt).", },
338 { "CookieAuthentication", "If this option is set to 1, don't allow any "
339 "connections to the control port except when the connecting process "
340 "can read a file that Tor creates in its data directory." },
341 { "DataDirectory", "Store working data, state, keys, and caches here." },
342 { "DirServer", "Tor only trusts directories signed with one of these "
343 "servers' keys. Used to override the standard list of directory "
344 "authorities." },
345 /* { "FastFirstHopPK", "" }, */
346 /* FetchServerDescriptors, FetchHidServDescriptors,
347 * FetchUselessDescriptors */
348 { "Group", "On startup, setgid to this group." },
349 { "HardwareAccel", "If set, Tor tries to use hardware crypto accelerators "
350 "when it can." },
351 /* HashedControlPassword */
352 { "HTTPProxy", "Force Tor to make all HTTP directory requests through this "
353 "host:port (or host:80 if port is not set)." },
354 { "HTTPProxyAuthenticator", "A username:password pair to be used with "
355 "HTTPProxy." },
356 { "HTTPSProxy", "Force Tor to make all TLS (SSL) connectinos through this "
357 "host:port (or host:80 if port is not set)." },
358 { "HTTPSProxyAuthenticator", "A username:password pair to be used with "
359 "HTTPSProxy." },
360 { "KeepalivePeriod", "Send a padding cell every N seconds to keep firewalls "
361 "from closing our connections while Tor is not in use." },
362 { "Log", "Where to send logging messages. Format is "
363 "minSeverity[-maxSeverity] (stderr|stdout|syslog|file FILENAME)." },
364 { "OutboundBindAddress", "Make all outbound connections originate from the "
365 "provided IP address (only useful for multiple network interfaces)." },
366 { "PIDFile", "On startup, write our PID to this file. On clean shutdown, "
367 "remove the file." },
368 { "PreferTunneledDirConns", "If non-zero, avoid directory servers that "
369 "don't support tunneled conncetions." },
370 /* PreferTunneledDirConns */
371 /* ProtocolWarnings */
372 /* RephistTrackTime */
373 { "RunAsDaemon", "If set, Tor forks and daemonizes to the background when "
374 "started. Unix only." },
375 { "SafeLogging", "If set to 0, Tor logs potentially sensitive strings "
376 "rather than replacing them with the string [scrubbed]." },
377 { "TunnelDirConns", "If non-zero, when a directory server we contact "
378 "supports it, we will build a one-hop circuit and make an encrypted "
379 "connection via its ORPort." },
380 { "User", "On startup, setuid to this user" },
382 /* ==== client options */
383 { "AllowInvalidNodes", "Where on our circuits should Tor allow servers "
384 "that the directory authorities haven't called \"valid\"?" },
385 { "AllowNonRFC953Hostnames", "If set to 1, we don't automatically reject "
386 "hostnames for having invalid characters." },
387 /* CircuitBuildTimeout, CircuitIdleTimeout */
388 { "ClientOnly", "If set to 1, Tor will under no circumstances run as a "
389 "server, even if ORPort is enabled." },
390 { "EntryNodes", "A list of preferred entry nodes to use for the first hop "
391 "in circuits, when possible." },
392 /* { "EnforceDistinctSubnets" , "" }, */
393 { "ExitNodes", "A list of preferred nodes to use for the last hop in "
394 "circuits, when possible." },
395 { "ExcludeNodes", "A list of nodes never to use when building a circuit." },
396 { "FascistFirewall", "If set, Tor will only create outgoing connections to "
397 "servers running on the ports listed in FirewallPorts." },
398 { "FirewallPorts", "A list of ports that we can connect to. Only used "
399 "when FascistFirewall is set." },
400 { "LongLivedPorts", "A list of ports for services that tend to require "
401 "high-uptime connections." },
402 { "MapAddress", "Force Tor to treat all requests for one address as if "
403 "they were for another." },
404 { "NewCircuitPeriod", "Force Tor to consider whether to build a new circuit "
405 "every NUM seconds." },
406 { "MaxCircuitDirtiness", "Do not attach new streams to a circuit that has "
407 "been used more than this many seconds ago." },
408 /* NatdPort, NatdListenAddress */
409 { "NodeFamily", "A list of servers that constitute a 'family' and should "
410 "never be used in the same circuit." },
411 { "NumEntryGuards", "How many entry guards should we keep at a time?" },
412 /* PathlenCoinWeight */
413 { "ReachableAddresses", "Addresses we can connect to, as IP/bits:port-port. "
414 "By default, we assume all addresses are reachable." },
415 /* reachablediraddresses, reachableoraddresses. */
416 { "RendNodes", "A list of preferred nodes to use for a rendezvous point, "
417 "when possible." },
418 { "RendExcludenodes", "A list of nodes never to use as rendezvous points." },
419 /* SafeSOCKS */
420 { "SOCKSPort", "The port where we listen for SOCKS connections from "
421 "applications." },
422 { "SOCKSListenAddress", "Bind to this address to listen to connections from "
423 "SOCKS-speaking applications." },
424 { "SOCKSPolicy", "Set an entry policy to limit which addresses can connect "
425 "to the SOCKSPort." },
426 /* SocksTimeout */
427 { "StrictExitNodes", "If set, Tor will fail to operate when none of the "
428 "configured ExitNodes can be used." },
429 { "StrictEntryNodes", "If set, Tor will fail to operate when none of the "
430 "configured EntryNodes can be used." },
431 /* TestSocks */
432 { "TrackHostsExit", "Hosts and domains which should, if possible, be "
433 "accessed from the same exit node each time we connect to them." },
434 { "TrackHostsExitExpire", "Time after which we forget which exit we were "
435 "using to connect to hosts in TrackHostsExit." },
436 /* "TransPort", "TransListenAddress */
437 { "UseEntryGuards", "Set to 0 if we want to pick from the whole set of "
438 "servers for the first position in each circuit, rather than picking a "
439 "set of 'Guards' to prevent profiling attacks." },
441 /* === server options */
442 { "Address", "The advertised (external) address we should use." },
443 /* Accounting* options. */
444 /* AssumeReachable */
445 { "ContactInfo", "Administrative contact information to advertise for this "
446 "server." },
447 { "ExitPolicy", "Address/port ranges for which to accept or reject outgoing "
448 "connections on behalf of Tor users." },
449 /* { "ExitPolicyRejectPrivate, "" }, */
450 { "MaxAdvertisedBandwidth", "If set, we will not advertise more than this "
451 "amount of bandwidth for our bandwidth rate, regardless of how much "
452 "bandwidth we actually detect." },
453 { "MaxOnionsPending", "Reject new attempts to extend circuits when we "
454 "already have this many pending." },
455 { "MyFamily", "Declare a list of other servers as belonging to the same "
456 "family as this one, so that clients will not use two from the same "
457 "family in the same circuit." },
458 { "Nickname", "Set the server nickname." },
459 { "NoPublish", "{DEPRECATED}" },
460 { "NumCPUs", "How many processes to use at once for public-key crypto." },
461 { "ORPort", "Advertise this port to listen for connections from Tor clients "
462 "and servers." },
463 { "ORListenAddress", "Bind to this address to listen for connections from "
464 "clients and servers, instead of the default 0.0.0.0:ORPort." },
465 { "PublishServerDescriptors", "Set to \"\" to keep the server from "
466 "uploading info to the directory authorities." },
467 /*{ "RedirectExit", "When an outgoing connection tries to connect to a "
468 *"given address, redirect it to another address instead." },
470 /* ServerDNS: DetectHijacking, ResolvConfFile, SearchDomains */
471 { "ShutdownWaitLength", "Wait this long for clients to finish when "
472 "shutting down because of a SIGINT." },
473 /* { "TestVia", } */
475 /* === directory cache options */
476 { "DirPort", "Serve directory information from this port, and act as a "
477 "directory cache." },
478 { "DirListenAddress", "Bind to this address to listen for connections from "
479 "clients and servers, instead of the default 0.0.0.0:DirPort." },
480 { "DirPolicy", "Set a policy to limit who can connect to the directory "
481 "port" },
483 /* Authority options: AuthDirBadExit, AuthDirInvalid, AuthDirReject,
484 * AuthDirRejectUnlisted, AuthDirListBadExits, AuthoritativeDirectory,
485 * DirAllowPrivateAddresses, HSAuthoritativeDir,
486 * NamingAuthoritativeDirectory, RecommendedVersions,
487 * RecommendedClientVersions, RecommendedServerVersions, RendPostPeriod,
488 * RunTesting, V1AuthoritativeDirectory, VersioningAuthoritativeDirectory, */
490 /* Hidden service options: HiddenService: dir,excludenodes, nodes,
491 * options, port. PublishHidServDescriptor */
493 /* Nonpersistent options: __LeaveStreamsUnattached, __AllDirActionsPrivate */
494 { NULL, NULL },
497 static config_var_description_t state_description[] = {
498 { "AccountingBytesReadInInterval",
499 "How many bytes have we read in this accounting period?" },
500 { "AccountingBytesWrittenInInterval",
501 "How many bytes have we written in this accounting period?" },
502 { "AccountingExpectedUsage",
503 "How many bytes did we expect to use per minute? (0 for no estimate.)" },
504 { "AccountingIntervalStart", "When did this accounting period begin?" },
505 { "AccountingSecondsActive", "How long have we been awake in this period?" },
507 { "BWHistoryReadEnds", "When does the last-recorded read-interval end?" },
508 { "BWHistoryReadInterval", "How long is each read-interval (in seconds)?" },
509 { "BWHistoryReadValues", "Number of bytes read in each interval." },
510 { "BWHistoryWriteEnds", "When does the last-recorded write-interval end?" },
511 { "BWHistoryWriteInterval", "How long is each write-interval (in seconds)?"},
512 { "BWHistoryWriteValues", "Number of bytes written in each interval." },
514 { "EntryGuard", "One of the nodes we have chosen as a fixed entry" },
515 { "EntryGuardDownSince",
516 "The last entry guard has been unreachable since this time." },
517 { "EntryGuardUnlistedSince",
518 "The last entry guard has been unusable since this time." },
519 { "LastRotatedOnionKey",
520 "The last time at which we changed the medium-term private key used for "
521 "building circuits." },
522 { "LastWritten", "When was this state file last regenerated?" },
524 { "TorVersion", "Which version of Tor generated this state file?" },
525 { NULL, NULL },
528 /** Type of a callback to validate whether a given configuration is
529 * well-formed and consistent. See options_trial_assign() for documentation
530 * of arguments. */
531 typedef int (*validate_fn_t)(void*,void*,int,char**);
533 /** Information on the keys, value types, key-to-struct-member mappings,
534 * variable descriptions, validation functions, and abbreviations for a
535 * configuration or storage format. */
536 typedef struct {
537 size_t size; /**< Size of the struct that everything gets parsed into. */
538 uint32_t magic; /**< Required 'magic value' to make sure we have a struct
539 * of the right type. */
540 off_t magic_offset; /**< Offset of the magic value within the struct. */
541 config_abbrev_t *abbrevs; /**< List of abbreviations that we expand when
542 * parsing this format. */
543 config_var_t *vars; /**< List of variables we recognize, their default
544 * values, and where we stick them in the structure. */
545 validate_fn_t validate_fn; /**< Function to validate config. */
546 /** Documentation for configuration variables. */
547 config_var_description_t *descriptions;
548 /** If present, extra is a LINELIST variable for unrecognized
549 * lines. Otherwise, unrecognized lines are an error. */
550 config_var_t *extra;
551 } config_format_t;
553 /** Macro: assert that <b>cfg</b> has the right magic field for format
554 * <b>fmt</b>. */
555 #define CHECK(fmt, cfg) do { \
556 tor_assert(fmt && cfg); \
557 tor_assert((fmt)->magic == \
558 *(uint32_t*)STRUCT_VAR_P(cfg,fmt->magic_offset)); \
559 } while (0)
561 static void config_line_append(config_line_t **lst,
562 const char *key, const char *val);
563 static void option_clear(config_format_t *fmt, or_options_t *options,
564 config_var_t *var);
565 static void option_reset(config_format_t *fmt, or_options_t *options,
566 config_var_t *var, int use_defaults);
567 static void config_free(config_format_t *fmt, void *options);
568 static int option_is_same(config_format_t *fmt,
569 or_options_t *o1, or_options_t *o2,
570 const char *name);
571 static or_options_t *options_dup(config_format_t *fmt, or_options_t *old);
572 static int options_validate(or_options_t *old_options, or_options_t *options,
573 int from_setconf, char **msg);
574 static int options_act_reversible(or_options_t *old_options, char **msg);
575 static int options_act(or_options_t *old_options);
576 static int options_transition_allowed(or_options_t *old, or_options_t *new,
577 char **msg);
578 static int options_transition_affects_workers(or_options_t *old_options,
579 or_options_t *new_options);
580 static int options_transition_affects_descriptor(or_options_t *old_options,
581 or_options_t *new_options);
582 static int check_nickname_list(const char *lst, const char *name, char **msg);
583 static void config_register_addressmaps(or_options_t *options);
585 static int parse_bridge_line(const char *line, int validate_only);
586 static int parse_dir_server_line(const char *line, int validate_only);
587 static int parse_redirect_line(smartlist_t *result,
588 config_line_t *line, char **msg);
589 static int parse_log_severity_range(const char *range, int *min_out,
590 int *max_out);
591 static int validate_data_directory(or_options_t *options);
592 static int write_configuration_file(const char *fname, or_options_t *options);
593 static config_line_t *get_assigned_option(config_format_t *fmt,
594 or_options_t *options, const char *key);
595 static void config_init(config_format_t *fmt, void *options);
596 static int or_state_validate(or_state_t *old_options, or_state_t *options,
597 int from_setconf, char **msg);
599 static uint64_t config_parse_memunit(const char *s, int *ok);
600 static int config_parse_interval(const char *s, int *ok);
601 static void print_svn_version(void);
602 static void init_libevent(void);
603 static int opt_streq(const char *s1, const char *s2);
604 /** Versions of libevent. */
605 typedef enum {
606 /* Note: we compare these, so it's important that "old" precede everything,
607 * and that "other" come last. */
608 LE_OLD=0, LE_10C, LE_10D, LE_10E, LE_11, LE_11A, LE_11B, LE_12, LE_12A,
609 LE_13, LE_13A, LE_13B,
610 LE_OTHER
611 } le_version_t;
612 static le_version_t decode_libevent_version(void);
613 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
614 static void check_libevent_version(const char *m, int server);
615 #endif
617 /** Magic value for or_options_t. */
618 #define OR_OPTIONS_MAGIC 9090909
620 /** Configuration format for or_options_t. */
621 static config_format_t options_format = {
622 sizeof(or_options_t),
623 OR_OPTIONS_MAGIC,
624 STRUCT_OFFSET(or_options_t, _magic),
625 _option_abbrevs,
626 _option_vars,
627 (validate_fn_t)options_validate,
628 options_description,
629 NULL
632 /** Magic value for or_state_t. */
633 #define OR_STATE_MAGIC 0x57A73f57
635 /** "Extra" variable in the state that receives lines we can't parse. This
636 * lets us preserve options from versions of Tor newer than us. */
637 static config_var_t state_extra_var = {
638 "__extra", CONFIG_TYPE_LINELIST, STRUCT_OFFSET(or_state_t, ExtraLines), NULL
641 /** Configuration format for or_state_t. */
642 static config_format_t state_format = {
643 sizeof(or_state_t),
644 OR_STATE_MAGIC,
645 STRUCT_OFFSET(or_state_t, _magic),
646 _state_abbrevs,
647 _state_vars,
648 (validate_fn_t)or_state_validate,
649 state_description,
650 &state_extra_var,
654 * Functions to read and write the global options pointer.
657 /** Command-line and config-file options. */
658 static or_options_t *global_options = NULL;
659 /** Name of most recently read torrc file. */
660 static char *torrc_fname = NULL;
661 /** Persistent serialized state. */
662 static or_state_t *global_state = NULL;
664 /** Allocate an empty configuration object of a given format type. */
665 static void *
666 config_alloc(config_format_t *fmt)
668 void *opts = tor_malloc_zero(fmt->size);
669 *(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
670 CHECK(fmt, opts);
671 return opts;
674 /** Return the currently configured options. */
675 or_options_t *
676 get_options(void)
678 tor_assert(global_options);
679 return global_options;
682 /** Change the current global options to contain <b>new_val</b> instead of
683 * their current value; take action based on the new value; free the old value
684 * as necessary.
687 set_options(or_options_t *new_val, char **msg)
689 or_options_t *old_options = global_options;
690 global_options = new_val;
691 /* Note that we pass the *old* options below, for comparison. It
692 * pulls the new options directly out of global_options. */
693 if (options_act_reversible(old_options, msg)<0) {
694 tor_assert(*msg);
695 global_options = old_options;
696 return -1;
698 if (options_act(old_options) < 0) { /* acting on the options failed. die. */
699 log_err(LD_BUG,
700 "Acting on config options left us in a broken state. Dying.");
701 exit(1);
703 if (old_options)
704 config_free(&options_format, old_options);
706 return 0;
709 extern const char tor_svn_revision[]; /* from tor_main.c */
711 /** Return the current Tor version, possibly */
712 const char *
713 get_version(void)
715 static char *version = NULL;
716 if (version == NULL) {
717 if (strlen(tor_svn_revision)) {
718 size_t len = strlen(VERSION)+strlen(tor_svn_revision)+8;
719 version = tor_malloc(len);
720 tor_snprintf(version, len, "%s (r%s)", VERSION, tor_svn_revision);
721 } else {
722 version = tor_strdup(VERSION);
725 return version;
728 /** Release all memory and resources held by global configuration structures.
730 void
731 config_free_all(void)
733 if (global_options) {
734 config_free(&options_format, global_options);
735 global_options = NULL;
737 if (global_state) {
738 config_free(&state_format, global_state);
739 global_state = NULL;
741 tor_free(torrc_fname);
744 /** If options->SafeLogging is on, return a not very useful string,
745 * else return address.
747 const char *
748 safe_str(const char *address)
750 if (get_options()->SafeLogging)
751 return "[scrubbed]";
752 else
753 return address;
756 /** Equivalent to escaped(safe_str(address)). See reentrancy note on
757 * escaped(): don't use this outside the main thread, or twice in the same
758 * log statement. */
759 const char *
760 escaped_safe_str(const char *address)
762 if (get_options()->SafeLogging)
763 return "[scrubbed]";
764 else
765 return escaped(address);
768 /** Add the default directory servers directly into the trusted dir list. */
769 static void
770 add_default_trusted_dirservers(void)
772 int i;
773 const char *dirservers[] = {
774 /* eventually we should mark moria1 as "v1only" */
775 "moria1 v1 orport=9001 128.31.0.34:9031 "
776 "FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441",
777 "moria2 v1 orport=9002 128.31.0.34:9032 "
778 "719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF",
779 "tor26 v1 orport=443 86.59.21.38:80 "
780 "847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
781 "lefkada orport=443 140.247.60.64:80 "
782 "38D4 F5FC F7B1 0232 28B8 95EA 56ED E7D5 CCDC AF32",
783 "dizum 194.109.206.212:80 "
784 "7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
785 NULL
787 for (i=0; dirservers[i]; i++)
788 parse_dir_server_line(dirservers[i], 0);
791 /** Fetch the active option list, and take actions based on it. All of the
792 * things we do should survive being done repeatedly. If present,
793 * <b>old_options</b> contains the previous value of the options.
795 * Return 0 if all goes well, return -1 if things went badly.
797 static int
798 options_act_reversible(or_options_t *old_options, char **msg)
800 smartlist_t *new_listeners = smartlist_create();
801 smartlist_t *replaced_listeners = smartlist_create();
802 static int libevent_initialized = 0;
803 or_options_t *options = get_options();
804 int running_tor = options->command == CMD_RUN_TOR;
805 int set_conn_limit = 0;
806 int r = -1;
807 int logs_marked = 0;
809 /* Daemonize _first_, since we only want to open most of this stuff in
810 * the subprocess. */
811 if (running_tor && options->RunAsDaemon) {
812 /* No need to roll back, since you can't change the value. */
813 start_daemon();
816 #ifndef HAVE_SYS_UN_H
817 if (options->ControlSocket) {
818 *msg = tor_strdup("Unix domain sockets (ControlSocket) not supported"
819 " on this OS/with this build.");
820 goto rollback;
822 #endif
824 if (running_tor) {
825 /* We need to set the connection limit before we can open the listeners. */
826 options->_ConnLimit =
827 set_max_file_descriptors((unsigned)options->ConnLimit, MAXCONNECTIONS);
828 if (options->_ConnLimit < 0) {
829 *msg = tor_strdup("Problem with ConnLimit value. See logs for details.");
830 goto rollback;
832 set_conn_limit = 1;
834 /* Set up libevent. (We need to do this before we can register the
835 * listeners as listeners.) */
836 if (running_tor && !libevent_initialized) {
837 init_libevent();
838 libevent_initialized = 1;
841 /* Launch the listeners. (We do this before we setuid, so we can bind to
842 * ports under 1024.) */
843 if (retry_all_listeners(replaced_listeners, new_listeners) < 0) {
844 *msg = tor_strdup("Failed to bind one of the listener ports.");
845 goto rollback;
849 /* Setuid/setgid as appropriate */
850 if (options->User || options->Group) {
851 if (switch_id(options->User, options->Group) != 0) {
852 /* No need to roll back, since you can't change the value. */
853 *msg = tor_strdup("Problem with User or Group value. "
854 "See logs for details.");
855 goto done;
859 /* Ensure data directory is private; create if possible. */
860 if (check_private_dir(options->DataDirectory, CPD_CREATE)<0) {
861 char buf[1024];
862 int tmp = tor_snprintf(buf, sizeof(buf),
863 "Couldn't access/create private data directory \"%s\"",
864 options->DataDirectory);
865 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
866 goto done;
867 /* No need to roll back, since you can't change the value. */
870 /* Bail out at this point if we're not going to be a client or server:
871 * we don't run Tor itself. */
872 if (!running_tor)
873 goto commit;
875 mark_logs_temp(); /* Close current logs once new logs are open. */
876 logs_marked = 1;
877 if (options_init_logs(options, 0)<0) { /* Configure the log(s) */
878 *msg = tor_strdup("Failed to init Log options. See logs for details.");
879 goto rollback;
882 commit:
883 r = 0;
884 if (logs_marked) {
885 close_temp_logs();
886 add_callback_log(LOG_ERR, LOG_ERR, control_event_logmsg);
887 control_adjust_event_log_severity();
889 SMARTLIST_FOREACH(replaced_listeners, connection_t *, conn,
891 log_notice(LD_NET, "Closing old %s on %s:%d",
892 conn_type_to_string(conn->type), conn->address, conn->port);
893 connection_close_immediate(conn);
894 connection_mark_for_close(conn);
896 goto done;
898 rollback:
899 r = -1;
900 tor_assert(*msg);
902 if (logs_marked) {
903 rollback_log_changes();
904 control_adjust_event_log_severity();
907 if (set_conn_limit && old_options)
908 set_max_file_descriptors((unsigned)old_options->ConnLimit,MAXCONNECTIONS);
910 SMARTLIST_FOREACH(new_listeners, connection_t *, conn,
912 log_notice(LD_NET, "Closing partially-constructed listener %s on %s:%d",
913 conn_type_to_string(conn->type), conn->address, conn->port);
914 connection_close_immediate(conn);
915 connection_mark_for_close(conn);
918 done:
919 smartlist_free(new_listeners);
920 smartlist_free(replaced_listeners);
921 return r;
924 /** Fetch the active option list, and take actions based on it. All of the
925 * things we do should survive being done repeatedly. If present,
926 * <b>old_options</b> contains the previous value of the options.
928 * Return 0 if all goes well, return -1 if it's time to die.
930 * Note: We haven't moved all the "act on new configuration" logic
931 * here yet. Some is still in do_hup() and other places.
933 static int
934 options_act(or_options_t *old_options)
936 config_line_t *cl;
937 char *fn;
938 size_t len;
939 or_options_t *options = get_options();
940 int running_tor = options->command == CMD_RUN_TOR;
941 char *msg;
943 clear_trusted_dir_servers();
944 if (options->DirServers) {
945 for (cl = options->DirServers; cl; cl = cl->next) {
946 if (parse_dir_server_line(cl->value, 0)<0) {
947 log_warn(LD_BUG,
948 "Previously validated DirServer line could not be added!");
949 return -1;
952 } else {
953 add_default_trusted_dirservers();
956 clear_bridge_list();
957 if (options->Bridges) {
958 for (cl = options->Bridges; cl; cl = cl->next) {
959 if (parse_bridge_line(cl->value, 0)<0) {
960 log_warn(LD_BUG,
961 "Previously validated Bridge line could not be added!");
962 return -1;
967 if (running_tor && rend_config_services(options, 0)<0) {
968 log_warn(LD_BUG,
969 "Previously validated hidden services line could not be added!");
970 return -1;
973 if (running_tor) {
974 len = strlen(options->DataDirectory)+32;
975 fn = tor_malloc(len);
976 tor_snprintf(fn, len, "%s"PATH_SEPARATOR"cached-status",
977 options->DataDirectory);
978 if (check_private_dir(fn, CPD_CREATE) != 0) {
979 log_warn(LD_CONFIG,
980 "Couldn't access/create private data directory \"%s\"", fn);
981 tor_free(fn);
982 return -1;
984 tor_free(fn);
987 /* Load state */
988 if (! global_state)
989 if (or_state_load())
990 return -1;
992 /* Bail out at this point if we're not going to be a client or server:
993 * we want to not fork, and to log stuff to stderr. */
994 if (options->command != CMD_RUN_TOR)
995 return 0;
998 smartlist_t *sl = smartlist_create();
999 char *errmsg = NULL;
1000 for (cl = options->RedirectExit; cl; cl = cl->next) {
1001 if (parse_redirect_line(sl, cl, &errmsg)<0) {
1002 log_warn(LD_CONFIG, "%s", errmsg);
1003 tor_free(errmsg);
1004 return -1;
1007 set_exit_redirects(sl);
1010 /* Finish backgrounding the process */
1011 if (running_tor && options->RunAsDaemon) {
1012 /* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
1013 finish_daemon(options->DataDirectory);
1016 /* Write our pid to the pid file. If we do not have write permissions we
1017 * will log a warning */
1018 if (running_tor && options->PidFile)
1019 write_pidfile(options->PidFile);
1021 /* Register addressmap directives */
1022 config_register_addressmaps(options);
1023 parse_virtual_addr_network(options->VirtualAddrNetwork, 0, &msg);
1025 /* Update address policies. */
1026 policies_parse_from_options(options);
1028 init_cookie_authentication(options->CookieAuthentication);
1030 /* reload keys as needed for rendezvous services. */
1031 if (rend_service_load_keys()<0) {
1032 log_warn(LD_GENERAL,"Error loading rendezvous service keys");
1033 return -1;
1036 /* Set up accounting */
1037 if (accounting_parse_options(options, 0)<0) {
1038 log_warn(LD_CONFIG,"Error in accounting options");
1039 return -1;
1041 if (accounting_is_enabled(options))
1042 configure_accounting(time(NULL));
1044 if (!running_tor)
1045 return 0;
1047 /* Check for transitions that need action. */
1048 if (old_options) {
1049 if (options->UseEntryGuards && !old_options->UseEntryGuards) {
1050 log_info(LD_CIRC,
1051 "Switching to entry guards; abandoning previous circuits");
1052 circuit_mark_all_unused_circs();
1053 circuit_expire_all_dirty_circs();
1056 if (options_transition_affects_workers(old_options, options)) {
1057 log_info(LD_GENERAL,
1058 "Worker-related options changed. Rotating workers.");
1059 if (server_mode(options) && !server_mode(old_options)) {
1060 if (init_keys() < 0) {
1061 log_warn(LD_BUG,"Error initializing keys; exiting");
1062 return -1;
1064 ip_address_changed(0);
1065 if (has_completed_circuit || !any_predicted_circuits(time(NULL)))
1066 inform_testing_reachability();
1068 cpuworkers_rotate();
1069 if (dns_reset())
1070 return -1;
1071 } else {
1072 if (dns_reset())
1073 return -1;
1075 /* XXXX020 init_keys() again if v3authoritativedir is newly set. */
1078 /* Check if we need to parse and add the EntryNodes config option. */
1079 if (options->EntryNodes &&
1080 (!old_options ||
1081 !opt_streq(old_options->EntryNodes, options->EntryNodes)))
1082 entry_nodes_should_be_added();
1084 /* Since our options changed, we might need to regenerate and upload our
1085 * server descriptor.
1087 if (!old_options ||
1088 options_transition_affects_descriptor(old_options, options))
1089 mark_my_descriptor_dirty();
1091 return 0;
1095 * Functions to parse config options
1098 /** If <b>option</b> is an official abbreviation for a longer option,
1099 * return the longer option. Otherwise return <b>option</b>.
1100 * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
1101 * apply abbreviations that work for the config file and the command line.
1102 * If <b>warn_obsolete</b> is set, warn about deprecated names. */
1103 static const char *
1104 expand_abbrev(config_format_t *fmt, const char *option, int command_line,
1105 int warn_obsolete)
1107 int i;
1108 if (! fmt->abbrevs)
1109 return option;
1110 for (i=0; fmt->abbrevs[i].abbreviated; ++i) {
1111 /* Abbreviations are casei. */
1112 if (!strcasecmp(option,fmt->abbrevs[i].abbreviated) &&
1113 (command_line || !fmt->abbrevs[i].commandline_only)) {
1114 if (warn_obsolete && fmt->abbrevs[i].warn) {
1115 log_warn(LD_CONFIG,
1116 "The configuration option '%s' is deprecated; "
1117 "use '%s' instead.",
1118 fmt->abbrevs[i].abbreviated,
1119 fmt->abbrevs[i].full);
1121 return fmt->abbrevs[i].full;
1124 return option;
1127 /** Helper: Read a list of configuration options from the command line.
1128 * If successful, put them in *<b>result</b> and return 0, and return
1129 * -1 and leave *<b>result</b> alone. */
1130 static int
1131 config_get_commandlines(int argc, char **argv, config_line_t **result)
1133 config_line_t *front = NULL;
1134 config_line_t **new = &front;
1135 char *s;
1136 int i = 1;
1138 while (i < argc) {
1139 if (!strcmp(argv[i],"-f") ||
1140 !strcmp(argv[i],"--hash-password")) {
1141 i += 2; /* command-line option with argument. ignore them. */
1142 continue;
1143 } else if (!strcmp(argv[i],"--list-fingerprint") ||
1144 !strcmp(argv[i],"--verify-config") ||
1145 !strcmp(argv[i],"--ignore-missing-torrc")) {
1146 i += 1; /* command-line option. ignore it. */
1147 continue;
1148 } else if (!strcmp(argv[i],"--nt-service") ||
1149 !strcmp(argv[i],"-nt-service")) {
1150 i += 1;
1151 continue;
1153 if (i == argc-1) {
1154 log_warn(LD_CONFIG,"Command-line option '%s' with no value. Failing.",
1155 argv[i]);
1156 config_free_lines(front);
1157 return -1;
1160 *new = tor_malloc_zero(sizeof(config_line_t));
1161 s = argv[i];
1163 while (*s == '-')
1164 s++;
1166 (*new)->key = tor_strdup(expand_abbrev(&options_format, s, 1, 1));
1167 (*new)->value = tor_strdup(argv[i+1]);
1168 (*new)->next = NULL;
1169 log(LOG_DEBUG, LD_CONFIG, "Commandline: parsed keyword '%s', value '%s'",
1170 (*new)->key, (*new)->value);
1172 new = &((*new)->next);
1173 i += 2;
1175 *result = front;
1176 return 0;
1179 /** Helper: allocate a new configuration option mapping 'key' to 'val',
1180 * append it to *<b>lst</b>. */
1181 static void
1182 config_line_append(config_line_t **lst,
1183 const char *key,
1184 const char *val)
1186 config_line_t *newline;
1188 newline = tor_malloc(sizeof(config_line_t));
1189 newline->key = tor_strdup(key);
1190 newline->value = tor_strdup(val);
1191 newline->next = NULL;
1192 while (*lst)
1193 lst = &((*lst)->next);
1195 (*lst) = newline;
1198 /** Helper: parse the config string and strdup into key/value
1199 * strings. Set *result to the list, or NULL if parsing the string
1200 * failed. Return 0 on success, -1 on failure. Warn and ignore any
1201 * misformatted lines. Modifies the contents of <b>string</b>. */
1203 config_get_lines(char *string, config_line_t **result)
1205 config_line_t *list = NULL, **next;
1206 char *k, *v;
1208 next = &list;
1209 do {
1210 string = parse_line_from_str(string, &k, &v);
1211 if (!string) {
1212 config_free_lines(list);
1213 return -1;
1215 if (k && v) {
1216 /* This list can get long, so we keep a pointer to the end of it
1217 * rather than using config_line_append over and over and getting n^2
1218 * performance. This is the only really long list. */
1219 *next = tor_malloc(sizeof(config_line_t));
1220 (*next)->key = tor_strdup(k);
1221 (*next)->value = tor_strdup(v);
1222 (*next)->next = NULL;
1223 next = &((*next)->next);
1225 } while (*string);
1227 *result = list;
1228 return 0;
1232 * Free all the configuration lines on the linked list <b>front</b>.
1234 void
1235 config_free_lines(config_line_t *front)
1237 config_line_t *tmp;
1239 while (front) {
1240 tmp = front;
1241 front = tmp->next;
1243 tor_free(tmp->key);
1244 tor_free(tmp->value);
1245 tor_free(tmp);
1249 /** Return the description for a given configuration variable, or NULL if no
1250 * description exists. */
1251 static const char *
1252 config_find_description(config_format_t *fmt, const char *name)
1254 int i;
1255 for (i=0; fmt->descriptions[i].name; ++i) {
1256 if (!strcasecmp(name, fmt->descriptions[i].name))
1257 return fmt->descriptions[i].description;
1259 return NULL;
1262 /** If <b>key</b> is a configuration option, return the corresponding
1263 * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
1264 * warn, and return the corresponding config_var_t. Otherwise return NULL.
1266 static config_var_t *
1267 config_find_option(config_format_t *fmt, const char *key)
1269 int i;
1270 size_t keylen = strlen(key);
1271 if (!keylen)
1272 return NULL; /* if they say "--" on the commandline, it's not an option */
1273 /* First, check for an exact (case-insensitive) match */
1274 for (i=0; fmt->vars[i].name; ++i) {
1275 if (!strcasecmp(key, fmt->vars[i].name)) {
1276 return &fmt->vars[i];
1279 /* If none, check for an abbreviated match */
1280 for (i=0; fmt->vars[i].name; ++i) {
1281 if (!strncasecmp(key, fmt->vars[i].name, keylen)) {
1282 log_warn(LD_CONFIG, "The abbreviation '%s' is deprecated. "
1283 "Please use '%s' instead",
1284 key, fmt->vars[i].name);
1285 return &fmt->vars[i];
1288 /* Okay, unrecognized option */
1289 return NULL;
1293 * Functions to assign config options.
1296 /** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
1297 * with <b>c</b>-\>value and return 0, or return -1 if bad value.
1299 * Called from config_assign_line() and option_reset().
1301 static int
1302 config_assign_value(config_format_t *fmt, or_options_t *options,
1303 config_line_t *c, char **msg)
1305 int i, r, ok;
1306 char buf[1024];
1307 config_var_t *var;
1308 void *lvalue;
1310 CHECK(fmt, options);
1312 var = config_find_option(fmt, c->key);
1313 tor_assert(var);
1315 lvalue = STRUCT_VAR_P(options, var->var_offset);
1317 switch (var->type) {
1319 case CONFIG_TYPE_UINT:
1320 i = tor_parse_long(c->value, 10, 0, INT_MAX, &ok, NULL);
1321 if (!ok) {
1322 r = tor_snprintf(buf, sizeof(buf),
1323 "Int keyword '%s %s' is malformed or out of bounds.",
1324 c->key, c->value);
1325 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1326 return -1;
1328 *(int *)lvalue = i;
1329 break;
1331 case CONFIG_TYPE_INTERVAL: {
1332 i = config_parse_interval(c->value, &ok);
1333 if (!ok) {
1334 r = tor_snprintf(buf, sizeof(buf),
1335 "Interval '%s %s' is malformed or out of bounds.",
1336 c->key, c->value);
1337 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1338 return -1;
1340 *(int *)lvalue = i;
1341 break;
1344 case CONFIG_TYPE_MEMUNIT: {
1345 uint64_t u64 = config_parse_memunit(c->value, &ok);
1346 if (!ok) {
1347 r = tor_snprintf(buf, sizeof(buf),
1348 "Value '%s %s' is malformed or out of bounds.",
1349 c->key, c->value);
1350 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1351 return -1;
1353 *(uint64_t *)lvalue = u64;
1354 break;
1357 case CONFIG_TYPE_BOOL:
1358 i = tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
1359 if (!ok) {
1360 r = tor_snprintf(buf, sizeof(buf),
1361 "Boolean '%s %s' expects 0 or 1.",
1362 c->key, c->value);
1363 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1364 return -1;
1366 *(int *)lvalue = i;
1367 break;
1369 case CONFIG_TYPE_STRING:
1370 tor_free(*(char **)lvalue);
1371 *(char **)lvalue = tor_strdup(c->value);
1372 break;
1374 case CONFIG_TYPE_DOUBLE:
1375 *(double *)lvalue = atof(c->value);
1376 break;
1378 case CONFIG_TYPE_ISOTIME:
1379 if (parse_iso_time(c->value, (time_t *)lvalue)) {
1380 r = tor_snprintf(buf, sizeof(buf),
1381 "Invalid time '%s' for keyword '%s'", c->value, c->key);
1382 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1383 return -1;
1385 break;
1387 case CONFIG_TYPE_CSV:
1388 if (*(smartlist_t**)lvalue) {
1389 SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
1390 smartlist_clear(*(smartlist_t**)lvalue);
1391 } else {
1392 *(smartlist_t**)lvalue = smartlist_create();
1395 smartlist_split_string(*(smartlist_t**)lvalue, c->value, ",",
1396 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1397 break;
1399 case CONFIG_TYPE_LINELIST:
1400 case CONFIG_TYPE_LINELIST_S:
1401 config_line_append((config_line_t**)lvalue, c->key, c->value);
1402 break;
1404 case CONFIG_TYPE_OBSOLETE:
1405 log_warn(LD_CONFIG, "Skipping obsolete configuration option '%s'", c->key);
1406 break;
1407 case CONFIG_TYPE_LINELIST_V:
1408 r = tor_snprintf(buf, sizeof(buf),
1409 "You may not provide a value for virtual option '%s'", c->key);
1410 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1411 return -1;
1412 default:
1413 tor_assert(0);
1414 break;
1416 return 0;
1419 /** If <b>c</b> is a syntactically valid configuration line, update
1420 * <b>options</b> with its value and return 0. Otherwise return -1 for bad
1421 * key, -2 for bad value.
1423 * If <b>clear_first</b> is set, clear the value first. Then if
1424 * <b>use_defaults</b> is set, set the value to the default.
1426 * Called from config_assign().
1428 static int
1429 config_assign_line(config_format_t *fmt, or_options_t *options,
1430 config_line_t *c, int use_defaults,
1431 int clear_first, char **msg)
1433 config_var_t *var;
1435 CHECK(fmt, options);
1437 var = config_find_option(fmt, c->key);
1438 if (!var) {
1439 if (fmt->extra) {
1440 void *lvalue = STRUCT_VAR_P(options, fmt->extra->var_offset);
1441 log_info(LD_CONFIG,
1442 "Found unrecognized option '%s'; saving it.", c->key);
1443 config_line_append((config_line_t**)lvalue, c->key, c->value);
1444 return 0;
1445 } else {
1446 char buf[1024];
1447 int tmp = tor_snprintf(buf, sizeof(buf),
1448 "Unknown option '%s'. Failing.", c->key);
1449 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
1450 return -1;
1453 /* Put keyword into canonical case. */
1454 if (strcmp(var->name, c->key)) {
1455 tor_free(c->key);
1456 c->key = tor_strdup(var->name);
1459 if (!strlen(c->value)) {
1460 /* reset or clear it, then return */
1461 if (!clear_first) {
1462 if (var->type == CONFIG_TYPE_LINELIST ||
1463 var->type == CONFIG_TYPE_LINELIST_S) {
1464 /* We got an empty linelist from the torrc or commandline.
1465 As a special case, call this an error. Warn and ignore. */
1466 log_warn(LD_CONFIG,
1467 "Linelist option '%s' has no value. Skipping.", c->key);
1468 } else { /* not already cleared */
1469 option_reset(fmt, options, var, use_defaults);
1472 return 0;
1475 if (config_assign_value(fmt, options, c, msg) < 0)
1476 return -2;
1477 return 0;
1480 /** Restore the option named <b>key</b> in options to its default value.
1481 * Called from config_assign(). */
1482 static void
1483 config_reset_line(config_format_t *fmt, or_options_t *options,
1484 const char *key, int use_defaults)
1486 config_var_t *var;
1488 CHECK(fmt, options);
1490 var = config_find_option(fmt, key);
1491 if (!var)
1492 return; /* give error on next pass. */
1494 option_reset(fmt, options, var, use_defaults);
1497 /** Return true iff key is a valid configuration option. */
1499 option_is_recognized(const char *key)
1501 config_var_t *var = config_find_option(&options_format, key);
1502 return (var != NULL);
1505 /** Return the canonical name of a configuration option. */
1506 const char *
1507 option_get_canonical_name(const char *key)
1509 config_var_t *var = config_find_option(&options_format, key);
1510 return var->name;
1513 /** Return a canonicalized list of the options assigned for key.
1515 config_line_t *
1516 option_get_assignment(or_options_t *options, const char *key)
1518 return get_assigned_option(&options_format, options, key);
1521 /** Return a newly allocated deep copy of the lines in <b>inp</b>. */
1522 static config_line_t *
1523 config_lines_dup(const config_line_t *inp)
1525 config_line_t *result = NULL;
1526 config_line_t **next_out = &result;
1527 while (inp) {
1528 *next_out = tor_malloc(sizeof(config_line_t));
1529 (*next_out)->key = tor_strdup(inp->key);
1530 (*next_out)->value = tor_strdup(inp->value);
1531 inp = inp->next;
1532 next_out = &((*next_out)->next);
1534 (*next_out) = NULL;
1535 return result;
1538 /** Return newly allocated line or lines corresponding to <b>key</b> in the
1539 * configuration <b>options</b>. Return NULL if no such key exists. */
1540 static config_line_t *
1541 get_assigned_option(config_format_t *fmt, or_options_t *options,
1542 const char *key)
1543 /* XXXX argument is options, but fmt is provided. Inconsistent. */
1545 config_var_t *var;
1546 const void *value;
1547 char buf[32];
1548 config_line_t *result;
1549 tor_assert(options && key);
1551 CHECK(fmt, options);
1553 var = config_find_option(fmt, key);
1554 if (!var) {
1555 log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key);
1556 return NULL;
1558 value = STRUCT_VAR_P(options, var->var_offset);
1560 result = tor_malloc_zero(sizeof(config_line_t));
1561 result->key = tor_strdup(var->name);
1562 switch (var->type)
1564 case CONFIG_TYPE_STRING:
1565 if (*(char**)value) {
1566 result->value = tor_strdup(*(char**)value);
1567 } else {
1568 tor_free(result->key);
1569 tor_free(result);
1570 return NULL;
1572 break;
1573 case CONFIG_TYPE_ISOTIME:
1574 if (*(time_t*)value) {
1575 result->value = tor_malloc(ISO_TIME_LEN+1);
1576 format_iso_time(result->value, *(time_t*)value);
1577 } else {
1578 tor_free(result->key);
1579 tor_free(result);
1581 break;
1582 case CONFIG_TYPE_INTERVAL:
1583 case CONFIG_TYPE_UINT:
1584 /* This means every or_options_t uint or bool element
1585 * needs to be an int. Not, say, a uint16_t or char. */
1586 tor_snprintf(buf, sizeof(buf), "%d", *(int*)value);
1587 result->value = tor_strdup(buf);
1588 break;
1589 case CONFIG_TYPE_MEMUNIT:
1590 tor_snprintf(buf, sizeof(buf), U64_FORMAT,
1591 U64_PRINTF_ARG(*(uint64_t*)value));
1592 result->value = tor_strdup(buf);
1593 break;
1594 case CONFIG_TYPE_DOUBLE:
1595 tor_snprintf(buf, sizeof(buf), "%f", *(double*)value);
1596 result->value = tor_strdup(buf);
1597 break;
1598 case CONFIG_TYPE_BOOL:
1599 result->value = tor_strdup(*(int*)value ? "1" : "0");
1600 break;
1601 case CONFIG_TYPE_CSV:
1602 if (*(smartlist_t**)value)
1603 result->value =
1604 smartlist_join_strings(*(smartlist_t**)value, ",", 0, NULL);
1605 else
1606 result->value = tor_strdup("");
1607 break;
1608 case CONFIG_TYPE_OBSOLETE:
1609 log_warn(LD_CONFIG,
1610 "You asked me for the value of an obsolete config option '%s'.",
1611 key);
1612 tor_free(result->key);
1613 tor_free(result);
1614 return NULL;
1615 case CONFIG_TYPE_LINELIST_S:
1616 log_warn(LD_CONFIG,
1617 "Can't return context-sensitive '%s' on its own", key);
1618 tor_free(result->key);
1619 tor_free(result);
1620 return NULL;
1621 case CONFIG_TYPE_LINELIST:
1622 case CONFIG_TYPE_LINELIST_V:
1623 tor_free(result->key);
1624 tor_free(result);
1625 return config_lines_dup(*(const config_line_t**)value);
1626 default:
1627 tor_free(result->key);
1628 tor_free(result);
1629 log_warn(LD_BUG,"Unknown type %d for known key '%s'",
1630 var->type, key);
1631 return NULL;
1634 return result;
1637 /** Iterate through the linked list of requested options <b>list</b>.
1638 * For each item, convert as appropriate and assign to <b>options</b>.
1639 * If an item is unrecognized, set *msg and return -1 immediately,
1640 * else return 0 for success.
1642 * If <b>clear_first</b>, interpret config options as replacing (not
1643 * extending) their previous values. If <b>clear_first</b> is set,
1644 * then <b>use_defaults</b> to decide if you set to defaults after
1645 * clearing, or make the value 0 or NULL.
1647 * Here are the use cases:
1648 * 1. A non-empty AllowInvalid line in your torrc. Appends to current
1649 * if linelist, replaces current if csv.
1650 * 2. An empty AllowInvalid line in your torrc. Should clear it.
1651 * 3. "RESETCONF AllowInvalid" sets it to default.
1652 * 4. "SETCONF AllowInvalid" makes it NULL.
1653 * 5. "SETCONF AllowInvalid=foo" clears it and sets it to "foo".
1655 * Use_defaults Clear_first
1656 * 0 0 "append"
1657 * 1 0 undefined, don't use
1658 * 0 1 "set to null first"
1659 * 1 1 "set to defaults first"
1660 * Return 0 on success, -1 on bad key, -2 on bad value.
1662 * As an additional special case, if a LINELIST config option has
1663 * no value and clear_first is 0, then warn and ignore it.
1667 There are three call cases for config_assign() currently.
1669 Case one: Torrc entry
1670 options_init_from_torrc() calls config_assign(0, 0)
1671 calls config_assign_line(0, 0).
1672 if value is empty, calls option_reset(0) and returns.
1673 calls config_assign_value(), appends.
1675 Case two: setconf
1676 options_trial_assign() calls config_assign(0, 1)
1677 calls config_reset_line(0)
1678 calls option_reset(0)
1679 calls option_clear().
1680 calls config_assign_line(0, 1).
1681 if value is empty, returns.
1682 calls config_assign_value(), appends.
1684 Case three: resetconf
1685 options_trial_assign() calls config_assign(1, 1)
1686 calls config_reset_line(1)
1687 calls option_reset(1)
1688 calls option_clear().
1689 calls config_assign_value(default)
1690 calls config_assign_line(1, 1).
1691 returns.
1693 static int
1694 config_assign(config_format_t *fmt, void *options, config_line_t *list,
1695 int use_defaults, int clear_first, char **msg)
1697 config_line_t *p;
1699 CHECK(fmt, options);
1701 /* pass 1: normalize keys */
1702 for (p = list; p; p = p->next) {
1703 const char *full = expand_abbrev(fmt, p->key, 0, 1);
1704 if (strcmp(full,p->key)) {
1705 tor_free(p->key);
1706 p->key = tor_strdup(full);
1710 /* pass 2: if we're reading from a resetting source, clear all
1711 * mentioned config options, and maybe set to their defaults. */
1712 if (clear_first) {
1713 for (p = list; p; p = p->next)
1714 config_reset_line(fmt, options, p->key, use_defaults);
1717 /* pass 3: assign. */
1718 while (list) {
1719 int r;
1720 if ((r=config_assign_line(fmt, options, list, use_defaults,
1721 clear_first, msg)))
1722 return r;
1723 list = list->next;
1725 return 0;
1728 /** Try assigning <b>list</b> to the global options. You do this by duping
1729 * options, assigning list to the new one, then validating it. If it's
1730 * ok, then throw out the old one and stick with the new one. Else,
1731 * revert to old and return failure. Return 0 on success, -1 on bad
1732 * keys, -2 on bad values, -3 on bad transition, and -4 on failed-to-set.
1734 * If not success, point *<b>msg</b> to a newly allocated string describing
1735 * what went wrong.
1738 options_trial_assign(config_line_t *list, int use_defaults,
1739 int clear_first, char **msg)
1741 int r;
1742 or_options_t *trial_options = options_dup(&options_format, get_options());
1744 if ((r=config_assign(&options_format, trial_options,
1745 list, use_defaults, clear_first, msg)) < 0) {
1746 config_free(&options_format, trial_options);
1747 return r;
1750 if (options_validate(get_options(), trial_options, 1, msg) < 0) {
1751 config_free(&options_format, trial_options);
1752 return -2;
1755 if (options_transition_allowed(get_options(), trial_options, msg) < 0) {
1756 config_free(&options_format, trial_options);
1757 return -3;
1760 if (set_options(trial_options, msg)<0) {
1761 config_free(&options_format, trial_options);
1762 return -4;
1765 /* we liked it. put it in place. */
1766 return 0;
1769 /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
1770 * Called from option_reset() and config_free(). */
1771 static void
1772 option_clear(config_format_t *fmt, or_options_t *options, config_var_t *var)
1774 void *lvalue = STRUCT_VAR_P(options, var->var_offset);
1775 (void)fmt; /* unused */
1776 switch (var->type) {
1777 case CONFIG_TYPE_STRING:
1778 tor_free(*(char**)lvalue);
1779 break;
1780 case CONFIG_TYPE_DOUBLE:
1781 *(double*)lvalue = 0.0;
1782 break;
1783 case CONFIG_TYPE_ISOTIME:
1784 *(time_t*)lvalue = 0;
1785 case CONFIG_TYPE_INTERVAL:
1786 case CONFIG_TYPE_UINT:
1787 case CONFIG_TYPE_BOOL:
1788 *(int*)lvalue = 0;
1789 break;
1790 case CONFIG_TYPE_MEMUNIT:
1791 *(uint64_t*)lvalue = 0;
1792 break;
1793 case CONFIG_TYPE_CSV:
1794 if (*(smartlist_t**)lvalue) {
1795 SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
1796 smartlist_free(*(smartlist_t **)lvalue);
1797 *(smartlist_t **)lvalue = NULL;
1799 break;
1800 case CONFIG_TYPE_LINELIST:
1801 case CONFIG_TYPE_LINELIST_S:
1802 config_free_lines(*(config_line_t **)lvalue);
1803 *(config_line_t **)lvalue = NULL;
1804 break;
1805 case CONFIG_TYPE_LINELIST_V:
1806 /* handled by linelist_s. */
1807 break;
1808 case CONFIG_TYPE_OBSOLETE:
1809 break;
1813 /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
1814 * <b>use_defaults</b>, set it to its default value.
1815 * Called by config_init() and option_reset_line() and option_assign_line(). */
1816 static void
1817 option_reset(config_format_t *fmt, or_options_t *options,
1818 config_var_t *var, int use_defaults)
1820 config_line_t *c;
1821 char *msg = NULL;
1822 CHECK(fmt, options);
1823 option_clear(fmt, options, var); /* clear it first */
1824 if (!use_defaults)
1825 return; /* all done */
1826 if (var->initvalue) {
1827 c = tor_malloc_zero(sizeof(config_line_t));
1828 c->key = tor_strdup(var->name);
1829 c->value = tor_strdup(var->initvalue);
1830 if (config_assign_value(fmt, options, c, &msg) < 0) {
1831 log_warn(LD_BUG, "Failed to assign default: %s", msg);
1832 tor_free(msg); /* if this happens it's a bug */
1834 config_free_lines(c);
1838 /** Print a usage message for tor. */
1839 static void
1840 print_usage(void)
1842 printf(
1843 "Copyright 2001-2007 Roger Dingledine, Nick Mathewson.\n\n"
1844 "tor -f <torrc> [args]\n"
1845 "See man page for options, or http://tor.eff.org/ for documentation.\n");
1848 /** Print all non-obsolete torrc options. */
1849 static void
1850 list_torrc_options(void)
1852 int i;
1853 smartlist_t *lines = smartlist_create();
1854 for (i = 0; _option_vars[i].name; ++i) {
1855 config_var_t *var = &_option_vars[i];
1856 const char *desc;
1857 if (var->type == CONFIG_TYPE_OBSOLETE ||
1858 var->type == CONFIG_TYPE_LINELIST_V)
1859 continue;
1860 desc = config_find_description(&options_format, var->name);
1861 printf("%s\n", var->name);
1862 if (desc) {
1863 wrap_string(lines, desc, 76, " ", " ");
1864 SMARTLIST_FOREACH(lines, char *, cp, {
1865 printf("%s", cp);
1866 tor_free(cp);
1868 smartlist_clear(lines);
1873 /** Last value actually set by resolve_my_address. */
1874 static uint32_t last_resolved_addr = 0;
1876 * Based on <b>options-\>Address</b>, guess our public IP address and put it
1877 * (in host order) into *<b>addr_out</b>. If <b>hostname_out</b> is provided,
1878 * set *<b>hostname_out</b> to a new string holding the hostname we used to
1879 * get the address. Return 0 if all is well, or -1 if we can't find a suitable
1880 * public IP address.
1883 resolve_my_address(int warn_severity, or_options_t *options,
1884 uint32_t *addr_out, char **hostname_out)
1886 struct in_addr in;
1887 struct hostent *rent;
1888 char hostname[256];
1889 int explicit_ip=1;
1890 int explicit_hostname=1;
1891 int from_interface=0;
1892 char tmpbuf[INET_NTOA_BUF_LEN];
1893 const char *address = options->Address;
1894 int notice_severity = warn_severity <= LOG_NOTICE ?
1895 LOG_NOTICE : warn_severity;
1897 tor_assert(addr_out);
1899 if (address && *address) {
1900 strlcpy(hostname, address, sizeof(hostname));
1901 } else { /* then we need to guess our address */
1902 explicit_ip = 0; /* it's implicit */
1903 explicit_hostname = 0; /* it's implicit */
1905 if (gethostname(hostname, sizeof(hostname)) < 0) {
1906 log_fn(warn_severity, LD_NET,"Error obtaining local hostname");
1907 return -1;
1909 log_debug(LD_CONFIG,"Guessed local host name as '%s'",hostname);
1912 /* now we know hostname. resolve it and keep only the IP address */
1914 if (tor_inet_aton(hostname, &in) == 0) {
1915 /* then we have to resolve it */
1916 explicit_ip = 0;
1917 rent = (struct hostent *)gethostbyname(hostname);
1918 if (!rent) {
1919 uint32_t interface_ip;
1921 if (explicit_hostname) {
1922 log_fn(warn_severity, LD_CONFIG,
1923 "Could not resolve local Address '%s'. Failing.", hostname);
1924 return -1;
1926 log_fn(notice_severity, LD_CONFIG,
1927 "Could not resolve guessed local hostname '%s'. "
1928 "Trying something else.", hostname);
1929 if (get_interface_address(warn_severity, &interface_ip)) {
1930 log_fn(warn_severity, LD_CONFIG,
1931 "Could not get local interface IP address. Failing.");
1932 return -1;
1934 from_interface = 1;
1935 in.s_addr = htonl(interface_ip);
1936 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
1937 log_fn(notice_severity, LD_CONFIG, "Learned IP address '%s' for "
1938 "local interface. Using that.", tmpbuf);
1939 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
1940 } else {
1941 tor_assert(rent->h_length == 4);
1942 memcpy(&in.s_addr, rent->h_addr, rent->h_length);
1944 if (!explicit_hostname &&
1945 is_internal_IP(ntohl(in.s_addr), 0)) {
1946 uint32_t interface_ip;
1948 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
1949 log_fn(notice_severity, LD_CONFIG, "Guessed local hostname '%s' "
1950 "resolves to a private IP address (%s). Trying something "
1951 "else.", hostname, tmpbuf);
1953 if (get_interface_address(warn_severity, &interface_ip)) {
1954 log_fn(warn_severity, LD_CONFIG,
1955 "Could not get local interface IP address. Too bad.");
1956 } else if (is_internal_IP(interface_ip, 0)) {
1957 struct in_addr in2;
1958 in2.s_addr = htonl(interface_ip);
1959 tor_inet_ntoa(&in2,tmpbuf,sizeof(tmpbuf));
1960 log_fn(notice_severity, LD_CONFIG,
1961 "Interface IP address '%s' is a private address too. "
1962 "Ignoring.", tmpbuf);
1963 } else {
1964 from_interface = 1;
1965 in.s_addr = htonl(interface_ip);
1966 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
1967 log_fn(notice_severity, LD_CONFIG,
1968 "Learned IP address '%s' for local interface."
1969 " Using that.", tmpbuf);
1970 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
1976 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
1977 if (is_internal_IP(ntohl(in.s_addr), 0) &&
1978 options->_PublishServerDescriptor) {
1979 /* make sure we're ok with publishing an internal IP */
1980 if (!options->DirServers) {
1981 /* if they are using the default dirservers, disallow internal IPs
1982 * always. */
1983 log_fn(warn_severity, LD_CONFIG,
1984 "Address '%s' resolves to private IP address '%s'. "
1985 "Tor servers that use the default DirServers must have public "
1986 "IP addresses.", hostname, tmpbuf);
1987 return -1;
1989 if (!explicit_ip) {
1990 /* even if they've set their own dirservers, require an explicit IP if
1991 * they're using an internal address. */
1992 log_fn(warn_severity, LD_CONFIG, "Address '%s' resolves to private "
1993 "IP address '%s'. Please set the Address config option to be "
1994 "the IP address you want to use.", hostname, tmpbuf);
1995 return -1;
1999 log_debug(LD_CONFIG, "Resolved Address to '%s'.", tmpbuf);
2000 *addr_out = ntohl(in.s_addr);
2001 if (last_resolved_addr && last_resolved_addr != *addr_out) {
2002 /* Leave this as a notice, regardless of the requested severity,
2003 * at least until dynamic IP address support becomes bulletproof. */
2004 log_notice(LD_NET, "Your IP address seems to have changed. Updating.");
2005 ip_address_changed(0);
2007 if (last_resolved_addr != *addr_out) {
2008 const char *method;
2009 const char *h = hostname;
2010 if (explicit_ip) {
2011 method = "CONFIGURED";
2012 h = NULL;
2013 } else if (explicit_hostname) {
2014 method = "RESOLVED";
2015 } else if (from_interface) {
2016 method = "INTERFACE";
2017 h = NULL;
2018 } else {
2019 method = "GETHOSTNAME";
2021 control_event_server_status(LOG_NOTICE,
2022 "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s %s%s",
2023 tmpbuf, method, h?"HOSTNAME=":"", h);
2025 last_resolved_addr = *addr_out;
2026 if (hostname_out)
2027 *hostname_out = tor_strdup(hostname);
2028 return 0;
2031 /** Return true iff <b>ip</b> (in host order) is judged to be on the
2032 * same network as us, or on a private network.
2035 is_local_IP(uint32_t ip)
2037 if (is_internal_IP(ip, 0))
2038 return 1;
2039 /* Check whether ip is on the same /24 as we are. */
2040 if (get_options()->EnforceDistinctSubnets == 0)
2041 return 0;
2042 /* It's possible that this next check will hit before the first time
2043 * resolve_my_address actually succeeds. (For clients, it is likely that
2044 * resolve_my_address will never be called at all). In those cases,
2045 * last_resolved_addr will be 0, and so checking to see whether ip is on the
2046 * same /24 as last_resolved_addr will be the same as checking whether it
2047 * was on net 0, which is already done by is_internal_IP.
2049 if ((last_resolved_addr & 0xffffff00ul) == (ip & 0xffffff00ul))
2050 return 1;
2051 return 0;
2054 /** Called when we don't have a nickname set. Try to guess a good nickname
2055 * based on the hostname, and return it in a newly allocated string. If we
2056 * can't, return NULL and let the caller warn if it wants to. */
2057 static char *
2058 get_default_nickname(void)
2060 static const char * const bad_default_nicknames[] = {
2061 "localhost",
2062 NULL,
2064 char localhostname[256];
2065 char *cp, *out, *outp;
2066 int i;
2068 if (gethostname(localhostname, sizeof(localhostname)) < 0)
2069 return NULL;
2071 /* Put it in lowercase; stop at the first dot. */
2072 if ((cp = strchr(localhostname, '.')))
2073 *cp = '\0';
2074 tor_strlower(localhostname);
2076 /* Strip invalid characters. */
2077 cp = localhostname;
2078 out = outp = tor_malloc(strlen(localhostname) + 1);
2079 while (*cp) {
2080 if (strchr(LEGAL_NICKNAME_CHARACTERS, *cp))
2081 *outp++ = *cp++;
2082 else
2083 cp++;
2085 *outp = '\0';
2087 /* Enforce length. */
2088 if (strlen(out) > MAX_NICKNAME_LEN)
2089 out[MAX_NICKNAME_LEN]='\0';
2091 /* Check for dumb names. */
2092 for (i = 0; bad_default_nicknames[i]; ++i) {
2093 if (!strcmp(out, bad_default_nicknames[i])) {
2094 tor_free(out);
2095 return NULL;
2099 return out;
2102 /** Release storage held by <b>options</b>. */
2103 static void
2104 config_free(config_format_t *fmt, void *options)
2106 int i;
2108 tor_assert(options);
2110 for (i=0; fmt->vars[i].name; ++i)
2111 option_clear(fmt, options, &(fmt->vars[i]));
2112 if (fmt->extra) {
2113 config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->var_offset);
2114 config_free_lines(*linep);
2115 *linep = NULL;
2117 tor_free(options);
2120 /** Return true iff a and b contain identical keys and values in identical
2121 * order. */
2122 static int
2123 config_lines_eq(config_line_t *a, config_line_t *b)
2125 while (a && b) {
2126 if (strcasecmp(a->key, b->key) || strcmp(a->value, b->value))
2127 return 0;
2128 a = a->next;
2129 b = b->next;
2131 if (a || b)
2132 return 0;
2133 return 1;
2136 /** Return true iff the option <b>var</b> has the same value in <b>o1</b>
2137 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
2139 static int
2140 option_is_same(config_format_t *fmt,
2141 or_options_t *o1, or_options_t *o2, const char *name)
2143 config_line_t *c1, *c2;
2144 int r = 1;
2145 CHECK(fmt, o1);
2146 CHECK(fmt, o2);
2148 c1 = get_assigned_option(fmt, o1, name);
2149 c2 = get_assigned_option(fmt, o2, name);
2150 r = config_lines_eq(c1, c2);
2151 config_free_lines(c1);
2152 config_free_lines(c2);
2153 return r;
2156 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
2157 static or_options_t *
2158 options_dup(config_format_t *fmt, or_options_t *old)
2160 or_options_t *newopts;
2161 int i;
2162 config_line_t *line;
2164 newopts = config_alloc(fmt);
2165 for (i=0; fmt->vars[i].name; ++i) {
2166 if (fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2167 continue;
2168 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE)
2169 continue;
2170 line = get_assigned_option(fmt, old, fmt->vars[i].name);
2171 if (line) {
2172 char *msg = NULL;
2173 if (config_assign(fmt, newopts, line, 0, 0, &msg) < 0) {
2174 log_err(LD_BUG, "Config_get_assigned_option() generated "
2175 "something we couldn't config_assign(): %s", msg);
2176 tor_free(msg);
2177 tor_assert(0);
2180 config_free_lines(line);
2182 return newopts;
2185 /** Return a new empty or_options_t. Used for testing. */
2186 or_options_t *
2187 options_new(void)
2189 return config_alloc(&options_format);
2192 /** Set <b>options</b> to hold reasonable defaults for most options.
2193 * Each option defaults to zero. */
2194 void
2195 options_init(or_options_t *options)
2197 config_init(&options_format, options);
2200 /* Set all vars in the configuration object 'options' to their default
2201 * values. */
2202 static void
2203 config_init(config_format_t *fmt, void *options)
2205 int i;
2206 config_var_t *var;
2207 CHECK(fmt, options);
2209 for (i=0; fmt->vars[i].name; ++i) {
2210 var = &fmt->vars[i];
2211 if (!var->initvalue)
2212 continue; /* defaults to NULL or 0 */
2213 option_reset(fmt, options, var, 1);
2217 /** Allocate and return a new string holding the written-out values of the vars
2218 * in 'options'. If 'minimal', do not write out any default-valued vars.
2219 * Else, if comment_defaults, write default values as comments.
2221 static char *
2222 config_dump(config_format_t *fmt, void *options, int minimal,
2223 int comment_defaults)
2225 smartlist_t *elements;
2226 or_options_t *defaults;
2227 config_line_t *line, *assigned;
2228 char *result;
2229 int i;
2230 const char *desc;
2231 char *msg = NULL;
2233 defaults = config_alloc(fmt);
2234 config_init(fmt, defaults);
2236 /* XXX use a 1 here so we don't add a new log line while dumping */
2237 if (fmt->validate_fn(NULL,defaults, 1, &msg) < 0) {
2238 log_err(LD_BUG, "Failed to validate default config.");
2239 tor_free(msg);
2240 tor_assert(0);
2243 elements = smartlist_create();
2244 for (i=0; fmt->vars[i].name; ++i) {
2245 int comment_option = 0;
2246 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE ||
2247 fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2248 continue;
2249 /* Don't save 'hidden' control variables. */
2250 if (!strcmpstart(fmt->vars[i].name, "__"))
2251 continue;
2252 if (minimal && option_is_same(fmt, options, defaults, fmt->vars[i].name))
2253 continue;
2254 else if (comment_defaults &&
2255 option_is_same(fmt, options, defaults, fmt->vars[i].name))
2256 comment_option = 1;
2258 desc = config_find_description(fmt, fmt->vars[i].name);
2259 line = assigned = get_assigned_option(fmt, options, fmt->vars[i].name);
2261 if (line && desc) {
2262 /* Only dump the description if there's something to describe. */
2263 wrap_string(elements, desc, 78, "# ", "# ");
2266 for (; line; line = line->next) {
2267 size_t len = strlen(line->key) + strlen(line->value) + 5;
2268 char *tmp;
2269 tmp = tor_malloc(len);
2270 if (tor_snprintf(tmp, len, "%s%s %s\n",
2271 comment_option ? "# " : "",
2272 line->key, line->value)<0) {
2273 log_err(LD_BUG,"Internal error writing option value");
2274 tor_assert(0);
2276 smartlist_add(elements, tmp);
2278 config_free_lines(assigned);
2281 if (fmt->extra) {
2282 line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->var_offset);
2283 for (; line; line = line->next) {
2284 size_t len = strlen(line->key) + strlen(line->value) + 3;
2285 char *tmp;
2286 tmp = tor_malloc(len);
2287 if (tor_snprintf(tmp, len, "%s %s\n", line->key, line->value)<0) {
2288 log_err(LD_BUG,"Internal error writing option value");
2289 tor_assert(0);
2291 smartlist_add(elements, tmp);
2295 result = smartlist_join_strings(elements, "", 0, NULL);
2296 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2297 smartlist_free(elements);
2298 config_free(fmt, defaults);
2299 return result;
2302 /** Return a string containing a possible configuration file that would give
2303 * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
2304 * include options that are the same as Tor's defaults.
2306 char *
2307 options_dump(or_options_t *options, int minimal)
2309 return config_dump(&options_format, options, minimal, 0);
2312 /** Return 0 if every element of sl is a string holding a decimal
2313 * representation of a port number, or if sl is NULL.
2314 * Otherwise set *msg and return -1. */
2315 static int
2316 validate_ports_csv(smartlist_t *sl, const char *name, char **msg)
2318 int i;
2319 char buf[1024];
2320 tor_assert(name);
2322 if (!sl)
2323 return 0;
2325 SMARTLIST_FOREACH(sl, const char *, cp,
2327 i = atoi(cp);
2328 if (i < 1 || i > 65535) {
2329 int r = tor_snprintf(buf, sizeof(buf),
2330 "Port '%s' out of range in %s", cp, name);
2331 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2332 return -1;
2335 return 0;
2338 /** If <b>value</b> exceeds ROUTER_MAX_DECLARED_BANDWIDTH, write
2339 * a complaint into *<b>msg</b> using string <b>desc</b>, and return -1.
2340 * Else return 0.
2342 static int
2343 ensure_bandwidth_cap(uint64_t *value, const char *desc, char **msg)
2345 int r;
2346 char buf[1024];
2347 if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
2348 /* This handles an understandable special case where somebody says "2gb"
2349 * whereas our actual maximum is 2gb-1 (INT_MAX) */
2350 --*value;
2352 if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
2353 r = tor_snprintf(buf, sizeof(buf), "%s ("U64_FORMAT") must be at most %d",
2354 desc, U64_PRINTF_ARG(*value),
2355 ROUTER_MAX_DECLARED_BANDWIDTH);
2356 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2357 return -1;
2359 return 0;
2362 /** Parse an authority type from <b>list</b> and write it to *<b>auth</b>. If
2363 * <b>compatible</b> is non-zero, treat "1" as "v1,v2" and treat "0" as "".
2364 * Return 0 on success or -(idx of first bad member) if not a recognized
2365 * authority type.
2367 static int
2368 parse_authority_type_from_list(smartlist_t *list, authority_type_t *auth,
2369 int compatible)
2371 tor_assert(auth);
2372 *auth = NO_AUTHORITY;
2373 SMARTLIST_FOREACH(list, const char *, string, {
2374 if (!strcasecmp(string, "v1"))
2375 *auth |= V1_AUTHORITY;
2376 else if (compatible && !strcmp(string, "1"))
2377 *auth |= V1_AUTHORITY | V2_AUTHORITY;
2378 else if (!strcasecmp(string, "v2"))
2379 *auth |= V2_AUTHORITY;
2380 else if (!strcasecmp(string, "v3"))
2381 *auth |= V3_AUTHORITY;
2382 else if (!strcasecmp(string, "bridge"))
2383 *auth |= BRIDGE_AUTHORITY;
2384 else if (!strcasecmp(string, "hidserv"))
2385 *auth |= HIDSERV_AUTHORITY;
2386 else if (!strcasecmp(string, "") || (compatible && !strcmp(string, "0")))
2387 /* no authority */;
2388 else
2389 return - string_sl_idx;
2391 return 0;
2394 /** Lowest allowable value for RendPostPeriod; if this is too low, hidden
2395 * services can overload the directory system. */
2396 #define MIN_REND_POST_PERIOD (10*60)
2398 /** Highest allowable value for RendPostPeriod. */
2399 #define MAX_DIR_PERIOD (MIN_ONION_KEY_LIFETIME/2)
2401 /** Return 0 if every setting in <b>options</b> is reasonable, and a
2402 * permissible transition from <b>old_options</b>. Else return -1.
2403 * Should have no side effects, except for normalizing the contents of
2404 * <b>options</b>.
2406 * On error, tor_strdup an error explanation into *<b>msg</b>.
2408 * XXX
2409 * If <b>from_setconf</b>, we were called by the controller, and our
2410 * Log line should stay empty. If it's 0, then give us a default log
2411 * if there are no logs defined.
2413 static int
2414 options_validate(or_options_t *old_options, or_options_t *options,
2415 int from_setconf, char **msg)
2417 int i, r;
2418 config_line_t *cl;
2419 const char *uname = get_uname();
2420 char buf[1024];
2421 #define REJECT(arg) \
2422 do { *msg = tor_strdup(arg); return -1; } while (0)
2423 #define COMPLAIN(arg) do { log(LOG_WARN, LD_CONFIG, arg); } while (0)
2425 tor_assert(msg);
2426 *msg = NULL;
2428 if (options->ORPort < 0 || options->ORPort > 65535)
2429 REJECT("ORPort option out of bounds.");
2431 if (server_mode(options) &&
2432 (!strcmpstart(uname, "Windows 95") ||
2433 !strcmpstart(uname, "Windows 98") ||
2434 !strcmpstart(uname, "Windows Me"))) {
2435 log(LOG_WARN, LD_CONFIG, "Tor is running as a server, but you are "
2436 "running %s; this probably won't work. See "
2437 "http://wiki.noreply.org/noreply/TheOnionRouter/TorFAQ#ServerOS "
2438 "for details.", uname);
2441 if (options->ORPort == 0 && options->ORListenAddress != NULL)
2442 REJECT("ORPort must be defined if ORListenAddress is defined.");
2444 if (options->DirPort == 0 && options->DirListenAddress != NULL)
2445 REJECT("DirPort must be defined if DirListenAddress is defined.");
2447 if (options->DNSPort == 0 && options->DNSListenAddress != NULL)
2448 REJECT("DirPort must be defined if DirListenAddress is defined.");
2450 if (options->ControlPort == 0 && options->ControlListenAddress != NULL)
2451 REJECT("ControlPort must be defined if ControlListenAddress is defined.");
2453 if (options->TransPort == 0 && options->TransListenAddress != NULL)
2454 REJECT("TransPort must be defined if TransListenAddress is defined.");
2456 if (options->NatdPort == 0 && options->NatdListenAddress != NULL)
2457 REJECT("NatdPort must be defined if NatdListenAddress is defined.");
2459 /* Don't gripe about SocksPort 0 with SocksListenAddress set; a standard
2460 * configuration does this. */
2462 for (i = 0; i < 3; ++i) {
2463 int is_socks = i==0;
2464 int is_trans = i==1;
2465 config_line_t *line, *opt, *old;
2466 const char *tp;
2467 if (is_socks) {
2468 opt = options->SocksListenAddress;
2469 old = old_options ? old_options->SocksListenAddress : NULL;
2470 tp = "SOCKS proxy";
2471 } else if (is_trans) {
2472 opt = options->TransListenAddress;
2473 old = old_options ? old_options->TransListenAddress : NULL;
2474 tp = "transparent proxy";
2475 } else {
2476 opt = options->NatdListenAddress;
2477 old = old_options ? old_options->NatdListenAddress : NULL;
2478 tp = "natd proxy";
2481 for (line = opt; line; line = line->next) {
2482 char *address = NULL;
2483 uint16_t port;
2484 uint32_t addr;
2485 if (parse_addr_port(LOG_WARN, line->value, &address, &addr, &port)<0)
2486 continue; /* We'll warn about this later. */
2487 if (!is_internal_IP(addr, 1) &&
2488 (!old_options || !config_lines_eq(old, opt))) {
2489 log_warn(LD_CONFIG,
2490 "You specified a public address '%s' for a %s. Other "
2491 "people on the Internet might find your computer and use it as "
2492 "an open %s. Please don't allow this unless you have "
2493 "a good reason.", address, tp, tp);
2495 tor_free(address);
2499 if (validate_data_directory(options)<0)
2500 REJECT("Invalid DataDirectory");
2502 if (options->Nickname == NULL) {
2503 if (server_mode(options)) {
2504 if (!(options->Nickname = get_default_nickname())) {
2505 log_notice(LD_CONFIG, "Couldn't pick a nickname based on "
2506 "our hostname; using %s instead.", UNNAMED_ROUTER_NICKNAME);
2507 options->Nickname = tor_strdup(UNNAMED_ROUTER_NICKNAME);
2508 } else {
2509 log_notice(LD_CONFIG, "Choosing default nickname '%s'",
2510 options->Nickname);
2513 } else {
2514 if (!is_legal_nickname(options->Nickname)) {
2515 r = tor_snprintf(buf, sizeof(buf),
2516 "Nickname '%s' is wrong length or contains illegal characters.",
2517 options->Nickname);
2518 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2519 return -1;
2523 if (server_mode(options) && !options->ContactInfo)
2524 log(LOG_NOTICE, LD_CONFIG, "Your ContactInfo config option is not set. "
2525 "Please consider setting it, so we can contact you if your server is "
2526 "misconfigured or something else goes wrong.");
2528 /* Special case on first boot if no Log options are given. */
2529 if (!options->Logs && !options->RunAsDaemon && !from_setconf)
2530 config_line_append(&options->Logs, "Log", "notice stdout");
2532 if (options_init_logs(options, 1)<0) /* Validate the log(s) */
2533 REJECT("Failed to validate Log options. See logs for details.");
2535 if (options->NoPublish) {
2536 log(LOG_WARN, LD_CONFIG,
2537 "NoPublish is obsolete. Use PublishServerDescriptor instead.");
2538 SMARTLIST_FOREACH(options->PublishServerDescriptor, char *, s,
2539 tor_free(s));
2540 smartlist_clear(options->PublishServerDescriptor);
2543 if (authdir_mode(options)) {
2544 /* confirm that our address isn't broken, so we can complain now */
2545 uint32_t tmp;
2546 if (resolve_my_address(LOG_WARN, options, &tmp, NULL) < 0)
2547 REJECT("Failed to resolve/guess local address. See logs for details.");
2550 #ifndef MS_WINDOWS
2551 if (options->RunAsDaemon && torrc_fname && path_is_relative(torrc_fname))
2552 REJECT("Can't use a relative path to torrc when RunAsDaemon is set.");
2553 #endif
2555 if (options->SocksPort < 0 || options->SocksPort > 65535)
2556 REJECT("SocksPort option out of bounds.");
2558 if (options->DNSPort < 0 || options->DNSPort > 65535)
2559 REJECT("DNSPort option out of bounds.");
2561 if (options->TransPort < 0 || options->TransPort > 65535)
2562 REJECT("TransPort option out of bounds.");
2564 if (options->NatdPort < 0 || options->NatdPort > 65535)
2565 REJECT("NatdPort option out of bounds.");
2567 if (options->SocksPort == 0 && options->TransPort == 0 &&
2568 options->NatdPort == 0 && options->ORPort == 0)
2569 REJECT("SocksPort, TransPort, NatdPort, and ORPort are all undefined? "
2570 "Quitting.");
2572 if (options->ControlPort < 0 || options->ControlPort > 65535)
2573 REJECT("ControlPort option out of bounds.");
2575 if (options->DirPort < 0 || options->DirPort > 65535)
2576 REJECT("DirPort option out of bounds.");
2578 #ifndef USE_TRANSPARENT
2579 if (options->TransPort || options->TransListenAddress)
2580 REJECT("TransPort and TransListenAddress are disabled in this build.");
2581 #endif
2583 if (options->StrictExitNodes &&
2584 (!options->ExitNodes || !strlen(options->ExitNodes)) &&
2585 (!old_options ||
2586 (old_options->StrictExitNodes != options->StrictExitNodes) ||
2587 (!opt_streq(old_options->ExitNodes, options->ExitNodes))))
2588 COMPLAIN("StrictExitNodes set, but no ExitNodes listed.");
2590 if (options->StrictEntryNodes &&
2591 (!options->EntryNodes || !strlen(options->EntryNodes)) &&
2592 (!old_options ||
2593 (old_options->StrictEntryNodes != options->StrictEntryNodes) ||
2594 (!opt_streq(old_options->EntryNodes, options->EntryNodes))))
2595 COMPLAIN("StrictEntryNodes set, but no EntryNodes listed.");
2597 if (options->AuthoritativeDir) {
2598 if (!options->ContactInfo)
2599 REJECT("Authoritative directory servers must set ContactInfo");
2600 if (options->V1AuthoritativeDir && !options->RecommendedVersions)
2601 REJECT("V1 auth dir servers must set RecommendedVersions.");
2602 if (!options->RecommendedClientVersions)
2603 options->RecommendedClientVersions =
2604 config_lines_dup(options->RecommendedVersions);
2605 if (!options->RecommendedServerVersions)
2606 options->RecommendedServerVersions =
2607 config_lines_dup(options->RecommendedVersions);
2608 if (options->VersioningAuthoritativeDir &&
2609 (!options->RecommendedClientVersions ||
2610 !options->RecommendedServerVersions))
2611 REJECT("Versioning auth dir servers must set Recommended*Versions.");
2612 if (options->UseEntryGuards) {
2613 log_info(LD_CONFIG, "Authoritative directory servers can't set "
2614 "UseEntryGuards. Disabling.");
2615 options->UseEntryGuards = 0;
2617 if (!options->DownloadExtraInfo) {
2618 log_info(LD_CONFIG, "Authoritative directories always try to download "
2619 "extra-info documents. Setting DownloadExtraInfo.");
2620 options->DownloadExtraInfo = 1;
2622 /* XXXX020 Check that at least one of Bridge/HS/V1/V2/V2{AoritativeDir}
2623 * is set. */
2626 if (options->AuthoritativeDir && !options->DirPort)
2627 REJECT("Running as authoritative directory, but no DirPort set.");
2629 if (options->AuthoritativeDir && !options->ORPort)
2630 REJECT("Running as authoritative directory, but no ORPort set.");
2632 if (options->AuthoritativeDir && options->ClientOnly)
2633 REJECT("Running as authoritative directory, but ClientOnly also set.");
2635 if (options->HSAuthorityRecordStats && !options->HSAuthoritativeDir)
2636 REJECT("HSAuthorityRecordStats is set but we're not running as "
2637 "a hidden service authority.");
2639 if (options->ConnLimit <= 0) {
2640 r = tor_snprintf(buf, sizeof(buf),
2641 "ConnLimit must be greater than 0, but was set to %d",
2642 options->ConnLimit);
2643 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2644 return -1;
2647 if (validate_ports_csv(options->FirewallPorts, "FirewallPorts", msg) < 0)
2648 return -1;
2650 if (validate_ports_csv(options->LongLivedPorts, "LongLivedPorts", msg) < 0)
2651 return -1;
2653 if (options->FascistFirewall && !options->ReachableAddresses) {
2654 if (options->FirewallPorts && smartlist_len(options->FirewallPorts)) {
2655 /* We already have firewall ports set, so migrate them to
2656 * ReachableAddresses, which will set ReachableORAddresses and
2657 * ReachableDirAddresses if they aren't set explicitly. */
2658 smartlist_t *instead = smartlist_create();
2659 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
2660 new_line->key = tor_strdup("ReachableAddresses");
2661 /* If we're configured with the old format, we need to prepend some
2662 * open ports. */
2663 SMARTLIST_FOREACH(options->FirewallPorts, const char *, portno,
2665 int p = atoi(portno);
2666 char *s;
2667 if (p<0) continue;
2668 s = tor_malloc(16);
2669 tor_snprintf(s, 16, "*:%d", p);
2670 smartlist_add(instead, s);
2672 new_line->value = smartlist_join_strings(instead,",",0,NULL);
2673 /* These have been deprecated since 0.1.1.5-alpha-cvs */
2674 log(LOG_NOTICE, LD_CONFIG,
2675 "Converting FascistFirewall and FirewallPorts "
2676 "config options to new format: \"ReachableAddresses %s\"",
2677 new_line->value);
2678 options->ReachableAddresses = new_line;
2679 SMARTLIST_FOREACH(instead, char *, cp, tor_free(cp));
2680 smartlist_free(instead);
2681 } else {
2682 /* We do not have FirewallPorts set, so add 80 to
2683 * ReachableDirAddresses, and 443 to ReachableORAddresses. */
2684 if (!options->ReachableDirAddresses) {
2685 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
2686 new_line->key = tor_strdup("ReachableDirAddresses");
2687 new_line->value = tor_strdup("*:80");
2688 options->ReachableDirAddresses = new_line;
2689 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
2690 "to new format: \"ReachableDirAddresses *:80\"");
2692 if (!options->ReachableORAddresses) {
2693 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
2694 new_line->key = tor_strdup("ReachableORAddresses");
2695 new_line->value = tor_strdup("*:443");
2696 options->ReachableORAddresses = new_line;
2697 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
2698 "to new format: \"ReachableORAddresses *:443\"");
2703 for (i=0; i<3; i++) {
2704 config_line_t **linep =
2705 (i==0) ? &options->ReachableAddresses :
2706 (i==1) ? &options->ReachableORAddresses :
2707 &options->ReachableDirAddresses;
2708 if (!*linep)
2709 continue;
2710 /* We need to end with a reject *:*, not an implicit accept *:* */
2711 for (;;) {
2712 if (!strcmp((*linep)->value, "reject *:*")) /* already there */
2713 break;
2714 linep = &((*linep)->next);
2715 if (!*linep) {
2716 *linep = tor_malloc_zero(sizeof(config_line_t));
2717 (*linep)->key = tor_strdup(
2718 (i==0) ? "ReachableAddresses" :
2719 (i==1) ? "ReachableORAddresses" :
2720 "ReachableDirAddresses");
2721 (*linep)->value = tor_strdup("reject *:*");
2722 break;
2727 if ((options->ReachableAddresses ||
2728 options->ReachableORAddresses ||
2729 options->ReachableDirAddresses) &&
2730 server_mode(options))
2731 REJECT("Servers must be able to freely connect to the rest "
2732 "of the Internet, so they must not set Reachable*Addresses "
2733 "or FascistFirewall.");
2735 options->_AllowInvalid = 0;
2736 if (options->AllowInvalidNodes) {
2737 SMARTLIST_FOREACH(options->AllowInvalidNodes, const char *, cp, {
2738 if (!strcasecmp(cp, "entry"))
2739 options->_AllowInvalid |= ALLOW_INVALID_ENTRY;
2740 else if (!strcasecmp(cp, "exit"))
2741 options->_AllowInvalid |= ALLOW_INVALID_EXIT;
2742 else if (!strcasecmp(cp, "middle"))
2743 options->_AllowInvalid |= ALLOW_INVALID_MIDDLE;
2744 else if (!strcasecmp(cp, "introduction"))
2745 options->_AllowInvalid |= ALLOW_INVALID_INTRODUCTION;
2746 else if (!strcasecmp(cp, "rendezvous"))
2747 options->_AllowInvalid |= ALLOW_INVALID_RENDEZVOUS;
2748 else {
2749 r = tor_snprintf(buf, sizeof(buf),
2750 "Unrecognized value '%s' in AllowInvalidNodes", cp);
2751 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2752 return -1;
2757 if ((i = parse_authority_type_from_list(options->PublishServerDescriptor,
2758 &options->_PublishServerDescriptor, 1) < 0)) {
2759 r = tor_snprintf(buf, sizeof(buf),
2760 "Unrecognized value '%s' for PublishServerDescriptor",
2761 (char*)smartlist_get(options->PublishServerDescriptor, -i));
2762 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2763 return -1;
2766 if (options->RendPostPeriod < MIN_REND_POST_PERIOD) {
2767 log(LOG_WARN,LD_CONFIG,"RendPostPeriod option must be at least %d seconds."
2768 " Clipping.", MIN_REND_POST_PERIOD);
2769 options->RendPostPeriod = MIN_REND_POST_PERIOD;
2772 if (options->RendPostPeriod > MAX_DIR_PERIOD) {
2773 log(LOG_WARN, LD_CONFIG, "RendPostPeriod is too large; clipping to %ds.",
2774 MAX_DIR_PERIOD);
2775 options->RendPostPeriod = MAX_DIR_PERIOD;
2778 if (options->KeepalivePeriod < 1)
2779 REJECT("KeepalivePeriod option must be positive.");
2781 if (ensure_bandwidth_cap(&options->BandwidthRate,
2782 "BandwidthRate", msg) < 0)
2783 return -1;
2784 if (ensure_bandwidth_cap(&options->BandwidthBurst,
2785 "BandwidthBurst", msg) < 0)
2786 return -1;
2787 if (ensure_bandwidth_cap(&options->MaxAdvertisedBandwidth,
2788 "MaxAdvertisedBandwidth", msg) < 0)
2789 return -1;
2790 if (ensure_bandwidth_cap(&options->RelayBandwidthRate,
2791 "RelayBandwidthRate", msg) < 0)
2792 return -1;
2793 if (ensure_bandwidth_cap(&options->RelayBandwidthBurst,
2794 "RelayBandwidthBurst", msg) < 0)
2795 return -1;
2797 if (server_mode(options)) {
2798 if (options->BandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH*2) {
2799 r = tor_snprintf(buf, sizeof(buf),
2800 "BandwidthRate is set to %d bytes/second. "
2801 "For servers, it must be at least %d.",
2802 (int)options->BandwidthRate,
2803 ROUTER_REQUIRED_MIN_BANDWIDTH*2);
2804 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2805 return -1;
2806 } else if (options->MaxAdvertisedBandwidth <
2807 ROUTER_REQUIRED_MIN_BANDWIDTH) {
2808 r = tor_snprintf(buf, sizeof(buf),
2809 "MaxAdvertisedBandwidth is set to %d bytes/second. "
2810 "For servers, it must be at least %d.",
2811 (int)options->MaxAdvertisedBandwidth,
2812 ROUTER_REQUIRED_MIN_BANDWIDTH);
2813 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2814 return -1;
2816 if (options->RelayBandwidthRate > options->RelayBandwidthBurst)
2817 REJECT("RelayBandwidthBurst must be at least equal "
2818 "to RelayBandwidthRate.");
2819 if (options->RelayBandwidthRate &&
2820 options->RelayBandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH) {
2821 r = tor_snprintf(buf, sizeof(buf),
2822 "RelayBandwidthRate is set to %d bytes/second. "
2823 "For servers, it must be at least %d.",
2824 (int)options->RelayBandwidthRate,
2825 ROUTER_REQUIRED_MIN_BANDWIDTH);
2826 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2827 return -1;
2831 if (options->BandwidthRate > options->BandwidthBurst)
2832 REJECT("BandwidthBurst must be at least equal to BandwidthRate.");
2834 if (accounting_parse_options(options, 1)<0)
2835 REJECT("Failed to parse accounting options. See logs for details.");
2837 if (options->HttpProxy) { /* parse it now */
2838 if (parse_addr_port(LOG_WARN, options->HttpProxy, NULL,
2839 &options->HttpProxyAddr, &options->HttpProxyPort) < 0)
2840 REJECT("HttpProxy failed to parse or resolve. Please fix.");
2841 if (options->HttpProxyPort == 0) { /* give it a default */
2842 options->HttpProxyPort = 80;
2846 if (options->HttpProxyAuthenticator) {
2847 if (strlen(options->HttpProxyAuthenticator) >= 48)
2848 REJECT("HttpProxyAuthenticator is too long (>= 48 chars).");
2851 if (options->HttpsProxy) { /* parse it now */
2852 if (parse_addr_port(LOG_WARN, options->HttpsProxy, NULL,
2853 &options->HttpsProxyAddr, &options->HttpsProxyPort) <0)
2854 REJECT("HttpsProxy failed to parse or resolve. Please fix.");
2855 if (options->HttpsProxyPort == 0) { /* give it a default */
2856 options->HttpsProxyPort = 443;
2860 if (options->HttpsProxyAuthenticator) {
2861 if (strlen(options->HttpsProxyAuthenticator) >= 48)
2862 REJECT("HttpsProxyAuthenticator is too long (>= 48 chars).");
2865 if (options->HashedControlPassword) {
2866 if (decode_hashed_password(NULL, options->HashedControlPassword)<0)
2867 REJECT("Bad HashedControlPassword: wrong length or bad encoding");
2869 if (options->HashedControlPassword && options->CookieAuthentication)
2870 REJECT("Cannot set both HashedControlPassword and CookieAuthentication");
2872 if (options->UseEntryGuards && ! options->NumEntryGuards)
2873 REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0");
2875 if (check_nickname_list(options->ExitNodes, "ExitNodes", msg))
2876 return -1;
2877 if (check_nickname_list(options->EntryNodes, "EntryNodes", msg))
2878 return -1;
2879 if (check_nickname_list(options->ExcludeNodes, "ExcludeNodes", msg))
2880 return -1;
2881 if (check_nickname_list(options->RendNodes, "RendNodes", msg))
2882 return -1;
2883 if (check_nickname_list(options->RendNodes, "RendExcludeNodes", msg))
2884 return -1;
2885 if (check_nickname_list(options->TestVia, "TestVia", msg))
2886 return -1;
2887 if (check_nickname_list(options->MyFamily, "MyFamily", msg))
2888 return -1;
2889 for (cl = options->NodeFamilies; cl; cl = cl->next) {
2890 if (check_nickname_list(cl->value, "NodeFamily", msg))
2891 return -1;
2894 if (validate_addr_policies(options, msg) < 0)
2895 return -1;
2897 for (cl = options->RedirectExit; cl; cl = cl->next) {
2898 if (parse_redirect_line(NULL, cl, msg)<0)
2899 return -1;
2902 if (options->DirServers) {
2903 if (!old_options ||
2904 !config_lines_eq(options->DirServers, old_options->DirServers))
2905 COMPLAIN("You have used DirServer to specify directory authorities in "
2906 "your configuration. This is potentially dangerous: it can "
2907 "make you look different from all other Tor users, and hurt "
2908 "your anonymity. Even if you've specified the same "
2909 "authorities as Tor uses by default, the defaults could "
2910 "change in the future. Be sure you know what you're doing.");
2911 for (cl = options->DirServers; cl; cl = cl->next) {
2912 if (parse_dir_server_line(cl->value, 1)<0)
2913 REJECT("DirServer line did not parse. See logs for details.");
2917 if (options->UseBridges && !options->Bridges)
2918 REJECT("If you set UseBridges, you must specify at least one bridge.");
2919 if (options->UseBridges && !options->TunnelDirConns)
2920 REJECT("If you set UseBridges, you must set TunnelDirConns.");
2921 if (options->Bridges) {
2922 for (cl = options->Bridges; cl; cl = cl->next) {
2923 if (parse_bridge_line(cl->value, 1)<0)
2924 REJECT("Bridge line did not parse. See logs for details.");
2928 if (rend_config_services(options, 1) < 0)
2929 REJECT("Failed to configure rendezvous options. See logs for details.");
2931 if (parse_virtual_addr_network(options->VirtualAddrNetwork, 1, NULL)<0)
2932 return -1;
2934 if (options->PreferTunneledDirConns && !options->TunnelDirConns)
2935 REJECT("Must set TunnelDirConns if PreferTunneledDirConns is set.");
2937 if (options->AutomapHostsSuffixes) {
2938 SMARTLIST_FOREACH(options->AutomapHostsSuffixes, char *, suf,
2940 size_t len = strlen(suf);
2941 if (len && suf[len-1] == '.')
2942 suf[len-1] = '\0';
2946 return 0;
2947 #undef REJECT
2948 #undef COMPLAIN
2951 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
2952 * equal strings. */
2953 static int
2954 opt_streq(const char *s1, const char *s2)
2956 if (!s1 && !s2)
2957 return 1;
2958 else if (s1 && s2 && !strcmp(s1,s2))
2959 return 1;
2960 else
2961 return 0;
2964 /** Check if any of the previous options have changed but aren't allowed to. */
2965 static int
2966 options_transition_allowed(or_options_t *old, or_options_t *new_val,
2967 char **msg)
2969 if (!old)
2970 return 0;
2972 if (!opt_streq(old->PidFile, new_val->PidFile)) {
2973 *msg = tor_strdup("PidFile is not allowed to change.");
2974 return -1;
2977 if (old->RunAsDaemon != new_val->RunAsDaemon) {
2978 *msg = tor_strdup("While Tor is running, changing RunAsDaemon "
2979 "is not allowed.");
2980 return -1;
2983 if (strcmp(old->DataDirectory,new_val->DataDirectory)!=0) {
2984 char buf[1024];
2985 int r = tor_snprintf(buf, sizeof(buf),
2986 "While Tor is running, changing DataDirectory "
2987 "(\"%s\"->\"%s\") is not allowed.",
2988 old->DataDirectory, new_val->DataDirectory);
2989 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2990 return -1;
2993 if (!opt_streq(old->User, new_val->User)) {
2994 *msg = tor_strdup("While Tor is running, changing User is not allowed.");
2995 return -1;
2998 if (!opt_streq(old->Group, new_val->Group)) {
2999 *msg = tor_strdup("While Tor is running, changing Group is not allowed.");
3000 return -1;
3003 if (old->HardwareAccel != new_val->HardwareAccel) {
3004 *msg = tor_strdup("While Tor is running, changing HardwareAccel is "
3005 "not allowed.");
3006 return -1;
3009 return 0;
3012 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
3013 * will require us to rotate the cpu and dns workers; else return 0. */
3014 static int
3015 options_transition_affects_workers(or_options_t *old_options,
3016 or_options_t *new_options)
3018 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
3019 old_options->NumCpus != new_options->NumCpus ||
3020 old_options->ORPort != new_options->ORPort ||
3021 old_options->ServerDNSSearchDomains !=
3022 new_options->ServerDNSSearchDomains ||
3023 old_options->SafeLogging != new_options->SafeLogging ||
3024 old_options->ClientOnly != new_options->ClientOnly ||
3025 !config_lines_eq(old_options->Logs, new_options->Logs))
3026 return 1;
3028 /* Check whether log options match. */
3030 /* Nothing that changed matters. */
3031 return 0;
3034 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
3035 * will require us to generate a new descriptor; else return 0. */
3036 static int
3037 options_transition_affects_descriptor(or_options_t *old_options,
3038 or_options_t *new_options)
3040 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
3041 !opt_streq(old_options->Nickname,new_options->Nickname) ||
3042 !opt_streq(old_options->Address,new_options->Address) ||
3043 !config_lines_eq(old_options->ExitPolicy,new_options->ExitPolicy) ||
3044 old_options->ORPort != new_options->ORPort ||
3045 old_options->DirPort != new_options->DirPort ||
3046 old_options->ClientOnly != new_options->ClientOnly ||
3047 old_options->NoPublish != new_options->NoPublish ||
3048 old_options->_PublishServerDescriptor !=
3049 new_options->_PublishServerDescriptor ||
3050 old_options->BandwidthRate != new_options->BandwidthRate ||
3051 old_options->BandwidthBurst != new_options->BandwidthBurst ||
3052 !opt_streq(old_options->ContactInfo, new_options->ContactInfo) ||
3053 !opt_streq(old_options->MyFamily, new_options->MyFamily) ||
3054 !opt_streq(old_options->AccountingStart, new_options->AccountingStart) ||
3055 old_options->AccountingMax != new_options->AccountingMax)
3056 return 1;
3058 return 0;
3061 #ifdef MS_WINDOWS
3062 /** Return the directory on windows where we expect to find our application
3063 * data. */
3064 static char *
3065 get_windows_conf_root(void)
3067 static int is_set = 0;
3068 static char path[MAX_PATH+1];
3070 LPITEMIDLIST idl;
3071 IMalloc *m;
3072 HRESULT result;
3074 if (is_set)
3075 return path;
3077 /* Find X:\documents and settings\username\application data\ .
3078 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
3080 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA,
3081 &idl))) {
3082 GetCurrentDirectory(MAX_PATH, path);
3083 is_set = 1;
3084 log_warn(LD_CONFIG,
3085 "I couldn't find your application data folder: are you "
3086 "running an ancient version of Windows 95? Defaulting to \"%s\"",
3087 path);
3088 return path;
3090 /* Convert the path from an "ID List" (whatever that is!) to a path. */
3091 result = SHGetPathFromIDList(idl, path);
3092 /* Now we need to free the */
3093 SHGetMalloc(&m);
3094 if (m) {
3095 m->lpVtbl->Free(m, idl);
3096 m->lpVtbl->Release(m);
3098 if (!SUCCEEDED(result)) {
3099 return NULL;
3101 strlcat(path,"\\tor",MAX_PATH);
3102 is_set = 1;
3103 return path;
3105 #endif
3107 /** Return the default location for our torrc file. */
3108 static const char *
3109 get_default_conf_file(void)
3111 #ifdef MS_WINDOWS
3112 static char path[MAX_PATH+1];
3113 strlcpy(path, get_windows_conf_root(), MAX_PATH);
3114 strlcat(path,"\\torrc",MAX_PATH);
3115 return path;
3116 #else
3117 return (CONFDIR "/torrc");
3118 #endif
3121 /** Verify whether lst is a string containing valid-looking space-separated
3122 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
3124 static int
3125 check_nickname_list(const char *lst, const char *name, char **msg)
3127 int r = 0;
3128 smartlist_t *sl;
3130 if (!lst)
3131 return 0;
3132 sl = smartlist_create();
3133 smartlist_split_string(sl, lst, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
3134 SMARTLIST_FOREACH(sl, const char *, s,
3136 if (!is_legal_nickname_or_hexdigest(s)) {
3137 char buf[1024];
3138 int tmp = tor_snprintf(buf, sizeof(buf),
3139 "Invalid nickname '%s' in %s line", s, name);
3140 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
3141 r = -1;
3142 break;
3145 SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
3146 smartlist_free(sl);
3147 return r;
3150 /** Read a configuration file into <b>options</b>, finding the configuration
3151 * file location based on the command line. After loading the options,
3152 * validate them for consistency, then take actions based on them.
3153 * Return 0 if success, -1 if failure. */
3155 options_init_from_torrc(int argc, char **argv)
3157 or_options_t *oldoptions, *newoptions;
3158 config_line_t *cl;
3159 char *cf=NULL, *fname=NULL, *errmsg=NULL;
3160 int i, retval;
3161 int using_default_torrc;
3162 int ignore_missing_torrc;
3163 static char **backup_argv;
3164 static int backup_argc;
3166 if (argv) { /* first time we're called. save commandline args */
3167 backup_argv = argv;
3168 backup_argc = argc;
3169 oldoptions = NULL;
3170 } else { /* we're reloading. need to clean up old options first. */
3171 argv = backup_argv;
3172 argc = backup_argc;
3173 oldoptions = get_options();
3175 if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
3176 print_usage();
3177 exit(0);
3179 if (argc > 1 && !strcmp(argv[1], "--list-torrc-options")) {
3180 /* For documenting validating whether we've documented everything. */
3181 list_torrc_options();
3182 exit(0);
3185 if (argc > 1 && (!strcmp(argv[1],"--version"))) {
3186 printf("Tor version %s.\n",get_version());
3187 if (argc > 2 && (!strcmp(argv[2],"--version"))) {
3188 print_svn_version();
3190 exit(0);
3193 newoptions = tor_malloc_zero(sizeof(or_options_t));
3194 newoptions->_magic = OR_OPTIONS_MAGIC;
3195 options_init(newoptions);
3197 /* learn config file name */
3198 fname = NULL;
3199 using_default_torrc = 1;
3200 ignore_missing_torrc = 0;
3201 newoptions->command = CMD_RUN_TOR;
3202 for (i = 1; i < argc; ++i) {
3203 if (i < argc-1 && !strcmp(argv[i],"-f")) {
3204 if (fname) {
3205 log(LOG_WARN, LD_CONFIG, "Duplicate -f options on command line.");
3206 tor_free(fname);
3208 #ifdef MS_WINDOWS
3209 /* XXX one day we might want to extend expand_filename to work
3210 * under Windows as well. */
3211 fname = tor_strdup(argv[i+1]);
3212 #else
3213 fname = expand_filename(argv[i+1]);
3214 #endif
3215 using_default_torrc = 0;
3216 ++i;
3217 } else if (!strcmp(argv[i],"--ignore-missing-torrc")) {
3218 ignore_missing_torrc = 1;
3219 } else if (!strcmp(argv[i],"--list-fingerprint")) {
3220 newoptions->command = CMD_LIST_FINGERPRINT;
3221 } else if (!strcmp(argv[i],"--hash-password")) {
3222 newoptions->command = CMD_HASH_PASSWORD;
3223 newoptions->command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : "");
3224 ++i;
3225 } else if (!strcmp(argv[i],"--verify-config")) {
3226 newoptions->command = CMD_VERIFY_CONFIG;
3229 if (using_default_torrc) {
3230 /* didn't find one, try CONFDIR */
3231 const char *dflt = get_default_conf_file();
3232 if (dflt && file_status(dflt) == FN_FILE) {
3233 fname = tor_strdup(dflt);
3234 } else {
3235 #ifndef MS_WINDOWS
3236 char *fn;
3237 fn = expand_filename("~/.torrc");
3238 if (fn && file_status(fn) == FN_FILE) {
3239 fname = fn;
3240 } else {
3241 tor_free(fn);
3242 fname = tor_strdup(dflt);
3244 #else
3245 fname = tor_strdup(dflt);
3246 #endif
3249 tor_assert(fname);
3250 log(LOG_DEBUG, LD_CONFIG, "Opening config file \"%s\"", fname);
3252 tor_free(torrc_fname);
3253 torrc_fname = fname;
3255 /* get config lines, assign them */
3256 if (file_status(fname) != FN_FILE ||
3257 !(cf = read_file_to_str(fname,0,NULL))) {
3258 if (using_default_torrc == 1 || ignore_missing_torrc ) {
3259 log(LOG_NOTICE, LD_CONFIG, "Configuration file \"%s\" not present, "
3260 "using reasonable defaults.", fname);
3261 tor_free(fname); /* sets fname to NULL */
3262 torrc_fname = NULL;
3263 } else {
3264 log(LOG_WARN, LD_CONFIG,
3265 "Unable to open configuration file \"%s\".", fname);
3266 goto err;
3268 } else { /* it opened successfully. use it. */
3269 retval = config_get_lines(cf, &cl);
3270 tor_free(cf);
3271 if (retval < 0)
3272 goto err;
3273 retval = config_assign(&options_format, newoptions, cl, 0, 0, &errmsg);
3274 config_free_lines(cl);
3275 if (retval < 0)
3276 goto err;
3279 /* Go through command-line variables too */
3280 if (config_get_commandlines(argc, argv, &cl) < 0)
3281 goto err;
3282 retval = config_assign(&options_format, newoptions, cl, 0, 0, &errmsg);
3283 config_free_lines(cl);
3284 if (retval < 0)
3285 goto err;
3287 /* Validate newoptions */
3288 if (options_validate(oldoptions, newoptions, 0, &errmsg) < 0)
3289 goto err;
3291 if (options_transition_allowed(oldoptions, newoptions, &errmsg) < 0)
3292 goto err;
3294 if (set_options(newoptions, &errmsg))
3295 goto err; /* frees and replaces old options */
3297 return 0;
3298 err:
3299 tor_free(fname);
3300 torrc_fname = NULL;
3301 config_free(&options_format, newoptions);
3302 if (errmsg) {
3303 log(LOG_WARN,LD_CONFIG,"Failed to parse/validate config: %s", errmsg);
3304 tor_free(errmsg);
3306 return -1;
3309 /** Return the location for our configuration file.
3311 const char *
3312 get_torrc_fname(void)
3314 if (torrc_fname)
3315 return torrc_fname;
3316 else
3317 return get_default_conf_file();
3320 /** Adjust the address map mased on the MapAddress elements in the
3321 * configuration <b>options</b>
3323 static void
3324 config_register_addressmaps(or_options_t *options)
3326 smartlist_t *elts;
3327 config_line_t *opt;
3328 char *from, *to;
3330 addressmap_clear_configured();
3331 elts = smartlist_create();
3332 for (opt = options->AddressMap; opt; opt = opt->next) {
3333 smartlist_split_string(elts, opt->value, NULL,
3334 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
3335 if (smartlist_len(elts) >= 2) {
3336 from = smartlist_get(elts,0);
3337 to = smartlist_get(elts,1);
3338 if (address_is_invalid_destination(to, 1)) {
3339 log_warn(LD_CONFIG,
3340 "Skipping invalid argument '%s' to MapAddress", to);
3341 } else {
3342 addressmap_register(from, tor_strdup(to), 0);
3343 if (smartlist_len(elts)>2) {
3344 log_warn(LD_CONFIG,"Ignoring extra arguments to MapAddress.");
3347 } else {
3348 log_warn(LD_CONFIG,"MapAddress '%s' has too few arguments. Ignoring.",
3349 opt->value);
3351 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
3352 smartlist_clear(elts);
3354 smartlist_free(elts);
3357 /** If <b>range</b> is of the form MIN-MAX, for MIN and MAX both
3358 * recognized log severity levels, set *<b>min_out</b> to MIN and
3359 * *<b>max_out</b> to MAX and return 0. Else, if <b>range</b> is of
3360 * the form MIN, act as if MIN-err had been specified. Else, warn and
3361 * return -1.
3363 static int
3364 parse_log_severity_range(const char *range, int *min_out, int *max_out)
3366 int levelMin, levelMax;
3367 const char *cp;
3368 cp = strchr(range, '-');
3369 if (cp) {
3370 if (cp == range) {
3371 levelMin = LOG_DEBUG;
3372 } else {
3373 char *tmp_sev = tor_strndup(range, cp - range);
3374 levelMin = parse_log_level(tmp_sev);
3375 if (levelMin < 0) {
3376 log_warn(LD_CONFIG, "Unrecognized minimum log severity '%s': must be "
3377 "one of err|warn|notice|info|debug", tmp_sev);
3378 tor_free(tmp_sev);
3379 return -1;
3381 tor_free(tmp_sev);
3383 if (!*(cp+1)) {
3384 levelMax = LOG_ERR;
3385 } else {
3386 levelMax = parse_log_level(cp+1);
3387 if (levelMax < 0) {
3388 log_warn(LD_CONFIG, "Unrecognized maximum log severity '%s': must be "
3389 "one of err|warn|notice|info|debug", cp+1);
3390 return -1;
3393 } else {
3394 levelMin = parse_log_level(range);
3395 if (levelMin < 0) {
3396 log_warn(LD_CONFIG, "Unrecognized log severity '%s': must be one of "
3397 "err|warn|notice|info|debug", range);
3398 return -1;
3400 levelMax = LOG_ERR;
3403 *min_out = levelMin;
3404 *max_out = levelMax;
3406 return 0;
3410 * Initialize the logs based on the configuration file.
3413 options_init_logs(or_options_t *options, int validate_only)
3415 config_line_t *opt;
3416 int ok;
3417 smartlist_t *elts;
3418 int daemon =
3419 #ifdef MS_WINDOWS
3421 #else
3422 options->RunAsDaemon;
3423 #endif
3425 ok = 1;
3426 elts = smartlist_create();
3428 for (opt = options->Logs; opt; opt = opt->next) {
3429 int levelMin=LOG_DEBUG, levelMax=LOG_ERR;
3430 smartlist_split_string(elts, opt->value, NULL,
3431 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
3432 if (smartlist_len(elts) == 0) {
3433 log_warn(LD_CONFIG, "No arguments to Log option 'Log %s'", opt->value);
3434 ok = 0; goto cleanup;
3436 if (parse_log_severity_range(smartlist_get(elts,0), &levelMin,
3437 &levelMax)) {
3438 ok = 0; goto cleanup;
3440 if (smartlist_len(elts) < 2) { /* only loglevels were provided */
3441 if (!validate_only) {
3442 if (daemon) {
3443 log_warn(LD_CONFIG,
3444 "Can't log to stdout with RunAsDaemon set; skipping stdout");
3445 } else {
3446 add_stream_log(levelMin, levelMax, "<stdout>", stdout);
3449 goto cleanup;
3451 if (!strcasecmp(smartlist_get(elts,1), "file")) {
3452 if (smartlist_len(elts) != 3) {
3453 log_warn(LD_CONFIG, "Bad syntax on file Log option 'Log %s'",
3454 opt->value);
3455 ok = 0; goto cleanup;
3457 if (!validate_only) {
3458 if (add_file_log(levelMin, levelMax, smartlist_get(elts, 2)) < 0) {
3459 log_warn(LD_CONFIG, "Couldn't open file for 'Log %s'", opt->value);
3460 ok = 0;
3463 goto cleanup;
3465 if (smartlist_len(elts) != 2) {
3466 log_warn(LD_CONFIG, "Wrong number of arguments on Log option 'Log %s'",
3467 opt->value);
3468 ok = 0; goto cleanup;
3470 if (!strcasecmp(smartlist_get(elts,1), "stdout")) {
3471 if (daemon) {
3472 log_warn(LD_CONFIG, "Can't log to stdout with RunAsDaemon set.");
3473 ok = 0; goto cleanup;
3475 if (!validate_only) {
3476 add_stream_log(levelMin, levelMax, "<stdout>", stdout);
3478 } else if (!strcasecmp(smartlist_get(elts,1), "stderr")) {
3479 if (daemon) {
3480 log_warn(LD_CONFIG, "Can't log to stderr with RunAsDaemon set.");
3481 ok = 0; goto cleanup;
3483 if (!validate_only) {
3484 add_stream_log(levelMin, levelMax, "<stderr>", stderr);
3486 } else if (!strcasecmp(smartlist_get(elts,1), "syslog")) {
3487 #ifdef HAVE_SYSLOG_H
3488 if (!validate_only)
3489 add_syslog_log(levelMin, levelMax);
3490 #else
3491 log_warn(LD_CONFIG, "Syslog is not supported on this system. Sorry.");
3492 #endif
3493 } else {
3494 log_warn(LD_CONFIG, "Unrecognized log type %s",
3495 (const char*)smartlist_get(elts,1));
3496 if (strchr(smartlist_get(elts,1), '/') ||
3497 strchr(smartlist_get(elts,1), '\\')) {
3498 log_warn(LD_CONFIG, "Did you mean to say 'Log %s file %s' ?",
3499 (const char *)smartlist_get(elts,0),
3500 (const char *)smartlist_get(elts,1));
3502 ok = 0; goto cleanup;
3504 cleanup:
3505 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
3506 smartlist_clear(elts);
3508 smartlist_free(elts);
3510 return ok?0:-1;
3513 /** Parse a single RedirectExit line's contents from <b>line</b>. If
3514 * they are valid, and <b>result</b> is not NULL, add an element to
3515 * <b>result</b> and return 0. Else if they are valid, return 0.
3516 * Else set *msg and return -1. */
3517 static int
3518 parse_redirect_line(smartlist_t *result, config_line_t *line, char **msg)
3520 smartlist_t *elements = NULL;
3521 exit_redirect_t *r;
3523 tor_assert(line);
3525 r = tor_malloc_zero(sizeof(exit_redirect_t));
3526 elements = smartlist_create();
3527 smartlist_split_string(elements, line->value, NULL,
3528 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
3529 if (smartlist_len(elements) != 2) {
3530 *msg = tor_strdup("Wrong number of elements in RedirectExit line");
3531 goto err;
3533 if (parse_addr_and_port_range(smartlist_get(elements,0),&r->addr,&r->mask,
3534 &r->port_min,&r->port_max)) {
3535 *msg = tor_strdup("Error parsing source address in RedirectExit line");
3536 goto err;
3538 if (0==strcasecmp(smartlist_get(elements,1), "pass")) {
3539 r->is_redirect = 0;
3540 } else {
3541 if (parse_addr_port(LOG_WARN, smartlist_get(elements,1),NULL,
3542 &r->addr_dest, &r->port_dest)) {
3543 *msg = tor_strdup("Error parsing dest address in RedirectExit line");
3544 goto err;
3546 r->is_redirect = 1;
3549 goto done;
3550 err:
3551 tor_free(r);
3552 done:
3553 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
3554 smartlist_free(elements);
3555 if (r) {
3556 if (result)
3557 smartlist_add(result, r);
3558 else
3559 tor_free(r);
3560 return 0;
3561 } else {
3562 tor_assert(*msg);
3563 return -1;
3567 /** Read the contents of a Bridge line from <b>line</b>. Return 0
3568 * if the line is well-formed, and -1 if it isn't. If
3569 * <b>validate_only</b> is 0, and the line is well-formed, then add
3570 * the bridge described in the line to our internal bridge list. */
3571 static int
3572 parse_bridge_line(const char *line, int validate_only)
3574 smartlist_t *items = NULL;
3575 int r;
3576 char *addrport=NULL, *address=NULL, *fingerprint=NULL;
3577 uint32_t addr = 0;
3578 uint16_t port = 0;
3579 char digest[DIGEST_LEN];
3581 items = smartlist_create();
3582 smartlist_split_string(items, line, NULL,
3583 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
3584 if (smartlist_len(items) < 1) {
3585 log_warn(LD_CONFIG, "Too few arguments to Bridge line.");
3586 goto err;
3588 addrport = smartlist_get(items, 0);
3589 smartlist_del_keeporder(items, 0);
3590 if (parse_addr_port(LOG_WARN, addrport, &address, &addr, &port)<0) {
3591 log_warn(LD_CONFIG, "Error parsing Bridge address '%s'", addrport);
3592 goto err;
3594 if (!port) {
3595 log_warn(LD_CONFIG, "Missing port in Bridge address '%s'",addrport);
3596 goto err;
3599 if (smartlist_len(items)) {
3600 fingerprint = smartlist_join_strings(items, "", 0, NULL);
3601 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
3602 log_warn(LD_CONFIG, "Key digest for Bridge is wrong length.");
3603 goto err;
3605 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
3606 log_warn(LD_CONFIG, "Unable to decode Bridge key digest.");
3607 goto err;
3611 if (!validate_only) {
3612 log_debug(LD_DIR, "Bridge at %s:%d (%s)", address,
3613 (int)port,
3614 fingerprint ? fingerprint : "no key listed");
3615 bridge_add_from_config(addr, port, fingerprint ? digest : NULL);
3618 r = 0;
3619 goto done;
3621 err:
3622 r = -1;
3624 done:
3625 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
3626 smartlist_free(items);
3627 tor_free(addrport);
3628 tor_free(address);
3629 tor_free(fingerprint);
3630 return r;
3633 /** Read the contents of a DirServer line from <b>line</b>. Return 0
3634 * if the line is well-formed, and -1 if it isn't. If
3635 * <b>validate_only</b> is 0, and the line is well-formed, then add
3636 * the dirserver described in the line as a valid authority. */
3637 static int
3638 parse_dir_server_line(const char *line, int validate_only)
3640 smartlist_t *items = NULL;
3641 int r;
3642 char *addrport=NULL, *address=NULL, *nickname=NULL, *fingerprint=NULL;
3643 uint16_t dir_port = 0, or_port = 0;
3644 char digest[DIGEST_LEN];
3645 char v3_digest[DIGEST_LEN];
3646 authority_type_t type = V2_AUTHORITY;
3647 int is_not_hidserv_authority = 0, is_not_v2_authority = 0;
3649 items = smartlist_create();
3650 smartlist_split_string(items, line, NULL,
3651 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
3652 if (smartlist_len(items) < 1) {
3653 log_warn(LD_CONFIG, "No arguments on DirServer line.");
3654 goto err;
3657 if (is_legal_nickname(smartlist_get(items, 0))) {
3658 nickname = smartlist_get(items, 0);
3659 smartlist_del_keeporder(items, 0);
3662 while (smartlist_len(items)) {
3663 char *flag = smartlist_get(items, 0);
3664 if (TOR_ISDIGIT(flag[0]))
3665 break;
3666 if (!strcasecmp(flag, "v1")) {
3667 type |= (V1_AUTHORITY | HIDSERV_AUTHORITY);
3668 } else if (!strcasecmp(flag, "hs")) {
3669 type |= HIDSERV_AUTHORITY;
3670 } else if (!strcasecmp(flag, "no-hs")) {
3671 is_not_hidserv_authority = 1;
3672 } else if (!strcasecmp(flag, "bridge")) {
3673 type |= BRIDGE_AUTHORITY;
3674 } else if (!strcasecmp(flag, "no-v2")) {
3675 is_not_v2_authority = 1;
3676 } else if (!strcasecmpstart(flag, "orport=")) {
3677 int ok;
3678 char *portstring = flag + strlen("orport=");
3679 or_port = (uint16_t) tor_parse_long(portstring, 10, 1, 65535, &ok, NULL);
3680 if (!ok)
3681 log_warn(LD_CONFIG, "Invalid orport '%s' on DirServer line.",
3682 portstring);
3683 } else if (!strcasecmpstart(flag, "v3ident=")) {
3684 char *idstr = flag + strlen("v3ident=");
3685 if (strlen(idstr) != HEX_DIGEST_LEN ||
3686 base16_decode(v3_digest, DIGEST_LEN, idstr, HEX_DIGEST_LEN)<0) {
3687 log_warn(LD_CONFIG, "Bad v3 identity digest '%s' on DirServer line",
3688 flag);
3689 } else {
3690 type |= V3_AUTHORITY;
3692 } else {
3693 log_warn(LD_CONFIG, "Unrecognized flag '%s' on DirServer line",
3694 flag);
3696 tor_free(flag);
3697 smartlist_del_keeporder(items, 0);
3699 if (is_not_hidserv_authority)
3700 type &= ~HIDSERV_AUTHORITY;
3701 if (is_not_v2_authority)
3702 type &= ~V2_AUTHORITY;
3704 if (smartlist_len(items) < 2) {
3705 log_warn(LD_CONFIG, "Too few arguments to DirServer line.");
3706 goto err;
3708 addrport = smartlist_get(items, 0);
3709 smartlist_del_keeporder(items, 0);
3710 if (parse_addr_port(LOG_WARN, addrport, &address, NULL, &dir_port)<0) {
3711 log_warn(LD_CONFIG, "Error parsing DirServer address '%s'", addrport);
3712 goto err;
3714 if (!dir_port) {
3715 log_warn(LD_CONFIG, "Missing port in DirServer address '%s'",addrport);
3716 goto err;
3719 fingerprint = smartlist_join_strings(items, "", 0, NULL);
3720 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
3721 log_warn(LD_CONFIG, "Key digest for DirServer is wrong length %d.",
3722 (int)strlen(fingerprint));
3723 goto err;
3725 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
3726 log_warn(LD_CONFIG, "Unable to decode DirServer key digest.");
3727 goto err;
3730 if (!validate_only) {
3731 log_debug(LD_DIR, "Trusted dirserver at %s:%d (%s)", address,
3732 (int)dir_port,
3733 (char*)smartlist_get(items,0));
3734 add_trusted_dir_server(nickname, address, dir_port, or_port, digest, type);
3737 r = 0;
3738 goto done;
3740 err:
3741 r = -1;
3743 done:
3744 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
3745 smartlist_free(items);
3746 tor_free(addrport);
3747 tor_free(address);
3748 tor_free(nickname);
3749 tor_free(fingerprint);
3750 return r;
3753 /** Adjust the value of options->DataDirectory, or fill it in if it's
3754 * absent. Return 0 on success, -1 on failure. */
3755 static int
3756 normalize_data_directory(or_options_t *options)
3758 #ifdef MS_WINDOWS
3759 char *p;
3760 if (options->DataDirectory)
3761 return 0; /* all set */
3762 p = tor_malloc(MAX_PATH);
3763 strlcpy(p,get_windows_conf_root(),MAX_PATH);
3764 options->DataDirectory = p;
3765 return 0;
3766 #else
3767 const char *d = options->DataDirectory;
3768 if (!d)
3769 d = "~/.tor";
3771 if (strncmp(d,"~/",2) == 0) {
3772 char *fn = expand_filename(d);
3773 if (!fn) {
3774 log_warn(LD_CONFIG,"Failed to expand filename \"%s\".", d);
3775 return -1;
3777 if (!options->DataDirectory && !strcmp(fn,"/.tor")) {
3778 /* If our homedir is /, we probably don't want to use it. */
3779 /* Default to LOCALSTATEDIR/tor which is probably closer to what we
3780 * want. */
3781 log_warn(LD_CONFIG,
3782 "Default DataDirectory is \"~/.tor\". This expands to "
3783 "\"%s\", which is probably not what you want. Using "
3784 "\"%s"PATH_SEPARATOR"tor\" instead", fn, LOCALSTATEDIR);
3785 tor_free(fn);
3786 fn = tor_strdup(LOCALSTATEDIR PATH_SEPARATOR "tor");
3788 tor_free(options->DataDirectory);
3789 options->DataDirectory = fn;
3791 return 0;
3792 #endif
3795 /** Check and normalize the value of options->DataDirectory; return 0 if it
3796 * sane, -1 otherwise. */
3797 static int
3798 validate_data_directory(or_options_t *options)
3800 if (normalize_data_directory(options) < 0)
3801 return -1;
3802 tor_assert(options->DataDirectory);
3803 if (strlen(options->DataDirectory) > (512-128)) {
3804 log_warn(LD_CONFIG, "DataDirectory is too long.");
3805 return -1;
3807 return 0;
3810 /** This string must remain the same forevermore. It is how we
3811 * recognize that the torrc file doesn't need to be backed up. */
3812 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; " \
3813 "if you edit it, comments will not be preserved"
3814 /** This string can change; it tries to give the reader an idea
3815 * that editing this file by hand is not a good plan. */
3816 #define GENERATED_FILE_COMMENT "# The old torrc file was renamed " \
3817 "to torrc.orig.1 or similar, and Tor will ignore it"
3819 /** Save a configuration file for the configuration in <b>options</b>
3820 * into the file <b>fname</b>. If the file already exists, and
3821 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
3822 * replace it. Return 0 on success, -1 on failure. */
3823 static int
3824 write_configuration_file(const char *fname, or_options_t *options)
3826 char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
3827 int rename_old = 0, r;
3828 size_t len;
3830 if (fname) {
3831 switch (file_status(fname)) {
3832 case FN_FILE:
3833 old_val = read_file_to_str(fname, 0, NULL);
3834 if (strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
3835 rename_old = 1;
3837 tor_free(old_val);
3838 break;
3839 case FN_NOENT:
3840 break;
3841 case FN_ERROR:
3842 case FN_DIR:
3843 default:
3844 log_warn(LD_CONFIG,
3845 "Config file \"%s\" is not a file? Failing.", fname);
3846 return -1;
3850 if (!(new_conf = options_dump(options, 1))) {
3851 log_warn(LD_BUG, "Couldn't get configuration string");
3852 goto err;
3855 len = strlen(new_conf)+256;
3856 new_val = tor_malloc(len);
3857 tor_snprintf(new_val, len, "%s\n%s\n\n%s",
3858 GENERATED_FILE_PREFIX, GENERATED_FILE_COMMENT, new_conf);
3860 if (rename_old) {
3861 int i = 1;
3862 size_t fn_tmp_len = strlen(fname)+32;
3863 char *fn_tmp;
3864 tor_assert(fn_tmp_len > strlen(fname)); /*check for overflow*/
3865 fn_tmp = tor_malloc(fn_tmp_len);
3866 while (1) {
3867 if (tor_snprintf(fn_tmp, fn_tmp_len, "%s.orig.%d", fname, i)<0) {
3868 log_warn(LD_BUG, "tor_snprintf failed inexplicably");
3869 tor_free(fn_tmp);
3870 goto err;
3872 if (file_status(fn_tmp) == FN_NOENT)
3873 break;
3874 ++i;
3876 log_notice(LD_CONFIG, "Renaming old configuration file to \"%s\"", fn_tmp);
3877 if (rename(fname, fn_tmp) < 0) {
3878 log_warn(LD_FS,
3879 "Couldn't rename configuration file \"%s\" to \"%s\": %s",
3880 fname, fn_tmp, strerror(errno));
3881 tor_free(fn_tmp);
3882 goto err;
3884 tor_free(fn_tmp);
3887 if (write_str_to_file(fname, new_val, 0) < 0)
3888 goto err;
3890 r = 0;
3891 goto done;
3892 err:
3893 r = -1;
3894 done:
3895 tor_free(new_val);
3896 tor_free(new_conf);
3897 return r;
3901 * Save the current configuration file value to disk. Return 0 on
3902 * success, -1 on failure.
3905 options_save_current(void)
3907 if (torrc_fname) {
3908 /* This fails if we can't write to our configuration file.
3910 * If we try falling back to datadirectory or something, we have a better
3911 * chance of saving the configuration, but a better chance of doing
3912 * something the user never expected. Let's just warn instead. */
3913 return write_configuration_file(torrc_fname, get_options());
3915 return write_configuration_file(get_default_conf_file(), get_options());
3918 /** Mapping from a unit name to a multiplier for converting that unit into a
3919 * base unit. */
3920 struct unit_table_t {
3921 const char *unit;
3922 uint64_t multiplier;
3925 static struct unit_table_t memory_units[] = {
3926 { "", 1 },
3927 { "b", 1<< 0 },
3928 { "byte", 1<< 0 },
3929 { "bytes", 1<< 0 },
3930 { "kb", 1<<10 },
3931 { "kilobyte", 1<<10 },
3932 { "kilobytes", 1<<10 },
3933 { "m", 1<<20 },
3934 { "mb", 1<<20 },
3935 { "megabyte", 1<<20 },
3936 { "megabytes", 1<<20 },
3937 { "gb", 1<<30 },
3938 { "gigabyte", 1<<30 },
3939 { "gigabytes", 1<<30 },
3940 { "tb", U64_LITERAL(1)<<40 },
3941 { "terabyte", U64_LITERAL(1)<<40 },
3942 { "terabytes", U64_LITERAL(1)<<40 },
3943 { NULL, 0 },
3946 static struct unit_table_t time_units[] = {
3947 { "", 1 },
3948 { "second", 1 },
3949 { "seconds", 1 },
3950 { "minute", 60 },
3951 { "minutes", 60 },
3952 { "hour", 60*60 },
3953 { "hours", 60*60 },
3954 { "day", 24*60*60 },
3955 { "days", 24*60*60 },
3956 { "week", 7*24*60*60 },
3957 { "weeks", 7*24*60*60 },
3958 { NULL, 0 },
3961 /** Parse a string <b>val</b> containing a number, zero or more
3962 * spaces, and an optional unit string. If the unit appears in the
3963 * table <b>u</b>, then multiply the number by the unit multiplier.
3964 * On success, set *<b>ok</b> to 1 and return this product.
3965 * Otherwise, set *<b>ok</b> to 0.
3967 static uint64_t
3968 config_parse_units(const char *val, struct unit_table_t *u, int *ok)
3970 uint64_t v;
3971 char *cp;
3973 tor_assert(ok);
3975 v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
3976 if (!*ok)
3977 return 0;
3978 if (!cp) {
3979 *ok = 1;
3980 return v;
3982 while (TOR_ISSPACE(*cp))
3983 ++cp;
3984 for ( ;u->unit;++u) {
3985 if (!strcasecmp(u->unit, cp)) {
3986 v *= u->multiplier;
3987 *ok = 1;
3988 return v;
3991 log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
3992 *ok = 0;
3993 return 0;
3996 /** Parse a string in the format "number unit", where unit is a unit of
3997 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
3998 * and return the number of bytes specified. Otherwise, set
3999 * *<b>ok</b> to false and return 0. */
4000 static uint64_t
4001 config_parse_memunit(const char *s, int *ok)
4003 return config_parse_units(s, memory_units, ok);
4006 /** Parse a string in the format "number unit", where unit is a unit of time.
4007 * On success, set *<b>ok</b> to true and return the number of seconds in
4008 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
4010 static int
4011 config_parse_interval(const char *s, int *ok)
4013 uint64_t r;
4014 r = config_parse_units(s, time_units, ok);
4015 if (!ok)
4016 return -1;
4017 if (r > INT_MAX) {
4018 log_warn(LD_CONFIG, "Interval '%s' is too long", s);
4019 *ok = 0;
4020 return -1;
4022 return (int)r;
4026 * Initialize the libevent library.
4028 static void
4029 init_libevent(void)
4031 configure_libevent_logging();
4032 /* If the kernel complains that some method (say, epoll) doesn't
4033 * exist, we don't care about it, since libevent will cope.
4035 suppress_libevent_log_msg("Function not implemented");
4036 #ifdef __APPLE__
4037 if (decode_libevent_version() < LE_11B) {
4038 setenv("EVENT_NOKQUEUE","1",1);
4039 } else if (!getenv("EVENT_NOKQUEUE")) {
4040 const char *ver = NULL;
4041 #ifdef HAVE_EVENT_GET_VERSION
4042 ver = event_get_version();
4043 #endif
4044 /* If we're 1.1b or later, we'd better have get_version() */
4045 tor_assert(ver);
4046 log(LOG_NOTICE, LD_GENERAL, "Enabling experimental OS X kqueue support "
4047 "with libevent %s. If this turns out to not work, "
4048 "set the environment variable EVENT_NOKQUEUE, and tell the Tor "
4049 "developers.", ver);
4051 #endif
4052 event_init();
4053 suppress_libevent_log_msg(NULL);
4054 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
4055 /* Making this a NOTICE for now so we can link bugs to a libevent versions
4056 * or methods better. */
4057 log(LOG_NOTICE, LD_GENERAL,
4058 "Initialized libevent version %s using method %s. Good.",
4059 event_get_version(), event_get_method());
4060 check_libevent_version(event_get_method(), get_options()->ORPort != 0);
4061 #else
4062 log(LOG_NOTICE, LD_GENERAL,
4063 "Initialized old libevent (version 1.0b or earlier).");
4064 log(LOG_WARN, LD_GENERAL,
4065 "You have a *VERY* old version of libevent. It is likely to be buggy; "
4066 "please build Tor with a more recent version.");
4067 #endif
4070 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
4071 /** Table mapping return value of event_get_version() to le_version_t. */
4072 static const struct {
4073 const char *name; le_version_t version;
4074 } le_version_table[] = {
4075 /* earlier versions don't have get_version. */
4076 { "1.0c", LE_10C },
4077 { "1.0d", LE_10D },
4078 { "1.0e", LE_10E },
4079 { "1.1", LE_11 },
4080 { "1.1a", LE_11A },
4081 { "1.1b", LE_11B },
4082 { "1.2", LE_12 },
4083 { "1.2a", LE_12A },
4084 { "1.3", LE_13 },
4085 { "1.3a", LE_13A },
4086 { "1.3b", LE_13B },
4087 { NULL, LE_OTHER }
4090 /** Return the le_version_t for the current version of libevent. If the
4091 * version is very new, return LE_OTHER. If the version is so old that it
4092 * doesn't support event_get_version(), return LE_OLD. */
4093 static le_version_t
4094 decode_libevent_version(void)
4096 const char *v = event_get_version();
4097 int i;
4098 for (i=0; le_version_table[i].name; ++i) {
4099 if (!strcmp(le_version_table[i].name, v)) {
4100 return le_version_table[i].version;
4103 return LE_OTHER;
4107 * Compare the given libevent method and version to a list of versions
4108 * which are known not to work. Warn the user as appropriate.
4110 static void
4111 check_libevent_version(const char *m, int server)
4113 int buggy = 0, iffy = 0, slow = 0, thread_unsafe = 0;
4114 le_version_t version;
4115 const char *v = event_get_version();
4116 const char *badness = NULL;
4117 const char *sad_os = "";
4119 version = decode_libevent_version();
4121 /* XXX Would it be worthwhile disabling the methods that we know
4122 * are buggy, rather than just warning about them and then proceeding
4123 * to use them? If so, we should probably not wrap this whole thing
4124 * in HAVE_EVENT_GET_VERSION and HAVE_EVENT_GET_METHOD. -RD */
4125 /* XXXX The problem is that it's not trivial to get libevent to change it's
4126 * method once it's initialized, and it's not trivial to tell what method it
4127 * will use without initializing it. I guess we could preemptively disable
4128 * buggy libevent modes based on the version _before_ initializing it,
4129 * though, but then there's no good way (afaict) to warn "I would have used
4130 * kqueue, but instead I'm using select." -NM */
4131 if (!strcmp(m, "kqueue")) {
4132 if (version < LE_11B)
4133 buggy = 1;
4134 } else if (!strcmp(m, "epoll")) {
4135 if (version < LE_11)
4136 iffy = 1;
4137 } else if (!strcmp(m, "poll")) {
4138 if (version < LE_10E)
4139 buggy = 1;
4140 else if (version < LE_11)
4141 slow = 1;
4142 } else if (!strcmp(m, "select")) {
4143 if (version < LE_11)
4144 slow = 1;
4145 } else if (!strcmp(m, "win32")) {
4146 if (version < LE_11B)
4147 buggy = 1;
4150 /* Libevent versions before 1.3b do very badly on operating systems with
4151 * user-space threading implementations. */
4152 #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
4153 if (server && version < LE_13B) {
4154 thread_unsafe = 1;
4155 sad_os = "BSD variants";
4157 #elif defined(__APPLE__) || defined(__darwin__)
4158 if (server && version < LE_13B) {
4159 thread_unsafe = 1;
4160 sad_os = "Mac OS X";
4162 #endif
4164 if (thread_unsafe) {
4165 log(LOG_WARN, LD_GENERAL,
4166 "Libevent version %s often crashes when running a Tor server with %s. "
4167 "Please use the latest version of libevent (1.3b or later)",v,sad_os);
4168 badness = "BROKEN";
4169 } else if (buggy) {
4170 log(LOG_WARN, LD_GENERAL,
4171 "There are known bugs in using %s with libevent %s. "
4172 "Please use the latest version of libevent.", m, v);
4173 badness = "BROKEN";
4174 } else if (iffy) {
4175 log(LOG_WARN, LD_GENERAL,
4176 "There are minor bugs in using %s with libevent %s. "
4177 "You may want to use the latest version of libevent.", m, v);
4178 badness = "BUGGY";
4179 } else if (slow && server) {
4180 log(LOG_WARN, LD_GENERAL,
4181 "libevent %s can be very slow with %s. "
4182 "When running a server, please use the latest version of libevent.",
4183 v,m);
4184 badness = "SLOW";
4186 if (badness) {
4187 control_event_general_status(LOG_WARN,
4188 "BAD_LIBEVENT VERSION=%s METHOD=%s BADNESS=%s RECOVERED=NO",
4189 v, m, badness);
4193 #else
4194 static le_version_t
4195 decode_libevent_version(void)
4197 return LE_OLD;
4199 #endif
4201 /** Return the persistent state struct for this Tor. */
4202 or_state_t *
4203 get_or_state(void)
4205 tor_assert(global_state);
4206 return global_state;
4209 /** Return the filename used to write and read the persistent state. */
4210 static char *
4211 get_or_state_fname(void)
4213 char *fname = NULL;
4214 or_options_t *options = get_options();
4215 size_t len = strlen(options->DataDirectory) + 16;
4216 fname = tor_malloc(len);
4217 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"state", options->DataDirectory);
4218 return fname;
4221 /** Return 0 if every setting in <b>state</b> is reasonable, and a
4222 * permissible transition from <b>old_state</b>. Else warn and return -1.
4223 * Should have no side effects, except for normalizing the contents of
4224 * <b>state</b>.
4226 /* XXX from_setconf is here because of bug 238 */
4227 static int
4228 or_state_validate(or_state_t *old_state, or_state_t *state,
4229 int from_setconf, char **msg)
4231 /* We don't use these; only options do. Still, we need to match that
4232 * signature. */
4233 (void) from_setconf;
4234 (void) old_state;
4235 if (entry_guards_parse_state(state, 0, msg)<0) {
4236 return -1;
4238 if (state->TorVersion) {
4239 tor_version_t v;
4240 if (tor_version_parse(state->TorVersion, &v)) {
4241 log_warn(LD_GENERAL, "Can't parse Tor version '%s' from your state "
4242 "file. Proceeding anyway.", state->TorVersion);
4243 } else { /* take action based on v */
4244 if (tor_version_as_new_as(state->TorVersion, "0.1.1.10-alpha") &&
4245 !tor_version_as_new_as(state->TorVersion, "0.1.1.16-rc-cvs")) {
4246 log_notice(LD_CONFIG, "Detected state file from buggy version '%s'. "
4247 "Enabling workaround to choose working entry guards.",
4248 state->TorVersion);
4249 config_free_lines(state->EntryGuards);
4250 state->EntryGuards = NULL;
4254 return 0;
4257 /** Replace the current persistent state with <b>new_state</b> */
4258 static void
4259 or_state_set(or_state_t *new_state)
4261 char *err = NULL;
4262 tor_assert(new_state);
4263 if (global_state)
4264 config_free(&state_format, global_state);
4265 global_state = new_state;
4266 if (entry_guards_parse_state(global_state, 1, &err)<0) {
4267 log_warn(LD_GENERAL,"%s",err);
4268 tor_free(err);
4270 if (rep_hist_load_state(global_state, &err)<0) {
4271 log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
4272 tor_free(err);
4276 /** Reload the persistent state from disk, generating a new state as needed.
4277 * Return 0 on success, less than 0 on failure.
4280 or_state_load(void)
4282 or_state_t *new_state = NULL;
4283 char *contents = NULL, *fname;
4284 char *errmsg = NULL;
4285 int r = -1, badstate = 0;
4287 fname = get_or_state_fname();
4288 switch (file_status(fname)) {
4289 case FN_FILE:
4290 if (!(contents = read_file_to_str(fname, 0, NULL))) {
4291 log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
4292 goto done;
4294 break;
4295 case FN_NOENT:
4296 break;
4297 case FN_ERROR:
4298 case FN_DIR:
4299 default:
4300 log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
4301 goto done;
4303 new_state = tor_malloc_zero(sizeof(or_state_t));
4304 new_state->_magic = OR_STATE_MAGIC;
4305 config_init(&state_format, new_state);
4306 if (contents) {
4307 config_line_t *lines=NULL;
4308 int assign_retval;
4309 if (config_get_lines(contents, &lines)<0)
4310 goto done;
4311 assign_retval = config_assign(&state_format, new_state,
4312 lines, 0, 0, &errmsg);
4313 config_free_lines(lines);
4314 if (assign_retval<0)
4315 badstate = 1;
4316 if (errmsg) {
4317 log_warn(LD_GENERAL, "%s", errmsg);
4318 tor_free(errmsg);
4322 if (!badstate && or_state_validate(NULL, new_state, 1, &errmsg) < 0)
4323 badstate = 1;
4325 if (errmsg) {
4326 log_warn(LD_GENERAL, "%s", errmsg);
4327 tor_free(errmsg);
4330 if (badstate && !contents) {
4331 log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
4332 " This is a bug in Tor.");
4333 goto done;
4334 } else if (badstate && contents) {
4335 int i;
4336 file_status_t status;
4337 size_t len = strlen(fname)+16;
4338 char *fname2 = tor_malloc(len);
4339 for (i = 0; i < 100; ++i) {
4340 tor_snprintf(fname2, len, "%s.%d", fname, i);
4341 status = file_status(fname2);
4342 if (status == FN_NOENT)
4343 break;
4345 if (i == 100) {
4346 log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
4347 "state files to move aside. Discarding the old state file.",
4348 fname);
4349 unlink(fname);
4350 } else {
4351 log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
4352 "to \"%s\". This could be a bug in Tor; please tell "
4353 "the developers.", fname, fname2);
4354 rename(fname, fname2);
4356 tor_free(fname2);
4357 tor_free(contents);
4358 config_free(&state_format, new_state);
4360 new_state = tor_malloc_zero(sizeof(or_state_t));
4361 new_state->_magic = OR_STATE_MAGIC;
4362 config_init(&state_format, new_state);
4363 } else if (contents) {
4364 log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
4365 } else {
4366 log_info(LD_GENERAL, "Initialized state");
4368 or_state_set(new_state);
4369 new_state = NULL;
4370 if (!contents) {
4371 global_state->next_write = 0;
4372 or_state_save(time(NULL));
4374 r = 0;
4376 done:
4377 tor_free(fname);
4378 tor_free(contents);
4379 if (new_state)
4380 config_free(&state_format, new_state);
4382 return r;
4385 /** Write the persistent state to disk. Return 0 for success, <0 on failure. */
4387 or_state_save(time_t now)
4389 char *state, *contents;
4390 char tbuf[ISO_TIME_LEN+1];
4391 size_t len;
4392 char *fname;
4394 tor_assert(global_state);
4396 if (global_state->next_write > now)
4397 return 0;
4399 /* Call everything else that might dirty the state even more, in order
4400 * to avoid redundant writes. */
4401 entry_guards_update_state(global_state);
4402 rep_hist_update_state(global_state);
4403 if (accounting_is_enabled(get_options()))
4404 accounting_run_housekeeping(now);
4406 global_state->LastWritten = time(NULL);
4407 tor_free(global_state->TorVersion);
4408 len = strlen(get_version())+8;
4409 global_state->TorVersion = tor_malloc(len);
4410 tor_snprintf(global_state->TorVersion, len, "Tor %s", get_version());
4412 state = config_dump(&state_format, global_state, 1, 0);
4413 len = strlen(state)+256;
4414 contents = tor_malloc(len);
4415 format_local_iso_time(tbuf, time(NULL));
4416 tor_snprintf(contents, len,
4417 "# Tor state file last generated on %s local time\n"
4418 "# Other times below are in GMT\n"
4419 "# You *do not* need to edit this file.\n\n%s",
4420 tbuf, state);
4421 tor_free(state);
4422 fname = get_or_state_fname();
4423 if (write_str_to_file(fname, contents, 0)<0) {
4424 log_warn(LD_FS, "Unable to write state to file \"%s\"", fname);
4425 tor_free(fname);
4426 tor_free(contents);
4427 return -1;
4429 log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
4430 tor_free(fname);
4431 tor_free(contents);
4433 global_state->next_write = TIME_MAX;
4434 return 0;
4437 /** Helper to implement GETINFO functions about configuration variables (not
4438 * their values). Given a "config/names" question, set *<b>answer</b> to a
4439 * new string describing the supported configuration variables and their
4440 * types. */
4442 getinfo_helper_config(control_connection_t *conn,
4443 const char *question, char **answer)
4445 (void) conn;
4446 if (!strcmp(question, "config/names")) {
4447 smartlist_t *sl = smartlist_create();
4448 int i;
4449 for (i = 0; _option_vars[i].name; ++i) {
4450 config_var_t *var = &_option_vars[i];
4451 const char *type, *desc;
4452 char *line;
4453 size_t len;
4454 desc = config_find_description(&options_format, var->name);
4455 switch (var->type) {
4456 case CONFIG_TYPE_STRING: type = "String"; break;
4457 case CONFIG_TYPE_UINT: type = "Integer"; break;
4458 case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
4459 case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
4460 case CONFIG_TYPE_DOUBLE: type = "Float"; break;
4461 case CONFIG_TYPE_BOOL: type = "Boolean"; break;
4462 case CONFIG_TYPE_ISOTIME: type = "Time"; break;
4463 case CONFIG_TYPE_CSV: type = "CommaList"; break;
4464 case CONFIG_TYPE_LINELIST: type = "LineList"; break;
4465 case CONFIG_TYPE_LINELIST_S: type = "Dependant"; break;
4466 case CONFIG_TYPE_LINELIST_V: type = "Virtual"; break;
4467 default:
4468 case CONFIG_TYPE_OBSOLETE:
4469 type = NULL; break;
4471 if (!type)
4472 continue;
4473 len = strlen(var->name)+strlen(type)+16;
4474 if (desc)
4475 len += strlen(desc);
4476 line = tor_malloc(len);
4477 if (desc)
4478 tor_snprintf(line, len, "%s %s %s\n",var->name,type,desc);
4479 else
4480 tor_snprintf(line, len, "%s %s\n",var->name,type);
4481 smartlist_add(sl, line);
4483 *answer = smartlist_join_strings(sl, "", 0, NULL);
4484 SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
4485 smartlist_free(sl);
4487 return 0;
4490 #include "../common/ht.h"
4491 #include "../common/test.h"
4493 extern const char aes_c_id[];
4494 extern const char compat_c_id[];
4495 extern const char container_c_id[];
4496 extern const char crypto_c_id[];
4497 extern const char log_c_id[];
4498 extern const char torgzip_c_id[];
4499 extern const char tortls_c_id[];
4500 extern const char util_c_id[];
4502 extern const char buffers_c_id[];
4503 extern const char circuitbuild_c_id[];
4504 extern const char circuitlist_c_id[];
4505 extern const char circuituse_c_id[];
4506 extern const char command_c_id[];
4507 // extern const char config_c_id[];
4508 extern const char connection_c_id[];
4509 extern const char connection_edge_c_id[];
4510 extern const char connection_or_c_id[];
4511 extern const char control_c_id[];
4512 extern const char cpuworker_c_id[];
4513 extern const char directory_c_id[];
4514 extern const char dirserv_c_id[];
4515 extern const char dns_c_id[];
4516 extern const char hibernate_c_id[];
4517 extern const char main_c_id[];
4518 extern const char onion_c_id[];
4519 extern const char policies_c_id[];
4520 extern const char relay_c_id[];
4521 extern const char rendclient_c_id[];
4522 extern const char rendcommon_c_id[];
4523 extern const char rendmid_c_id[];
4524 extern const char rendservice_c_id[];
4525 extern const char rephist_c_id[];
4526 extern const char router_c_id[];
4527 extern const char routerlist_c_id[];
4528 extern const char routerparse_c_id[];
4530 /** Dump the version of every file to the log. */
4531 static void
4532 print_svn_version(void)
4534 puts(AES_H_ID);
4535 puts(COMPAT_H_ID);
4536 puts(CONTAINER_H_ID);
4537 puts(CRYPTO_H_ID);
4538 puts(HT_H_ID);
4539 puts(TEST_H_ID);
4540 puts(LOG_H_ID);
4541 puts(TORGZIP_H_ID);
4542 puts(TORINT_H_ID);
4543 puts(TORTLS_H_ID);
4544 puts(UTIL_H_ID);
4545 puts(aes_c_id);
4546 puts(compat_c_id);
4547 puts(container_c_id);
4548 puts(crypto_c_id);
4549 puts(log_c_id);
4550 puts(torgzip_c_id);
4551 puts(tortls_c_id);
4552 puts(util_c_id);
4554 puts(OR_H_ID);
4555 puts(buffers_c_id);
4556 puts(circuitbuild_c_id);
4557 puts(circuitlist_c_id);
4558 puts(circuituse_c_id);
4559 puts(command_c_id);
4560 puts(config_c_id);
4561 puts(connection_c_id);
4562 puts(connection_edge_c_id);
4563 puts(connection_or_c_id);
4564 puts(control_c_id);
4565 puts(cpuworker_c_id);
4566 puts(directory_c_id);
4567 puts(dirserv_c_id);
4568 puts(dns_c_id);
4569 puts(hibernate_c_id);
4570 puts(main_c_id);
4571 puts(onion_c_id);
4572 puts(policies_c_id);
4573 puts(relay_c_id);
4574 puts(rendclient_c_id);
4575 puts(rendcommon_c_id);
4576 puts(rendmid_c_id);
4577 puts(rendservice_c_id);
4578 puts(rephist_c_id);
4579 puts(router_c_id);
4580 puts(routerlist_c_id);
4581 puts(routerparse_c_id);