r13715@catbus: nickm | 2007-07-12 12:11:09 -0400
[tor.git] / src / or / config.c
blob13c7a56f6feaf4fdc56fad4f493cae8166de6a6b
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, LE_13A, LE_13B,
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 128.31.0.34:9031 "
737 "FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441",
738 "moria2 v1 orport=9002 128.31.0.34:9032 "
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 (10*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 > ROUTER_MAX_DECLARED_BANDWIDTH) {
2639 r = tor_snprintf(buf, sizeof(buf),
2640 "BandwidthRate must be at most %d",
2641 ROUTER_MAX_DECLARED_BANDWIDTH);
2642 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2643 return -1;
2645 if (options->BandwidthBurst > ROUTER_MAX_DECLARED_BANDWIDTH) {
2646 r = tor_snprintf(buf, sizeof(buf),
2647 "BandwidthBurst must be at most %d",
2648 ROUTER_MAX_DECLARED_BANDWIDTH);
2649 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2650 return -1;
2652 if (server_mode(options)) {
2653 if (options->BandwidthRate < ROUTER_REQUIRED_MIN_BANDWIDTH*2) {
2654 r = tor_snprintf(buf, sizeof(buf),
2655 "BandwidthRate is set to %d bytes/second. "
2656 "For servers, it must be at least %d.",
2657 (int)options->BandwidthRate,
2658 ROUTER_REQUIRED_MIN_BANDWIDTH*2);
2659 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2660 return -1;
2661 } else if (options->MaxAdvertisedBandwidth <
2662 ROUTER_REQUIRED_MIN_BANDWIDTH) {
2663 r = tor_snprintf(buf, sizeof(buf),
2664 "MaxAdvertisedBandwidth is set to %d bytes/second. "
2665 "For servers, it must be at least %d.",
2666 (int)options->MaxAdvertisedBandwidth,
2667 ROUTER_REQUIRED_MIN_BANDWIDTH);
2668 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2669 return -1;
2673 if (options->BandwidthRate > options->BandwidthBurst)
2674 REJECT("BandwidthBurst must be at least equal to BandwidthRate.");
2676 if (accounting_parse_options(options, 1)<0)
2677 REJECT("Failed to parse accounting options. See logs for details.");
2679 if (options->HttpProxy) { /* parse it now */
2680 if (parse_addr_port(LOG_WARN, options->HttpProxy, NULL,
2681 &options->HttpProxyAddr, &options->HttpProxyPort) < 0)
2682 REJECT("HttpProxy failed to parse or resolve. Please fix.");
2683 if (options->HttpProxyPort == 0) { /* give it a default */
2684 options->HttpProxyPort = 80;
2688 if (options->HttpProxyAuthenticator) {
2689 if (strlen(options->HttpProxyAuthenticator) >= 48)
2690 REJECT("HttpProxyAuthenticator is too long (>= 48 chars).");
2693 if (options->HttpsProxy) { /* parse it now */
2694 if (parse_addr_port(LOG_WARN, options->HttpsProxy, NULL,
2695 &options->HttpsProxyAddr, &options->HttpsProxyPort) <0)
2696 REJECT("HttpsProxy failed to parse or resolve. Please fix.");
2697 if (options->HttpsProxyPort == 0) { /* give it a default */
2698 options->HttpsProxyPort = 443;
2702 if (options->HttpsProxyAuthenticator) {
2703 if (strlen(options->HttpsProxyAuthenticator) >= 48)
2704 REJECT("HttpsProxyAuthenticator is too long (>= 48 chars).");
2707 if (options->HashedControlPassword) {
2708 if (decode_hashed_password(NULL, options->HashedControlPassword)<0)
2709 REJECT("Bad HashedControlPassword: wrong length or bad encoding");
2711 if (options->HashedControlPassword && options->CookieAuthentication)
2712 REJECT("Cannot set both HashedControlPassword and CookieAuthentication");
2714 if (options->UseEntryGuards && ! options->NumEntryGuards)
2715 REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0");
2717 #ifndef USE_EVENTDNS
2718 if (options->ServerDNSResolvConfFile)
2719 log(LOG_WARN, LD_CONFIG,
2720 "ServerDNSResolvConfFile only works when eventdns support is enabled.");
2721 #endif
2723 if (check_nickname_list(options->ExitNodes, "ExitNodes", msg))
2724 return -1;
2725 if (check_nickname_list(options->EntryNodes, "EntryNodes", msg))
2726 return -1;
2727 if (check_nickname_list(options->ExcludeNodes, "ExcludeNodes", msg))
2728 return -1;
2729 if (check_nickname_list(options->RendNodes, "RendNodes", msg))
2730 return -1;
2731 if (check_nickname_list(options->RendNodes, "RendExcludeNodes", msg))
2732 return -1;
2733 if (check_nickname_list(options->TestVia, "TestVia", msg))
2734 return -1;
2735 if (check_nickname_list(options->MyFamily, "MyFamily", msg))
2736 return -1;
2738 if (options->NodeFamilies)
2739 COMPLAIN("NodeFamily config option is broken in this version of Tor.");
2740 for (cl = options->NodeFamilies; cl; cl = cl->next) {
2741 if (check_nickname_list(cl->value, "NodeFamily", msg))
2742 return -1;
2745 if (validate_addr_policies(options, msg) < 0)
2746 return -1;
2748 for (cl = options->RedirectExit; cl; cl = cl->next) {
2749 if (parse_redirect_line(NULL, cl, msg)<0)
2750 return -1;
2753 if (options->DirServers) {
2754 if (!old_options ||
2755 !config_lines_eq(options->DirServers, old_options->DirServers))
2756 COMPLAIN("You have used DirServer to specify directory authorities in "
2757 "your configuration. This is potentially dangerous: it can "
2758 "make you look different from all other Tor users, and hurt "
2759 "your anonymity. Even if you've specified the same "
2760 "authorities as Tor uses by default, the defaults could "
2761 "change in the future. Be sure you know what you're doing.");
2762 for (cl = options->DirServers; cl; cl = cl->next) {
2763 if (parse_dir_server_line(cl->value, 1)<0)
2764 REJECT("DirServer line did not parse. See logs for details.");
2768 if (rend_config_services(options, 1) < 0)
2769 REJECT("Failed to configure rendezvous options. See logs for details.");
2771 if (parse_virtual_addr_network(options->VirtualAddrNetwork, 1, NULL)<0)
2772 return -1;
2774 if (options->PreferTunneledDirConns && !options->TunnelDirConns)
2775 REJECT("Must set TunnelDirConns if PreferTunneledDirConns is set.");
2777 return 0;
2778 #undef REJECT
2779 #undef COMPLAIN
2782 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
2783 * equal strings. */
2784 static int
2785 opt_streq(const char *s1, const char *s2)
2787 if (!s1 && !s2)
2788 return 1;
2789 else if (s1 && s2 && !strcmp(s1,s2))
2790 return 1;
2791 else
2792 return 0;
2795 /** Check if any of the previous options have changed but aren't allowed to. */
2796 static int
2797 options_transition_allowed(or_options_t *old, or_options_t *new_val,
2798 char **msg)
2800 if (!old)
2801 return 0;
2803 if (!opt_streq(old->PidFile, new_val->PidFile)) {
2804 *msg = tor_strdup("PidFile is not allowed to change.");
2805 return -1;
2808 if (old->RunAsDaemon != new_val->RunAsDaemon) {
2809 *msg = tor_strdup("While Tor is running, changing RunAsDaemon "
2810 "is not allowed.");
2811 return -1;
2814 if (strcmp(old->DataDirectory,new_val->DataDirectory)!=0) {
2815 char buf[1024];
2816 int r = tor_snprintf(buf, sizeof(buf),
2817 "While Tor is running, changing DataDirectory "
2818 "(\"%s\"->\"%s\") is not allowed.",
2819 old->DataDirectory, new_val->DataDirectory);
2820 *msg = tor_strdup(r >= 0 ? buf : "internal error");
2821 return -1;
2824 if (!opt_streq(old->User, new_val->User)) {
2825 *msg = tor_strdup("While Tor is running, changing User is not allowed.");
2826 return -1;
2829 if (!opt_streq(old->Group, new_val->Group)) {
2830 *msg = tor_strdup("While Tor is running, changing Group is not allowed.");
2831 return -1;
2834 if (old->HardwareAccel != new_val->HardwareAccel) {
2835 *msg = tor_strdup("While Tor is running, changing HardwareAccel is "
2836 "not allowed.");
2837 return -1;
2840 return 0;
2843 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
2844 * will require us to rotate the cpu and dns workers; else return 0. */
2845 static int
2846 options_transition_affects_workers(or_options_t *old_options,
2847 or_options_t *new_options)
2849 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
2850 old_options->NumCpus != new_options->NumCpus ||
2851 old_options->ORPort != new_options->ORPort ||
2852 old_options->ServerDNSSearchDomains !=
2853 new_options->ServerDNSSearchDomains ||
2854 old_options->SafeLogging != new_options->SafeLogging ||
2855 old_options->ClientOnly != new_options->ClientOnly ||
2856 !config_lines_eq(old_options->Logs, new_options->Logs))
2857 return 1;
2859 /* Check whether log options match. */
2861 /* Nothing that changed matters. */
2862 return 0;
2865 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
2866 * will require us to generate a new descriptor; else return 0. */
2867 static int
2868 options_transition_affects_descriptor(or_options_t *old_options,
2869 or_options_t *new_options)
2871 if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
2872 !opt_streq(old_options->Nickname,new_options->Nickname) ||
2873 !opt_streq(old_options->Address,new_options->Address) ||
2874 !config_lines_eq(old_options->ExitPolicy,new_options->ExitPolicy) ||
2875 old_options->ORPort != new_options->ORPort ||
2876 old_options->DirPort != new_options->DirPort ||
2877 old_options->ClientOnly != new_options->ClientOnly ||
2878 old_options->NoPublish != new_options->NoPublish ||
2879 old_options->PublishServerDescriptor !=
2880 new_options->PublishServerDescriptor ||
2881 old_options->BandwidthRate != new_options->BandwidthRate ||
2882 old_options->BandwidthBurst != new_options->BandwidthBurst ||
2883 !opt_streq(old_options->ContactInfo, new_options->ContactInfo) ||
2884 !opt_streq(old_options->MyFamily, new_options->MyFamily) ||
2885 !opt_streq(old_options->AccountingStart, new_options->AccountingStart) ||
2886 old_options->AccountingMax != new_options->AccountingMax)
2887 return 1;
2889 return 0;
2892 #ifdef MS_WINDOWS
2893 /** Return the directory on windows where we expect to find our application
2894 * data. */
2895 static char *
2896 get_windows_conf_root(void)
2898 static int is_set = 0;
2899 static char path[MAX_PATH+1];
2901 LPITEMIDLIST idl;
2902 IMalloc *m;
2903 HRESULT result;
2905 if (is_set)
2906 return path;
2908 /* Find X:\documents and settings\username\application data\ .
2909 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
2911 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA,
2912 &idl))) {
2913 GetCurrentDirectory(MAX_PATH, path);
2914 is_set = 1;
2915 log_warn(LD_CONFIG,
2916 "I couldn't find your application data folder: are you "
2917 "running an ancient version of Windows 95? Defaulting to \"%s\"",
2918 path);
2919 return path;
2921 /* Convert the path from an "ID List" (whatever that is!) to a path. */
2922 result = SHGetPathFromIDList(idl, path);
2923 /* Now we need to free the */
2924 SHGetMalloc(&m);
2925 if (m) {
2926 m->lpVtbl->Free(m, idl);
2927 m->lpVtbl->Release(m);
2929 if (!SUCCEEDED(result)) {
2930 return NULL;
2932 strlcat(path,"\\tor",MAX_PATH);
2933 is_set = 1;
2934 return path;
2936 #endif
2938 /** Return the default location for our torrc file. */
2939 static const char *
2940 get_default_conf_file(void)
2942 #ifdef MS_WINDOWS
2943 static char path[MAX_PATH+1];
2944 strlcpy(path, get_windows_conf_root(), MAX_PATH);
2945 strlcat(path,"\\torrc",MAX_PATH);
2946 return path;
2947 #else
2948 return (CONFDIR "/torrc");
2949 #endif
2952 /** Verify whether lst is a string containing valid-looking space-separated
2953 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
2955 static int
2956 check_nickname_list(const char *lst, const char *name, char **msg)
2958 int r = 0;
2959 smartlist_t *sl;
2961 if (!lst)
2962 return 0;
2963 sl = smartlist_create();
2964 smartlist_split_string(sl, lst, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2965 SMARTLIST_FOREACH(sl, const char *, s,
2967 if (!is_legal_nickname_or_hexdigest(s)) {
2968 char buf[1024];
2969 int tmp = tor_snprintf(buf, sizeof(buf),
2970 "Invalid nickname '%s' in %s line", s, name);
2971 *msg = tor_strdup(tmp >= 0 ? buf : "internal error");
2972 r = -1;
2973 break;
2976 SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
2977 smartlist_free(sl);
2978 return r;
2981 /** Read a configuration file into <b>options</b>, finding the configuration
2982 * file location based on the command line. After loading the options,
2983 * validate them for consistency, then take actions based on them.
2984 * Return 0 if success, -1 if failure. */
2986 options_init_from_torrc(int argc, char **argv)
2988 or_options_t *oldoptions, *newoptions;
2989 config_line_t *cl;
2990 char *cf=NULL, *fname=NULL, *errmsg=NULL;
2991 int i, retval;
2992 int using_default_torrc;
2993 int ignore_missing_torrc;
2994 static char **backup_argv;
2995 static int backup_argc;
2997 if (argv) { /* first time we're called. save commandline args */
2998 backup_argv = argv;
2999 backup_argc = argc;
3000 oldoptions = NULL;
3001 } else { /* we're reloading. need to clean up old options first. */
3002 argv = backup_argv;
3003 argc = backup_argc;
3004 oldoptions = get_options();
3006 if (argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1],"--help"))) {
3007 print_usage();
3008 exit(0);
3010 if (argc > 1 && !strcmp(argv[1], "--list-torrc-options")) {
3011 /* For documenting validating whether we've documented everything. */
3012 list_torrc_options();
3013 exit(0);
3016 if (argc > 1 && (!strcmp(argv[1],"--version"))) {
3017 printf("Tor version %s.\n",VERSION);
3018 if (argc > 2 && (!strcmp(argv[2],"--version"))) {
3019 print_svn_version();
3021 exit(0);
3024 newoptions = tor_malloc_zero(sizeof(or_options_t));
3025 newoptions->_magic = OR_OPTIONS_MAGIC;
3026 options_init(newoptions);
3028 /* learn config file name */
3029 fname = NULL;
3030 using_default_torrc = 1;
3031 ignore_missing_torrc = 0;
3032 newoptions->command = CMD_RUN_TOR;
3033 for (i = 1; i < argc; ++i) {
3034 if (i < argc-1 && !strcmp(argv[i],"-f")) {
3035 if (fname) {
3036 log(LOG_WARN, LD_CONFIG, "Duplicate -f options on command line.");
3037 tor_free(fname);
3039 fname = tor_strdup(argv[i+1]);
3040 using_default_torrc = 0;
3041 ++i;
3042 } else if (!strcmp(argv[i],"--ignore-missing-torrc")) {
3043 ignore_missing_torrc = 1;
3044 } else if (!strcmp(argv[i],"--list-fingerprint")) {
3045 newoptions->command = CMD_LIST_FINGERPRINT;
3046 } else if (!strcmp(argv[i],"--hash-password")) {
3047 newoptions->command = CMD_HASH_PASSWORD;
3048 newoptions->command_arg = tor_strdup( (i < argc-1) ? argv[i+1] : "");
3049 ++i;
3050 } else if (!strcmp(argv[i],"--verify-config")) {
3051 newoptions->command = CMD_VERIFY_CONFIG;
3054 if (using_default_torrc) {
3055 /* didn't find one, try CONFDIR */
3056 const char *dflt = get_default_conf_file();
3057 if (dflt && file_status(dflt) == FN_FILE) {
3058 fname = tor_strdup(dflt);
3059 } else {
3060 #ifndef MS_WINDOWS
3061 char *fn;
3062 fn = expand_filename("~/.torrc");
3063 if (fn && file_status(fn) == FN_FILE) {
3064 fname = fn;
3065 } else {
3066 tor_free(fn);
3067 fname = tor_strdup(dflt);
3069 #else
3070 fname = tor_strdup(dflt);
3071 #endif
3074 tor_assert(fname);
3075 log(LOG_DEBUG, LD_CONFIG, "Opening config file \"%s\"", fname);
3077 tor_free(torrc_fname);
3078 torrc_fname = fname;
3080 /* get config lines, assign them */
3081 if (file_status(fname) != FN_FILE ||
3082 !(cf = read_file_to_str(fname,0,NULL))) {
3083 if (using_default_torrc == 1 || ignore_missing_torrc ) {
3084 log(LOG_NOTICE, LD_CONFIG, "Configuration file \"%s\" not present, "
3085 "using reasonable defaults.", fname);
3086 tor_free(fname); /* sets fname to NULL */
3087 torrc_fname = NULL;
3088 } else {
3089 log(LOG_WARN, LD_CONFIG,
3090 "Unable to open configuration file \"%s\".", fname);
3091 goto err;
3093 } else { /* it opened successfully. use it. */
3094 retval = config_get_lines(cf, &cl);
3095 tor_free(cf);
3096 if (retval < 0)
3097 goto err;
3098 retval = config_assign(&options_format, newoptions, cl, 0, 0, &errmsg);
3099 config_free_lines(cl);
3100 if (retval < 0)
3101 goto err;
3104 /* Go through command-line variables too */
3105 if (config_get_commandlines(argc, argv, &cl) < 0)
3106 goto err;
3107 retval = config_assign(&options_format, newoptions, cl, 0, 0, &errmsg);
3108 config_free_lines(cl);
3109 if (retval < 0)
3110 goto err;
3112 /* Validate newoptions */
3113 if (options_validate(oldoptions, newoptions, 0, &errmsg) < 0)
3114 goto err;
3116 if (options_transition_allowed(oldoptions, newoptions, &errmsg) < 0)
3117 goto err;
3119 if (set_options(newoptions, &errmsg))
3120 goto err; /* frees and replaces old options */
3122 return 0;
3123 err:
3124 tor_free(fname);
3125 torrc_fname = NULL;
3126 config_free(&options_format, newoptions);
3127 if (errmsg) {
3128 log(LOG_WARN,LD_CONFIG,"Failed to parse/validate config: %s", errmsg);
3129 tor_free(errmsg);
3131 return -1;
3134 /** Return the location for our configuration file.
3136 const char *
3137 get_torrc_fname(void)
3139 if (torrc_fname)
3140 return torrc_fname;
3141 else
3142 return get_default_conf_file();
3145 /** Adjust the address map mased on the MapAddress elements in the
3146 * configuration <b>options</b>
3148 static void
3149 config_register_addressmaps(or_options_t *options)
3151 smartlist_t *elts;
3152 config_line_t *opt;
3153 char *from, *to;
3155 addressmap_clear_configured();
3156 elts = smartlist_create();
3157 for (opt = options->AddressMap; opt; opt = opt->next) {
3158 smartlist_split_string(elts, opt->value, NULL,
3159 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
3160 if (smartlist_len(elts) >= 2) {
3161 from = smartlist_get(elts,0);
3162 to = smartlist_get(elts,1);
3163 if (address_is_invalid_destination(to, 1)) {
3164 log_warn(LD_CONFIG,
3165 "Skipping invalid argument '%s' to MapAddress", to);
3166 } else {
3167 addressmap_register(from, tor_strdup(to), 0);
3168 if (smartlist_len(elts)>2) {
3169 log_warn(LD_CONFIG,"Ignoring extra arguments to MapAddress.");
3172 } else {
3173 log_warn(LD_CONFIG,"MapAddress '%s' has too few arguments. Ignoring.",
3174 opt->value);
3176 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
3177 smartlist_clear(elts);
3179 smartlist_free(elts);
3182 /** If <b>range</b> is of the form MIN-MAX, for MIN and MAX both
3183 * recognized log severity levels, set *<b>min_out</b> to MIN and
3184 * *<b>max_out</b> to MAX and return 0. Else, if <b>range</b> is of
3185 * the form MIN, act as if MIN-err had been specified. Else, warn and
3186 * return -1.
3188 static int
3189 parse_log_severity_range(const char *range, int *min_out, int *max_out)
3191 int levelMin, levelMax;
3192 const char *cp;
3193 cp = strchr(range, '-');
3194 if (cp) {
3195 if (cp == range) {
3196 levelMin = LOG_DEBUG;
3197 } else {
3198 char *tmp_sev = tor_strndup(range, cp - range);
3199 levelMin = parse_log_level(tmp_sev);
3200 if (levelMin < 0) {
3201 log_warn(LD_CONFIG, "Unrecognized minimum log severity '%s': must be "
3202 "one of err|warn|notice|info|debug", tmp_sev);
3203 tor_free(tmp_sev);
3204 return -1;
3206 tor_free(tmp_sev);
3208 if (!*(cp+1)) {
3209 levelMax = LOG_ERR;
3210 } else {
3211 levelMax = parse_log_level(cp+1);
3212 if (levelMax < 0) {
3213 log_warn(LD_CONFIG, "Unrecognized maximum log severity '%s': must be "
3214 "one of err|warn|notice|info|debug", cp+1);
3215 return -1;
3218 } else {
3219 levelMin = parse_log_level(range);
3220 if (levelMin < 0) {
3221 log_warn(LD_CONFIG, "Unrecognized log severity '%s': must be one of "
3222 "err|warn|notice|info|debug", range);
3223 return -1;
3225 levelMax = LOG_ERR;
3228 *min_out = levelMin;
3229 *max_out = levelMax;
3231 return 0;
3235 * Initialize the logs based on the configuration file.
3238 options_init_logs(or_options_t *options, int validate_only)
3240 config_line_t *opt;
3241 int ok;
3242 smartlist_t *elts;
3243 int daemon =
3244 #ifdef MS_WINDOWS
3246 #else
3247 options->RunAsDaemon;
3248 #endif
3250 ok = 1;
3251 elts = smartlist_create();
3253 for (opt = options->Logs; opt; opt = opt->next) {
3254 int levelMin=LOG_DEBUG, levelMax=LOG_ERR;
3255 smartlist_split_string(elts, opt->value, NULL,
3256 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
3257 if (smartlist_len(elts) == 0) {
3258 log_warn(LD_CONFIG, "No arguments to Log option 'Log %s'", opt->value);
3259 ok = 0; goto cleanup;
3261 if (parse_log_severity_range(smartlist_get(elts,0), &levelMin,
3262 &levelMax)) {
3263 ok = 0; goto cleanup;
3265 if (smartlist_len(elts) < 2) { /* only loglevels were provided */
3266 if (!validate_only) {
3267 if (daemon) {
3268 log_warn(LD_CONFIG,
3269 "Can't log to stdout with RunAsDaemon set; skipping stdout");
3270 } else {
3271 add_stream_log(levelMin, levelMax, "<stdout>", stdout);
3274 goto cleanup;
3276 if (!strcasecmp(smartlist_get(elts,1), "file")) {
3277 if (smartlist_len(elts) != 3) {
3278 log_warn(LD_CONFIG, "Bad syntax on file Log option 'Log %s'",
3279 opt->value);
3280 ok = 0; goto cleanup;
3282 if (!validate_only) {
3283 if (add_file_log(levelMin, levelMax, smartlist_get(elts, 2)) < 0) {
3284 log_warn(LD_CONFIG, "Couldn't open file for 'Log %s'", opt->value);
3285 ok = 0;
3288 goto cleanup;
3290 if (smartlist_len(elts) != 2) {
3291 log_warn(LD_CONFIG, "Wrong number of arguments on Log option 'Log %s'",
3292 opt->value);
3293 ok = 0; goto cleanup;
3295 if (!strcasecmp(smartlist_get(elts,1), "stdout")) {
3296 if (daemon) {
3297 log_warn(LD_CONFIG, "Can't log to stdout with RunAsDaemon set.");
3298 ok = 0; goto cleanup;
3300 if (!validate_only) {
3301 add_stream_log(levelMin, levelMax, "<stdout>", stdout);
3303 } else if (!strcasecmp(smartlist_get(elts,1), "stderr")) {
3304 if (daemon) {
3305 log_warn(LD_CONFIG, "Can't log to stderr with RunAsDaemon set.");
3306 ok = 0; goto cleanup;
3308 if (!validate_only) {
3309 add_stream_log(levelMin, levelMax, "<stderr>", stderr);
3311 } else if (!strcasecmp(smartlist_get(elts,1), "syslog")) {
3312 #ifdef HAVE_SYSLOG_H
3313 if (!validate_only)
3314 add_syslog_log(levelMin, levelMax);
3315 #else
3316 log_warn(LD_CONFIG, "Syslog is not supported on this system. Sorry.");
3317 #endif
3318 } else {
3319 log_warn(LD_CONFIG, "Unrecognized log type %s",
3320 (const char*)smartlist_get(elts,1));
3321 if (strchr(smartlist_get(elts,1), '/') ||
3322 strchr(smartlist_get(elts,1), '\\')) {
3323 log_warn(LD_CONFIG, "Did you mean to say 'Log %s file %s' ?",
3324 (const char *)smartlist_get(elts,0),
3325 (const char *)smartlist_get(elts,1));
3327 ok = 0; goto cleanup;
3329 cleanup:
3330 SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
3331 smartlist_clear(elts);
3333 smartlist_free(elts);
3335 return ok?0:-1;
3338 /** Parse a single RedirectExit line's contents from <b>line</b>. If
3339 * they are valid, and <b>result</b> is not NULL, add an element to
3340 * <b>result</b> and return 0. Else if they are valid, return 0.
3341 * Else set *msg and return -1. */
3342 static int
3343 parse_redirect_line(smartlist_t *result, config_line_t *line, char **msg)
3345 smartlist_t *elements = NULL;
3346 exit_redirect_t *r;
3348 tor_assert(line);
3350 r = tor_malloc_zero(sizeof(exit_redirect_t));
3351 elements = smartlist_create();
3352 smartlist_split_string(elements, line->value, NULL,
3353 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
3354 if (smartlist_len(elements) != 2) {
3355 *msg = tor_strdup("Wrong number of elements in RedirectExit line");
3356 goto err;
3358 if (parse_addr_and_port_range(smartlist_get(elements,0),&r->addr,&r->mask,
3359 &r->port_min,&r->port_max)) {
3360 *msg = tor_strdup("Error parsing source address in RedirectExit line");
3361 goto err;
3363 if (0==strcasecmp(smartlist_get(elements,1), "pass")) {
3364 r->is_redirect = 0;
3365 } else {
3366 if (parse_addr_port(LOG_WARN, smartlist_get(elements,1),NULL,
3367 &r->addr_dest, &r->port_dest)) {
3368 *msg = tor_strdup("Error parsing dest address in RedirectExit line");
3369 goto err;
3371 r->is_redirect = 1;
3374 goto done;
3375 err:
3376 tor_free(r);
3377 done:
3378 SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
3379 smartlist_free(elements);
3380 if (r) {
3381 if (result)
3382 smartlist_add(result, r);
3383 else
3384 tor_free(r);
3385 return 0;
3386 } else {
3387 tor_assert(*msg);
3388 return -1;
3392 /** Read the contents of a DirServer line from <b>line</b>. Return 0
3393 * if the line is well-formed, and -1 if it isn't. If
3394 * <b>validate_only</b> is 0, and the line is well-formed, then add
3395 * the dirserver described in the line as a valid server. */
3396 static int
3397 parse_dir_server_line(const char *line, int validate_only)
3399 smartlist_t *items = NULL;
3400 int r;
3401 char *addrport=NULL, *address=NULL, *nickname=NULL, *fingerprint=NULL;
3402 uint16_t dir_port = 0, or_port = 0;
3403 char digest[DIGEST_LEN];
3404 int is_v1_authority = 0, is_hidserv_authority = 0,
3405 is_not_hidserv_authority = 0, is_v2_authority = 1;
3407 items = smartlist_create();
3408 smartlist_split_string(items, line, NULL,
3409 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
3410 if (smartlist_len(items) < 1) {
3411 log_warn(LD_CONFIG, "No arguments on DirServer line.");
3412 goto err;
3415 if (is_legal_nickname(smartlist_get(items, 0))) {
3416 nickname = smartlist_get(items, 0);
3417 smartlist_del_keeporder(items, 0);
3420 while (smartlist_len(items)) {
3421 char *flag = smartlist_get(items, 0);
3422 if (TOR_ISDIGIT(flag[0]))
3423 break;
3424 if (!strcasecmp(flag, "v1")) {
3425 is_v1_authority = is_hidserv_authority = 1;
3426 } else if (!strcasecmp(flag, "hs")) {
3427 is_hidserv_authority = 1;
3428 } else if (!strcasecmp(flag, "no-hs")) {
3429 is_not_hidserv_authority = 1;
3430 } else if (!strcasecmp(flag, "no-v2")) {
3431 is_v2_authority = 0;
3432 } else if (!strcasecmpstart(flag, "orport=")) {
3433 int ok;
3434 char *portstring = flag + strlen("orport=");
3435 or_port = (uint16_t) tor_parse_long(portstring, 10, 1, 65535, &ok, NULL);
3436 if (!ok)
3437 log_warn(LD_CONFIG, "Invalid orport '%s' on DirServer line.",
3438 portstring);
3439 } else {
3440 log_warn(LD_CONFIG, "Unrecognized flag '%s' on DirServer line",
3441 flag);
3443 tor_free(flag);
3444 smartlist_del_keeporder(items, 0);
3447 if (is_not_hidserv_authority)
3448 is_hidserv_authority = 0;
3450 if (smartlist_len(items) < 2) {
3451 log_warn(LD_CONFIG, "Too few arguments to DirServer line.");
3452 goto err;
3454 addrport = smartlist_get(items, 0);
3455 smartlist_del_keeporder(items, 0);
3456 if (parse_addr_port(LOG_WARN, addrport, &address, NULL, &dir_port)<0) {
3457 log_warn(LD_CONFIG, "Error parsing DirServer address '%s'", addrport);
3458 goto err;
3460 if (!dir_port) {
3461 log_warn(LD_CONFIG, "Missing port in DirServer address '%s'",addrport);
3462 goto err;
3465 fingerprint = smartlist_join_strings(items, "", 0, NULL);
3466 if (strlen(fingerprint) != HEX_DIGEST_LEN) {
3467 log_warn(LD_CONFIG, "Key digest for DirServer is wrong length.");
3468 goto err;
3470 if (base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN)<0) {
3471 log_warn(LD_CONFIG, "Unable to decode DirServer key digest.");
3472 goto err;
3475 if (!validate_only) {
3476 log_debug(LD_DIR, "Trusted dirserver at %s:%d (%s)", address,
3477 (int)dir_port,
3478 (char*)smartlist_get(items,1));
3479 add_trusted_dir_server(nickname, address, dir_port, or_port, digest,
3480 is_v1_authority,
3481 is_v2_authority, is_hidserv_authority);
3485 r = 0;
3486 goto done;
3488 err:
3489 r = -1;
3491 done:
3492 SMARTLIST_FOREACH(items, char*, s, tor_free(s));
3493 smartlist_free(items);
3494 tor_free(addrport);
3495 tor_free(address);
3496 tor_free(nickname);
3497 tor_free(fingerprint);
3498 return r;
3501 /** Adjust the value of options->DataDirectory, or fill it in if it's
3502 * absent. Return 0 on success, -1 on failure. */
3503 static int
3504 normalize_data_directory(or_options_t *options)
3506 #ifdef MS_WINDOWS
3507 char *p;
3508 if (options->DataDirectory)
3509 return 0; /* all set */
3510 p = tor_malloc(MAX_PATH);
3511 strlcpy(p,get_windows_conf_root(),MAX_PATH);
3512 options->DataDirectory = p;
3513 return 0;
3514 #else
3515 const char *d = options->DataDirectory;
3516 if (!d)
3517 d = "~/.tor";
3519 if (strncmp(d,"~/",2) == 0) {
3520 char *fn = expand_filename(d);
3521 if (!fn) {
3522 log_err(LD_CONFIG,"Failed to expand filename \"%s\".", d);
3523 return -1;
3525 if (!options->DataDirectory && !strcmp(fn,"/.tor")) {
3526 /* If our homedir is /, we probably don't want to use it. */
3527 /* Default to LOCALSTATEDIR/tor which is probably closer to what we
3528 * want. */
3529 log_warn(LD_CONFIG,
3530 "Default DataDirectory is \"~/.tor\". This expands to "
3531 "\"%s\", which is probably not what you want. Using \"%s/tor\" "
3532 "instead", fn, LOCALSTATEDIR);
3533 tor_free(fn);
3534 fn = tor_strdup(LOCALSTATEDIR"/tor");
3537 tor_free(options->DataDirectory);
3538 options->DataDirectory = fn;
3540 return 0;
3541 #endif
3544 /** Check and normalize the value of options->DataDirectory; return 0 if it
3545 * sane, -1 otherwise. */
3546 static int
3547 validate_data_directory(or_options_t *options)
3549 if (normalize_data_directory(options) < 0)
3550 return -1;
3551 tor_assert(options->DataDirectory);
3552 if (strlen(options->DataDirectory) > (512-128)) {
3553 log_err(LD_CONFIG, "DataDirectory is too long.");
3554 return -1;
3556 return 0;
3559 /** This string must remain the same forevermore. It is how we
3560 * recognize that the torrc file doesn't need to be backed up. */
3561 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; " \
3562 "if you edit it, comments will not be preserved"
3563 /** This string can change; it tries to give the reader an idea
3564 * that editing this file by hand is not a good plan. */
3565 #define GENERATED_FILE_COMMENT "# The old torrc file was renamed " \
3566 "to torrc.orig.1 or similar, and Tor will ignore it"
3568 /** Save a configuration file for the configuration in <b>options</b>
3569 * into the file <b>fname</b>. If the file already exists, and
3570 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
3571 * replace it. Return 0 on success, -1 on failure. */
3572 static int
3573 write_configuration_file(const char *fname, or_options_t *options)
3575 char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
3576 int rename_old = 0, r;
3577 size_t len;
3579 if (fname) {
3580 switch (file_status(fname)) {
3581 case FN_FILE:
3582 old_val = read_file_to_str(fname, 0, NULL);
3583 if (strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
3584 rename_old = 1;
3586 tor_free(old_val);
3587 break;
3588 case FN_NOENT:
3589 break;
3590 case FN_ERROR:
3591 case FN_DIR:
3592 default:
3593 log_warn(LD_CONFIG,
3594 "Config file \"%s\" is not a file? Failing.", fname);
3595 return -1;
3599 if (!(new_conf = options_dump(options, 1))) {
3600 log_warn(LD_BUG, "Couldn't get configuration string");
3601 goto err;
3604 len = strlen(new_conf)+256;
3605 new_val = tor_malloc(len);
3606 tor_snprintf(new_val, len, "%s\n%s\n\n%s",
3607 GENERATED_FILE_PREFIX, GENERATED_FILE_COMMENT, new_conf);
3609 if (rename_old) {
3610 int i = 1;
3611 size_t fn_tmp_len = strlen(fname)+32;
3612 char *fn_tmp;
3613 tor_assert(fn_tmp_len > strlen(fname)); /*check for overflow*/
3614 fn_tmp = tor_malloc(fn_tmp_len);
3615 while (1) {
3616 if (tor_snprintf(fn_tmp, fn_tmp_len, "%s.orig.%d", fname, i)<0) {
3617 log_warn(LD_BUG, "tor_snprintf failed inexplicably");
3618 tor_free(fn_tmp);
3619 goto err;
3621 if (file_status(fn_tmp) == FN_NOENT)
3622 break;
3623 ++i;
3625 log_notice(LD_CONFIG, "Renaming old configuration file to \"%s\"", fn_tmp);
3626 if (rename(fname, fn_tmp) < 0) {
3627 log_warn(LD_FS,
3628 "Couldn't rename configuration file \"%s\" to \"%s\": %s",
3629 fname, fn_tmp, strerror(errno));
3630 tor_free(fn_tmp);
3631 goto err;
3633 tor_free(fn_tmp);
3636 if (write_str_to_file(fname, new_val, 0) < 0)
3637 goto err;
3639 r = 0;
3640 goto done;
3641 err:
3642 r = -1;
3643 done:
3644 tor_free(new_val);
3645 tor_free(new_conf);
3646 return r;
3650 * Save the current configuration file value to disk. Return 0 on
3651 * success, -1 on failure.
3654 options_save_current(void)
3656 if (torrc_fname) {
3657 /* This fails if we can't write to our configuration file.
3659 * If we try falling back to datadirectory or something, we have a better
3660 * chance of saving the configuration, but a better chance of doing
3661 * something the user never expected. Let's just warn instead. */
3662 return write_configuration_file(torrc_fname, get_options());
3664 return write_configuration_file(get_default_conf_file(), get_options());
3667 /** Mapping from a unit name to a multiplier for converting that unit into a
3668 * base unit. */
3669 struct unit_table_t {
3670 const char *unit;
3671 uint64_t multiplier;
3674 static struct unit_table_t memory_units[] = {
3675 { "", 1 },
3676 { "b", 1<< 0 },
3677 { "byte", 1<< 0 },
3678 { "bytes", 1<< 0 },
3679 { "kb", 1<<10 },
3680 { "kilobyte", 1<<10 },
3681 { "kilobytes", 1<<10 },
3682 { "m", 1<<20 },
3683 { "mb", 1<<20 },
3684 { "megabyte", 1<<20 },
3685 { "megabytes", 1<<20 },
3686 { "gb", 1<<30 },
3687 { "gigabyte", 1<<30 },
3688 { "gigabytes", 1<<30 },
3689 { "tb", U64_LITERAL(1)<<40 },
3690 { "terabyte", U64_LITERAL(1)<<40 },
3691 { "terabytes", U64_LITERAL(1)<<40 },
3692 { NULL, 0 },
3695 static struct unit_table_t time_units[] = {
3696 { "", 1 },
3697 { "second", 1 },
3698 { "seconds", 1 },
3699 { "minute", 60 },
3700 { "minutes", 60 },
3701 { "hour", 60*60 },
3702 { "hours", 60*60 },
3703 { "day", 24*60*60 },
3704 { "days", 24*60*60 },
3705 { "week", 7*24*60*60 },
3706 { "weeks", 7*24*60*60 },
3707 { NULL, 0 },
3710 /** Parse a string <b>val</b> containing a number, zero or more
3711 * spaces, and an optional unit string. If the unit appears in the
3712 * table <b>u</b>, then multiply the number by the unit multiplier.
3713 * On success, set *<b>ok</b> to 1 and return this product.
3714 * Otherwise, set *<b>ok</b> to 0.
3716 static uint64_t
3717 config_parse_units(const char *val, struct unit_table_t *u, int *ok)
3719 uint64_t v;
3720 char *cp;
3722 tor_assert(ok);
3724 v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
3725 if (!*ok)
3726 return 0;
3727 if (!cp) {
3728 *ok = 1;
3729 return v;
3731 while (TOR_ISSPACE(*cp))
3732 ++cp;
3733 for ( ;u->unit;++u) {
3734 if (!strcasecmp(u->unit, cp)) {
3735 v *= u->multiplier;
3736 *ok = 1;
3737 return v;
3740 log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
3741 *ok = 0;
3742 return 0;
3745 /** Parse a string in the format "number unit", where unit is a unit of
3746 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
3747 * and return the number of bytes specified. Otherwise, set
3748 * *<b>ok</b> to false and return 0. */
3749 static uint64_t
3750 config_parse_memunit(const char *s, int *ok)
3752 return config_parse_units(s, memory_units, ok);
3755 /** Parse a string in the format "number unit", where unit is a unit of time.
3756 * On success, set *<b>ok</b> to true and return the number of seconds in
3757 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
3759 static int
3760 config_parse_interval(const char *s, int *ok)
3762 uint64_t r;
3763 r = config_parse_units(s, time_units, ok);
3764 if (!ok)
3765 return -1;
3766 if (r > INT_MAX) {
3767 log_warn(LD_CONFIG, "Interval '%s' is too long", s);
3768 *ok = 0;
3769 return -1;
3771 return (int)r;
3775 * Initialize the libevent library.
3777 static void
3778 init_libevent(void)
3780 configure_libevent_logging();
3781 /* If the kernel complains that some method (say, epoll) doesn't
3782 * exist, we don't care about it, since libevent will cope.
3784 suppress_libevent_log_msg("Function not implemented");
3785 #ifdef __APPLE__
3786 if (decode_libevent_version() < LE_11B) {
3787 setenv("EVENT_NOKQUEUE","1",1);
3788 } else if (!getenv("EVENT_NOKQUEUE")) {
3789 const char *ver = NULL;
3790 #ifdef HAVE_EVENT_GET_VERSION
3791 ver = event_get_version();
3792 #endif
3793 /* If we're 1.1b or later, we'd better have get_version() */
3794 tor_assert(ver);
3795 log(LOG_NOTICE, LD_GENERAL, "Enabling experimental OS X kqueue support "
3796 "with libevent %s. If this turns out to not work, "
3797 "set the environment variable EVENT_NOKQUEUE, and tell the Tor "
3798 "developers.", ver);
3800 #endif
3801 event_init();
3802 suppress_libevent_log_msg(NULL);
3803 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
3804 /* Making this a NOTICE for now so we can link bugs to a libevent versions
3805 * or methods better. */
3806 log(LOG_NOTICE, LD_GENERAL,
3807 "Initialized libevent version %s using method %s. Good.",
3808 event_get_version(), event_get_method());
3809 check_libevent_version(event_get_method(), get_options()->ORPort != 0);
3810 #else
3811 log(LOG_NOTICE, LD_GENERAL,
3812 "Initialized old libevent (version 1.0b or earlier).");
3813 log(LOG_WARN, LD_GENERAL,
3814 "You have a *VERY* old version of libevent. It is likely to be buggy; "
3815 "please build Tor with a more recent version.");
3816 #endif
3819 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
3820 /** Table mapping return value of event_get_version() to le_version_t. */
3821 static const struct {
3822 const char *name; le_version_t version;
3823 } le_version_table[] = {
3824 /* earlier versions don't have get_version. */
3825 { "1.0c", LE_10C },
3826 { "1.0d", LE_10D },
3827 { "1.0e", LE_10E },
3828 { "1.1", LE_11 },
3829 { "1.1a", LE_11A },
3830 { "1.1b", LE_11B },
3831 { "1.2", LE_12 },
3832 { "1.2a", LE_12A },
3833 { "1.3", LE_13 },
3834 { "1.3a", LE_13A },
3835 { "1.3b", LE_13B },
3836 { NULL, LE_OTHER }
3839 /** Return the le_version_t for the current version of libevent. If the
3840 * version is very new, return LE_OTHER. If the version is so old that it
3841 * doesn't support event_get_version(), return LE_OLD. */
3842 static le_version_t
3843 decode_libevent_version(void)
3845 const char *v = event_get_version();
3846 int i;
3847 for (i=0; le_version_table[i].name; ++i) {
3848 if (!strcmp(le_version_table[i].name, v)) {
3849 return le_version_table[i].version;
3852 return LE_OTHER;
3856 * Compare the given libevent method and version to a list of versions
3857 * which are known not to work. Warn the user as appropriate.
3859 static void
3860 check_libevent_version(const char *m, int server)
3862 int buggy = 0, iffy = 0, slow = 0, thread_unsafe = 0;
3863 le_version_t version;
3864 const char *v = event_get_version();
3865 const char *badness = NULL;
3866 const char *sad_os = "";
3868 version = decode_libevent_version();
3870 /* XXX Would it be worthwhile disabling the methods that we know
3871 * are buggy, rather than just warning about them and then proceeding
3872 * to use them? If so, we should probably not wrap this whole thing
3873 * in HAVE_EVENT_GET_VERSION and HAVE_EVENT_GET_METHOD. -RD */
3874 /* XXXX The problem is that it's not trivial to get libevent to change it's
3875 * method once it's initialized, and it's not trivial to tell what method it
3876 * will use without initializing it. I guess we could preemptively disable
3877 * buggy libevent modes based on the version _before_ initializing it,
3878 * though, but then there's no good way (afaict) to warn "I would have used
3879 * kqueue, but instead I'm using select." -NM */
3880 if (!strcmp(m, "kqueue")) {
3881 if (version < LE_11B)
3882 buggy = 1;
3883 } else if (!strcmp(m, "epoll")) {
3884 if (version < LE_11)
3885 iffy = 1;
3886 } else if (!strcmp(m, "poll")) {
3887 if (version < LE_10E)
3888 buggy = 1;
3889 else if (version < LE_11)
3890 slow = 1;
3891 } else if (!strcmp(m, "select")) {
3892 if (version < LE_11)
3893 slow = 1;
3894 } else if (!strcmp(m, "win32")) {
3895 if (version < LE_11B)
3896 buggy = 1;
3899 /* Libevent versions before 1.3b do very badly on operating systems with
3900 * user-space threading implementations. */
3901 #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
3902 if (server && version < LE_13B) {
3903 thread_unsafe = 1;
3904 sad_os = "BSD variants";
3906 #elif defined(__APPLE__) || defined(__darwin__)
3907 if (server && version < LE_13B) {
3908 thread_unsafe = 1;
3909 sad_os = "Mac OS X";
3911 #endif
3913 if (thread_unsafe) {
3914 log(LOG_WARN, LD_GENERAL,
3915 "Libevent version %s often crashes when running a Tor server with %s. "
3916 "Please use the latest version of libevent (1.3b or later)",v,sad_os);
3917 badness = "BROKEN";
3918 } else if (buggy) {
3919 log(LOG_WARN, LD_GENERAL,
3920 "There are known bugs in using %s with libevent %s. "
3921 "Please use the latest version of libevent.", m, v);
3922 badness = "BROKEN";
3923 } else if (iffy) {
3924 log(LOG_WARN, LD_GENERAL,
3925 "There are minor bugs in using %s with libevent %s. "
3926 "You may want to use the latest version of libevent.", m, v);
3927 badness = "BUGGY";
3928 } else if (slow && server) {
3929 log(LOG_WARN, LD_GENERAL,
3930 "libevent %s can be very slow with %s. "
3931 "When running a server, please use the latest version of libevent.",
3932 v,m);
3933 badness = "SLOW";
3935 if (badness) {
3936 control_event_general_status(LOG_WARN,
3937 "BAD_LIBEVENT VERSION=%s METHOD=%s BADNESS=%s RECOVERED=NO",
3938 v, m, badness);
3942 #else
3943 static le_version_t
3944 decode_libevent_version(void)
3946 return LE_OLD;
3948 #endif
3950 /** Return the persistent state struct for this Tor. */
3951 or_state_t *
3952 get_or_state(void)
3954 tor_assert(global_state);
3955 return global_state;
3958 /** Return the filename used to write and read the persistent state. */
3959 static char *
3960 get_or_state_fname(void)
3962 char *fname = NULL;
3963 or_options_t *options = get_options();
3964 size_t len = strlen(options->DataDirectory) + 16;
3965 fname = tor_malloc(len);
3966 tor_snprintf(fname, len, "%s/state", options->DataDirectory);
3967 return fname;
3970 /** Return 0 if every setting in <b>state</b> is reasonable, and a
3971 * permissible transition from <b>old_state</b>. Else warn and return -1.
3972 * Should have no side effects, except for normalizing the contents of
3973 * <b>state</b>.
3975 /* XXX from_setconf is here because of bug 238 */
3976 static int
3977 or_state_validate(or_state_t *old_state, or_state_t *state,
3978 int from_setconf, char **msg)
3980 /* We don't use these; only options do. Still, we need to match that
3981 * signature. */
3982 (void) from_setconf;
3983 (void) old_state;
3984 if (entry_guards_parse_state(state, 0, msg)<0) {
3985 return -1;
3987 if (state->TorVersion) {
3988 tor_version_t v;
3989 if (tor_version_parse(state->TorVersion, &v)) {
3990 log_warn(LD_GENERAL, "Can't parse Tor version '%s' from your state "
3991 "file. Proceeding anyway.", state->TorVersion);
3992 } else { /* take action based on v */
3993 if (tor_version_as_new_as(state->TorVersion, "0.1.1.10-alpha") &&
3994 !tor_version_as_new_as(state->TorVersion, "0.1.1.16-rc-cvs")) {
3995 log_notice(LD_CONFIG, "Detected state file from buggy version '%s'. "
3996 "Enabling workaround to choose working entry guards.",
3997 state->TorVersion);
3998 config_free_lines(state->EntryGuards);
3999 state->EntryGuards = NULL;
4003 return 0;
4006 /** Replace the current persistent state with <b>new_state</b> */
4007 static void
4008 or_state_set(or_state_t *new_state)
4010 char *err = NULL;
4011 tor_assert(new_state);
4012 if (global_state)
4013 config_free(&state_format, global_state);
4014 global_state = new_state;
4015 if (entry_guards_parse_state(global_state, 1, &err)<0) {
4016 log_warn(LD_GENERAL,"%s",err);
4017 tor_free(err);
4019 if (rep_hist_load_state(global_state, &err)<0) {
4020 log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
4021 tor_free(err);
4025 /** Reload the persistent state from disk, generating a new state as needed.
4026 * Return 0 on success, less than 0 on failure.
4029 or_state_load(void)
4031 or_state_t *new_state = NULL;
4032 char *contents = NULL, *fname;
4033 char *errmsg = NULL;
4034 int r = -1, badstate = 0;
4036 fname = get_or_state_fname();
4037 switch (file_status(fname)) {
4038 case FN_FILE:
4039 if (!(contents = read_file_to_str(fname, 0, NULL))) {
4040 log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
4041 goto done;
4043 break;
4044 case FN_NOENT:
4045 break;
4046 case FN_ERROR:
4047 case FN_DIR:
4048 default:
4049 log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
4050 goto done;
4052 new_state = tor_malloc_zero(sizeof(or_state_t));
4053 new_state->_magic = OR_STATE_MAGIC;
4054 config_init(&state_format, new_state);
4055 if (contents) {
4056 config_line_t *lines=NULL;
4057 int assign_retval;
4058 if (config_get_lines(contents, &lines)<0)
4059 goto done;
4060 assign_retval = config_assign(&state_format, new_state,
4061 lines, 0, 0, &errmsg);
4062 config_free_lines(lines);
4063 if (assign_retval<0)
4064 badstate = 1;
4065 if (errmsg) {
4066 log_warn(LD_GENERAL, "%s", errmsg);
4067 tor_free(errmsg);
4071 if (!badstate && or_state_validate(NULL, new_state, 1, &errmsg) < 0)
4072 badstate = 1;
4074 if (errmsg) {
4075 log_warn(LD_GENERAL, "%s", errmsg);
4076 tor_free(errmsg);
4079 if (badstate && !contents) {
4080 log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
4081 " This is a bug in Tor.");
4082 goto done;
4083 } else if (badstate && contents) {
4084 int i;
4085 file_status_t status;
4086 size_t len = strlen(fname)+16;
4087 char *fname2 = tor_malloc(len);
4088 for (i = 0; i < 100; ++i) {
4089 tor_snprintf(fname2, len, "%s.%d", fname, i);
4090 status = file_status(fname2);
4091 if (status == FN_NOENT)
4092 break;
4094 if (i == 100) {
4095 log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
4096 "state files to move aside. Discarding the old state file.",
4097 fname);
4098 unlink(fname);
4099 } else {
4100 log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
4101 "to \"%s\". This could be a bug in Tor; please tell "
4102 "the developers.", fname, fname2);
4103 rename(fname, fname2);
4105 tor_free(fname2);
4106 tor_free(contents);
4107 config_free(&state_format, new_state);
4109 new_state = tor_malloc_zero(sizeof(or_state_t));
4110 new_state->_magic = OR_STATE_MAGIC;
4111 config_init(&state_format, new_state);
4112 } else if (contents) {
4113 log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
4114 } else {
4115 log_info(LD_GENERAL, "Initialized state");
4117 or_state_set(new_state);
4118 new_state = NULL;
4119 if (!contents) {
4120 global_state->next_write = 0;
4121 or_state_save(time(NULL));
4123 r = 0;
4125 done:
4126 tor_free(fname);
4127 tor_free(contents);
4128 if (new_state)
4129 config_free(&state_format, new_state);
4131 return r;
4134 /** Write the persistent state to disk. Return 0 for success, <0 on failure. */
4136 or_state_save(time_t now)
4138 char *state, *contents;
4139 char tbuf[ISO_TIME_LEN+1];
4140 size_t len;
4141 char *fname;
4143 tor_assert(global_state);
4145 if (global_state->next_write > now)
4146 return 0;
4148 /* Call everything else that might dirty the state even more, in order
4149 * to avoid redundant writes. */
4150 entry_guards_update_state(global_state);
4151 rep_hist_update_state(global_state);
4152 if (accounting_is_enabled(get_options()))
4153 accounting_run_housekeeping(now);
4155 global_state->LastWritten = time(NULL);
4156 tor_free(global_state->TorVersion);
4157 global_state->TorVersion = tor_strdup("Tor " VERSION);
4158 state = config_dump(&state_format, global_state, 1, 0);
4159 len = strlen(state)+256;
4160 contents = tor_malloc(len);
4161 format_local_iso_time(tbuf, time(NULL));
4162 tor_snprintf(contents, len,
4163 "# Tor state file last generated on %s local time\n"
4164 "# Other times below are in GMT\n"
4165 "# You *do not* need to edit this file.\n\n%s",
4166 tbuf, state);
4167 tor_free(state);
4168 fname = get_or_state_fname();
4169 if (write_str_to_file(fname, contents, 0)<0) {
4170 log_warn(LD_FS, "Unable to write state to file \"%s\"", fname);
4171 tor_free(fname);
4172 tor_free(contents);
4173 return -1;
4175 log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
4176 tor_free(fname);
4177 tor_free(contents);
4179 global_state->next_write = TIME_MAX;
4180 return 0;
4183 /** Helper to implement GETINFO functions about configuration variables (not
4184 * their values). Given a "config/names" question, set *<b>answer</b> to a
4185 * new string describing the supported configuration variables and their
4186 * types. */
4188 getinfo_helper_config(control_connection_t *conn,
4189 const char *question, char **answer)
4191 (void) conn;
4192 if (!strcmp(question, "config/names")) {
4193 smartlist_t *sl = smartlist_create();
4194 int i;
4195 for (i = 0; _option_vars[i].name; ++i) {
4196 config_var_t *var = &_option_vars[i];
4197 const char *type, *desc;
4198 char *line;
4199 size_t len;
4200 desc = config_find_description(&options_format, var->name);
4201 switch (var->type) {
4202 case CONFIG_TYPE_STRING: type = "String"; break;
4203 case CONFIG_TYPE_UINT: type = "Integer"; break;
4204 case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
4205 case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
4206 case CONFIG_TYPE_DOUBLE: type = "Float"; break;
4207 case CONFIG_TYPE_BOOL: type = "Boolean"; break;
4208 case CONFIG_TYPE_ISOTIME: type = "Time"; break;
4209 case CONFIG_TYPE_CSV: type = "CommaList"; break;
4210 case CONFIG_TYPE_LINELIST: type = "LineList"; break;
4211 case CONFIG_TYPE_LINELIST_S: type = "Dependant"; break;
4212 case CONFIG_TYPE_LINELIST_V: type = "Virtual"; break;
4213 default:
4214 case CONFIG_TYPE_OBSOLETE:
4215 type = NULL; break;
4217 if (!type)
4218 continue;
4219 len = strlen(var->name)+strlen(type)+16;
4220 if (desc)
4221 len += strlen(desc);
4222 line = tor_malloc(len);
4223 if (desc)
4224 tor_snprintf(line, len, "%s %s %s\n",var->name,type,desc);
4225 else
4226 tor_snprintf(line, len, "%s %s\n",var->name,type);
4227 smartlist_add(sl, line);
4229 *answer = smartlist_join_strings(sl, "", 0, NULL);
4230 SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
4231 smartlist_free(sl);
4233 return 0;
4236 #include "../common/ht.h"
4237 #include "../common/test.h"
4239 extern const char aes_c_id[];
4240 extern const char compat_c_id[];
4241 extern const char container_c_id[];
4242 extern const char crypto_c_id[];
4243 extern const char log_c_id[];
4244 extern const char torgzip_c_id[];
4245 extern const char tortls_c_id[];
4246 extern const char util_c_id[];
4248 extern const char buffers_c_id[];
4249 extern const char circuitbuild_c_id[];
4250 extern const char circuitlist_c_id[];
4251 extern const char circuituse_c_id[];
4252 extern const char command_c_id[];
4253 // extern const char config_c_id[];
4254 extern const char connection_c_id[];
4255 extern const char connection_edge_c_id[];
4256 extern const char connection_or_c_id[];
4257 extern const char control_c_id[];
4258 extern const char cpuworker_c_id[];
4259 extern const char directory_c_id[];
4260 extern const char dirserv_c_id[];
4261 extern const char dns_c_id[];
4262 extern const char hibernate_c_id[];
4263 extern const char main_c_id[];
4264 extern const char onion_c_id[];
4265 extern const char policies_c_id[];
4266 extern const char relay_c_id[];
4267 extern const char rendclient_c_id[];
4268 extern const char rendcommon_c_id[];
4269 extern const char rendmid_c_id[];
4270 extern const char rendservice_c_id[];
4271 extern const char rephist_c_id[];
4272 extern const char router_c_id[];
4273 extern const char routerlist_c_id[];
4274 extern const char routerparse_c_id[];
4276 /** Dump the version of every file to the log. */
4277 static void
4278 print_svn_version(void)
4280 puts(AES_H_ID);
4281 puts(COMPAT_H_ID);
4282 puts(CONTAINER_H_ID);
4283 puts(CRYPTO_H_ID);
4284 puts(HT_H_ID);
4285 puts(TEST_H_ID);
4286 puts(LOG_H_ID);
4287 puts(TORGZIP_H_ID);
4288 puts(TORINT_H_ID);
4289 puts(TORTLS_H_ID);
4290 puts(UTIL_H_ID);
4291 puts(aes_c_id);
4292 puts(compat_c_id);
4293 puts(container_c_id);
4294 puts(crypto_c_id);
4295 puts(log_c_id);
4296 puts(torgzip_c_id);
4297 puts(tortls_c_id);
4298 puts(util_c_id);
4300 puts(OR_H_ID);
4301 puts(buffers_c_id);
4302 puts(circuitbuild_c_id);
4303 puts(circuitlist_c_id);
4304 puts(circuituse_c_id);
4305 puts(command_c_id);
4306 puts(config_c_id);
4307 puts(connection_c_id);
4308 puts(connection_edge_c_id);
4309 puts(connection_or_c_id);
4310 puts(control_c_id);
4311 puts(cpuworker_c_id);
4312 puts(directory_c_id);
4313 puts(dirserv_c_id);
4314 puts(dns_c_id);
4315 puts(hibernate_c_id);
4316 puts(main_c_id);
4317 puts(onion_c_id);
4318 puts(policies_c_id);
4319 puts(relay_c_id);
4320 puts(rendclient_c_id);
4321 puts(rendcommon_c_id);
4322 puts(rendmid_c_id);
4323 puts(rendservice_c_id);
4324 puts(rephist_c_id);
4325 puts(router_c_id);
4326 puts(routerlist_c_id);
4327 puts(routerparse_c_id);