r11944@catbus: nickm | 2007-02-25 14:43:18 -0500
[tor.git] / src / or / config.c
blob70b4dc598d5417d76c7c36013449a10c34d3550d
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 #include "or.h"
15 #ifdef MS_WINDOWS
16 #include <shlobj.h>
17 #endif
18 #include "../common/aes.h"
20 /** Enumeration of types which option values can take */
21 typedef enum config_type_t {
22 CONFIG_TYPE_STRING = 0, /**< An arbitrary string. */
23 CONFIG_TYPE_UINT, /**< A non-negative integer less than MAX_INT */
24 CONFIG_TYPE_INTERVAL, /**< A number of seconds, with optional units*/
25 CONFIG_TYPE_MEMUNIT, /**< A number of bytes, with optional units*/
26 CONFIG_TYPE_DOUBLE, /**< A floating-point value */
27 CONFIG_TYPE_BOOL, /**< A boolean value, expressed as 0 or 1. */
28 CONFIG_TYPE_ISOTIME, /**< An ISO-formated time relative to GMT. */
29 CONFIG_TYPE_CSV, /**< A list of strings, separated by commas and
30 * optional whitespace. */
31 CONFIG_TYPE_LINELIST, /**< Uninterpreted config lines */
32 CONFIG_TYPE_LINELIST_S, /**< Uninterpreted, context-sensitive config lines,
33 * mixed with other keywords. */
34 CONFIG_TYPE_LINELIST_V, /**< Catch-all "virtual" option to summarize
35 * context-sensitive config lines when fetching.
37 CONFIG_TYPE_OBSOLETE, /**< Obsolete (ignored) option. */
38 } config_type_t;
40 /** An abbreviation for a configuration option allowed on the command line. */
41 typedef struct config_abbrev_t {
42 const char *abbreviated;
43 const char *full;
44 int commandline_only;
45 int warn;
46 } config_abbrev_t;
48 /* Handy macro for declaring "In the config file or on the command line,
49 * you can abbreviate <b>tok</b>s as <b>tok</b>". */
50 #define PLURAL(tok) { #tok, #tok "s", 0, 0 }
52 /* A list of command-line abbreviations. */
53 static config_abbrev_t _option_abbrevs[] = {
54 PLURAL(ExitNode),
55 PLURAL(EntryNode),
56 PLURAL(ExcludeNode),
57 PLURAL(FirewallPort),
58 PLURAL(LongLivedPort),
59 PLURAL(HiddenServiceNode),
60 PLURAL(HiddenServiceExcludeNode),
61 PLURAL(NumCpu),
62 PLURAL(RendNode),
63 PLURAL(RendExcludeNode),
64 PLURAL(StrictEntryNode),
65 PLURAL(StrictExitNode),
66 { "l", "Log", 1, 0},
67 { "AllowUnverifiedNodes", "AllowInvalidNodes", 0, 0},
68 { "BandwidthRateBytes", "BandwidthRate", 0, 0},
69 { "BandwidthBurstBytes", "BandwidthBurst", 0, 0},
70 { "DirFetchPostPeriod", "StatusFetchPeriod", 0, 0},
71 { "MaxConn", "ConnLimit", 0, 1},
72 { "ORBindAddress", "ORListenAddress", 0, 0},
73 { "DirBindAddress", "DirListenAddress", 0, 0},
74 { "SocksBindAddress", "SocksListenAddress", 0, 0},
75 { "UseHelperNodes", "UseEntryGuards", 0, 0},
76 { "NumHelperNodes", "NumEntryGuards", 0, 0},
77 { "UseEntryNodes", "UseEntryGuards", 0, 0},
78 { "NumEntryNodes", "NumEntryGuards", 0, 0},
79 { "ResolvConf", "ServerDNSResolvConfFile", 0, 1},
80 { "SearchDomains", "ServerDNSSearchDomains", 0, 1},
81 { NULL, NULL, 0, 0},
83 /* A list of state-file abbreviations, for compatibility. */
84 static config_abbrev_t _state_abbrevs[] = {
85 { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
86 { "HelperNode", "EntryGuard", 0, 0 },
87 { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
88 { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
89 { "EntryNode", "EntryGuard", 0, 0 },
90 { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
91 { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
92 { NULL, NULL, 0, 0},
94 #undef PLURAL
96 /** A variable allowed in the configuration file or on the command line. */
97 typedef struct config_var_t {
98 const char *name; /**< The full keyword (case insensitive). */
99 config_type_t type; /**< How to interpret the type and turn it into a
100 * value. */
101 off_t var_offset; /**< Offset of the corresponding member of or_options_t. */
102 const char *initvalue; /**< String (or null) describing initial value. */
103 } config_var_t;
105 /** An entry for config_vars: "The option <b>name</b> has type
106 * CONFIG_TYPE_<b>conftype</b>, and corresponds to
107 * or_options_t.<b>member</b>"
109 #define VAR(name,conftype,member,initvalue) \
110 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), \
111 initvalue }
112 /** An entry for config_vars: "The option <b>name</b> is obsolete." */
113 #define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
115 /** Array of configuration options. Until we disallow nonstandard
116 * abbreviations, order is significant, since the first matching option will
117 * be chosen first.
119 static config_var_t _option_vars[] = {
120 OBSOLETE("AccountingMaxKB"),
121 VAR("AccountingMax", MEMUNIT, AccountingMax, "0 bytes"),
122 VAR("AccountingStart", STRING, AccountingStart, NULL),
123 VAR("Address", STRING, Address, NULL),
124 VAR("__AllDirActionsPrivate",BOOL, AllDirActionsPrivate, "0"),
125 VAR("AllowInvalidNodes", CSV, AllowInvalidNodes,
126 "middle,rendezvous"),
127 VAR("AllowNonRFC953Hostnames", BOOL, AllowNonRFC953Hostnames, "0"),
128 VAR("AssumeReachable", BOOL, AssumeReachable, "0"),
129 VAR("AuthDirBadExit", LINELIST, AuthDirBadExit, NULL),
130 VAR("AuthDirInvalid", LINELIST, AuthDirInvalid, NULL),
131 VAR("AuthDirReject", LINELIST, AuthDirReject, NULL),
132 VAR("AuthDirRejectUnlisted",BOOL, AuthDirRejectUnlisted,"0"),
133 VAR("AuthDirListBadExits", BOOL, AuthDirListBadExits, "0"),
134 VAR("AuthoritativeDirectory",BOOL, AuthoritativeDir, "0"),
135 VAR("AvoidDiskWrites", BOOL, AvoidDiskWrites, "0"),
136 VAR("BandwidthBurst", MEMUNIT, BandwidthBurst, "6 MB"),
137 VAR("BandwidthRate", MEMUNIT, BandwidthRate, "3 MB"),
138 VAR("CircuitBuildTimeout", INTERVAL, CircuitBuildTimeout, "1 minute"),
139 VAR("CircuitIdleTimeout", INTERVAL, CircuitIdleTimeout, "1 hour"),
140 VAR("ClientOnly", BOOL, ClientOnly, "0"),
141 VAR("ConnLimit", UINT, ConnLimit, "1000"),
142 VAR("ContactInfo", STRING, ContactInfo, NULL),
143 VAR("ControlListenAddress",LINELIST, ControlListenAddress, NULL),
144 VAR("ControlPort", UINT, ControlPort, "0"),
145 VAR("CookieAuthentication",BOOL, CookieAuthentication, "0"),
146 VAR("DataDirectory", STRING, DataDirectory, NULL),
147 OBSOLETE("DebugLogFile"),
148 VAR("DirAllowPrivateAddresses",BOOL, DirAllowPrivateAddresses, NULL),
149 VAR("DirListenAddress", LINELIST, DirListenAddress, NULL),
150 OBSOLETE("DirFetchPeriod"),
151 VAR("DirPolicy", LINELIST, DirPolicy, NULL),
152 VAR("DirPort", UINT, DirPort, "0"),
153 OBSOLETE("DirPostPeriod"),
154 VAR("DirServer", LINELIST, DirServers, NULL),
155 VAR("EnforceDistinctSubnets", BOOL, EnforceDistinctSubnets,"1"),
156 VAR("EntryNodes", STRING, EntryNodes, NULL),
157 VAR("ExcludeNodes", STRING, ExcludeNodes, NULL),
158 VAR("ExitNodes", STRING, ExitNodes, NULL),
159 VAR("ExitPolicy", LINELIST, ExitPolicy, NULL),
160 VAR("ExitPolicyRejectPrivate", BOOL, ExitPolicyRejectPrivate, "1"),
161 VAR("FascistFirewall", BOOL, FascistFirewall, "0"),
162 VAR("FirewallPorts", CSV, FirewallPorts, ""),
163 VAR("FastFirstHopPK", BOOL, FastFirstHopPK, "1"),
164 VAR("FetchServerDescriptors",BOOL, FetchServerDescriptors,"1"),
165 VAR("FetchHidServDescriptors",BOOL, FetchHidServDescriptors, "1"),
166 VAR("FetchUselessDescriptors",BOOL, FetchUselessDescriptors, "0"),
167 VAR("Group", STRING, Group, NULL),
168 VAR("HardwareAccel", BOOL, HardwareAccel, "0"),
169 VAR("HashedControlPassword",STRING, HashedControlPassword, NULL),
170 VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
171 VAR("HiddenServiceExcludeNodes", LINELIST_S, RendConfigLines, NULL),
172 VAR("HiddenServiceNodes", LINELIST_S, RendConfigLines, NULL),
173 VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
174 VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
175 VAR("HSAuthoritativeDir", BOOL, HSAuthoritativeDir, "0"),
176 VAR("HttpProxy", STRING, HttpProxy, NULL),
177 VAR("HttpProxyAuthenticator",STRING, HttpProxyAuthenticator,NULL),
178 VAR("HttpsProxy", STRING, HttpsProxy, NULL),
179 VAR("HttpsProxyAuthenticator",STRING,HttpsProxyAuthenticator,NULL),
180 OBSOLETE("IgnoreVersion"),
181 VAR("KeepalivePeriod", INTERVAL, KeepalivePeriod, "5 minutes"),
182 VAR("Log", LINELIST, Logs, NULL),
183 OBSOLETE("LinkPadding"),
184 OBSOLETE("LogLevel"),
185 OBSOLETE("LogFile"),
186 VAR("LongLivedPorts", CSV, LongLivedPorts,
187 "21,22,706,1863,5050,5190,5222,5223,6667,6697,8300"),
188 VAR("MapAddress", LINELIST, AddressMap, NULL),
189 VAR("MaxAdvertisedBandwidth",MEMUNIT,MaxAdvertisedBandwidth,"128 TB"),
190 VAR("MaxCircuitDirtiness", INTERVAL, MaxCircuitDirtiness, "10 minutes"),
191 VAR("MaxOnionsPending", UINT, MaxOnionsPending, "100"),
192 OBSOLETE("MonthlyAccountingStart"),
193 VAR("MyFamily", STRING, MyFamily, NULL),
194 VAR("NewCircuitPeriod", INTERVAL, NewCircuitPeriod, "30 seconds"),
195 VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "0"),
196 VAR("NatdListenAddress", LINELIST, NatdListenAddress, NULL),
197 VAR("NatdPort", UINT, NatdPort, "0"),
198 VAR("Nickname", STRING, Nickname, NULL),
199 VAR("NoPublish", BOOL, NoPublish, "0"),
200 VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
201 VAR("NumCpus", UINT, NumCpus, "1"),
202 VAR("NumEntryGuards", UINT, NumEntryGuards, "3"),
203 VAR("ORListenAddress", LINELIST, ORListenAddress, NULL),
204 VAR("ORPort", UINT, ORPort, "0"),
205 VAR("OutboundBindAddress", STRING, OutboundBindAddress, NULL),
206 OBSOLETE("PathlenCoinWeight"),
207 VAR("PidFile", STRING, PidFile, NULL),
208 VAR("PreferTunneledDirConns", BOOL, PreferTunneledDirConns, "0"),
209 VAR("ProtocolWarnings", BOOL, ProtocolWarnings, "0"),
210 VAR("PublishServerDescriptor",BOOL, PublishServerDescriptor,"1"),
211 VAR("PublishHidServDescriptors",BOOL,PublishHidServDescriptors, "1"),
212 VAR("ReachableAddresses", LINELIST, ReachableAddresses, NULL),
213 VAR("ReachableDirAddresses",LINELIST,ReachableDirAddresses,NULL),
214 VAR("ReachableORAddresses",LINELIST, ReachableORAddresses, NULL),
215 VAR("RecommendedVersions", LINELIST, RecommendedVersions, NULL),
216 VAR("RecommendedClientVersions", LINELIST, RecommendedClientVersions, NULL),
217 VAR("RecommendedServerVersions", LINELIST, RecommendedServerVersions, NULL),
218 VAR("RedirectExit", LINELIST, RedirectExit, NULL),
219 VAR("RendExcludeNodes", STRING, RendExcludeNodes, NULL),
220 VAR("RendNodes", STRING, RendNodes, NULL),
221 VAR("RendPostPeriod", INTERVAL, RendPostPeriod, "1 hour"),
222 VAR("RephistTrackTime", INTERVAL, RephistTrackTime, "24 hours"),
223 OBSOLETE("RouterFile"),
224 VAR("RunAsDaemon", BOOL, RunAsDaemon, "0"),
225 VAR("RunTesting", BOOL, RunTesting, "0"),
226 VAR("SafeLogging", BOOL, SafeLogging, "1"),
227 VAR("SafeSocks", BOOL, SafeSocks, "0"),
228 VAR("ServerDNSAllowNonRFC953Hostnames",
229 BOOL, ServerDNSAllowNonRFC953Hostnames, "0"),
230 VAR("ServerDNSDetectHijacking",BOOL, ServerDNSDetectHijacking,"1"),
231 VAR("ServerDNSResolvConfFile", STRING, ServerDNSResolvConfFile, NULL),
232 VAR("ServerDNSSearchDomains", BOOL, ServerDNSSearchDomains, "0"),
233 VAR("ServerDNSTestAddresses", CSV, ServerDNSTestAddresses,
234 "www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"),
235 VAR("ShutdownWaitLength", INTERVAL, ShutdownWaitLength, "30 seconds"),
236 VAR("SocksListenAddress", LINELIST, SocksListenAddress, NULL),
237 VAR("SocksPolicy", LINELIST, SocksPolicy, NULL),
238 VAR("SocksPort", UINT, SocksPort, "9050"),
239 VAR("SocksTimeout", INTERVAL, SocksTimeout, "2 minutes"),
240 OBSOLETE("StatusFetchPeriod"),
241 VAR("StrictEntryNodes", BOOL, StrictEntryNodes, "0"),
242 VAR("StrictExitNodes", BOOL, StrictExitNodes, "0"),
243 OBSOLETE("SysLog"),
244 VAR("TestSocks", BOOL, TestSocks, "0"),
245 VAR("TestVia", STRING, TestVia, NULL),
246 VAR("TrackHostExits", CSV, TrackHostExits, NULL),
247 VAR("TrackHostExitsExpire",INTERVAL, TrackHostExitsExpire, "30 minutes"),
248 OBSOLETE("TrafficShaping"),
249 VAR("TransListenAddress", LINELIST, TransListenAddress, NULL),
250 VAR("TransPort", UINT, TransPort, "0"),
251 VAR("TunnelDirConns", BOOL, TunnelDirConns, "0"),
252 VAR("UseEntryGuards", BOOL, UseEntryGuards, "1"),
253 VAR("User", STRING, User, NULL),
254 VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
255 VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
256 VAR("VirtualAddrNetwork", STRING, VirtualAddrNetwork, "127.192.0.0/10"),
257 VAR("__LeaveStreamsUnattached", BOOL,LeaveStreamsUnattached, "0"),
258 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
260 #undef VAR
262 #define VAR(name,conftype,member,initvalue) \
263 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member), \
264 initvalue }
265 static config_var_t _state_vars[] = {
266 VAR("AccountingBytesReadInInterval", MEMUNIT,
267 AccountingBytesReadInInterval, NULL),
268 VAR("AccountingBytesWrittenInInterval", MEMUNIT,
269 AccountingBytesWrittenInInterval, NULL),
270 VAR("AccountingExpectedUsage", MEMUNIT, AccountingExpectedUsage, NULL),
271 VAR("AccountingIntervalStart", ISOTIME, AccountingIntervalStart, NULL),
272 VAR("AccountingSecondsActive", INTERVAL, AccountingSecondsActive, NULL),
273 VAR("EntryGuard", LINELIST_S, EntryGuards, NULL),
274 VAR("EntryGuardDownSince", LINELIST_S, EntryGuards, NULL),
275 VAR("EntryGuardUnlistedSince", LINELIST_S, EntryGuards, NULL),
276 VAR("EntryGuards", LINELIST_V, EntryGuards, NULL),
278 VAR("BWHistoryReadEnds", ISOTIME, BWHistoryReadEnds, NULL),
279 VAR("BWHistoryReadInterval", UINT, BWHistoryReadInterval, "900"),
280 VAR("BWHistoryReadValues", CSV, BWHistoryReadValues, ""),
281 VAR("BWHistoryWriteEnds", ISOTIME, BWHistoryWriteEnds, NULL),
282 VAR("BWHistoryWriteInterval", UINT, BWHistoryWriteInterval, "900"),
283 VAR("BWHistoryWriteValues", CSV, BWHistoryWriteValues, ""),
285 VAR("TorVersion", STRING, TorVersion, NULL),
287 VAR("LastRotatedOnionKey", ISOTIME, LastRotatedOnionKey, NULL),
288 VAR("LastWritten", ISOTIME, LastWritten, NULL),
290 { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
293 #undef VAR
294 #undef OBSOLETE
296 /** Represents an English description of a configuration variable; used when
297 * generating configuration file comments. */
298 typedef struct config_var_description_t {
299 const char *name;
300 const char *description;
301 } config_var_description_t;
303 static config_var_description_t options_description[] = {
304 /* ==== general options */
305 { "AvoidDiskWrites", "If non-zero, try to write to disk less frequently than"
306 " we would otherwise." },
307 { "BandwidthRate", "A token bucket limits the average incoming bandwidth on "
308 "this node to the specified number of bytes per second." },
309 { "BandwidthBurst", "Limit the maximum token buffer size (also known as "
310 "burst) to the given number of bytes." },
311 { "ConnLimit", "Maximum number of simultaneous sockets allowed." },
312 /* ControlListenAddress */
313 { "ControlPort", "If set, Tor will accept connections from the same machine "
314 "(localhost only) on this port, and allow those connections to control "
315 "the Tor process using the Tor Control Protocol (described in"
316 "control-spec.txt).", },
317 { "CookieAuthentication", "If this option is set to 1, don't allow any "
318 "connections to the control port except when the connecting process "
319 "can read a file that Tor creates in its data directory." },
320 { "DataDirectory", "Store working data, state, keys, and caches here." },
321 { "DirServer", "Tor only trusts directories signed with one of these "
322 "servers' keys. Used to override the standard list of directory "
323 "authorities." },
324 /* { "FastFirstHopPK", "" }, */
325 /* FetchServerDescriptors, FetchHidServDescriptors,
326 * FetchUselessDescriptors */
327 { "Group", "On startup, setgid to this group." },
328 { "HardwareAccel", "If set, Tor tries to use hardware crypto accelerators "
329 "when it can." },
330 /* HashedControlPassword */
331 { "HTTPProxy", "Force Tor to make all HTTP directory requests through this "
332 "host:port (or host:80 if port is not set)." },
333 { "HTTPProxyAuthenticator", "A username:password pair to be used with "
334 "HTTPProxy." },
335 { "HTTPSProxy", "Force Tor to make all TLS (SSL) connectinos through this "
336 "host:port (or host:80 if port is not set)." },
337 { "HTTPSProxyAuthenticator", "A username:password pair to be used with "
338 "HTTPSProxy." },
339 { "KeepalivePeriod", "Send a padding cell every N seconds to keep firewalls "
340 "from closing our connections while Tor is not in use." },
341 { "Log", "Where to send logging messages. Format is "
342 "minSeverity[-maxSeverity] (stderr|stdout|syslog|file FILENAME)." },
343 { "OutboundBindAddress", "Make all outbound connections originate from the "
344 "provided IP address (only useful for multiple network interfaces)." },
345 { "PIDFile", "On startup, write our PID to this file. On clean shutdown, "
346 "remove the file." },
347 { "PreferTunneledDirConns", "If non-zero, avoid directory servers that "
348 "don't support tunneled conncetions." },
349 /* PreferTunneledDirConns */
350 /* ProtocolWarnings */
351 /* RephistTrackTime */
352 { "RunAsDaemon", "If set, Tor forks and daemonizes to the background when "
353 "started. Unix only." },
354 { "SafeLogging", "If set to 0, Tor logs potentially sensitive strings "
355 "rather than replacing them with the string [scrubbed]." },
356 { "TunnelDirConns", "If non-zero, when a directory server we contact "
357 "supports it, we will build a one-hop circuit and make an encrypted "
358 "connection via its ORPort." },
359 { "User", "On startup, setuid to this user" },
361 /* ==== client options */
362 { "AllowInvalidNodes", "Where on our circuits should Tor allow servers "
363 "that the directory authorities haven't called \"valid\"?" },
364 { "AllowNonRFC953Hostnames", "If set to 1, we don't automatically reject "
365 "hostnames for having invalid characters." },
366 /* CircuitBuildTimeout, CircuitIdleTimeout */
367 { "ClientOnly", "If set to 1, Tor will under no circumstances run as a "
368 "server, even if ORPort is enabled." },
369 { "EntryNodes", "A list of preferred entry nodes to use for the first hop "
370 "in circuits, when possible." },
371 /* { "EnforceDistinctSubnets" , "" }, */
372 { "ExitNodes", "A list of preferred nodes to use for the last hop in "
373 "circuits, when possible." },
374 { "ExcludeNodes", "A list of nodes never to use when building a circuit." },
375 { "FascistFirewall", "If set, Tor will only create outgoing connections to "
376 "servers running on the ports listed in FirewallPorts." },
377 { "FirewallPorts", "A list of ports that we can connect to. Only used "
378 "when FascistFirewall is set." },
379 { "LongLivedPorts", "A list of ports for services that tend to require "
380 "high-uptime connections." },
381 { "MapAddress", "Force Tor to treat all requests for one address as if "
382 "they were for another." },
383 { "NewCircuitPeriod", "Force Tor to consider whether to build a new circuit "
384 "every NUM seconds." },
385 { "MaxCircuitDirtiness", "Do not attach new streams to a circuit that has "
386 "been used more than this many seconds ago." },
387 /* NatdPort, NatdListenAddress */
388 { "NodeFamily", "A list of servers that constitute a 'family' and should "
389 "never be used in the same circuit." },
390 { "NumEntryGuards", "How many entry guards should we keep at a time?" },
391 /* PathlenCoinWeight */
392 { "ReachableAddresses", "Addresses we can connect to, as IP/bits:port-port. "
393 "By default, we assume all addresses are reachable." },
394 /* reachablediraddresses, reachableoraddresses. */
395 { "RendNodes", "A list of preferred nodes to use for a rendezvous point, "
396 "when possible." },
397 { "RendExcludenodes", "A list of nodes never to use as rendezvous points." },
398 /* SafeSOCKS */
399 { "SOCKSPort", "The port where we listen for SOCKS connections from "
400 "applications." },
401 { "SOCKSListenAddress", "Bind to this address to listen to connections from "
402 "SOCKS-speaking applications." },
403 { "SOCKSPolicy", "Set an entry policy to limit which addresses can connect "
404 "to the SOCKSPort." },
405 /* SocksTimeout */
406 { "StrictExitNodes", "If set, Tor will fail to operate when none of the "
407 "configured ExitNodes can be used." },
408 { "StrictEntryNodes", "If set, Tor will fail to operate when none of the "
409 "configured EntryNodes can be used." },
410 /* TestSocks */
411 { "TrackHostsExit", "Hosts and domains which should, if possible, be "
412 "accessed from the same exit node each time we connect to them." },
413 { "TrackHostsExitExpire", "Time after which we forget which exit we were "
414 "using to connect to hosts in TrackHostsExit." },
415 /* "TransPort", "TransListenAddress */
416 { "UseEntryGuards", "Set to 0 if we want to pick from the whole set of "
417 "servers for the first position in each circuit, rather than picking a "
418 "set of 'Guards' to prevent profiling attacks." },
420 /* === server options */
421 { "Address", "The advertised (external) address we should use." },
422 /* Accounting* options. */
423 /* AssumeReachable */
424 { "ContactInfo", "Administrative contact information to advertise for this "
425 "server." },
426 { "ExitPolicy", "Address/port ranges for which to accept or reject outgoing "
427 "connections on behalf of Tor users." },
428 /* { "ExitPolicyRejectPrivate, "" }, */
429 { "MaxAdvertisedBandwidth", "If set, we will not advertise more than this "
430 "amount of bandwidth for our bandwidth rate, regardless of how much "
431 "bandwidth we actually detect." },
432 { "MaxOnionsPending", "Reject new attempts to extend circuits when we "
433 "already have this many pending." },
434 { "MyFamily", "Declare a list of other servers as belonging to the same "
435 "family as this one, so that clients will not use two from the same "
436 "family in the same circuit." },
437 { "Nickname", "Set the server nickname." },
438 { "NoPublish", "{DEPRECATED}" },
439 { "NumCPUs", "How many processes to use at once for public-key crypto." },
440 { "ORPort", "Advertise this port to listen for connections from Tor clients "
441 "and servers." },
442 { "ORListenAddress", "Bind to this address to listen for connections from "
443 "clients and servers, instead of the default 0.0.0.0:ORPort." },
444 { "PublishServerDescriptors", "Set to 0 in order to keep the server from "
445 "uploading info to the directory authorities." },
446 /*{ "RedirectExit", "When an outgoing connection tries to connect to a "
447 *"given address, redirect it to another address instead." },
449 /* ServerDNS: DetectHijacking, ResolvConfFile, SearchDomains */
450 { "ShutdownWaitLength", "Wait this long for clients to finish when "
451 "shutting down because of a SIGINT." },
452 /* { "TestVia", } */
454 /* === directory cache options */
455 { "DirPort", "Serve directory information from this port, and act as a "
456 "directory cache." },
457 { "DirListenAddress", "Bind to this address to listen for connections from "
458 "clients and servers, instead of the default 0.0.0.0:DirPort." },
459 { "DirPolicy", "Set a policy to limit who can connect to the directory "
460 "port" },
462 /* Authority options: AuthDirBadExit, AuthDirInvalid, AuthDirReject,
463 * AuthDirRejectUnlisted, AuthDirListBadExits, AuthoritativeDirectory,
464 * DirAllowPrivateAddresses, HSAuthoritativeDir,
465 * NamingAuthoritativeDirectory, RecommendedVersions,
466 * RecommendedClientVersions, RecommendedServerVersions, RendPostPeriod,
467 * RunTesting, V1AuthoritativeDirectory, VersioningAuthoritativeDirectory, */
469 /* Hidden service options: HiddenService: dir,excludenodes, nodes,
470 * options, port. PublishHidServDescriptor */
472 /* Nonpersistent options: __LeaveStreamsUnattached, __AllDirActionsPrivate */
473 { NULL, NULL },
476 static config_var_description_t state_description[] = {
477 { "AccountingBytesReadInInterval",
478 "How many bytes have we read in this accounting period?" },
479 { "AccountingBytesWrittenInInterval",
480 "How many bytes have we written in this accounting period?" },
481 { "AccountingExpectedUsage",
482 "How many bytes did we expect to use per minute? (0 for no estimate.)" },
483 { "AccountingIntervalStart", "When did this accounting period begin?" },
484 { "AccountingSecondsActive", "How long have we been awake in this period?" },
486 { "BWHistoryReadEnds", "When does the last-recorded read-interval end?" },
487 { "BWHistoryReadInterval", "How long is each read-interval (in seconds)?" },
488 { "BWHistoryReadValues", "Number of bytes read in each interval." },
489 { "BWHistoryWriteEnds", "When does the last-recorded write-interval end?" },
490 { "BWHistoryWriteInterval", "How long is each write-interval (in seconds)?"},
491 { "BWHistoryWriteValues", "Number of bytes written in each interval." },
493 { "EntryGuard", "One of the nodes we have chosen as a fixed entry" },
494 { "EntryGuardDownSince",
495 "The last entry guard has been unreachable since this time." },
496 { "EntryGuardUnlistedSince",
497 "The last entry guard has been unusable since this time." },
498 { "LastRotatedOnionKey",
499 "The last time at which we changed the medium-term private key used for "
500 "building circuits." },
501 { "LastWritten", "When was this state file last regenerated?" },
503 { "TorVersion", "Which version of Tor generated this state file?" },
504 { NULL, NULL },
507 /** Type of a callback to validate whether a given configuration is
508 * well-formed and consistent. See options_trial_assign() for documentation
509 * of arguments. */
510 typedef int (*validate_fn_t)(void*,void*,int,char**);
512 /** Information on the keys, value types, key-to-struct-member mappings,
513 * variable descriptions, validation functions, and abbreviations for a
514 * configuration or storage format. */
515 typedef struct {
516 size_t size; /**< Size of the struct that everything gets parsed into. */
517 uint32_t magic; /**< Required 'magic value' to make sure we have a struct
518 * of the right type. */
519 off_t magic_offset; /**< Offset of the magic value within the struct. */
520 config_abbrev_t *abbrevs; /**< List of abbreviations that we expand when
521 * parsing this format. */
522 config_var_t *vars; /**< List of variables we recognize, their default
523 * values, and where we stick them in the structure. */
524 validate_fn_t validate_fn; /**< Function to validate config. */
525 /** Documentation for configuration variables. */
526 config_var_description_t *descriptions;
527 /** If present, extra is a LINELIST variable for unrecognized
528 * lines. Otherwise, unrecognized lines are an error. */
529 config_var_t *extra;
530 } config_format_t;
532 /** Macro: assert that <b>cfg</b> has the right magic field for format
533 * <b>fmt</b>. */
534 #define CHECK(fmt, cfg) do { \
535 tor_assert(fmt && cfg); \
536 tor_assert((fmt)->magic == \
537 *(uint32_t*)STRUCT_VAR_P(cfg,fmt->magic_offset)); \
538 } while (0)
540 static void config_line_append(config_line_t **lst,
541 const char *key, const char *val);
542 static void option_clear(config_format_t *fmt, or_options_t *options,
543 config_var_t *var);
544 static void option_reset(config_format_t *fmt, or_options_t *options,
545 config_var_t *var, int use_defaults);
546 static void config_free(config_format_t *fmt, void *options);
547 static int option_is_same(config_format_t *fmt,
548 or_options_t *o1, or_options_t *o2,
549 const char *name);
550 static or_options_t *options_dup(config_format_t *fmt, or_options_t *old);
551 static int options_validate(or_options_t *old_options, or_options_t *options,
552 int from_setconf, char **msg);
553 static int options_act_reversible(or_options_t *old_options, char **msg);
554 static int options_act(or_options_t *old_options);
555 static int options_transition_allowed(or_options_t *old, or_options_t *new,
556 char **msg);
557 static int options_transition_affects_workers(or_options_t *old_options,
558 or_options_t *new_options);
559 static int options_transition_affects_descriptor(or_options_t *old_options,
560 or_options_t *new_options);
561 static int check_nickname_list(const char *lst, const char *name, char **msg);
562 static void config_register_addressmaps(or_options_t *options);
564 static int parse_dir_server_line(const char *line, int validate_only);
565 static int parse_redirect_line(smartlist_t *result,
566 config_line_t *line, char **msg);
567 static int parse_log_severity_range(const char *range, int *min_out,
568 int *max_out);
569 static int validate_data_directory(or_options_t *options);
570 static int write_configuration_file(const char *fname, or_options_t *options);
571 static config_line_t *get_assigned_option(config_format_t *fmt,
572 or_options_t *options, const char *key);
573 static void config_init(config_format_t *fmt, void *options);
574 static int or_state_validate(or_state_t *old_options, or_state_t *options,
575 int from_setconf, char **msg);
577 static uint64_t config_parse_memunit(const char *s, int *ok);
578 static int config_parse_interval(const char *s, int *ok);
579 static void print_svn_version(void);
580 static void init_libevent(void);
581 static int opt_streq(const char *s1, const char *s2);
582 /** Versions of libevent. */
583 typedef enum {
584 /* Note: we compare these, so it's important that "old" precede everything,
585 * and that "other" come last. */
586 LE_OLD=0, LE_10C, LE_10D, LE_10E, LE_11, LE_11A, LE_11B, LE_12, LE_12A,
587 LE_13,
588 LE_OTHER
589 } le_version_t;
590 static le_version_t decode_libevent_version(void);
591 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
592 static void check_libevent_version(const char *m, int server);
593 #endif
595 /*static*/ or_options_t *options_new(void);
597 /** Magic value for or_options_t. */
598 #define OR_OPTIONS_MAGIC 9090909
600 /** Configuration format for or_options_t. */
601 static config_format_t options_format = {
602 sizeof(or_options_t),
603 OR_OPTIONS_MAGIC,
604 STRUCT_OFFSET(or_options_t, _magic),
605 _option_abbrevs,
606 _option_vars,
607 (validate_fn_t)options_validate,
608 options_description,
609 NULL
612 /** Magic value for or_state_t. */
613 #define OR_STATE_MAGIC 0x57A73f57
615 /** "Extra" variable in the state that receives lines we can't parse. This
616 * lets us preserve options from versions of Tor newer than us. */
617 static config_var_t state_extra_var = {
618 "__extra", CONFIG_TYPE_LINELIST, STRUCT_OFFSET(or_state_t, ExtraLines), NULL
621 /** Configuration format for or_state_t. */
622 static config_format_t state_format = {
623 sizeof(or_state_t),
624 OR_STATE_MAGIC,
625 STRUCT_OFFSET(or_state_t, _magic),
626 _state_abbrevs,
627 _state_vars,
628 (validate_fn_t)or_state_validate,
629 state_description,
630 &state_extra_var,
634 * Functions to read and write the global options pointer.
637 /** Command-line and config-file options. */
638 static or_options_t *global_options = NULL;
639 /** Name of most recently read torrc file. */
640 static char *torrc_fname = NULL;
641 /** Persistent serialized state. */
642 static or_state_t *global_state = NULL;
644 /** Allocate an empty configuration object of a given format type. */
645 static void *
646 config_alloc(config_format_t *fmt)
648 void *opts = tor_malloc_zero(fmt->size);
649 *(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
650 CHECK(fmt, opts);
651 return opts;
654 /** Return the currently configured options. */
655 or_options_t *
656 get_options(void)
658 tor_assert(global_options);
659 return global_options;
662 /** Change the current global options to contain <b>new_val</b> instead of
663 * their current value; take action based on the new value; free the old value
664 * as necessary.
667 set_options(or_options_t *new_val, char **msg)
669 or_options_t *old_options = global_options;
670 global_options = new_val;
671 /* Note that we pass the *old* options below, for comparison. It
672 * pulls the new options directly out of global_options. */
673 if (options_act_reversible(old_options, msg)<0) {
674 tor_assert(*msg);
675 global_options = old_options;
676 return -1;
678 if (options_act(old_options) < 0) { /* acting on the options failed. die. */
679 log_err(LD_BUG,
680 "Acting on config options left us in a broken state. Dying.");
681 exit(1);
683 if (old_options)
684 config_free(&options_format, old_options);
686 return 0;
689 /** Release all memory and resources held by global configuration structures.
691 void
692 config_free_all(void)
694 if (global_options) {
695 config_free(&options_format, global_options);
696 global_options = NULL;
698 if (global_state) {
699 config_free(&state_format, global_state);
700 global_state = NULL;
702 tor_free(torrc_fname);
705 /** If options->SafeLogging is on, return a not very useful string,
706 * else return address.
708 const char *
709 safe_str(const char *address)
711 if (get_options()->SafeLogging)
712 return "[scrubbed]";
713 else
714 return address;
717 /** Equivalent to escaped(safe_str(address)). See reentrancy note on
718 * escaped(): don't use this outside the main thread, or twice in the same
719 * log statement. */
720 const char *
721 escaped_safe_str(const char *address)
723 if (get_options()->SafeLogging)
724 return "[scrubbed]";
725 else
726 return escaped(address);
729 /** Add the default directory servers directly into the trusted dir list. */
730 static void
731 add_default_trusted_dirservers(void)
733 int i;
734 const char *dirservers[] = {
735 /* eventually we should mark moria1 as "v1only" */
736 "moria1 v1 orport=9001 18.244.0.188:9031 "
737 "FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441",
738 "moria2 v1 orport=443 18.244.0.114:80 "
739 "719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF",
740 "tor26 v1 orport=443 86.59.21.38:80 "
741 "847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
742 "lefkada orport=443 140.247.60.64:80 "
743 "38D4 F5FC F7B1 0232 28B8 95EA 56ED E7D5 CCDC AF32",
744 "dizum 194.109.206.212:80 "
745 "7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
746 NULL
748 for (i=0; dirservers[i]; i++)
749 parse_dir_server_line(dirservers[i], 0);
752 /** Fetch the active option list, and take actions based on it. All of the
753 * things we do should survive being done repeatedly. If present,
754 * <b>old_options</b> contains the previous value of the options.
756 * Return 0 if all goes well, return -1 if things went badly.
758 static int
759 options_act_reversible(or_options_t *old_options, char **msg)
761 smartlist_t *new_listeners = smartlist_create();
762 smartlist_t *replaced_listeners = smartlist_create();
763 static int libevent_initialized = 0;
764 or_options_t *options = get_options();
765 int running_tor = options->command == CMD_RUN_TOR;
766 int set_conn_limit = 0;
767 int r = -1;
768 int logs_marked = 0;
770 if (running_tor && options->RunAsDaemon) {
771 /* No need to roll back, since you can't change the value. */
772 start_daemon();
775 /* Setuid/setgid as appropriate */
776 if (options->User || options->Group) {
777 if (switch_id(options->User, options->Group) != 0) {
778 /* No need to roll back, since you can't change the value. */
779 *msg = tor_strdup("Problem with User or Group value. "
780 "See logs for details.");
781 goto done;
785 /* Set up libevent. */
786 if (running_tor && !libevent_initialized) {
787 init_libevent();
788 libevent_initialized = 1;
791 /* Ensure data directory is private; create if possible. */
792 if (check_private_dir(options->DataDirectory, CPD_CREATE)<0) {
793 char buf[1024];
794 int tmp = tor_snprintf(buf, sizeof(buf),
795 "Couldn't access/create private data directory \"%s\"",
796 options->DataDirectory);
797 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
798 goto done;
799 /* No need to roll back, since you can't change the value. */
802 /* Bail out at this point if we're not going to be a client or server:
803 * we don't run Tor itself. */
804 if (options->command != CMD_RUN_TOR)
805 goto commit;
807 options->_ConnLimit =
808 set_max_file_descriptors((unsigned)options->ConnLimit, MAXCONNECTIONS);
809 if (options->_ConnLimit < 0) {
810 *msg = tor_strdup("Problem with ConnLimit value. See logs for details.");
811 goto rollback;
813 set_conn_limit = 1;
815 if (retry_all_listeners(0, replaced_listeners, new_listeners) < 0) {
816 *msg = tor_strdup("Failed to bind one of the listener ports.");
817 goto rollback;
820 mark_logs_temp(); /* Close current logs once new logs are open. */
821 logs_marked = 1;
822 if (options_init_logs(options, 0)<0) { /* Configure the log(s) */
823 *msg = tor_strdup("Failed to init Log options. See logs for details.");
824 goto rollback;
827 commit:
828 r = 0;
829 if (logs_marked) {
830 close_temp_logs();
831 add_callback_log(LOG_ERR, LOG_ERR, control_event_logmsg);
832 control_adjust_event_log_severity();
834 SMARTLIST_FOREACH(replaced_listeners, connection_t *, conn,
836 log_notice(LD_NET, "Closing old %s on %s:%d",
837 conn_type_to_string(conn->type), conn->address, conn->port);
838 connection_close_immediate(conn);
839 connection_mark_for_close(conn);
841 goto done;
843 rollback:
844 r = -1;
845 tor_assert(*msg);
847 if (logs_marked) {
848 rollback_log_changes();
849 control_adjust_event_log_severity();
852 if (set_conn_limit && old_options)
853 set_max_file_descriptors((unsigned)old_options->ConnLimit,MAXCONNECTIONS);
855 SMARTLIST_FOREACH(new_listeners, connection_t *, conn,
857 log_notice(LD_NET, "Closing partially-constructed listener %s on %s:%d",
858 conn_type_to_string(conn->type), conn->address, conn->port);
859 connection_close_immediate(conn);
860 connection_mark_for_close(conn);
863 done:
864 smartlist_free(new_listeners);
865 smartlist_free(replaced_listeners);
866 return r;
869 /** Fetch the active option list, and take actions based on it. All of the
870 * things we do should survive being done repeatedly. If present,
871 * <b>old_options</b> contains the previous value of the options.
873 * Return 0 if all goes well, return -1 if it's time to die.
875 * Note: We haven't moved all the "act on new configuration" logic
876 * here yet. Some is still in do_hup() and other places.
878 static int
879 options_act(or_options_t *old_options)
881 config_line_t *cl;
882 char *fn;
883 size_t len;
884 or_options_t *options = get_options();
885 int running_tor = options->command == CMD_RUN_TOR;
886 char *msg;
888 clear_trusted_dir_servers();
889 if (options->DirServers) {
890 for (cl = options->DirServers; cl; cl = cl->next) {
891 if (parse_dir_server_line(cl->value, 0)<0) {
892 log_err(LD_BUG,
893 "Bug: Previously validated DirServer line could not be added!");
894 return -1;
897 } else {
898 add_default_trusted_dirservers();
901 if (running_tor && rend_config_services(options, 0)<0) {
902 log_err(LD_BUG,
903 "Bug: Previously validated hidden services line could not be added!");
904 return -1;
907 if (running_tor) {
908 len = strlen(options->DataDirectory)+32;
909 fn = tor_malloc(len);
910 tor_snprintf(fn, len, "%s/cached-status", options->DataDirectory);
911 if (check_private_dir(fn, CPD_CREATE) != 0) {
912 log_err(LD_CONFIG,
913 "Couldn't access/create private data directory \"%s\"", fn);
914 tor_free(fn);
915 return -1;
917 tor_free(fn);
920 /* Load state */
921 if (! global_state)
922 if (or_state_load())
923 return -1;
925 /* Bail out at this point if we're not going to be a client or server:
926 * we want to not fork, and to log stuff to stderr. */
927 if (options->command != CMD_RUN_TOR)
928 return 0;
931 smartlist_t *sl = smartlist_create();
932 char *errmsg = NULL;
933 for (cl = options->RedirectExit; cl; cl = cl->next) {
934 if (parse_redirect_line(sl, cl, &errmsg)<0) {
935 log_warn(LD_CONFIG, "%s", errmsg);
936 tor_free(errmsg);
937 return -1;
940 set_exit_redirects(sl);
943 /* Finish backgrounding the process */
944 if (running_tor && options->RunAsDaemon) {
945 /* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
946 finish_daemon(options->DataDirectory);
949 /* Write our pid to the pid file. If we do not have write permissions we
950 * will log a warning */
951 if (running_tor && options->PidFile)
952 write_pidfile(options->PidFile);
954 /* Register addressmap directives */
955 config_register_addressmaps(options);
956 parse_virtual_addr_network(options->VirtualAddrNetwork, 0, &msg);
958 /* Update address policies. */
959 policies_parse_from_options(options);
961 init_cookie_authentication(options->CookieAuthentication);
963 /* reload keys as needed for rendezvous services. */
964 if (rend_service_load_keys()<0) {
965 log_err(LD_GENERAL,"Error loading rendezvous service keys");
966 return -1;
969 /* Set up accounting */
970 if (accounting_parse_options(options, 0)<0) {
971 log_err(LD_CONFIG,"Error in accounting options");
972 return -1;
974 if (accounting_is_enabled(options))
975 configure_accounting(time(NULL));
977 if (!running_tor)
978 return 0;
980 /* Check for transitions that need action. */
981 if (old_options) {
982 if (options->UseEntryGuards && !old_options->UseEntryGuards) {
983 log_info(LD_CIRC,
984 "Switching to entry guards; abandoning previous circuits");
985 circuit_mark_all_unused_circs();
986 circuit_expire_all_dirty_circs();
989 if (options_transition_affects_workers(old_options, options)) {
990 log_info(LD_GENERAL,
991 "Worker-related options changed. Rotating workers.");
992 if (server_mode(options) && !server_mode(old_options)) {
993 if (init_keys() < 0) {
994 log_err(LD_BUG,"Error initializing keys; exiting");
995 return -1;
997 ip_address_changed(0);
998 if (has_completed_circuit || !any_predicted_circuits(time(NULL)))
999 inform_testing_reachability();
1001 cpuworkers_rotate();
1002 if (dns_reset())
1003 return -1;
1005 #ifdef USE_EVENTDNS
1006 else {
1007 if (dns_reset())
1008 return -1;
1010 #endif
1013 /* Check if we need to parse and add the EntryNodes config option. */
1014 if (options->EntryNodes &&
1015 (!old_options ||
1016 !opt_streq(old_options->EntryNodes, options->EntryNodes)))
1017 entry_nodes_should_be_added();
1019 /* Since our options changed, we might need to regenerate and upload our
1020 * server descriptor.
1022 if (!old_options ||
1023 options_transition_affects_descriptor(old_options, options))
1024 mark_my_descriptor_dirty();
1026 return 0;
1030 * Functions to parse config options
1033 /** If <b>option</b> is an official abbreviation for a longer option,
1034 * return the longer option. Otherwise return <b>option</b>.
1035 * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
1036 * apply abbreviations that work for the config file and the command line.
1037 * If <b>warn_obsolete</b> is set, warn about deprecated names. */
1038 static const char *
1039 expand_abbrev(config_format_t *fmt, const char *option, int command_line,
1040 int warn_obsolete)
1042 int i;
1043 if (! fmt->abbrevs)
1044 return option;
1045 for (i=0; fmt->abbrevs[i].abbreviated; ++i) {
1046 /* Abbreviations are casei. */
1047 if (!strcasecmp(option,fmt->abbrevs[i].abbreviated) &&
1048 (command_line || !fmt->abbrevs[i].commandline_only)) {
1049 if (warn_obsolete && fmt->abbrevs[i].warn) {
1050 log_warn(LD_CONFIG,
1051 "The configuration option '%s' is deprecated; "
1052 "use '%s' instead.",
1053 fmt->abbrevs[i].abbreviated,
1054 fmt->abbrevs[i].full);
1056 return fmt->abbrevs[i].full;
1059 return option;
1062 /** Helper: Read a list of configuration options from the command line.
1063 * If successful, put them in *<b>result</b> and return 0, and return
1064 * -1 and leave *<b>result</b> alone. */
1065 static int
1066 config_get_commandlines(int argc, char **argv, config_line_t **result)
1068 config_line_t *front = NULL;
1069 config_line_t **new = &front;
1070 char *s;
1071 int i = 1;
1073 while (i < argc) {
1074 if (!strcmp(argv[i],"-f") ||
1075 !strcmp(argv[i],"--hash-password")) {
1076 i += 2; /* command-line option with argument. ignore them. */
1077 continue;
1078 } else if (!strcmp(argv[i],"--list-fingerprint") ||
1079 !strcmp(argv[i],"--verify-config") ||
1080 !strcmp(argv[i],"--ignore-missing-torrc")) {
1081 i += 1; /* command-line option. ignore it. */
1082 continue;
1083 } else if (!strcmp(argv[i],"--nt-service") ||
1084 !strcmp(argv[i],"-nt-service")) {
1085 i += 1;
1086 continue;
1088 if (i == argc-1) {
1089 log_warn(LD_CONFIG,"Command-line option '%s' with no value. Failing.",
1090 argv[i]);
1091 config_free_lines(front);
1092 return -1;
1095 *new = tor_malloc_zero(sizeof(config_line_t));
1096 s = argv[i];
1098 while (*s == '-')
1099 s++;
1101 (*new)->key = tor_strdup(expand_abbrev(&options_format, s, 1, 1));
1102 (*new)->value = tor_strdup(argv[i+1]);
1103 (*new)->next = NULL;
1104 log(LOG_DEBUG, LD_CONFIG, "Commandline: parsed keyword '%s', value '%s'",
1105 (*new)->key, (*new)->value);
1107 new = &((*new)->next);
1108 i += 2;
1110 *result = front;
1111 return 0;
1114 /** Helper: allocate a new configuration option mapping 'key' to 'val',
1115 * append it to *<b>lst</b>. */
1116 static void
1117 config_line_append(config_line_t **lst,
1118 const char *key,
1119 const char *val)
1121 config_line_t *newline;
1123 newline = tor_malloc(sizeof(config_line_t));
1124 newline->key = tor_strdup(key);
1125 newline->value = tor_strdup(val);
1126 newline->next = NULL;
1127 while (*lst)
1128 lst = &((*lst)->next);
1130 (*lst) = newline;
1133 /** Helper: parse the config string and strdup into key/value
1134 * strings. Set *result to the list, or NULL if parsing the string
1135 * failed. Return 0 on success, -1 on failure. Warn and ignore any
1136 * misformatted lines. Modifies the contents of <b>string</b>. */
1138 config_get_lines(char *string, config_line_t **result)
1140 config_line_t *list = NULL, **next;
1141 char *k, *v;
1143 next = &list;
1144 do {
1145 string = parse_line_from_str(string, &k, &v);
1146 if (!string) {
1147 config_free_lines(list);
1148 return -1;
1150 if (k && v) {
1151 /* This list can get long, so we keep a pointer to the end of it
1152 * rather than using config_line_append over and over and getting n^2
1153 * performance. This is the only really long list. */
1154 *next = tor_malloc(sizeof(config_line_t));
1155 (*next)->key = tor_strdup(k);
1156 (*next)->value = tor_strdup(v);
1157 (*next)->next = NULL;
1158 next = &((*next)->next);
1160 } while (*string);
1162 *result = list;
1163 return 0;
1167 * Free all the configuration lines on the linked list <b>front</b>.
1169 void
1170 config_free_lines(config_line_t *front)
1172 config_line_t *tmp;
1174 while (front) {
1175 tmp = front;
1176 front = tmp->next;
1178 tor_free(tmp->key);
1179 tor_free(tmp->value);
1180 tor_free(tmp);
1184 /** Return the description for a given configuration variable, or NULL if no
1185 * description exists. */
1186 static const char *
1187 config_find_description(config_format_t *fmt, const char *name)
1189 int i;
1190 for (i=0; fmt->descriptions[i].name; ++i) {
1191 if (!strcasecmp(name, fmt->descriptions[i].name))
1192 return fmt->descriptions[i].description;
1194 return NULL;
1197 /** If <b>key</b> is a configuration option, return the corresponding
1198 * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
1199 * warn, and return the corresponding config_var_t. Otherwise return NULL.
1201 static config_var_t *
1202 config_find_option(config_format_t *fmt, const char *key)
1204 int i;
1205 size_t keylen = strlen(key);
1206 if (!keylen)
1207 return NULL; /* if they say "--" on the commandline, it's not an option */
1208 /* First, check for an exact (case-insensitive) match */
1209 for (i=0; fmt->vars[i].name; ++i) {
1210 if (!strcasecmp(key, fmt->vars[i].name)) {
1211 return &fmt->vars[i];
1214 /* If none, check for an abbreviated match */
1215 for (i=0; fmt->vars[i].name; ++i) {
1216 if (!strncasecmp(key, fmt->vars[i].name, keylen)) {
1217 log_warn(LD_CONFIG, "The abbreviation '%s' is deprecated. "
1218 "Please use '%s' instead",
1219 key, fmt->vars[i].name);
1220 return &fmt->vars[i];
1223 /* Okay, unrecognized option */
1224 return NULL;
1228 * Functions to assign config options.
1231 /** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
1232 * with <b>c</b>-\>value and return 0, or return -1 if bad value.
1234 * Called from config_assign_line() and option_reset().
1236 static int
1237 config_assign_value(config_format_t *fmt, or_options_t *options,
1238 config_line_t *c, char **msg)
1240 int i, r, ok;
1241 char buf[1024];
1242 config_var_t *var;
1243 void *lvalue;
1245 CHECK(fmt, options);
1247 var = config_find_option(fmt, c->key);
1248 tor_assert(var);
1250 lvalue = STRUCT_VAR_P(options, var->var_offset);
1252 switch (var->type) {
1254 case CONFIG_TYPE_UINT:
1255 i = tor_parse_long(c->value, 10, 0, INT_MAX, &ok, NULL);
1256 if (!ok) {
1257 r = tor_snprintf(buf, sizeof(buf),
1258 "Int keyword '%s %s' is malformed or out of bounds.",
1259 c->key, c->value);
1260 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1261 return -1;
1263 *(int *)lvalue = i;
1264 break;
1266 case CONFIG_TYPE_INTERVAL: {
1267 i = config_parse_interval(c->value, &ok);
1268 if (!ok) {
1269 r = tor_snprintf(buf, sizeof(buf),
1270 "Interval '%s %s' is malformed or out of bounds.",
1271 c->key, c->value);
1272 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1273 return -1;
1275 *(int *)lvalue = i;
1276 break;
1279 case CONFIG_TYPE_MEMUNIT: {
1280 uint64_t u64 = config_parse_memunit(c->value, &ok);
1281 if (!ok) {
1282 r = tor_snprintf(buf, sizeof(buf),
1283 "Value '%s %s' is malformed or out of bounds.",
1284 c->key, c->value);
1285 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1286 return -1;
1288 *(uint64_t *)lvalue = u64;
1289 break;
1292 case CONFIG_TYPE_BOOL:
1293 i = tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
1294 if (!ok) {
1295 r = tor_snprintf(buf, sizeof(buf),
1296 "Boolean '%s %s' expects 0 or 1.",
1297 c->key, c->value);
1298 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1299 return -1;
1301 *(int *)lvalue = i;
1302 break;
1304 case CONFIG_TYPE_STRING:
1305 tor_free(*(char **)lvalue);
1306 *(char **)lvalue = tor_strdup(c->value);
1307 break;
1309 case CONFIG_TYPE_DOUBLE:
1310 *(double *)lvalue = atof(c->value);
1311 break;
1313 case CONFIG_TYPE_ISOTIME:
1314 if (parse_iso_time(c->value, (time_t *)lvalue)) {
1315 r = tor_snprintf(buf, sizeof(buf),
1316 "Invalid time '%s' for keyword '%s'", c->value, c->key);
1317 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1318 return -1;
1320 break;
1322 case CONFIG_TYPE_CSV:
1323 if (*(smartlist_t**)lvalue) {
1324 SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
1325 smartlist_clear(*(smartlist_t**)lvalue);
1326 } else {
1327 *(smartlist_t**)lvalue = smartlist_create();
1330 smartlist_split_string(*(smartlist_t**)lvalue, c->value, ",",
1331 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1332 break;
1334 case CONFIG_TYPE_LINELIST:
1335 case CONFIG_TYPE_LINELIST_S:
1336 config_line_append((config_line_t**)lvalue, c->key, c->value);
1337 break;
1339 case CONFIG_TYPE_OBSOLETE:
1340 log_warn(LD_CONFIG, "Skipping obsolete configuration option '%s'", c->key);
1341 break;
1342 case CONFIG_TYPE_LINELIST_V:
1343 r = tor_snprintf(buf, sizeof(buf),
1344 "You may not provide a value for virtual option '%s'", c->key);
1345 *msg = tor_strdup(r >= 0 ? buf : "internal error");
1346 return -1;
1347 default:
1348 tor_assert(0);
1349 break;
1351 return 0;
1354 /** If <b>c</b> is a syntactically valid configuration line, update
1355 * <b>options</b> with its value and return 0. Otherwise return -1 for bad
1356 * key, -2 for bad value.
1358 * If <b>clear_first</b> is set, clear the value first. Then if
1359 * <b>use_defaults</b> is set, set the value to the default.
1361 * Called from config_assign().
1363 static int
1364 config_assign_line(config_format_t *fmt, or_options_t *options,
1365 config_line_t *c, int use_defaults,
1366 int clear_first, char **msg)
1368 config_var_t *var;
1370 CHECK(fmt, options);
1372 var = config_find_option(fmt, c->key);
1373 if (!var) {
1374 if (fmt->extra) {
1375 void *lvalue = STRUCT_VAR_P(options, fmt->extra->var_offset);
1376 log_info(LD_CONFIG,
1377 "Found unrecognized option '%s'; saving it.", c->key);
1378 config_line_append((config_line_t**)lvalue, c->key, c->value);
1379 return 0;
1380 } else {
1381 char buf[1024];
1382 int tmp = tor_snprintf(buf, sizeof(buf),
1383 "Unknown option '%s'. Failing.", c->key);
1384 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
1385 return -1;
1388 /* Put keyword into canonical case. */
1389 if (strcmp(var->name, c->key)) {
1390 tor_free(c->key);
1391 c->key = tor_strdup(var->name);
1394 if (!strlen(c->value)) {
1395 /* reset or clear it, then return */
1396 if (!clear_first) {
1397 if (var->type == CONFIG_TYPE_LINELIST ||
1398 var->type == CONFIG_TYPE_LINELIST_S) {
1399 /* We got an empty linelist from the torrc or commandline.
1400 As a special case, call this an error. Warn and ignore. */
1401 log_warn(LD_CONFIG,
1402 "Linelist option '%s' has no value. Skipping.", c->key);
1403 } else { /* not already cleared */
1404 option_reset(fmt, options, var, use_defaults);
1407 return 0;
1410 if (config_assign_value(fmt, options, c, msg) < 0)
1411 return -2;
1412 return 0;
1415 /** Restore the option named <b>key</b> in options to its default value.
1416 * Called from config_assign(). */
1417 static void
1418 config_reset_line(config_format_t *fmt, or_options_t *options,
1419 const char *key, int use_defaults)
1421 config_var_t *var;
1423 CHECK(fmt, options);
1425 var = config_find_option(fmt, key);
1426 if (!var)
1427 return; /* give error on next pass. */
1429 option_reset(fmt, options, var, use_defaults);
1432 /** Return true iff key is a valid configuration option. */
1434 option_is_recognized(const char *key)
1436 config_var_t *var = config_find_option(&options_format, key);
1437 return (var != NULL);
1440 /** Return the canonical name of a configuration option. */
1441 const char *
1442 option_get_canonical_name(const char *key)
1444 config_var_t *var = config_find_option(&options_format, key);
1445 return var->name;
1448 /** Return a canonicalized list of the options assigned for key.
1450 config_line_t *
1451 option_get_assignment(or_options_t *options, const char *key)
1453 return get_assigned_option(&options_format, options, key);
1456 /** Return a newly allocated deep copy of the lines in <b>inp</b>. */
1457 static config_line_t *
1458 config_lines_dup(const config_line_t *inp)
1460 config_line_t *result = NULL;
1461 config_line_t **next_out = &result;
1462 while (inp) {
1463 *next_out = tor_malloc(sizeof(config_line_t));
1464 (*next_out)->key = tor_strdup(inp->key);
1465 (*next_out)->value = tor_strdup(inp->value);
1466 inp = inp->next;
1467 next_out = &((*next_out)->next);
1469 (*next_out) = NULL;
1470 return result;
1473 /** Return newly allocated line or lines corresponding to <b>key</b> in the
1474 * configuration <b>options</b>. Return NULL if no such key exists. */
1475 static config_line_t *
1476 get_assigned_option(config_format_t *fmt, or_options_t *options,
1477 const char *key)
1478 /* XXXX argument is options, but fmt is provided. Inconsistent. */
1480 config_var_t *var;
1481 const void *value;
1482 char buf[32];
1483 config_line_t *result;
1484 tor_assert(options && key);
1486 CHECK(fmt, options);
1488 var = config_find_option(fmt, key);
1489 if (!var) {
1490 log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key);
1491 return NULL;
1493 value = STRUCT_VAR_P(options, var->var_offset);
1495 result = tor_malloc_zero(sizeof(config_line_t));
1496 result->key = tor_strdup(var->name);
1497 switch (var->type)
1499 case CONFIG_TYPE_STRING:
1500 if (*(char**)value) {
1501 result->value = tor_strdup(*(char**)value);
1502 } else {
1503 tor_free(result->key);
1504 tor_free(result);
1505 return NULL;
1507 break;
1508 case CONFIG_TYPE_ISOTIME:
1509 if (*(time_t*)value) {
1510 result->value = tor_malloc(ISO_TIME_LEN+1);
1511 format_iso_time(result->value, *(time_t*)value);
1512 } else {
1513 tor_free(result->key);
1514 tor_free(result);
1516 break;
1517 case CONFIG_TYPE_INTERVAL:
1518 case CONFIG_TYPE_UINT:
1519 /* This means every or_options_t uint or bool element
1520 * needs to be an int. Not, say, a uint16_t or char. */
1521 tor_snprintf(buf, sizeof(buf), "%d", *(int*)value);
1522 result->value = tor_strdup(buf);
1523 break;
1524 case CONFIG_TYPE_MEMUNIT:
1525 tor_snprintf(buf, sizeof(buf), U64_FORMAT,
1526 U64_PRINTF_ARG(*(uint64_t*)value));
1527 result->value = tor_strdup(buf);
1528 break;
1529 case CONFIG_TYPE_DOUBLE:
1530 tor_snprintf(buf, sizeof(buf), "%f", *(double*)value);
1531 result->value = tor_strdup(buf);
1532 break;
1533 case CONFIG_TYPE_BOOL:
1534 result->value = tor_strdup(*(int*)value ? "1" : "0");
1535 break;
1536 case CONFIG_TYPE_CSV:
1537 if (*(smartlist_t**)value)
1538 result->value =
1539 smartlist_join_strings(*(smartlist_t**)value, ",", 0, NULL);
1540 else
1541 result->value = tor_strdup("");
1542 break;
1543 case CONFIG_TYPE_OBSOLETE:
1544 log_warn(LD_CONFIG,
1545 "You asked me for the value of an obsolete config option '%s'.",
1546 key);
1547 tor_free(result->key);
1548 tor_free(result);
1549 return NULL;
1550 case CONFIG_TYPE_LINELIST_S:
1551 log_warn(LD_CONFIG,
1552 "Can't return context-sensitive '%s' on its own", key);
1553 tor_free(result->key);
1554 tor_free(result);
1555 return NULL;
1556 case CONFIG_TYPE_LINELIST:
1557 case CONFIG_TYPE_LINELIST_V:
1558 tor_free(result->key);
1559 tor_free(result);
1560 return config_lines_dup(*(const config_line_t**)value);
1561 default:
1562 tor_free(result->key);
1563 tor_free(result);
1564 log_warn(LD_BUG,"Bug: unknown type %d for known key '%s'",
1565 var->type, key);
1566 return NULL;
1569 return result;
1572 /** Iterate through the linked list of requested options <b>list</b>.
1573 * For each item, convert as appropriate and assign to <b>options</b>.
1574 * If an item is unrecognized, set *msg and return -1 immediately,
1575 * else return 0 for success.
1577 * If <b>clear_first</b>, interpret config options as replacing (not
1578 * extending) their previous values. If <b>clear_first</b> is set,
1579 * then <b>use_defaults</b> to decide if you set to defaults after
1580 * clearing, or make the value 0 or NULL.
1582 * Here are the use cases:
1583 * 1. A non-empty AllowInvalid line in your torrc. Appends to current
1584 * if linelist, replaces current if csv.
1585 * 2. An empty AllowInvalid line in your torrc. Should clear it.
1586 * 3. "RESETCONF AllowInvalid" sets it to default.
1587 * 4. "SETCONF AllowInvalid" makes it NULL.
1588 * 5. "SETCONF AllowInvalid=foo" clears it and sets it to "foo".
1590 * Use_defaults Clear_first
1591 * 0 0 "append"
1592 * 1 0 undefined, don't use
1593 * 0 1 "set to null first"
1594 * 1 1 "set to defaults first"
1595 * Return 0 on success, -1 on bad key, -2 on bad value.
1597 * As an additional special case, if a LINELIST config option has
1598 * no value and clear_first is 0, then warn and ignore it.
1602 There are three call cases for config_assign() currently.
1604 Case one: Torrc entry
1605 options_init_from_torrc() calls config_assign(0, 0)
1606 calls config_assign_line(0, 0).
1607 if value is empty, calls option_reset(0) and returns.
1608 calls config_assign_value(), appends.
1610 Case two: setconf
1611 options_trial_assign() calls config_assign(0, 1)
1612 calls config_reset_line(0)
1613 calls option_reset(0)
1614 calls option_clear().
1615 calls config_assign_line(0, 1).
1616 if value is empty, returns.
1617 calls config_assign_value(), appends.
1619 Case three: resetconf
1620 options_trial_assign() calls config_assign(1, 1)
1621 calls config_reset_line(1)
1622 calls option_reset(1)
1623 calls option_clear().
1624 calls config_assign_value(default)
1625 calls config_assign_line(1, 1).
1626 returns.
1628 static int
1629 config_assign(config_format_t *fmt, void *options, config_line_t *list,
1630 int use_defaults, int clear_first, char **msg)
1632 config_line_t *p;
1634 CHECK(fmt, options);
1636 /* pass 1: normalize keys */
1637 for (p = list; p; p = p->next) {
1638 const char *full = expand_abbrev(fmt, p->key, 0, 1);
1639 if (strcmp(full,p->key)) {
1640 tor_free(p->key);
1641 p->key = tor_strdup(full);
1645 /* pass 2: if we're reading from a resetting source, clear all
1646 * mentioned config options, and maybe set to their defaults. */
1647 if (clear_first) {
1648 for (p = list; p; p = p->next)
1649 config_reset_line(fmt, options, p->key, use_defaults);
1652 /* pass 3: assign. */
1653 while (list) {
1654 int r;
1655 if ((r=config_assign_line(fmt, options, list, use_defaults,
1656 clear_first, msg)))
1657 return r;
1658 list = list->next;
1660 return 0;
1663 /** Try assigning <b>list</b> to the global options. You do this by duping
1664 * options, assigning list to the new one, then validating it. If it's
1665 * ok, then throw out the old one and stick with the new one. Else,
1666 * revert to old and return failure. Return 0 on success, -1 on bad
1667 * keys, -2 on bad values, -3 on bad transition, and -4 on failed-to-set.
1669 * If not success, point *<b>msg</b> to a newly allocated string describing
1670 * what went wrong.
1673 options_trial_assign(config_line_t *list, int use_defaults,
1674 int clear_first, char **msg)
1676 int r;
1677 or_options_t *trial_options = options_dup(&options_format, get_options());
1679 if ((r=config_assign(&options_format, trial_options,
1680 list, use_defaults, clear_first, msg)) < 0) {
1681 config_free(&options_format, trial_options);
1682 return r;
1685 if (options_validate(get_options(), trial_options, 1, msg) < 0) {
1686 config_free(&options_format, trial_options);
1687 return -2;
1690 if (options_transition_allowed(get_options(), trial_options, msg) < 0) {
1691 config_free(&options_format, trial_options);
1692 return -3;
1695 if (set_options(trial_options, msg)<0) {
1696 config_free(&options_format, trial_options);
1697 return -4;
1700 /* we liked it. put it in place. */
1701 return 0;
1704 /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
1705 * Called from option_reset() and config_free(). */
1706 static void
1707 option_clear(config_format_t *fmt, or_options_t *options, config_var_t *var)
1709 void *lvalue = STRUCT_VAR_P(options, var->var_offset);
1710 (void)fmt; /* unused */
1711 switch (var->type) {
1712 case CONFIG_TYPE_STRING:
1713 tor_free(*(char**)lvalue);
1714 break;
1715 case CONFIG_TYPE_DOUBLE:
1716 *(double*)lvalue = 0.0;
1717 break;
1718 case CONFIG_TYPE_ISOTIME:
1719 *(time_t*)lvalue = 0;
1720 case CONFIG_TYPE_INTERVAL:
1721 case CONFIG_TYPE_UINT:
1722 case CONFIG_TYPE_BOOL:
1723 *(int*)lvalue = 0;
1724 break;
1725 case CONFIG_TYPE_MEMUNIT:
1726 *(uint64_t*)lvalue = 0;
1727 break;
1728 case CONFIG_TYPE_CSV:
1729 if (*(smartlist_t**)lvalue) {
1730 SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
1731 smartlist_free(*(smartlist_t **)lvalue);
1732 *(smartlist_t **)lvalue = NULL;
1734 break;
1735 case CONFIG_TYPE_LINELIST:
1736 case CONFIG_TYPE_LINELIST_S:
1737 config_free_lines(*(config_line_t **)lvalue);
1738 *(config_line_t **)lvalue = NULL;
1739 break;
1740 case CONFIG_TYPE_LINELIST_V:
1741 /* handled by linelist_s. */
1742 break;
1743 case CONFIG_TYPE_OBSOLETE:
1744 break;
1748 /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
1749 * <b>use_defaults</b>, set it to its default value.
1750 * Called by config_init() and option_reset_line() and option_assign_line(). */
1751 static void
1752 option_reset(config_format_t *fmt, or_options_t *options,
1753 config_var_t *var, int use_defaults)
1755 config_line_t *c;
1756 char *msg = NULL;
1757 CHECK(fmt, options);
1758 option_clear(fmt, options, var); /* clear it first */
1759 if (!use_defaults)
1760 return; /* all done */
1761 if (var->initvalue) {
1762 c = tor_malloc_zero(sizeof(config_line_t));
1763 c->key = tor_strdup(var->name);
1764 c->value = tor_strdup(var->initvalue);
1765 if (config_assign_value(fmt, options, c, &msg) < 0) {
1766 log_warn(LD_BUG, "Failed to assign default: %s", msg);
1767 tor_free(msg); /* if this happens it's a bug */
1769 config_free_lines(c);
1773 /** Print a usage message for tor. */
1774 static void
1775 print_usage(void)
1777 printf(
1778 "Copyright 2001-2007 Roger Dingledine, Nick Mathewson.\n\n"
1779 "tor -f <torrc> [args]\n"
1780 "See man page for options, or http://tor.eff.org/ for documentation.\n");
1783 /** Print all non-obsolete torrc options. */
1784 static void
1785 list_torrc_options(void)
1787 int i;
1788 smartlist_t *lines = smartlist_create();
1789 for (i = 0; _option_vars[i].name; ++i) {
1790 config_var_t *var = &_option_vars[i];
1791 const char *desc;
1792 if (var->type == CONFIG_TYPE_OBSOLETE ||
1793 var->type == CONFIG_TYPE_LINELIST_V)
1794 continue;
1795 desc = config_find_description(&options_format, var->name);
1796 printf("%s\n", var->name);
1797 if (desc) {
1798 wrap_string(lines, desc, 76, " ", " ");
1799 SMARTLIST_FOREACH(lines, char *, cp, {
1800 printf("%s", cp);
1801 tor_free(cp);
1803 smartlist_clear(lines);
1808 /** Last value actually set by resolve_my_address. */
1809 static uint32_t last_resolved_addr = 0;
1811 * Based on <b>options-\>Address</b>, guess our public IP address and put it
1812 * (in host order) into *<b>addr_out</b>. If <b>hostname_out</b> is provided,
1813 * set *<b>hostname_out</b> to a new string holding the hostname we used to
1814 * get the address. Return 0 if all is well, or -1 if we can't find a suitable
1815 * public IP address.
1818 resolve_my_address(int warn_severity, or_options_t *options,
1819 uint32_t *addr_out, char **hostname_out)
1821 struct in_addr in;
1822 struct hostent *rent;
1823 char hostname[256];
1824 int explicit_ip=1;
1825 int explicit_hostname=1;
1826 int from_interface=0;
1827 char tmpbuf[INET_NTOA_BUF_LEN];
1828 const char *address = options->Address;
1829 int notice_severity = warn_severity <= LOG_NOTICE ?
1830 LOG_NOTICE : warn_severity;
1832 tor_assert(addr_out);
1834 if (address && *address) {
1835 strlcpy(hostname, address, sizeof(hostname));
1836 } else { /* then we need to guess our address */
1837 explicit_ip = 0; /* it's implicit */
1838 explicit_hostname = 0; /* it's implicit */
1840 if (gethostname(hostname, sizeof(hostname)) < 0) {
1841 log_fn(warn_severity, LD_NET,"Error obtaining local hostname");
1842 return -1;
1844 log_debug(LD_CONFIG,"Guessed local host name as '%s'",hostname);
1847 /* now we know hostname. resolve it and keep only the IP address */
1849 if (tor_inet_aton(hostname, &in) == 0) {
1850 /* then we have to resolve it */
1851 explicit_ip = 0;
1852 rent = (struct hostent *)gethostbyname(hostname);
1853 if (!rent) {
1854 uint32_t interface_ip;
1856 if (explicit_hostname) {
1857 log_fn(warn_severity, LD_CONFIG,
1858 "Could not resolve local Address '%s'. Failing.", hostname);
1859 return -1;
1861 log_fn(notice_severity, LD_CONFIG,
1862 "Could not resolve guessed local hostname '%s'. "
1863 "Trying something else.", hostname);
1864 if (get_interface_address(warn_severity, &interface_ip)) {
1865 log_fn(warn_severity, LD_CONFIG,
1866 "Could not get local interface IP address. Failing.");
1867 return -1;
1869 from_interface = 1;
1870 in.s_addr = htonl(interface_ip);
1871 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
1872 log_fn(notice_severity, LD_CONFIG, "Learned IP address '%s' for "
1873 "local interface. Using that.", tmpbuf);
1874 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
1875 } else {
1876 tor_assert(rent->h_length == 4);
1877 memcpy(&in.s_addr, rent->h_addr, rent->h_length);
1879 if (!explicit_hostname &&
1880 is_internal_IP(ntohl(in.s_addr), 0)) {
1881 uint32_t interface_ip;
1883 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
1884 log_fn(notice_severity, LD_CONFIG, "Guessed local hostname '%s' "
1885 "resolves to a private IP address (%s). Trying something "
1886 "else.", hostname, tmpbuf);
1888 if (get_interface_address(warn_severity, &interface_ip)) {
1889 log_fn(warn_severity, LD_CONFIG,
1890 "Could not get local interface IP address. Too bad.");
1891 } else if (is_internal_IP(interface_ip, 0)) {
1892 struct in_addr in2;
1893 in2.s_addr = htonl(interface_ip);
1894 tor_inet_ntoa(&in2,tmpbuf,sizeof(tmpbuf));
1895 log_fn(notice_severity, LD_CONFIG,
1896 "Interface IP address '%s' is a private address too. "
1897 "Ignoring.", tmpbuf);
1898 } else {
1899 from_interface = 1;
1900 in.s_addr = htonl(interface_ip);
1901 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
1902 log_fn(notice_severity, LD_CONFIG,
1903 "Learned IP address '%s' for local interface."
1904 " Using that.", tmpbuf);
1905 strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
1911 tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
1912 if (is_internal_IP(ntohl(in.s_addr), 0) &&
1913 options->PublishServerDescriptor) {
1914 /* make sure we're ok with publishing an internal IP */
1915 if (!options->DirServers) {
1916 /* if they are using the default dirservers, disallow internal IPs
1917 * always. */
1918 log_fn(warn_severity, LD_CONFIG,
1919 "Address '%s' resolves to private IP address '%s'. "
1920 "Tor servers that use the default DirServers must have public "
1921 "IP addresses.", hostname, tmpbuf);
1922 return -1;
1924 if (!explicit_ip) {
1925 /* even if they've set their own dirservers, require an explicit IP if
1926 * they're using an internal address. */
1927 log_fn(warn_severity, LD_CONFIG, "Address '%s' resolves to private "
1928 "IP address '%s'. Please set the Address config option to be "
1929 "the IP address you want to use.", hostname, tmpbuf);
1930 return -1;
1934 log_debug(LD_CONFIG, "Resolved Address to '%s'.", tmpbuf);
1935 *addr_out = ntohl(in.s_addr);
1936 if (last_resolved_addr && last_resolved_addr != *addr_out) {
1937 /* Leave this as a notice, regardless of the requested severity,
1938 * at least until dynamic IP address support becomes bulletproof. */
1939 log_notice(LD_NET, "Your IP address seems to have changed. Updating.");
1940 ip_address_changed(0);
1942 if (last_resolved_addr != *addr_out) {
1943 const char *method;
1944 const char *h = hostname;
1945 if (explicit_ip) {
1946 method = "CONFIGURED";
1947 h = NULL;
1948 } else if (explicit_hostname) {
1949 method = "RESOLVED";
1950 } else if (from_interface) {
1951 method = "INTERFACE";
1952 h = NULL;
1953 } else {
1954 method = "GETHOSTNAME";
1956 control_event_server_status(LOG_NOTICE,
1957 "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s %s%s",
1958 tmpbuf, method, h?"HOSTNAME=":"", h);
1960 last_resolved_addr = *addr_out;
1961 if (hostname_out)
1962 *hostname_out = tor_strdup(hostname);
1963 return 0;
1966 /** Return true iff <b>ip</b> (in host order) is judged to be on the
1967 * same network as us, or on a private network.
1970 is_local_IP(uint32_t ip)
1972 if (is_internal_IP(ip, 0))
1973 return 1;
1974 /* Check whether ip is on the same /24 as we are. */
1975 if (get_options()->EnforceDistinctSubnets == 0)
1976 return 0;
1977 /* It's possible that this next check will hit before the first time
1978 * resolve_my_address actually succeeds. (For clients, it is likely that
1979 * resolve_my_address will never be called at all). In those cases,
1980 * last_resolved_addr will be 0, and so checking to see whether ip is on the
1981 * same /24 as last_resolved_addr will be the same as checking whether it
1982 * was on net 0, which is already done by is_internal_IP.
1984 if ((last_resolved_addr & 0xffffff00ul) == (ip & 0xffffff00ul))
1985 return 1;
1986 return 0;
1989 /** Called when we don't have a nickname set. Try to guess a good nickname
1990 * based on the hostname, and return it in a newly allocated string. If we
1991 * can't, return NULL and let the caller warn if it wants to. */
1992 static char *
1993 get_default_nickname(void)
1995 static const char * const bad_default_nicknames[] = {
1996 "localhost",
1997 NULL,
1999 char localhostname[256];
2000 char *cp, *out, *outp;
2001 int i;
2003 if (gethostname(localhostname, sizeof(localhostname)) < 0)
2004 return NULL;
2006 /* Put it in lowercase; stop at the first dot. */
2007 if ((cp = strchr(localhostname, '.')))
2008 *cp = '\0';
2009 tor_strlower(localhostname);
2011 /* Strip invalid characters. */
2012 cp = localhostname;
2013 out = outp = tor_malloc(strlen(localhostname) + 1);
2014 while (*cp) {
2015 if (strchr(LEGAL_NICKNAME_CHARACTERS, *cp))
2016 *outp++ = *cp++;
2017 else
2018 cp++;
2020 *outp = '\0';
2022 /* Enforce length. */
2023 if (strlen(out) > MAX_NICKNAME_LEN)
2024 out[MAX_NICKNAME_LEN]='\0';
2026 /* Check for dumb names. */
2027 for (i = 0; bad_default_nicknames[i]; ++i) {
2028 if (!strcmp(out, bad_default_nicknames[i])) {
2029 tor_free(out);
2030 return NULL;
2034 return out;
2037 /** Release storage held by <b>options</b> */
2038 static void
2039 config_free(config_format_t *fmt, void *options)
2041 int i;
2043 tor_assert(options);
2045 for (i=0; fmt->vars[i].name; ++i)
2046 option_clear(fmt, options, &(fmt->vars[i]));
2047 if (fmt->extra) {
2048 config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->var_offset);
2049 config_free_lines(*linep);
2050 *linep = NULL;
2052 tor_free(options);
2055 /** Return true iff a and b contain identical keys and values in identical
2056 * order. */
2057 static int
2058 config_lines_eq(config_line_t *a, config_line_t *b)
2060 while (a && b) {
2061 if (strcasecmp(a->key, b->key) || strcmp(a->value, b->value))
2062 return 0;
2063 a = a->next;
2064 b = b->next;
2066 if (a || b)
2067 return 0;
2068 return 1;
2071 /** Return true iff the option <b>var</b> has the same value in <b>o1</b>
2072 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
2074 static int
2075 option_is_same(config_format_t *fmt,
2076 or_options_t *o1, or_options_t *o2, const char *name)
2078 config_line_t *c1, *c2;
2079 int r = 1;
2080 CHECK(fmt, o1);
2081 CHECK(fmt, o2);
2083 c1 = get_assigned_option(fmt, o1, name);
2084 c2 = get_assigned_option(fmt, o2, name);
2085 r = config_lines_eq(c1, c2);
2086 config_free_lines(c1);
2087 config_free_lines(c2);
2088 return r;
2091 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
2092 static or_options_t *
2093 options_dup(config_format_t *fmt, or_options_t *old)
2095 or_options_t *newopts;
2096 int i;
2097 config_line_t *line;
2099 newopts = config_alloc(fmt);
2100 for (i=0; fmt->vars[i].name; ++i) {
2101 if (fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2102 continue;
2103 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE)
2104 continue;
2105 line = get_assigned_option(fmt, old, fmt->vars[i].name);
2106 if (line) {
2107 char *msg = NULL;
2108 if (config_assign(fmt, newopts, line, 0, 0, &msg) < 0) {
2109 log_err(LD_BUG, "Bug: config_get_assigned_option() generated "
2110 "something we couldn't config_assign(): %s", msg);
2111 tor_free(msg);
2112 tor_assert(0);
2115 config_free_lines(line);
2117 return newopts;
2120 /** Return a new empty or_options_t. Used for testing. */
2121 or_options_t *
2122 options_new(void)
2124 return config_alloc(&options_format);
2127 /** Set <b>options</b> to hold reasonable defaults for most options.
2128 * Each option defaults to zero. */
2129 void
2130 options_init(or_options_t *options)
2132 config_init(&options_format, options);
2135 /* Set all vars in the configuration object 'options' to their default
2136 * values. */
2137 static void
2138 config_init(config_format_t *fmt, void *options)
2140 int i;
2141 config_var_t *var;
2142 CHECK(fmt, options);
2144 for (i=0; fmt->vars[i].name; ++i) {
2145 var = &fmt->vars[i];
2146 if (!var->initvalue)
2147 continue; /* defaults to NULL or 0 */
2148 option_reset(fmt, options, var, 1);
2152 /** Allocate and return a new string holding the written-out values of the vars
2153 * in 'options'. If 'minimal', do not write out any default-valued vars.
2154 * Else, if comment_defaults, write default values as comments.
2156 static char *
2157 config_dump(config_format_t *fmt, void *options, int minimal,
2158 int comment_defaults)
2160 smartlist_t *elements;
2161 or_options_t *defaults;
2162 config_line_t *line, *assigned;
2163 char *result;
2164 int i;
2165 const char *desc;
2166 char *msg = NULL;
2168 defaults = config_alloc(fmt);
2169 config_init(fmt, defaults);
2171 /* XXX use a 1 here so we don't add a new log line while dumping */
2172 if (fmt->validate_fn(NULL,defaults, 1, &msg) < 0) {
2173 log_err(LD_BUG, "Failed to validate default config.");
2174 tor_free(msg);
2175 tor_assert(0);
2178 elements = smartlist_create();
2179 for (i=0; fmt->vars[i].name; ++i) {
2180 int comment_option = 0;
2181 if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE ||
2182 fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
2183 continue;
2184 /* Don't save 'hidden' control variables. */
2185 if (!strcmpstart(fmt->vars[i].name, "__"))
2186 continue;
2187 if (minimal && option_is_same(fmt, options, defaults, fmt->vars[i].name))
2188 continue;
2189 else if (comment_defaults &&
2190 option_is_same(fmt, options, defaults, fmt->vars[i].name))
2191 comment_option = 1;
2193 desc = config_find_description(fmt, fmt->vars[i].name);
2194 line = assigned = get_assigned_option(fmt, options, fmt->vars[i].name);
2196 if (line && desc) {
2197 /* Only dump the description if there's something to describe. */
2198 wrap_string(elements, desc, 78, "# ", "# ");
2201 for (; line; line = line->next) {
2202 size_t len = strlen(line->key) + strlen(line->value) + 5;
2203 char *tmp;
2204 tmp = tor_malloc(len);
2205 if (tor_snprintf(tmp, len, "%s%s %s\n",
2206 comment_option ? "# " : "",
2207 line->key, line->value)<0) {
2208 log_err(LD_BUG,"Internal error writing option value");
2209 tor_assert(0);
2211 smartlist_add(elements, tmp);
2213 config_free_lines(assigned);
2216 if (fmt->extra) {
2217 line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->var_offset);
2218 for (; line; line = line->next) {
2219 size_t len = strlen(line->key) + strlen(line->value) + 3;
2220 char *tmp;
2221 tmp = tor_malloc(len);
2222 if (tor_snprintf(tmp, len, "%s %s\n", line->key, line->value)<0) {
2223 log_err(LD_BUG,"Internal error writing option value");
2224 tor_assert(0);
2226 smartlist_add(elements, tmp);
2230 result = smartlist_join_strings(elements, "", 0, NULL);
2231 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
2232 smartlist_free(elements);
2233 config_free(fmt, defaults);
2234 return result;
2237 /** Return a string containing a possible configuration file that would give
2238 * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
2239 * include options that are the same as Tor's defaults.
2241 char *
2242 options_dump(or_options_t *options, int minimal)
2244 return config_dump(&options_format, options, minimal, 0);
2247 /** Return 0 if every element of sl is a string holding a decimal
2248 * representation of a port number, or if sl is NULL.
2249 * Otherwise set *msg and return -1. */
2250 static int
2251 validate_ports_csv(smartlist_t *sl, const char *name, char **msg)
2253 int i;
2254 char buf[1024];
2255 tor_assert(name);
2257 if (!sl)
2258 return 0;
2260 SMARTLIST_FOREACH(sl, const char *, cp,
2262 i = atoi(cp);
2263 if (i < 1 || i > 65535) {
2264 int r = tor_snprintf(buf, sizeof(buf),
2265 "Port '%s' out of range in %s", cp, name);
2266 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2267 return -1;
2270 return 0;
2273 /** Lowest allowable value for RendPostPeriod; if this is too low, hidden
2274 * services can overload the directory system. */
2275 #define MIN_REND_POST_PERIOD (5*60)
2277 /** Highest allowable value for RendPostPeriod. */
2278 #define MAX_DIR_PERIOD (MIN_ONION_KEY_LIFETIME/2)
2280 /** Return 0 if every setting in <b>options</b> is reasonable, and a
2281 * permissible transition from <b>old_options</b>. Else return -1.
2282 * Should have no side effects, except for normalizing the contents of
2283 * <b>options</b>.
2285 * On error, tor_strdup an error explanation into *<b>msg</b>.
2287 * XXX
2288 * If <b>from_setconf</b>, we were called by the controller, and our
2289 * Log line should stay empty. If it's 0, then give us a default log
2290 * if there are no logs defined.
2292 static int
2293 options_validate(or_options_t *old_options, or_options_t *options,
2294 int from_setconf, char **msg)
2296 int i, r;
2297 config_line_t *cl;
2298 const char *uname = get_uname();
2299 char buf[1024];
2300 #define REJECT(arg) \
2301 do { *msg = tor_strdup(arg); return -1; } while (0)
2302 #define COMPLAIN(arg) do { log(LOG_WARN, LD_CONFIG, arg); } while (0)
2304 tor_assert(msg);
2305 *msg = NULL;
2307 if (options->ORPort < 0 || options->ORPort > 65535)
2308 REJECT("ORPort option out of bounds.");
2310 if (server_mode(options) &&
2311 (!strcmpstart(uname, "Windows 95") ||
2312 !strcmpstart(uname, "Windows 98") ||
2313 !strcmpstart(uname, "Windows Me"))) {
2314 log(LOG_WARN, LD_CONFIG, "Tor is running as a server, but you are "
2315 "running %s; this probably won't work. See "
2316 "http://wiki.noreply.org/noreply/TheOnionRouter/TorFAQ#ServerOS "
2317 "for details.", uname);
2320 if (options->ORPort == 0 && options->ORListenAddress != NULL)
2321 REJECT("ORPort must be defined if ORListenAddress is defined.");
2323 if (options->DirPort == 0 && options->DirListenAddress != NULL)
2324 REJECT("DirPort must be defined if DirListenAddress is defined.");
2326 if (options->ControlPort == 0 && options->ControlListenAddress != NULL)
2327 REJECT("ControlPort must be defined if ControlListenAddress is defined.");
2329 if (options->TransPort == 0 && options->TransListenAddress != NULL)
2330 REJECT("TransPort must be defined if TransListenAddress is defined.");
2332 if (options->NatdPort == 0 && options->NatdListenAddress != NULL)
2333 REJECT("NatdPort must be defined if NatdListenAddress is defined.");
2335 /* Don't gripe about SocksPort 0 with SocksListenAddress set; a standard
2336 * configuration does this. */
2338 for (i = 0; i < 3; ++i) {
2339 int is_socks = i==0;
2340 int is_trans = i==1;
2341 config_line_t *line, *opt, *old;
2342 const char *tp;
2343 if (is_socks) {
2344 opt = options->SocksListenAddress;
2345 old = old_options ? old_options->SocksListenAddress : NULL;
2346 tp = "SOCKS proxy";
2347 } else if (is_trans) {
2348 opt = options->TransListenAddress;
2349 old = old_options ? old_options->TransListenAddress : NULL;
2350 tp = "transparent proxy";
2351 } else {
2352 opt = options->NatdListenAddress;
2353 old = old_options ? old_options->NatdListenAddress : NULL;
2354 tp = "natd proxy";
2357 for (line = opt; line; line = line->next) {
2358 char *address = NULL;
2359 uint16_t port;
2360 uint32_t addr;
2361 if (parse_addr_port(LOG_WARN, line->value, &address, &addr, &port)<0)
2362 continue; /* We'll warn about this later. */
2363 if (!is_internal_IP(addr, 1) &&
2364 (!old_options || !config_lines_eq(old, opt))) {
2365 log_warn(LD_CONFIG,
2366 "You specified a public address '%s' for a %s. Other "
2367 "people on the Internet might find your computer and use it as "
2368 "an open %s. Please don't allow this unless you have "
2369 "a good reason.", address, tp, tp);
2371 tor_free(address);
2375 if (validate_data_directory(options)<0)
2376 REJECT("Invalid DataDirectory");
2378 if (options->Nickname == NULL) {
2379 if (server_mode(options)) {
2380 if (!(options->Nickname = get_default_nickname())) {
2381 log_notice(LD_CONFIG, "Couldn't pick a nickname based on "
2382 "our hostname; using %s instead.", UNNAMED_ROUTER_NICKNAME);
2383 options->Nickname = tor_strdup(UNNAMED_ROUTER_NICKNAME);
2384 } else {
2385 log_notice(LD_CONFIG, "Choosing default nickname '%s'",
2386 options->Nickname);
2389 } else {
2390 if (!is_legal_nickname(options->Nickname)) {
2391 r = tor_snprintf(buf, sizeof(buf),
2392 "Nickname '%s' is wrong length or contains illegal characters.",
2393 options->Nickname);
2394 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2395 return -1;
2399 if (server_mode(options) && !options->ContactInfo)
2400 log(LOG_NOTICE, LD_CONFIG, "Your ContactInfo config option is not set. "
2401 "Please consider setting it, so we can contact you if your server is "
2402 "misconfigured or something else goes wrong.");
2404 /* Special case on first boot if no Log options are given. */
2405 if (!options->Logs && !options->RunAsDaemon && !from_setconf)
2406 config_line_append(&options->Logs, "Log", "notice stdout");
2408 if (options_init_logs(options, 1)<0) /* Validate the log(s) */
2409 REJECT("Failed to validate Log options. See logs for details.");
2411 if (options->NoPublish) {
2412 log(LOG_WARN, LD_CONFIG,
2413 "NoPublish is obsolete. Use PublishServerDescriptor instead.");
2414 options->PublishServerDescriptor = 0;
2417 if (authdir_mode(options)) {
2418 /* confirm that our address isn't broken, so we can complain now */
2419 uint32_t tmp;
2420 if (resolve_my_address(LOG_WARN, options, &tmp, NULL) < 0)
2421 REJECT("Failed to resolve/guess local address. See logs for details.");
2424 #ifndef MS_WINDOWS
2425 if (options->RunAsDaemon && torrc_fname && path_is_relative(torrc_fname))
2426 REJECT("Can't use a relative path to torrc when RunAsDaemon is set.");
2427 #endif
2429 if (options->SocksPort < 0 || options->SocksPort > 65535)
2430 REJECT("SocksPort option out of bounds.");
2432 if (options->TransPort < 0 || options->TransPort > 65535)
2433 REJECT("TransPort option out of bounds.");
2435 if (options->NatdPort < 0 || options->NatdPort > 65535)
2436 REJECT("NatdPort option out of bounds.");
2438 if (options->SocksPort == 0 && options->TransPort == 0 &&
2439 options->NatdPort == 0 && options->ORPort == 0)
2440 REJECT("SocksPort, TransPort, NatdPort, and ORPort are all undefined? "
2441 "Quitting.");
2443 if (options->ControlPort < 0 || options->ControlPort > 65535)
2444 REJECT("ControlPort option out of bounds.");
2446 if (options->DirPort < 0 || options->DirPort > 65535)
2447 REJECT("DirPort option out of bounds.");
2449 #ifndef USE_TRANSPARENT
2450 if (options->TransPort || options->TransListenAddress)
2451 REJECT("TransPort and TransListenAddress are disabled in this build.");
2452 #endif
2454 if (options->StrictExitNodes &&
2455 (!options->ExitNodes || !strlen(options->ExitNodes)) &&
2456 (!old_options ||
2457 (old_options->StrictExitNodes != options->StrictExitNodes) ||
2458 (!opt_streq(old_options->ExitNodes, options->ExitNodes))))
2459 COMPLAIN("StrictExitNodes set, but no ExitNodes listed.");
2461 if (options->StrictEntryNodes &&
2462 (!options->EntryNodes || !strlen(options->EntryNodes)) &&
2463 (!old_options ||
2464 (old_options->StrictEntryNodes != options->StrictEntryNodes) ||
2465 (!opt_streq(old_options->EntryNodes, options->EntryNodes))))
2466 COMPLAIN("StrictEntryNodes set, but no EntryNodes listed.");
2468 if (options->AuthoritativeDir) {
2469 if (!options->ContactInfo)
2470 REJECT("Authoritative directory servers must set ContactInfo");
2471 if (options->V1AuthoritativeDir && !options->RecommendedVersions)
2472 REJECT("V1 auth dir servers must set RecommendedVersions.");
2473 if (!options->RecommendedClientVersions)
2474 options->RecommendedClientVersions =
2475 config_lines_dup(options->RecommendedVersions);
2476 if (!options->RecommendedServerVersions)
2477 options->RecommendedServerVersions =
2478 config_lines_dup(options->RecommendedVersions);
2479 if (options->VersioningAuthoritativeDir &&
2480 (!options->RecommendedClientVersions ||
2481 !options->RecommendedServerVersions))
2482 REJECT("Versioning auth dir servers must set Recommended*Versions.");
2483 if (options->UseEntryGuards) {
2484 log_info(LD_CONFIG, "Authoritative directory servers can't set "
2485 "UseEntryGuards. Disabling.");
2486 options->UseEntryGuards = 0;
2490 if (options->AuthoritativeDir && !options->DirPort)
2491 REJECT("Running as authoritative directory, but no DirPort set.");
2493 if (options->AuthoritativeDir && !options->ORPort)
2494 REJECT("Running as authoritative directory, but no ORPort set.");
2496 if (options->AuthoritativeDir && options->ClientOnly)
2497 REJECT("Running as authoritative directory, but ClientOnly also set.");
2499 if (options->ConnLimit <= 0) {
2500 r = tor_snprintf(buf, sizeof(buf),
2501 "ConnLimit must be greater than 0, but was set to %d",
2502 options->ConnLimit);
2503 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2504 return -1;
2507 if (validate_ports_csv(options->FirewallPorts, "FirewallPorts", msg) < 0)
2508 return -1;
2510 if (validate_ports_csv(options->LongLivedPorts, "LongLivedPorts", msg) < 0)
2511 return -1;
2513 if (options->FascistFirewall && !options->ReachableAddresses) {
2514 if (options->FirewallPorts && smartlist_len(options->FirewallPorts)) {
2515 /* We already have firewall ports set, so migrate them to
2516 * ReachableAddresses, which will set ReachableORAddresses and
2517 * ReachableDirAddresses if they aren't set explicitly. */
2518 smartlist_t *instead = smartlist_create();
2519 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
2520 new_line->key = tor_strdup("ReachableAddresses");
2521 /* If we're configured with the old format, we need to prepend some
2522 * open ports. */
2523 SMARTLIST_FOREACH(options->FirewallPorts, const char *, portno,
2525 int p = atoi(portno);
2526 char *s;
2527 if (p<0) continue;
2528 s = tor_malloc(16);
2529 tor_snprintf(s, 16, "*:%d", p);
2530 smartlist_add(instead, s);
2532 new_line->value = smartlist_join_strings(instead,",",0,NULL);
2533 /* These have been deprecated since 0.1.1.5-alpha-cvs */
2534 log(LOG_NOTICE, LD_CONFIG,
2535 "Converting FascistFirewall and FirewallPorts "
2536 "config options to new format: \"ReachableAddresses %s\"",
2537 new_line->value);
2538 options->ReachableAddresses = new_line;
2539 SMARTLIST_FOREACH(instead, char *, cp, tor_free(cp));
2540 smartlist_free(instead);
2541 } else {
2542 /* We do not have FirewallPorts set, so add 80 to
2543 * ReachableDirAddresses, and 443 to ReachableORAddresses. */
2544 if (!options->ReachableDirAddresses) {
2545 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
2546 new_line->key = tor_strdup("ReachableDirAddresses");
2547 new_line->value = tor_strdup("*:80");
2548 options->ReachableDirAddresses = new_line;
2549 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
2550 "to new format: \"ReachableDirAddresses *:80\"");
2552 if (!options->ReachableORAddresses) {
2553 config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
2554 new_line->key = tor_strdup("ReachableORAddresses");
2555 new_line->value = tor_strdup("*:443");
2556 options->ReachableORAddresses = new_line;
2557 log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
2558 "to new format: \"ReachableORAddresses *:443\"");
2563 for (i=0; i<3; i++) {
2564 config_line_t **linep =
2565 (i==0) ? &options->ReachableAddresses :
2566 (i==1) ? &options->ReachableORAddresses :
2567 &options->ReachableDirAddresses;
2568 if (!*linep)
2569 continue;
2570 /* We need to end with a reject *:*, not an implicit accept *:* */
2571 for (;;) {
2572 if (!strcmp((*linep)->value, "reject *:*")) /* already there */
2573 break;
2574 linep = &((*linep)->next);
2575 if (!*linep) {
2576 *linep = tor_malloc_zero(sizeof(config_line_t));
2577 (*linep)->key = tor_strdup(
2578 (i==0) ? "ReachableAddresses" :
2579 (i==1) ? "ReachableORAddresses" :
2580 "ReachableDirAddresses");
2581 (*linep)->value = tor_strdup("reject *:*");
2582 break;
2587 if ((options->ReachableAddresses ||
2588 options->ReachableORAddresses ||
2589 options->ReachableDirAddresses) &&
2590 server_mode(options))
2591 REJECT("Servers must be able to freely connect to the rest "
2592 "of the Internet, so they must not set Reachable*Addresses "
2593 "or FascistFirewall.");
2595 options->_AllowInvalid = 0;
2596 if (options->AllowInvalidNodes) {
2597 SMARTLIST_FOREACH(options->AllowInvalidNodes, const char *, cp, {
2598 if (!strcasecmp(cp, "entry"))
2599 options->_AllowInvalid |= ALLOW_INVALID_ENTRY;
2600 else if (!strcasecmp(cp, "exit"))
2601 options->_AllowInvalid |= ALLOW_INVALID_EXIT;
2602 else if (!strcasecmp(cp, "middle"))
2603 options->_AllowInvalid |= ALLOW_INVALID_MIDDLE;
2604 else if (!strcasecmp(cp, "introduction"))
2605 options->_AllowInvalid |= ALLOW_INVALID_INTRODUCTION;
2606 else if (!strcasecmp(cp, "rendezvous"))
2607 options->_AllowInvalid |= ALLOW_INVALID_RENDEZVOUS;
2608 else {
2609 r = tor_snprintf(buf, sizeof(buf),
2610 "Unrecognized value '%s' in AllowInvalidNodes", cp);
2611 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2612 return -1;
2617 #if 0
2618 if (options->SocksPort >= 1 &&
2619 (options->PathlenCoinWeight < 0.0 || options->PathlenCoinWeight >= 1.0))
2620 REJECT("PathlenCoinWeight option must be >=0.0 and <1.0.");
2621 #endif
2623 if (options->RendPostPeriod < MIN_REND_POST_PERIOD) {
2624 log(LOG_WARN,LD_CONFIG,"RendPostPeriod option must be at least %d seconds."
2625 " Clipping.", MIN_REND_POST_PERIOD);
2626 options->RendPostPeriod = MIN_REND_POST_PERIOD;
2629 if (options->RendPostPeriod > MAX_DIR_PERIOD) {
2630 log(LOG_WARN, LD_CONFIG, "RendPostPeriod is too large; clipping to %ds.",
2631 MAX_DIR_PERIOD);
2632 options->RendPostPeriod = MAX_DIR_PERIOD;
2635 if (options->KeepalivePeriod < 1)
2636 REJECT("KeepalivePeriod option must be positive.");
2638 if (options->BandwidthRate > INT_MAX) {
2639 r = tor_snprintf(buf, sizeof(buf),
2640 "BandwidthRate must be less than %d",INT_MAX);
2641 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2642 return -1;
2644 if (options->BandwidthBurst > INT_MAX) {
2645 r = tor_snprintf(buf, sizeof(buf),
2646 "BandwidthBurst must be less than %d",INT_MAX);
2647 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2648 return -1;
2650 if (server_mode(options)) {
2651 if (options->BandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH*2) {
2652 r = tor_snprintf(buf, sizeof(buf),
2653 "BandwidthRate is set to %d bytes/second. "
2654 "For servers, it must be at least %d.",
2655 (int)options->BandwidthRate,
2656 ROUTER_REQUIRED_MIN_BANDWIDTH*2);
2657 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2658 return -1;
2659 } else if (options->MaxAdvertisedBandwidth <
2660 ROUTER_REQUIRED_MIN_BANDWIDTH) {
2661 r = tor_snprintf(buf, sizeof(buf),
2662 "MaxAdvertisedBandwidth is set to %d bytes/second. "
2663 "For servers, it must be at least %d.",
2664 (int)options->MaxAdvertisedBandwidth,
2665 ROUTER_REQUIRED_MIN_BANDWIDTH);
2666 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2667 return -1;
2671 if (options->BandwidthRate > options->BandwidthBurst)
2672 REJECT("BandwidthBurst must be at least equal to BandwidthRate.");
2674 if (accounting_parse_options(options, 1)<0)
2675 REJECT("Failed to parse accounting options. See logs for details.");
2677 if (options->HttpProxy) { /* parse it now */
2678 if (parse_addr_port(LOG_WARN, options->HttpProxy, NULL,
2679 &options->HttpProxyAddr, &options->HttpProxyPort) < 0)
2680 REJECT("HttpProxy failed to parse or resolve. Please fix.");
2681 if (options->HttpProxyPort == 0) { /* give it a default */
2682 options->HttpProxyPort = 80;
2686 if (options->HttpProxyAuthenticator) {
2687 if (strlen(options->HttpProxyAuthenticator) >= 48)
2688 REJECT("HttpProxyAuthenticator is too long (>= 48 chars).");
2691 if (options->HttpsProxy) { /* parse it now */
2692 if (parse_addr_port(LOG_WARN, options->HttpsProxy, NULL,
2693 &options->HttpsProxyAddr, &options->HttpsProxyPort) <0)
2694 REJECT("HttpsProxy failed to parse or resolve. Please fix.");
2695 if (options->HttpsProxyPort == 0) { /* give it a default */
2696 options->HttpsProxyPort = 443;
2700 if (options->HttpsProxyAuthenticator) {
2701 if (strlen(options->HttpsProxyAuthenticator) >= 48)
2702 REJECT("HttpsProxyAuthenticator is too long (>= 48 chars).");
2705 if (options->HashedControlPassword) {
2706 if (decode_hashed_password(NULL, options->HashedControlPassword)<0)
2707 REJECT("Bad HashedControlPassword: wrong length or bad encoding");
2709 if (options->HashedControlPassword && options->CookieAuthentication)
2710 REJECT("Cannot set both HashedControlPassword and CookieAuthentication");
2712 if (options->UseEntryGuards && ! options->NumEntryGuards)
2713 REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0");
2715 #ifndef USE_EVENTDNS
2716 if (options->ServerDNSResolvConfFile)
2717 log(LOG_WARN, LD_CONFIG,
2718 "ServerDNSResolvConfFile only works when eventdns support is enabled.");
2719 #endif
2721 if (check_nickname_list(options->ExitNodes, "ExitNodes", msg))
2722 return -1;
2723 if (check_nickname_list(options->EntryNodes, "EntryNodes", msg))
2724 return -1;
2725 if (check_nickname_list(options->ExcludeNodes, "ExcludeNodes", msg))
2726 return -1;
2727 if (check_nickname_list(options->RendNodes, "RendNodes", msg))
2728 return -1;
2729 if (check_nickname_list(options->RendNodes, "RendExcludeNodes", msg))
2730 return -1;
2731 if (check_nickname_list(options->TestVia, "TestVia", msg))
2732 return -1;
2733 if (check_nickname_list(options->MyFamily, "MyFamily", msg))
2734 return -1;
2735 for (cl = options->NodeFamilies; cl; cl = cl->next) {
2736 if (check_nickname_list(cl->value, "NodeFamily", msg))
2737 return -1;
2740 if (validate_addr_policies(options, msg) < 0)
2741 return -1;
2743 for (cl = options->RedirectExit; cl; cl = cl->next) {
2744 if (parse_redirect_line(NULL, cl, msg)<0)
2745 return -1;
2748 if (options->DirServers) {
2749 if (!old_options ||
2750 !config_lines_eq(options->DirServers, old_options->DirServers))
2751 COMPLAIN("You have used DirServer to specify directory authorities in "
2752 "your configuration. This is potentially dangerous: it can "
2753 "make you look different from all other Tor users, and hurt "
2754 "your anonymity. Even if you've specified the same "
2755 "authorities as Tor uses by default, the defaults could "
2756 "change in the future. Be sure you know what you're doing.");
2757 for (cl = options->DirServers; cl; cl = cl->next) {
2758 if (parse_dir_server_line(cl->value, 1)<0)
2759 REJECT("DirServer line did not parse. See logs for details.");
2763 if (rend_config_services(options, 1) < 0)
2764 REJECT("Failed to configure rendezvous options. See logs for details.");
2766 if (parse_virtual_addr_network(options->VirtualAddrNetwork, 1, NULL)<0)
2767 return -1;
2769 if (options->PreferTunneledDirConns && !options->TunnelDirConns)
2770 REJECT("Must set TunnelDirConns if PreferTunneledDirConns is set.");
2772 return 0;
2773 #undef REJECT
2774 #undef COMPLAIN
2777 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
2778 * equal strings. */
2779 static int
2780 opt_streq(const char *s1, const char *s2)
2782 if (!s1 && !s2)
2783 return 1;
2784 else if (s1 && s2 && !strcmp(s1,s2))
2785 return 1;
2786 else
2787 return 0;
2790 /** Check if any of the previous options have changed but aren't allowed to. */
2791 static int
2792 options_transition_allowed(or_options_t *old, or_options_t *new_val,
2793 char **msg)
2795 if (!old)
2796 return 0;
2798 if (!opt_streq(old->PidFile, new_val->PidFile)) {
2799 *msg = tor_strdup("PidFile is not allowed to change.");
2800 return -1;
2803 if (old->RunAsDaemon != new_val->RunAsDaemon) {
2804 *msg = tor_strdup("While Tor is running, changing RunAsDaemon "
2805 "is not allowed.");
2806 return -1;
2809 if (strcmp(old->DataDirectory,new_val->DataDirectory)!=0) {
2810 char buf[1024];
2811 int r = tor_snprintf(buf, sizeof(buf),
2812 "While Tor is running, changing DataDirectory "
2813 "(\"%s\"->\"%s\") is not allowed.",
2814 old->DataDirectory, new_val->DataDirectory);
2815 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2816 return -1;
2819 if (!opt_streq(old->User, new_val->User)) {
2820 *msg = tor_strdup("While Tor is running, changing User is not allowed.");
2821 return -1;
2824 if (!opt_streq(old->Group, new_val->Group)) {
2825 *msg = tor_strdup("While Tor is running, changing Group is not allowed.");
2826 return -1;
2829 if (old->HardwareAccel != new_val->HardwareAccel) {
2830 *msg = tor_strdup("While Tor is running, changing HardwareAccel is "
2831 "not allowed.");
2832 return -1;
2835 return 0;
2838 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
2839 * will require us to rotate the cpu and dns workers; else return 0. */
2840 static int
2841 options_transition_affects_workers(or_options_t *old_options,
2842 or_options_t *new_options)
2844 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
2845 old_options->NumCpus != new_options->NumCpus ||
2846 old_options->ORPort != new_options->ORPort ||
2847 old_options->ServerDNSSearchDomains !=
2848 new_options->ServerDNSSearchDomains ||
2849 old_options->SafeLogging != new_options->SafeLogging ||
2850 old_options->ClientOnly != new_options->ClientOnly ||
2851 !config_lines_eq(old_options->Logs, new_options->Logs))
2852 return 1;
2854 /* Check whether log options match. */
2856 /* Nothing that changed matters. */
2857 return 0;
2860 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
2861 * will require us to generate a new descriptor; else return 0. */
2862 static int
2863 options_transition_affects_descriptor(or_options_t *old_options,
2864 or_options_t *new_options)
2866 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
2867 !opt_streq(old_options->Nickname,new_options->Nickname) ||
2868 !opt_streq(old_options->Address,new_options->Address) ||
2869 !config_lines_eq(old_options->ExitPolicy,new_options->ExitPolicy) ||
2870 old_options->ORPort != new_options->ORPort ||
2871 old_options->DirPort != new_options->DirPort ||
2872 old_options->ClientOnly != new_options->ClientOnly ||
2873 old_options->NoPublish != new_options->NoPublish ||
2874 old_options->PublishServerDescriptor !=
2875 new_options->PublishServerDescriptor ||
2876 old_options->BandwidthRate != new_options->BandwidthRate ||
2877 old_options->BandwidthBurst != new_options->BandwidthBurst ||
2878 !opt_streq(old_options->ContactInfo, new_options->ContactInfo) ||
2879 !opt_streq(old_options->MyFamily, new_options->MyFamily) ||
2880 !opt_streq(old_options->AccountingStart, new_options->AccountingStart) ||
2881 old_options->AccountingMax != new_options->AccountingMax)
2882 return 1;
2884 return 0;
2887 #ifdef MS_WINDOWS
2888 /** Return the directory on windows where we expect to find our application
2889 * data. */
2890 static char *
2891 get_windows_conf_root(void)
2893 static int is_set = 0;
2894 static char path[MAX_PATH+1];
2896 LPITEMIDLIST idl;
2897 IMalloc *m;
2898 HRESULT result;
2900 if (is_set)
2901 return path;
2903 /* Find X:\documents and settings\username\application data\ .
2904 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
2906 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA,
2907 &idl))) {
2908 GetCurrentDirectory(MAX_PATH, path);
2909 is_set = 1;
2910 log_warn(LD_CONFIG,
2911 "I couldn't find your application data folder: are you "
2912 "running an ancient version of Windows 95? Defaulting to \"%s\"",
2913 path);
2914 return path;
2916 /* Convert the path from an "ID List" (whatever that is!) to a path. */
2917 result = SHGetPathFromIDList(idl, path);
2918 /* Now we need to free the */
2919 SHGetMalloc(&m);
2920 if (m) {
2921 m->lpVtbl->Free(m, idl);
2922 m->lpVtbl->Release(m);
2924 if (!SUCCEEDED(result)) {
2925 return NULL;
2927 strlcat(path,"\\tor",MAX_PATH);
2928 is_set = 1;
2929 return path;
2931 #endif
2933 /** Return the default location for our torrc file. */
2934 static const char *
2935 get_default_conf_file(void)
2937 #ifdef MS_WINDOWS
2938 static char path[MAX_PATH+1];
2939 strlcpy(path, get_windows_conf_root(), MAX_PATH);
2940 strlcat(path,"\\torrc",MAX_PATH);
2941 return path;
2942 #else
2943 return (CONFDIR "/torrc");
2944 #endif
2947 /** Verify whether lst is a string containing valid-looking space-separated
2948 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
2950 static int
2951 check_nickname_list(const char *lst, const char *name, char **msg)
2953 int r = 0;
2954 smartlist_t *sl;
2956 if (!lst)
2957 return 0;
2958 sl = smartlist_create();
2959 smartlist_split_string(sl, lst, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2960 SMARTLIST_FOREACH(sl, const char *, s,
2962 if (!is_legal_nickname_or_hexdigest(s)) {
2963 char buf[1024];
2964 int tmp = tor_snprintf(buf, sizeof(buf),
2965 "Invalid nickname '%s' in %s line", s, name);
2966 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
2967 r = -1;
2968 break;
2971 SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
2972 smartlist_free(sl);
2973 return r;
2976 /** Read a configuration file into <b>options</b>, finding the configuration
2977 * file location based on the command line. After loading the options,
2978 * validate them for consistency, then take actions based on them.
2979 * Return 0 if success, -1 if failure. */
2981 options_init_from_torrc(int argc, char **argv)
2983 or_options_t *oldoptions, *newoptions;
2984 config_line_t *cl;
2985 char *cf=NULL, *fname=NULL, *errmsg=NULL;
2986 int i, retval;
2987 int using_default_torrc;
2988 int ignore_missing_torrc;
2989 static char **backup_argv;
2990 static int backup_argc;
2992 if (argv) { /* first time we're called. save commandline args */
2993 backup_argv = argv;
2994 backup_argc = argc;
2995 oldoptions = NULL;
2996 } else { /* we're reloading. need to clean up old options first. */
2997 argv = backup_argv;
2998 argc = backup_argc;
2999 oldoptions = get_options();
3001 if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
3002 print_usage();
3003 exit(0);
3005 if (argc > 1 && !strcmp(argv[1], "--list-torrc-options")) {
3006 /* For documenting validating whether we've documented everything. */
3007 list_torrc_options();
3008 exit(0);
3011 if (argc > 1 && (!strcmp(argv[1],"--version"))) {
3012 printf("Tor version %s.\n",VERSION);
3013 if (argc > 2 && (!strcmp(argv[2],"--version"))) {
3014 print_svn_version();
3016 exit(0);
3019 newoptions = tor_malloc_zero(sizeof(or_options_t));
3020 newoptions->_magic = OR_OPTIONS_MAGIC;
3021 options_init(newoptions);
3023 /* learn config file name */
3024 fname = NULL;
3025 using_default_torrc = 1;
3026 ignore_missing_torrc = 0;
3027 newoptions->command = CMD_RUN_TOR;
3028 for (i = 1; i < argc; ++i) {
3029 if (i < argc-1 && !strcmp(argv[i],"-f")) {
3030 if (fname) {
3031 log(LOG_WARN, LD_CONFIG, "Duplicate -f options on command line.");
3032 tor_free(fname);
3034 fname = tor_strdup(argv[i+1]);
3035 using_default_torrc = 0;
3036 ++i;
3037 } else if (!strcmp(argv[i],"--ignore-missing-torrc")) {
3038 ignore_missing_torrc = 1;
3039 } else if (!strcmp(argv[i],"--list-fingerprint")) {
3040 newoptions->command = CMD_LIST_FINGERPRINT;
3041 } else if (!strcmp(argv[i],"--hash-password")) {
3042 newoptions->command = CMD_HASH_PASSWORD;
3043 newoptions->command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : "");
3044 ++i;
3045 } else if (!strcmp(argv[i],"--verify-config")) {
3046 newoptions->command = CMD_VERIFY_CONFIG;
3049 if (using_default_torrc) {
3050 /* didn't find one, try CONFDIR */
3051 const char *dflt = get_default_conf_file();
3052 if (dflt && file_status(dflt) == FN_FILE) {
3053 fname = tor_strdup(dflt);
3054 } else {
3055 #ifndef MS_WINDOWS
3056 char *fn;
3057 fn = expand_filename("~/.torrc");
3058 if (fn && file_status(fn) == FN_FILE) {
3059 fname = fn;
3060 } else {
3061 tor_free(fn);
3062 fname = tor_strdup(dflt);
3064 #else
3065 fname = tor_strdup(dflt);
3066 #endif
3069 tor_assert(fname);
3070 log(LOG_DEBUG, LD_CONFIG, "Opening config file \"%s\"", fname);
3072 tor_free(torrc_fname);
3073 torrc_fname = fname;
3075 /* get config lines, assign them */
3076 if (file_status(fname) != FN_FILE ||
3077 !(cf = read_file_to_str(fname,0,NULL))) {
3078 if (using_default_torrc == 1 || ignore_missing_torrc ) {
3079 log(LOG_NOTICE, LD_CONFIG, "Configuration file \"%s\" not present, "
3080 "using reasonable defaults.", fname);
3081 tor_free(fname); /* sets fname to NULL */
3082 torrc_fname = NULL;
3083 } else {
3084 log(LOG_WARN, LD_CONFIG,
3085 "Unable to open configuration file \"%s\".", fname);
3086 goto err;
3088 } else { /* it opened successfully. use it. */
3089 retval = config_get_lines(cf, &cl);
3090 tor_free(cf);
3091 if (retval < 0)
3092 goto err;
3093 retval = config_assign(&options_format, newoptions, cl, 0, 0, &errmsg);
3094 config_free_lines(cl);
3095 if (retval < 0)
3096 goto err;
3099 /* Go through command-line variables too */
3100 if (config_get_commandlines(argc, argv, &cl) < 0)
3101 goto err;
3102 retval = config_assign(&options_format, newoptions, cl, 0, 0, &errmsg);
3103 config_free_lines(cl);
3104 if (retval < 0)
3105 goto err;
3107 /* Validate newoptions */
3108 if (options_validate(oldoptions, newoptions, 0, &errmsg) < 0)
3109 goto err;
3111 if (options_transition_allowed(oldoptions, newoptions, &errmsg) < 0)
3112 goto err;
3114 if (set_options(newoptions, &errmsg))
3115 goto err; /* frees and replaces old options */
3117 return 0;
3118 err:
3119 tor_free(fname);
3120 torrc_fname = NULL;
3121 config_free(&options_format, newoptions);
3122 if (errmsg) {
3123 log(LOG_WARN,LD_CONFIG,"Failed to parse/validate config: %s", errmsg);
3124 tor_free(errmsg);
3126 return -1;
3129 /** Return the location for our configuration file.
3131 const char *
3132 get_torrc_fname(void)
3134 if (torrc_fname)
3135 return torrc_fname;
3136 else
3137 return get_default_conf_file();
3140 /** Adjust the address map mased on the MapAddress elements in the
3141 * configuration <b>options</b>
3143 static void
3144 config_register_addressmaps(or_options_t *options)
3146 smartlist_t *elts;
3147 config_line_t *opt;
3148 char *from, *to;
3150 addressmap_clear_configured();
3151 elts = smartlist_create();
3152 for (opt = options->AddressMap; opt; opt = opt->next) {
3153 smartlist_split_string(elts, opt->value, NULL,
3154 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
3155 if (smartlist_len(elts) >= 2) {
3156 from = smartlist_get(elts,0);
3157 to = smartlist_get(elts,1);
3158 if (address_is_invalid_destination(to, 1)) {
3159 log_warn(LD_CONFIG,
3160 "Skipping invalid argument '%s' to MapAddress", to);
3161 } else {
3162 addressmap_register(from, tor_strdup(to), 0);
3163 if (smartlist_len(elts)>2) {
3164 log_warn(LD_CONFIG,"Ignoring extra arguments to MapAddress.");
3167 } else {
3168 log_warn(LD_CONFIG,"MapAddress '%s' has too few arguments. Ignoring.",
3169 opt->value);
3171 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
3172 smartlist_clear(elts);
3174 smartlist_free(elts);
3177 /** If <b>range</b> is of the form MIN-MAX, for MIN and MAX both
3178 * recognized log severity levels, set *<b>min_out</b> to MIN and
3179 * *<b>max_out</b> to MAX and return 0. Else, if <b>range</b> is of
3180 * the form MIN, act as if MIN-err had been specified. Else, warn and
3181 * return -1.
3183 static int
3184 parse_log_severity_range(const char *range, int *min_out, int *max_out)
3186 int levelMin, levelMax;
3187 const char *cp;
3188 cp = strchr(range, '-');
3189 if (cp) {
3190 if (cp == range) {
3191 levelMin = LOG_DEBUG;
3192 } else {
3193 char *tmp_sev = tor_strndup(range, cp - range);
3194 levelMin = parse_log_level(tmp_sev);
3195 if (levelMin < 0) {
3196 log_warn(LD_CONFIG, "Unrecognized minimum log severity '%s': must be "
3197 "one of err|warn|notice|info|debug", tmp_sev);
3198 tor_free(tmp_sev);
3199 return -1;
3201 tor_free(tmp_sev);
3203 if (!*(cp+1)) {
3204 levelMax = LOG_ERR;
3205 } else {
3206 levelMax = parse_log_level(cp+1);
3207 if (levelMax < 0) {
3208 log_warn(LD_CONFIG, "Unrecognized maximum log severity '%s': must be "
3209 "one of err|warn|notice|info|debug", cp+1);
3210 return -1;
3213 } else {
3214 levelMin = parse_log_level(range);
3215 if (levelMin < 0) {
3216 log_warn(LD_CONFIG, "Unrecognized log severity '%s': must be one of "
3217 "err|warn|notice|info|debug", range);
3218 return -1;
3220 levelMax = LOG_ERR;
3223 *min_out = levelMin;
3224 *max_out = levelMax;
3226 return 0;
3230 * Initialize the logs based on the configuration file.
3233 options_init_logs(or_options_t *options, int validate_only)
3235 config_line_t *opt;
3236 int ok;
3237 smartlist_t *elts;
3238 int daemon =
3239 #ifdef MS_WINDOWS
3241 #else
3242 options->RunAsDaemon;
3243 #endif
3245 ok = 1;
3246 elts = smartlist_create();
3248 for (opt = options->Logs; opt; opt = opt->next) {
3249 int levelMin=LOG_DEBUG, levelMax=LOG_ERR;
3250 smartlist_split_string(elts, opt->value, NULL,
3251 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
3252 if (smartlist_len(elts) == 0) {
3253 log_warn(LD_CONFIG, "No arguments to Log option 'Log %s'", opt->value);
3254 ok = 0; goto cleanup;
3256 if (parse_log_severity_range(smartlist_get(elts,0), &levelMin,
3257 &levelMax)) {
3258 ok = 0; goto cleanup;
3260 if (smartlist_len(elts) < 2) { /* only loglevels were provided */
3261 if (!validate_only) {
3262 if (daemon) {
3263 log_warn(LD_CONFIG,
3264 "Can't log to stdout with RunAsDaemon set; skipping stdout");
3265 } else {
3266 add_stream_log(levelMin, levelMax, "<stdout>", stdout);
3269 goto cleanup;
3271 if (!strcasecmp(smartlist_get(elts,1), "file")) {
3272 if (smartlist_len(elts) != 3) {
3273 log_warn(LD_CONFIG, "Bad syntax on file Log option 'Log %s'",
3274 opt->value);
3275 ok = 0; goto cleanup;
3277 if (!validate_only) {
3278 if (add_file_log(levelMin, levelMax, smartlist_get(elts, 2)) < 0) {
3279 log_warn(LD_CONFIG, "Couldn't open file for 'Log %s'", opt->value);
3280 ok = 0;
3283 goto cleanup;
3285 if (smartlist_len(elts) != 2) {
3286 log_warn(LD_CONFIG, "Wrong number of arguments on Log option 'Log %s'",
3287 opt->value);
3288 ok = 0; goto cleanup;
3290 if (!strcasecmp(smartlist_get(elts,1), "stdout")) {
3291 if (daemon) {
3292 log_warn(LD_CONFIG, "Can't log to stdout with RunAsDaemon set.");
3293 ok = 0; goto cleanup;
3295 if (!validate_only) {
3296 add_stream_log(levelMin, levelMax, "<stdout>", stdout);
3298 } else if (!strcasecmp(smartlist_get(elts,1), "stderr")) {
3299 if (daemon) {
3300 log_warn(LD_CONFIG, "Can't log to stderr with RunAsDaemon set.");
3301 ok = 0; goto cleanup;
3303 if (!validate_only) {
3304 add_stream_log(levelMin, levelMax, "<stderr>", stderr);
3306 } else if (!strcasecmp(smartlist_get(elts,1), "syslog")) {
3307 #ifdef HAVE_SYSLOG_H
3308 if (!validate_only)
3309 add_syslog_log(levelMin, levelMax);
3310 #else
3311 log_warn(LD_CONFIG, "Syslog is not supported on this system. Sorry.");
3312 #endif
3313 } else {
3314 log_warn(LD_CONFIG, "Unrecognized log type %s",
3315 (const char*)smartlist_get(elts,1));
3316 if (strchr(smartlist_get(elts,1), '/') ||
3317 strchr(smartlist_get(elts,1), '\\')) {
3318 log_warn(LD_CONFIG, "Did you mean to say 'Log %s file %s' ?",
3319 (const char *)smartlist_get(elts,0),
3320 (const char *)smartlist_get(elts,1));
3322 ok = 0; goto cleanup;
3324 cleanup:
3325 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
3326 smartlist_clear(elts);
3328 smartlist_free(elts);
3330 return ok?0:-1;
3333 /** Parse a single RedirectExit line's contents from <b>line</b>. If
3334 * they are valid, and <b>result</b> is not NULL, add an element to
3335 * <b>result</b> and return 0. Else if they are valid, return 0.
3336 * Else set *msg and return -1. */
3337 static int
3338 parse_redirect_line(smartlist_t *result, config_line_t *line, char **msg)
3340 smartlist_t *elements = NULL;
3341 exit_redirect_t *r;
3343 tor_assert(line);
3345 r = tor_malloc_zero(sizeof(exit_redirect_t));
3346 elements = smartlist_create();
3347 smartlist_split_string(elements, line->value, NULL,
3348 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
3349 if (smartlist_len(elements) != 2) {
3350 *msg = tor_strdup("Wrong number of elements in RedirectExit line");
3351 goto err;
3353 if (parse_addr_and_port_range(smartlist_get(elements,0),&r->addr,&r->mask,
3354 &r->port_min,&r->port_max)) {
3355 *msg = tor_strdup("Error parsing source address in RedirectExit line");
3356 goto err;
3358 if (0==strcasecmp(smartlist_get(elements,1), "pass")) {
3359 r->is_redirect = 0;
3360 } else {
3361 if (parse_addr_port(LOG_WARN, smartlist_get(elements,1),NULL,
3362 &r->addr_dest, &r->port_dest)) {
3363 *msg = tor_strdup("Error parsing dest address in RedirectExit line");
3364 goto err;
3366 r->is_redirect = 1;
3369 goto done;
3370 err:
3371 tor_free(r);
3372 done:
3373 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
3374 smartlist_free(elements);
3375 if (r) {
3376 if (result)
3377 smartlist_add(result, r);
3378 else
3379 tor_free(r);
3380 return 0;
3381 } else {
3382 tor_assert(*msg);
3383 return -1;
3387 /** Read the contents of a DirServer line from <b>line</b>. Return 0
3388 * if the line is well-formed, and -1 if it isn't. If
3389 * <b>validate_only</b> is 0, and the line is well-formed, then add
3390 * the dirserver described in the line as a valid server. */
3391 static int
3392 parse_dir_server_line(const char *line, int validate_only)
3394 smartlist_t *items = NULL;
3395 int r;
3396 char *addrport=NULL, *address=NULL, *nickname=NULL, *fingerprint=NULL;
3397 uint16_t dir_port = 0, or_port = 0;
3398 char digest[DIGEST_LEN];
3399 int is_v1_authority = 0, is_hidserv_authority = 0,
3400 is_not_hidserv_authority = 0, is_v2_authority = 1;
3402 items = smartlist_create();
3403 smartlist_split_string(items, line, NULL,
3404 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
3405 if (smartlist_len(items) < 1) {
3406 log_warn(LD_CONFIG, "No arguments on DirServer line.");
3407 goto err;
3410 if (is_legal_nickname(smartlist_get(items, 0))) {
3411 nickname = smartlist_get(items, 0);
3412 smartlist_del_keeporder(items, 0);
3415 while (smartlist_len(items)) {
3416 char *flag = smartlist_get(items, 0);
3417 if (TOR_ISDIGIT(flag[0]))
3418 break;
3419 if (!strcasecmp(flag, "v1")) {
3420 is_v1_authority = is_hidserv_authority = 1;
3421 } else if (!strcasecmp(flag, "hs")) {
3422 is_hidserv_authority = 1;
3423 } else if (!strcasecmp(flag, "no-hs")) {
3424 is_not_hidserv_authority = 1;
3425 } else if (!strcasecmp(flag, "no-v2")) {
3426 is_v2_authority = 0;
3427 } else if (!strcasecmpstart(flag, "orport=")) {
3428 int ok;
3429 char *portstring = flag + strlen("orport=");
3430 or_port = (uint16_t) tor_parse_long(portstring, 10, 1, 65535, &ok, NULL);
3431 if (!ok)
3432 log_warn(LD_CONFIG, "Invalid orport '%s' on DirServer line.",
3433 portstring);
3434 } else {
3435 log_warn(LD_CONFIG, "Unrecognized flag '%s' on DirServer line",
3436 flag);
3438 tor_free(flag);
3439 smartlist_del_keeporder(items, 0);
3442 if (is_not_hidserv_authority)
3443 is_hidserv_authority = 0;
3445 if (smartlist_len(items) < 2) {
3446 log_warn(LD_CONFIG, "Too few arguments to DirServer line.");
3447 goto err;
3449 addrport = smartlist_get(items, 0);
3450 smartlist_del_keeporder(items, 0);
3451 if (parse_addr_port(LOG_WARN, addrport, &address, NULL, &dir_port)<0) {
3452 log_warn(LD_CONFIG, "Error parsing DirServer address '%s'", addrport);
3453 goto err;
3455 if (!dir_port) {
3456 log_warn(LD_CONFIG, "Missing port in DirServer address '%s'",addrport);
3457 goto err;
3460 fingerprint = smartlist_join_strings(items, "", 0, NULL);
3461 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
3462 log_warn(LD_CONFIG, "Key digest for DirServer is wrong length.");
3463 goto err;
3465 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
3466 log_warn(LD_CONFIG, "Unable to decode DirServer key digest.");
3467 goto err;
3470 if (!validate_only) {
3471 log_debug(LD_DIR, "Trusted dirserver at %s:%d (%s)", address,
3472 (int)dir_port,
3473 (char*)smartlist_get(items,1));
3474 add_trusted_dir_server(nickname, address, dir_port, or_port, digest,
3475 is_v1_authority,
3476 is_v2_authority, is_hidserv_authority);
3480 r = 0;
3481 goto done;
3483 err:
3484 r = -1;
3486 done:
3487 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
3488 smartlist_free(items);
3489 tor_free(addrport);
3490 tor_free(address);
3491 tor_free(nickname);
3492 tor_free(fingerprint);
3493 return r;
3496 /** Adjust the value of options->DataDirectory, or fill it in if it's
3497 * absent. Return 0 on success, -1 on failure. */
3498 static int
3499 normalize_data_directory(or_options_t *options)
3501 #ifdef MS_WINDOWS
3502 char *p;
3503 if (options->DataDirectory)
3504 return 0; /* all set */
3505 p = tor_malloc(MAX_PATH);
3506 strlcpy(p,get_windows_conf_root(),MAX_PATH);
3507 options->DataDirectory = p;
3508 return 0;
3509 #else
3510 const char *d = options->DataDirectory;
3511 if (!d)
3512 d = "~/.tor";
3514 if (strncmp(d,"~/",2) == 0) {
3515 char *fn = expand_filename(d);
3516 if (!fn) {
3517 log_err(LD_CONFIG,"Failed to expand filename \"%s\".", d);
3518 return -1;
3520 if (!options->DataDirectory && !strcmp(fn,"/.tor")) {
3521 /* If our homedir is /, we probably don't want to use it. */
3522 /* Default to LOCALSTATEDIR/tor which is probably closer to what we
3523 * want. */
3524 log_warn(LD_CONFIG,
3525 "Default DataDirectory is \"~/.tor\". This expands to "
3526 "\"%s\", which is probably not what you want. Using \"%s/tor\" "
3527 "instead", fn, LOCALSTATEDIR);
3528 tor_free(fn);
3529 fn = tor_strdup(LOCALSTATEDIR"/tor");
3532 tor_free(options->DataDirectory);
3533 options->DataDirectory = fn;
3535 return 0;
3536 #endif
3539 /** Check and normalize the value of options->DataDirectory; return 0 if it
3540 * sane, -1 otherwise. */
3541 static int
3542 validate_data_directory(or_options_t *options)
3544 if (normalize_data_directory(options) < 0)
3545 return -1;
3546 tor_assert(options->DataDirectory);
3547 if (strlen(options->DataDirectory) > (512-128)) {
3548 log_err(LD_CONFIG, "DataDirectory is too long.");
3549 return -1;
3551 return 0;
3554 /** This string must remain the same forevermore. It is how we
3555 * recognize that the torrc file doesn't need to be backed up. */
3556 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; " \
3557 "if you edit it, comments will not be preserved"
3558 /** This string can change; it tries to give the reader an idea
3559 * that editing this file by hand is not a good plan. */
3560 #define GENERATED_FILE_COMMENT "# The old torrc file was renamed " \
3561 "to torrc.orig.1 or similar, and Tor will ignore it"
3563 /** Save a configuration file for the configuration in <b>options</b>
3564 * into the file <b>fname</b>. If the file already exists, and
3565 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
3566 * replace it. Return 0 on success, -1 on failure. */
3567 static int
3568 write_configuration_file(const char *fname, or_options_t *options)
3570 char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
3571 int rename_old = 0, r;
3572 size_t len;
3574 if (fname) {
3575 switch (file_status(fname)) {
3576 case FN_FILE:
3577 old_val = read_file_to_str(fname, 0, NULL);
3578 if (strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
3579 rename_old = 1;
3581 tor_free(old_val);
3582 break;
3583 case FN_NOENT:
3584 break;
3585 case FN_ERROR:
3586 case FN_DIR:
3587 default:
3588 log_warn(LD_CONFIG,
3589 "Config file \"%s\" is not a file? Failing.", fname);
3590 return -1;
3594 if (!(new_conf = options_dump(options, 1))) {
3595 log_warn(LD_BUG, "Couldn't get configuration string");
3596 goto err;
3599 len = strlen(new_conf)+256;
3600 new_val = tor_malloc(len);
3601 tor_snprintf(new_val, len, "%s\n%s\n\n%s",
3602 GENERATED_FILE_PREFIX, GENERATED_FILE_COMMENT, new_conf);
3604 if (rename_old) {
3605 int i = 1;
3606 size_t fn_tmp_len = strlen(fname)+32;
3607 char *fn_tmp;
3608 tor_assert(fn_tmp_len > strlen(fname)); /*check for overflow*/
3609 fn_tmp = tor_malloc(fn_tmp_len);
3610 while (1) {
3611 if (tor_snprintf(fn_tmp, fn_tmp_len, "%s.orig.%d", fname, i)<0) {
3612 log_warn(LD_BUG, "tor_snprintf failed inexplicably");
3613 tor_free(fn_tmp);
3614 goto err;
3616 if (file_status(fn_tmp) == FN_NOENT)
3617 break;
3618 ++i;
3620 log_notice(LD_CONFIG, "Renaming old configuration file to \"%s\"", fn_tmp);
3621 if (rename(fname, fn_tmp) < 0) {
3622 log_warn(LD_FS,
3623 "Couldn't rename configuration file \"%s\" to \"%s\": %s",
3624 fname, fn_tmp, strerror(errno));
3625 tor_free(fn_tmp);
3626 goto err;
3628 tor_free(fn_tmp);
3631 if (write_str_to_file(fname, new_val, 0) < 0)
3632 goto err;
3634 r = 0;
3635 goto done;
3636 err:
3637 r = -1;
3638 done:
3639 tor_free(new_val);
3640 tor_free(new_conf);
3641 return r;
3645 * Save the current configuration file value to disk. Return 0 on
3646 * success, -1 on failure.
3649 options_save_current(void)
3651 if (torrc_fname) {
3652 /* This fails if we can't write to our configuration file.
3654 * If we try falling back to datadirectory or something, we have a better
3655 * chance of saving the configuration, but a better chance of doing
3656 * something the user never expected. Let's just warn instead. */
3657 return write_configuration_file(torrc_fname, get_options());
3659 return write_configuration_file(get_default_conf_file(), get_options());
3662 /** Mapping from a unit name to a multiplier for converting that unit into a
3663 * base unit. */
3664 struct unit_table_t {
3665 const char *unit;
3666 uint64_t multiplier;
3669 static struct unit_table_t memory_units[] = {
3670 { "", 1 },
3671 { "b", 1<< 0 },
3672 { "byte", 1<< 0 },
3673 { "bytes", 1<< 0 },
3674 { "kb", 1<<10 },
3675 { "kilobyte", 1<<10 },
3676 { "kilobytes", 1<<10 },
3677 { "m", 1<<20 },
3678 { "mb", 1<<20 },
3679 { "megabyte", 1<<20 },
3680 { "megabytes", 1<<20 },
3681 { "gb", 1<<30 },
3682 { "gigabyte", 1<<30 },
3683 { "gigabytes", 1<<30 },
3684 { "tb", U64_LITERAL(1)<<40 },
3685 { "terabyte", U64_LITERAL(1)<<40 },
3686 { "terabytes", U64_LITERAL(1)<<40 },
3687 { NULL, 0 },
3690 static struct unit_table_t time_units[] = {
3691 { "", 1 },
3692 { "second", 1 },
3693 { "seconds", 1 },
3694 { "minute", 60 },
3695 { "minutes", 60 },
3696 { "hour", 60*60 },
3697 { "hours", 60*60 },
3698 { "day", 24*60*60 },
3699 { "days", 24*60*60 },
3700 { "week", 7*24*60*60 },
3701 { "weeks", 7*24*60*60 },
3702 { NULL, 0 },
3705 /** Parse a string <b>val</b> containing a number, zero or more
3706 * spaces, and an optional unit string. If the unit appears in the
3707 * table <b>u</b>, then multiply the number by the unit multiplier.
3708 * On success, set *<b>ok</b> to 1 and return this product.
3709 * Otherwise, set *<b>ok</b> to 0.
3711 static uint64_t
3712 config_parse_units(const char *val, struct unit_table_t *u, int *ok)
3714 uint64_t v;
3715 char *cp;
3717 tor_assert(ok);
3719 v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
3720 if (!*ok)
3721 return 0;
3722 if (!cp) {
3723 *ok = 1;
3724 return v;
3726 while (TOR_ISSPACE(*cp))
3727 ++cp;
3728 for ( ;u->unit;++u) {
3729 if (!strcasecmp(u->unit, cp)) {
3730 v *= u->multiplier;
3731 *ok = 1;
3732 return v;
3735 log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
3736 *ok = 0;
3737 return 0;
3740 /** Parse a string in the format "number unit", where unit is a unit of
3741 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
3742 * and return the number of bytes specified. Otherwise, set
3743 * *<b>ok</b> to false and return 0. */
3744 static uint64_t
3745 config_parse_memunit(const char *s, int *ok)
3747 return config_parse_units(s, memory_units, ok);
3750 /** Parse a string in the format "number unit", where unit is a unit of time.
3751 * On success, set *<b>ok</b> to true and return the number of seconds in
3752 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
3754 static int
3755 config_parse_interval(const char *s, int *ok)
3757 uint64_t r;
3758 r = config_parse_units(s, time_units, ok);
3759 if (!ok)
3760 return -1;
3761 if (r > INT_MAX) {
3762 log_warn(LD_CONFIG, "Interval '%s' is too long", s);
3763 *ok = 0;
3764 return -1;
3766 return (int)r;
3770 * Initialize the libevent library.
3772 static void
3773 init_libevent(void)
3775 configure_libevent_logging();
3776 /* If the kernel complains that some method (say, epoll) doesn't
3777 * exist, we don't care about it, since libevent will cope.
3779 suppress_libevent_log_msg("Function not implemented");
3780 #ifdef __APPLE__
3781 if (decode_libevent_version() < LE_11B) {
3782 setenv("EVENT_NOKQUEUE","1",1);
3783 } else if (!getenv("EVENT_NOKQUEUE")) {
3784 const char *ver = NULL;
3785 #ifdef HAVE_EVENT_GET_VERSION
3786 ver = event_get_version();
3787 #endif
3788 /* If we're 1.1b or later, we'd better have get_version() */
3789 tor_assert(ver);
3790 log(LOG_NOTICE, LD_GENERAL, "Enabling experimental OS X kqueue support "
3791 "with libevent %s. If this turns out to not work, "
3792 "set the environment variable EVENT_NOKQUEUE, and tell the Tor "
3793 "developers.", ver);
3795 #endif
3796 event_init();
3797 suppress_libevent_log_msg(NULL);
3798 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
3799 /* Making this a NOTICE for now so we can link bugs to a libevent versions
3800 * or methods better. */
3801 log(LOG_NOTICE, LD_GENERAL,
3802 "Initialized libevent version %s using method %s. Good.",
3803 event_get_version(), event_get_method());
3804 check_libevent_version(event_get_method(), get_options()->ORPort != 0);
3805 #else
3806 log(LOG_NOTICE, LD_GENERAL,
3807 "Initialized old libevent (version 1.0b or earlier).");
3808 log(LOG_WARN, LD_GENERAL,
3809 "You have a *VERY* old version of libevent. It is likely to be buggy; "
3810 "please build Tor with a more recent version.");
3811 #endif
3814 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
3815 /** Table mapping return value of event_get_version() to le_version_t. */
3816 static const struct {
3817 const char *name; le_version_t version;
3818 } le_version_table[] = {
3819 /* earlier versions don't have get_version. */
3820 { "1.0c", LE_10C },
3821 { "1.0d", LE_10D },
3822 { "1.0e", LE_10E },
3823 { "1.1", LE_11 },
3824 { "1.1a", LE_11A },
3825 { "1.1b", LE_11B },
3826 { "1.2", LE_12 },
3827 { "1.2a", LE_12A },
3828 { "1.3", LE_13 },
3829 { NULL, LE_OTHER }
3832 /** Return the le_version_t for the current version of libevent. If the
3833 * version is very new, return LE_OTHER. If the version is so old that it
3834 * doesn't support event_get_version(), return LE_OLD. */
3835 static le_version_t
3836 decode_libevent_version(void)
3838 const char *v = event_get_version();
3839 int i;
3840 for (i=0; le_version_table[i].name; ++i) {
3841 if (!strcmp(le_version_table[i].name, v)) {
3842 return le_version_table[i].version;
3845 return LE_OTHER;
3849 * Compare the given libevent method and version to a list of versions
3850 * which are known not to work. Warn the user as appropriate.
3852 static void
3853 check_libevent_version(const char *m, int server)
3855 int buggy = 0, iffy = 0, slow = 0;
3856 le_version_t version;
3857 const char *v = event_get_version();
3858 const char *badness = NULL;
3860 version = decode_libevent_version();
3862 /* XXX Would it be worthwhile disabling the methods that we know
3863 * are buggy, rather than just warning about them and then proceeding
3864 * to use them? If so, we should probably not wrap this whole thing
3865 * in HAVE_EVENT_GET_VERSION and HAVE_EVENT_GET_METHOD. -RD */
3866 /* XXXX The problem is that it's not trivial to get libevent to change it's
3867 * method once it's initialized, and it's not trivial to tell what method it
3868 * will use without initializing it. I guess we could preemptively disable
3869 * buggy libevent modes based on the version _before_ initializing it,
3870 * though, but then there's no good way (afaict) to warn "I would have used
3871 * kqueue, but instead I'm using select." -NM */
3872 if (!strcmp(m, "kqueue")) {
3873 if (version < LE_11B)
3874 buggy = 1;
3875 } else if (!strcmp(m, "epoll")) {
3876 if (version < LE_11)
3877 iffy = 1;
3878 } else if (!strcmp(m, "poll")) {
3879 if (version < LE_10E)
3880 buggy = 1;
3881 else if (version < LE_11)
3882 slow = 1;
3883 } else if (!strcmp(m, "select")) {
3884 if (version < LE_11)
3885 slow = 1;
3886 } else if (!strcmp(m, "win32")) {
3887 if (version < LE_11B)
3888 buggy = 1;
3891 if (buggy) {
3892 log(LOG_WARN, LD_GENERAL,
3893 "There are known bugs in using %s with libevent %s. "
3894 "Please use the latest version of libevent.", m, v);
3895 badness = "BROKEN";
3896 } else if (iffy) {
3897 log(LOG_WARN, LD_GENERAL,
3898 "There are minor bugs in using %s with libevent %s. "
3899 "You may want to use the latest version of libevent.", m, v);
3900 badness = "BUGGY";
3901 } else if (slow && server) {
3902 log(LOG_WARN, LD_GENERAL,
3903 "libevent %s can be very slow with %s. "
3904 "When running a server, please use the latest version of libevent.",
3905 v,m);
3906 badness = "SLOW";
3908 if (badness) {
3909 control_event_general_status(LOG_WARN,
3910 "BAD_LIBEVENT VERSION=%s METHOD=%s BADNESS=%s RECOVERED=NO",
3911 v, m, badness);
3915 #else
3916 static le_version_t
3917 decode_libevent_version(void)
3919 return LE_OLD;
3921 #endif
3923 /** Return the persistent state struct for this Tor. */
3924 or_state_t *
3925 get_or_state(void)
3927 tor_assert(global_state);
3928 return global_state;
3931 /** Return the filename used to write and read the persistent state. */
3932 static char *
3933 get_or_state_fname(void)
3935 char *fname = NULL;
3936 or_options_t *options = get_options();
3937 size_t len = strlen(options->DataDirectory) + 16;
3938 fname = tor_malloc(len);
3939 tor_snprintf(fname, len, "%s/state", options->DataDirectory);
3940 return fname;
3943 /** Return 0 if every setting in <b>state</b> is reasonable, and a
3944 * permissible transition from <b>old_state</b>. Else warn and return -1.
3945 * Should have no side effects, except for normalizing the contents of
3946 * <b>state</b>.
3948 /* XXX from_setconf is here because of bug 238 */
3949 static int
3950 or_state_validate(or_state_t *old_state, or_state_t *state,
3951 int from_setconf, char **msg)
3953 /* We don't use these; only options do. Still, we need to match that
3954 * signature. */
3955 (void) from_setconf;
3956 (void) old_state;
3957 if (entry_guards_parse_state(state, 0, msg)<0) {
3958 return -1;
3960 if (state->TorVersion) {
3961 tor_version_t v;
3962 if (tor_version_parse(state->TorVersion, &v)) {
3963 log_warn(LD_GENERAL, "Can't parse Tor version '%s' from your state "
3964 "file. Proceeding anyway.", state->TorVersion);
3965 } else { /* take action based on v */
3966 if (tor_version_as_new_as(state->TorVersion, "0.1.1.10-alpha") &&
3967 !tor_version_as_new_as(state->TorVersion, "0.1.1.16-rc-cvs")) {
3968 log_notice(LD_CONFIG, "Detected state file from buggy version '%s'. "
3969 "Enabling workaround to choose working entry guards.",
3970 state->TorVersion);
3971 config_free_lines(state->EntryGuards);
3972 state->EntryGuards = NULL;
3976 return 0;
3979 /** Replace the current persistent state with <b>new_state</b> */
3980 static void
3981 or_state_set(or_state_t *new_state)
3983 char *err = NULL;
3984 tor_assert(new_state);
3985 if (global_state)
3986 config_free(&state_format, global_state);
3987 global_state = new_state;
3988 if (entry_guards_parse_state(global_state, 1, &err)<0) {
3989 log_warn(LD_GENERAL,"%s",err);
3990 tor_free(err);
3992 if (rep_hist_load_state(global_state, &err)<0) {
3993 log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
3994 tor_free(err);
3998 /** Reload the persistent state from disk, generating a new state as needed.
3999 * Return 0 on success, less than 0 on failure.
4002 or_state_load(void)
4004 or_state_t *new_state = NULL;
4005 char *contents = NULL, *fname;
4006 char *errmsg = NULL;
4007 int r = -1, badstate = 0;
4009 fname = get_or_state_fname();
4010 switch (file_status(fname)) {
4011 case FN_FILE:
4012 if (!(contents = read_file_to_str(fname, 0, NULL))) {
4013 log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
4014 goto done;
4016 break;
4017 case FN_NOENT:
4018 break;
4019 case FN_ERROR:
4020 case FN_DIR:
4021 default:
4022 log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
4023 goto done;
4025 new_state = tor_malloc_zero(sizeof(or_state_t));
4026 new_state->_magic = OR_STATE_MAGIC;
4027 config_init(&state_format, new_state);
4028 if (contents) {
4029 config_line_t *lines=NULL;
4030 int assign_retval;
4031 if (config_get_lines(contents, &lines)<0)
4032 goto done;
4033 assign_retval = config_assign(&state_format, new_state,
4034 lines, 0, 0, &errmsg);
4035 config_free_lines(lines);
4036 if (assign_retval<0)
4037 badstate = 1;
4038 if (errmsg) {
4039 log_warn(LD_GENERAL, "%s", errmsg);
4040 tor_free(errmsg);
4044 if (!badstate && or_state_validate(NULL, new_state, 1, &errmsg) < 0)
4045 badstate = 1;
4047 if (errmsg) {
4048 log_warn(LD_GENERAL, "%s", errmsg);
4049 tor_free(errmsg);
4052 if (badstate && !contents) {
4053 log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
4054 " This is a bug in Tor.");
4055 goto done;
4056 } else if (badstate && contents) {
4057 int i;
4058 file_status_t status;
4059 size_t len = strlen(fname)+16;
4060 char *fname2 = tor_malloc(len);
4061 for (i = 0; i < 100; ++i) {
4062 tor_snprintf(fname2, len, "%s.%d", fname, i);
4063 status = file_status(fname2);
4064 if (status == FN_NOENT)
4065 break;
4067 if (i == 100) {
4068 log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
4069 "state files to move aside. Discarding the old state file.",
4070 fname);
4071 unlink(fname);
4072 } else {
4073 log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
4074 "to \"%s\". This could be a bug in Tor; please tell "
4075 "the developers.", fname, fname2);
4076 rename(fname, fname2);
4078 tor_free(fname2);
4079 tor_free(contents);
4080 config_free(&state_format, new_state);
4082 new_state = tor_malloc_zero(sizeof(or_state_t));
4083 new_state->_magic = OR_STATE_MAGIC;
4084 config_init(&state_format, new_state);
4085 } else if (contents) {
4086 log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
4087 } else {
4088 log_info(LD_GENERAL, "Initialized state");
4090 or_state_set(new_state);
4091 new_state = NULL;
4092 if (!contents) {
4093 global_state->next_write = 0;
4094 or_state_save(time(NULL));
4096 r = 0;
4098 done:
4099 tor_free(fname);
4100 tor_free(contents);
4101 if (new_state)
4102 config_free(&state_format, new_state);
4104 return r;
4107 /** Write the persistent state to disk. Return 0 for success, <0 on failure. */
4109 or_state_save(time_t now)
4111 char *state, *contents;
4112 char tbuf[ISO_TIME_LEN+1];
4113 size_t len;
4114 char *fname;
4116 tor_assert(global_state);
4118 if (global_state->next_write > now)
4119 return 0;
4121 /* Call everything else that might dirty the state even more, in order
4122 * to avoid redundant writes. */
4123 entry_guards_update_state(global_state);
4124 rep_hist_update_state(global_state);
4125 if (accounting_is_enabled(get_options()))
4126 accounting_run_housekeeping(now);
4128 global_state->LastWritten = time(NULL);
4129 tor_free(global_state->TorVersion);
4130 global_state->TorVersion = tor_strdup("Tor " VERSION);
4131 state = config_dump(&state_format, global_state, 1, 0);
4132 len = strlen(state)+256;
4133 contents = tor_malloc(len);
4134 format_local_iso_time(tbuf, time(NULL));
4135 tor_snprintf(contents, len,
4136 "# Tor state file last generated on %s local time\n"
4137 "# Other times below are in GMT\n"
4138 "# You *do not* need to edit this file.\n\n%s",
4139 tbuf, state);
4140 tor_free(state);
4141 fname = get_or_state_fname();
4142 if (write_str_to_file(fname, contents, 0)<0) {
4143 log_warn(LD_FS, "Unable to write state to file \"%s\"", fname);
4144 tor_free(fname);
4145 tor_free(contents);
4146 return -1;
4148 log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
4149 tor_free(fname);
4150 tor_free(contents);
4152 global_state->next_write = TIME_MAX;
4153 return 0;
4156 /** Helper to implement GETINFO functions about configuration variables (not
4157 * their values). Given a "config/names" question, set *<b>answer</b> to a
4158 * new string describing the supported configuration variables and their
4159 * types. */
4161 getinfo_helper_config(control_connection_t *conn,
4162 const char *question, char **answer)
4164 (void) conn;
4165 if (!strcmp(question, "config/names")) {
4166 smartlist_t *sl = smartlist_create();
4167 int i;
4168 for (i = 0; _option_vars[i].name; ++i) {
4169 config_var_t *var = &_option_vars[i];
4170 const char *type, *desc;
4171 char *line;
4172 size_t len;
4173 desc = config_find_description(&options_format, var->name);
4174 switch (var->type) {
4175 case CONFIG_TYPE_STRING: type = "String"; break;
4176 case CONFIG_TYPE_UINT: type = "Integer"; break;
4177 case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
4178 case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
4179 case CONFIG_TYPE_DOUBLE: type = "Float"; break;
4180 case CONFIG_TYPE_BOOL: type = "Boolean"; break;
4181 case CONFIG_TYPE_ISOTIME: type = "Time"; break;
4182 case CONFIG_TYPE_CSV: type = "CommaList"; break;
4183 case CONFIG_TYPE_LINELIST: type = "LineList"; break;
4184 case CONFIG_TYPE_LINELIST_S: type = "Dependant"; break;
4185 case CONFIG_TYPE_LINELIST_V: type = "Virtual"; break;
4186 default:
4187 case CONFIG_TYPE_OBSOLETE:
4188 type = NULL; break;
4190 if (!type)
4191 continue;
4192 len = strlen(var->name)+strlen(type)+16;
4193 if (desc)
4194 len += strlen(desc);
4195 line = tor_malloc(len);
4196 if (desc)
4197 tor_snprintf(line, len, "%s %s %s\n",var->name,type,desc);
4198 else
4199 tor_snprintf(line, len, "%s %s\n",var->name,type);
4200 smartlist_add(sl, line);
4202 *answer = smartlist_join_strings(sl, "", 0, NULL);
4203 SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
4204 smartlist_free(sl);
4206 return 0;
4209 #include "../common/ht.h"
4210 #include "../common/test.h"
4212 extern const char aes_c_id[];
4213 extern const char compat_c_id[];
4214 extern const char container_c_id[];
4215 extern const char crypto_c_id[];
4216 extern const char log_c_id[];
4217 extern const char torgzip_c_id[];
4218 extern const char tortls_c_id[];
4219 extern const char util_c_id[];
4221 extern const char buffers_c_id[];
4222 extern const char circuitbuild_c_id[];
4223 extern const char circuitlist_c_id[];
4224 extern const char circuituse_c_id[];
4225 extern const char command_c_id[];
4226 // extern const char config_c_id[];
4227 extern const char connection_c_id[];
4228 extern const char connection_edge_c_id[];
4229 extern const char connection_or_c_id[];
4230 extern const char control_c_id[];
4231 extern const char cpuworker_c_id[];
4232 extern const char directory_c_id[];
4233 extern const char dirserv_c_id[];
4234 extern const char dns_c_id[];
4235 extern const char hibernate_c_id[];
4236 extern const char main_c_id[];
4237 extern const char onion_c_id[];
4238 extern const char policies_c_id[];
4239 extern const char relay_c_id[];
4240 extern const char rendclient_c_id[];
4241 extern const char rendcommon_c_id[];
4242 extern const char rendmid_c_id[];
4243 extern const char rendservice_c_id[];
4244 extern const char rephist_c_id[];
4245 extern const char router_c_id[];
4246 extern const char routerlist_c_id[];
4247 extern const char routerparse_c_id[];
4249 /** Dump the version of every file to the log. */
4250 static void
4251 print_svn_version(void)
4253 puts(AES_H_ID);
4254 puts(COMPAT_H_ID);
4255 puts(CONTAINER_H_ID);
4256 puts(CRYPTO_H_ID);
4257 puts(HT_H_ID);
4258 puts(TEST_H_ID);
4259 puts(LOG_H_ID);
4260 puts(TORGZIP_H_ID);
4261 puts(TORINT_H_ID);
4262 puts(TORTLS_H_ID);
4263 puts(UTIL_H_ID);
4264 puts(aes_c_id);
4265 puts(compat_c_id);
4266 puts(container_c_id);
4267 puts(crypto_c_id);
4268 puts(log_c_id);
4269 puts(torgzip_c_id);
4270 puts(tortls_c_id);
4271 puts(util_c_id);
4273 puts(OR_H_ID);
4274 puts(buffers_c_id);
4275 puts(circuitbuild_c_id);
4276 puts(circuitlist_c_id);
4277 puts(circuituse_c_id);
4278 puts(command_c_id);
4279 puts(config_c_id);
4280 puts(connection_c_id);
4281 puts(connection_edge_c_id);
4282 puts(connection_or_c_id);
4283 puts(control_c_id);
4284 puts(cpuworker_c_id);
4285 puts(directory_c_id);
4286 puts(dirserv_c_id);
4287 puts(dns_c_id);
4288 puts(hibernate_c_id);
4289 puts(main_c_id);
4290 puts(onion_c_id);
4291 puts(policies_c_id);
4292 puts(relay_c_id);
4293 puts(rendclient_c_id);
4294 puts(rendcommon_c_id);
4295 puts(rendmid_c_id);
4296 puts(rendservice_c_id);
4297 puts(rephist_c_id);
4298 puts(router_c_id);
4299 puts(routerlist_c_id);
4300 puts(routerparse_c_id);