Line data Source code
1 : /* Copyright (c) 2001 Matej Pfajfar.
2 : * Copyright (c) 2001-2004, Roger Dingledine.
3 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
5 : /* See LICENSE for licensing information */
6 :
7 : /**
8 : * \file config.c
9 : * \brief Code to interpret the user's configuration of Tor.
10 : *
11 : * This module handles torrc configuration file, including parsing it,
12 : * combining it with torrc.defaults and the command line, allowing
13 : * user changes to it (via editing and SIGHUP or via the control port),
14 : * writing it back to disk (because of SAVECONF from the control port),
15 : * and -- most importantly, acting on it.
16 : *
17 : * The module additionally has some tools for manipulating and
18 : * inspecting values that are calculated as a result of the
19 : * configured options.
20 : *
21 : * <h3>How to add new options</h3>
22 : *
23 : * To add new items to the torrc, there are a minimum of three places to edit:
24 : * <ul>
25 : * <li>The or_options_t structure in or_options_st.h, where the options are
26 : * stored.
27 : * <li>The option_vars_ array below in this module, which configures
28 : * the names of the torrc options, their types, their multiplicities,
29 : * and their mappings to fields in or_options_t.
30 : * <li>The manual in doc/man/tor.1.txt, to document what the new option
31 : * is, and how it works.
32 : * </ul>
33 : *
34 : * Additionally, you might need to edit these places too:
35 : * <ul>
36 : * <li>options_validate_cb() below, in case you want to reject some possible
37 : * values of the new configuration option.
38 : * <li>options_transition_allowed() below, in case you need to
39 : * forbid some or all changes in the option while Tor is
40 : * running.
41 : * <li>options_transition_affects_workers(), in case changes in the option
42 : * might require Tor to relaunch or reconfigure its worker threads.
43 : * (This function is now in the relay module.)
44 : * <li>options_transition_affects_descriptor(), in case changes in the
45 : * option might require a Tor relay to build and publish a new server
46 : * descriptor.
47 : * (This function is now in the relay module.)
48 : * <li>options_act() and/or options_act_reversible(), in case there's some
49 : * action that needs to be taken immediately based on the option's
50 : * value.
51 : * </ul>
52 : *
53 : * <h3>Changing the value of an option</h3>
54 : *
55 : * Because of the SAVECONF command from the control port, it's a bad
56 : * idea to change the value of any user-configured option in the
57 : * or_options_t. If you want to sometimes do this anyway, we recommend
58 : * that you create a secondary field in or_options_t; that you have the
59 : * user option linked only to the secondary field; that you use the
60 : * secondary field to initialize the one that Tor actually looks at; and that
61 : * you use the one Tor looks as the one that you modify.
62 : **/
63 :
64 : #define CONFIG_PRIVATE
65 : #include "core/or/or.h"
66 : #include "app/config/config.h"
67 : #include "lib/confmgt/confmgt.h"
68 : #include "app/config/statefile.h"
69 : #include "app/main/main.h"
70 : #include "app/main/subsysmgr.h"
71 : #include "core/mainloop/connection.h"
72 : #include "core/mainloop/mainloop.h"
73 : #include "core/mainloop/netstatus.h"
74 : #include "core/or/channel.h"
75 : #include "core/or/circuitlist.h"
76 : #include "core/or/circuitmux.h"
77 : #include "core/or/circuitmux_ewma.h"
78 : #include "core/or/circuitstats.h"
79 : #include "core/or/connection_edge.h"
80 : #include "core/or/dos.h"
81 : #include "core/or/policies.h"
82 : #include "core/or/relay.h"
83 : #include "core/or/scheduler.h"
84 : #include "feature/client/addressmap.h"
85 : #include "feature/client/bridges.h"
86 : #include "feature/client/entrynodes.h"
87 : #include "feature/client/transports.h"
88 : #include "feature/control/control.h"
89 : #include "feature/control/control_auth.h"
90 : #include "feature/control/control_events.h"
91 : #include "feature/dirclient/dirclient_modes.h"
92 : #include "feature/hibernate/hibernate.h"
93 : #include "feature/hs/hs_config.h"
94 : #include "feature/metrics/metrics.h"
95 : #include "feature/nodelist/dirlist.h"
96 : #include "feature/nodelist/networkstatus.h"
97 : #include "feature/nodelist/nickname.h"
98 : #include "feature/nodelist/nodelist.h"
99 : #include "feature/nodelist/routerlist.h"
100 : #include "feature/nodelist/routerset.h"
101 : #include "feature/relay/dns.h"
102 : #include "feature/relay/ext_orport.h"
103 : #include "feature/relay/routermode.h"
104 : #include "feature/relay/relay_config.h"
105 : #include "feature/relay/transport_config.h"
106 : #include "lib/geoip/geoip.h"
107 : #include "feature/stats/geoip_stats.h"
108 : #include "lib/compress/compress.h"
109 : #include "lib/confmgt/structvar.h"
110 : #include "lib/crypt_ops/crypto_init.h"
111 : #include "lib/crypt_ops/crypto_rand.h"
112 : #include "lib/crypt_ops/crypto_util.h"
113 : #include "lib/encoding/confline.h"
114 : #include "lib/net/resolve.h"
115 : #include "lib/sandbox/sandbox.h"
116 : #include "lib/version/torversion.h"
117 :
118 : #ifdef ENABLE_NSS
119 : #include "lib/crypt_ops/crypto_nss_mgt.h"
120 : #else
121 : #include "lib/crypt_ops/crypto_openssl_mgt.h"
122 : #endif
123 :
124 : #ifdef _WIN32
125 : #include <shlobj.h>
126 : #endif
127 : #ifdef HAVE_FCNTL_H
128 : #include <fcntl.h>
129 : #endif
130 : #ifdef HAVE_SYS_STAT_H
131 : #include <sys/stat.h>
132 : #endif
133 : #ifdef HAVE_SYS_PARAM_H
134 : #include <sys/param.h>
135 : #endif
136 : #ifdef HAVE_UNISTD_H
137 : #include <unistd.h>
138 : #endif
139 :
140 : #include "lib/meminfo/meminfo.h"
141 : #include "lib/osinfo/uname.h"
142 : #include "lib/osinfo/libc.h"
143 : #include "lib/process/daemon.h"
144 : #include "lib/process/pidfile.h"
145 : #include "lib/process/restrict.h"
146 : #include "lib/process/setuid.h"
147 : #include "lib/process/process.h"
148 : #include "lib/net/gethostname.h"
149 : #include "lib/thread/numcpus.h"
150 :
151 : #include "lib/encoding/keyval.h"
152 : #include "lib/fs/conffile.h"
153 : #include "lib/evloop/procmon.h"
154 :
155 : #include "feature/dirauth/authmode.h"
156 : #include "feature/dirauth/dirauth_config.h"
157 :
158 : #include "core/or/connection_st.h"
159 : #include "core/or/port_cfg_st.h"
160 :
161 : #ifdef HAVE_SYSTEMD
162 : # if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__)
163 : /* Systemd's use of gcc's __INCLUDE_LEVEL__ extension macro appears to confuse
164 : * Coverity. Here's a kludge to unconfuse it.
165 : */
166 : # define __INCLUDE_LEVEL__ 2
167 : #endif /* defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) */
168 : #include <systemd/sd-daemon.h>
169 : #endif /* defined(HAVE_SYSTEMD) */
170 :
171 : /* Prefix used to indicate a Unix socket in a FooPort configuration. */
172 : static const char unix_socket_prefix[] = "unix:";
173 : /* Prefix used to indicate a Unix socket with spaces in it, in a FooPort
174 : * configuration. */
175 : static const char unix_q_socket_prefix[] = "unix:\"";
176 :
177 : /* limits for TCP send and recv buffer size used for constrained sockets */
178 : #define MIN_CONSTRAINED_TCP_BUFFER 2048
179 : #define MAX_CONSTRAINED_TCP_BUFFER 262144 /* 256k */
180 :
181 : /** macro to help with the bulk rename of *DownloadSchedule to
182 : * *DowloadInitialDelay . */
183 : #ifndef COCCI
184 : #define DOWNLOAD_SCHEDULE(name) \
185 : { (#name "DownloadSchedule"), (#name "DownloadInitialDelay"), 0, 1 }
186 : #else
187 : #define DOWNLOAD_SCHEDULE(name) { NULL, NULL, 0, 1 }
188 : #endif /* !defined(COCCI) */
189 :
190 : /** A list of abbreviations and aliases to map command-line options, obsolete
191 : * option names, or alternative option names, to their current values. */
192 : static const config_abbrev_t option_abbrevs_[] = {
193 : PLURAL(AuthDirBadDirCC),
194 : PLURAL(AuthDirBadExitCC),
195 : PLURAL(AuthDirInvalidCC),
196 : PLURAL(AuthDirRejectCC),
197 : PLURAL(EntryNode),
198 : PLURAL(ExcludeNode),
199 : PLURAL(FirewallPort),
200 : PLURAL(LongLivedPort),
201 : PLURAL(HiddenServiceNode),
202 : PLURAL(HiddenServiceExcludeNode),
203 : PLURAL(NumCPU),
204 : PLURAL(RendNode),
205 : PLURAL(RecommendedPackage),
206 : PLURAL(RendExcludeNode),
207 : PLURAL(StrictEntryNode),
208 : PLURAL(StrictExitNode),
209 : PLURAL(StrictNode),
210 : { "l", "Log", 1, 0},
211 : { "AllowUnverifiedNodes", "AllowInvalidNodes", 0, 0},
212 : { "AutomapHostSuffixes", "AutomapHostsSuffixes", 0, 0},
213 : { "AutomapHostOnResolve", "AutomapHostsOnResolve", 0, 0},
214 : { "BandwidthRateBytes", "BandwidthRate", 0, 0},
215 : { "BandwidthBurstBytes", "BandwidthBurst", 0, 0},
216 : { "DirFetchPostPeriod", "StatusFetchPeriod", 0, 0},
217 : { "DirServer", "DirAuthority", 0, 0}, /* XXXX later, make this warn? */
218 : { "MaxConn", "ConnLimit", 0, 1},
219 : { "MaxMemInCellQueues", "MaxMemInQueues", 0, 0},
220 : { "ORBindAddress", "ORListenAddress", 0, 0},
221 : { "DirBindAddress", "DirListenAddress", 0, 0},
222 : { "SocksBindAddress", "SocksListenAddress", 0, 0},
223 : { "UseHelperNodes", "UseEntryGuards", 0, 0},
224 : { "NumHelperNodes", "NumEntryGuards", 0, 0},
225 : { "UseEntryNodes", "UseEntryGuards", 0, 0},
226 : { "NumEntryNodes", "NumEntryGuards", 0, 0},
227 : { "ResolvConf", "ServerDNSResolvConfFile", 0, 1},
228 : { "SearchDomains", "ServerDNSSearchDomains", 0, 1},
229 : { "ServerDNSAllowBrokenResolvConf", "ServerDNSAllowBrokenConfig", 0, 0},
230 : { "PreferTunnelledDirConns", "PreferTunneledDirConns", 0, 0},
231 : { "BridgeAuthoritativeDirectory", "BridgeAuthoritativeDir", 0, 0},
232 : { "HashedControlPassword", "__HashedControlSessionPassword", 1, 0},
233 : { "VirtualAddrNetwork", "VirtualAddrNetworkIPv4", 0, 0},
234 : { "SocksSocketsGroupWritable", "UnixSocksGroupWritable", 0, 1},
235 : { "_HSLayer2Nodes", "HSLayer2Nodes", 0, 1 },
236 : { "_HSLayer3Nodes", "HSLayer3Nodes", 0, 1 },
237 :
238 : DOWNLOAD_SCHEDULE(ClientBootstrapConsensusAuthority),
239 : DOWNLOAD_SCHEDULE(ClientBootstrapConsensusAuthorityOnly),
240 : DOWNLOAD_SCHEDULE(ClientBootstrapConsensusFallback),
241 : DOWNLOAD_SCHEDULE(TestingBridge),
242 : DOWNLOAD_SCHEDULE(TestingBridgeBootstrap),
243 : DOWNLOAD_SCHEDULE(TestingClient),
244 : DOWNLOAD_SCHEDULE(TestingClientConsensus),
245 : DOWNLOAD_SCHEDULE(TestingServer),
246 : DOWNLOAD_SCHEDULE(TestingServerConsensus),
247 :
248 : { NULL, NULL, 0, 0},
249 : };
250 :
251 : /** dummy instance of or_options_t, used for type-checking its
252 : * members with CONF_CHECK_VAR_TYPE. */
253 : DUMMY_TYPECHECK_INSTANCE(or_options_t);
254 :
255 : /** An entry for config_vars: "The option <b>varname</b> has type
256 : * CONFIG_TYPE_<b>conftype</b>, and corresponds to
257 : * or_options_t.<b>member</b>"
258 : */
259 : #define VAR(varname,conftype,member,initvalue) \
260 : CONFIG_VAR_ETYPE(or_options_t, varname, conftype, member, 0, initvalue)
261 :
262 : /* As VAR, but uses a type definition in addition to a type enum. */
263 : #define VAR_D(varname,conftype,member,initvalue) \
264 : CONFIG_VAR_DEFN(or_options_t, varname, conftype, member, 0, initvalue)
265 :
266 : #define VAR_NODUMP(varname,conftype,member,initvalue) \
267 : CONFIG_VAR_ETYPE(or_options_t, varname, conftype, member, \
268 : CFLG_NODUMP, initvalue)
269 : #define VAR_NODUMP_IMMUTABLE(varname,conftype,member,initvalue) \
270 : CONFIG_VAR_ETYPE(or_options_t, varname, conftype, member, \
271 : CFLG_NODUMP | CFLG_IMMUTABLE, initvalue)
272 : #define VAR_INVIS(varname,conftype,member,initvalue) \
273 : CONFIG_VAR_ETYPE(or_options_t, varname, conftype, member, \
274 : CFLG_NODUMP | CFLG_NOSET | CFLG_NOLIST, initvalue)
275 :
276 : #define V(member,conftype,initvalue) \
277 : VAR(#member, conftype, member, initvalue)
278 :
279 : #define VAR_IMMUTABLE(varname, conftype, member, initvalue) \
280 : CONFIG_VAR_ETYPE(or_options_t, varname, conftype, member, \
281 : CFLG_IMMUTABLE, initvalue)
282 :
283 : #define V_IMMUTABLE(member,conftype,initvalue) \
284 : VAR_IMMUTABLE(#member, conftype, member, initvalue)
285 :
286 : /** As V, but uses a type definition instead of a type enum */
287 : #define V_D(member,type,initvalue) \
288 : VAR_D(#member, type, member, initvalue)
289 :
290 : /** An entry for config_vars: "The option <b>varname</b> is obsolete." */
291 : #define OBSOLETE(varname) CONFIG_VAR_OBSOLETE(varname)
292 :
293 : /**
294 : * Macro to declare *Port options. Each one comes in three entries.
295 : * For example, most users should use "SocksPort" to configure the
296 : * socks port, but TorBrowser wants to use __SocksPort so that it
297 : * isn't stored by SAVECONF. The SocksPortLines virtual option is
298 : * used to query both options from the controller.
299 : */
300 : #define VPORT(member) \
301 : VAR(#member "Lines", LINELIST_V, member ## _lines, NULL), \
302 : VAR(#member, LINELIST_S, member ## _lines, NULL), \
303 : VAR_NODUMP("__" #member, LINELIST_S, member ## _lines, NULL)
304 :
305 : /** UINT64_MAX as a decimal string */
306 : #define UINT64_MAX_STRING "18446744073709551615"
307 :
308 : /** Array of configuration options. Until we disallow nonstandard
309 : * abbreviations, order is significant, since the first matching option will
310 : * be chosen first.
311 : */
312 : static const config_var_t option_vars_[] = {
313 : V(AccountingMax, MEMUNIT, "0 bytes"),
314 : VAR("AccountingRule", STRING, AccountingRule_option, "max"),
315 : V(AccountingStart, STRING, NULL),
316 : V(Address, LINELIST, NULL),
317 : V(AddressDisableIPv6, BOOL, "0"),
318 : OBSOLETE("AllowDotExit"),
319 : OBSOLETE("AllowInvalidNodes"),
320 : V(AllowNonRFC953Hostnames, BOOL, "0"),
321 : OBSOLETE("AllowSingleHopCircuits"),
322 : OBSOLETE("AllowSingleHopExits"),
323 : V(AlternateBridgeAuthority, LINELIST, NULL),
324 : V(AlternateDirAuthority, LINELIST, NULL),
325 : OBSOLETE("AlternateHSAuthority"),
326 : V(AssumeReachable, BOOL, "0"),
327 : V(AssumeReachableIPv6, AUTOBOOL, "auto"),
328 : OBSOLETE("AuthDirBadDir"),
329 : OBSOLETE("AuthDirBadDirCCs"),
330 : V(AuthDirBadExit, LINELIST, NULL),
331 : V(AuthDirBadExitCCs, CSV, ""),
332 : V(AuthDirInvalid, LINELIST, NULL),
333 : V(AuthDirInvalidCCs, CSV, ""),
334 : V(AuthDirReject, LINELIST, NULL),
335 : V(AuthDirRejectCCs, CSV, ""),
336 : OBSOLETE("AuthDirRejectUnlisted"),
337 : OBSOLETE("AuthDirListBadDirs"),
338 : OBSOLETE("AuthDirMaxServersPerAuthAddr"),
339 : VAR("AuthoritativeDirectory", BOOL, AuthoritativeDir, "0"),
340 : V(AutomapHostsOnResolve, BOOL, "0"),
341 : V(AutomapHostsSuffixes, CSV, ".onion,.exit"),
342 : V(AvoidDiskWrites, BOOL, "0"),
343 : V(BandwidthBurst, MEMUNIT, "1 GB"),
344 : V(BandwidthRate, MEMUNIT, "1 GB"),
345 : V(BridgeAuthoritativeDir, BOOL, "0"),
346 : VAR("Bridge", LINELIST, Bridges, NULL),
347 : V(BridgePassword, STRING, NULL),
348 : V(BridgeRecordUsageByCountry, BOOL, "1"),
349 : V(BridgeRelay, BOOL, "0"),
350 : V(BridgeDistribution, STRING, NULL),
351 : VAR_IMMUTABLE("CacheDirectory",FILENAME, CacheDirectory_option, NULL),
352 : V(CacheDirectoryGroupReadable, AUTOBOOL, "auto"),
353 : V(CellStatistics, BOOL, "0"),
354 : V(PaddingStatistics, BOOL, "1"),
355 : V(OverloadStatistics, BOOL, "1"),
356 : V(LearnCircuitBuildTimeout, BOOL, "1"),
357 : V(CircuitBuildTimeout, INTERVAL, "0"),
358 : OBSOLETE("CircuitIdleTimeout"),
359 : V(CircuitsAvailableTimeout, INTERVAL, "0"),
360 : V(CircuitStreamTimeout, INTERVAL, "0"),
361 : V(CircuitPriorityHalflife, DOUBLE, "-1.0"), /*negative:'Use default'*/
362 : V(ClientDNSRejectInternalAddresses, BOOL,"1"),
363 : #if defined(HAVE_MODULE_RELAY) || defined(TOR_UNIT_TESTS)
364 : /* The unit tests expect the ClientOnly default to be 0. */
365 : V(ClientOnly, BOOL, "0"),
366 : #else
367 : /* We must be a Client if the relay module is disabled. */
368 : V(ClientOnly, BOOL, "1"),
369 : #endif /* defined(HAVE_MODULE_RELAY) || defined(TOR_UNIT_TESTS) */
370 : V(ClientPreferIPv6ORPort, AUTOBOOL, "auto"),
371 : V(ClientPreferIPv6DirPort, AUTOBOOL, "auto"),
372 : OBSOLETE("ClientAutoIPv6ORPort"),
373 : V(ClientRejectInternalAddresses, BOOL, "1"),
374 : V(ClientTransportPlugin, LINELIST, NULL),
375 : V(ClientUseIPv6, BOOL, "0"),
376 : V(ClientUseIPv4, BOOL, "1"),
377 : V(ConnLimit, POSINT, "1000"),
378 : V(ConnDirectionStatistics, BOOL, "0"),
379 : V(ConstrainedSockets, BOOL, "0"),
380 : V(ConstrainedSockSize, MEMUNIT, "8192"),
381 : V(ContactInfo, STRING, NULL),
382 : OBSOLETE("ControlListenAddress"),
383 : VPORT(ControlPort),
384 : V(ControlPortFileGroupReadable,BOOL, "0"),
385 : V(ControlPortWriteToFile, FILENAME, NULL),
386 : V(ControlSocket, LINELIST, NULL),
387 : V(ControlSocketsGroupWritable, BOOL, "0"),
388 : V(UnixSocksGroupWritable, BOOL, "0"),
389 : V(CookieAuthentication, BOOL, "0"),
390 : V(CookieAuthFileGroupReadable, BOOL, "0"),
391 : V(CookieAuthFile, FILENAME, NULL),
392 : V(CountPrivateBandwidth, BOOL, "0"),
393 : VAR_IMMUTABLE("DataDirectory", FILENAME, DataDirectory_option, NULL),
394 : V(DataDirectoryGroupReadable, BOOL, "0"),
395 : V(DisableOOSCheck, BOOL, "1"),
396 : V(DisableNetwork, BOOL, "0"),
397 : V(DirAllowPrivateAddresses, BOOL, "0"),
398 : OBSOLETE("DirListenAddress"),
399 : V(DirPolicy, LINELIST, NULL),
400 : VPORT(DirPort),
401 : V(DirPortFrontPage, FILENAME, NULL),
402 : VAR("DirReqStatistics", BOOL, DirReqStatistics_option, "1"),
403 : VAR("DirAuthority", LINELIST, DirAuthorities, NULL),
404 : #if defined(HAVE_MODULE_RELAY) || defined(TOR_UNIT_TESTS)
405 : /* The unit tests expect the DirCache default to be 1. */
406 : V(DirCache, BOOL, "1"),
407 : #else
408 : /* We can't be a DirCache if the relay module is disabled. */
409 : V(DirCache, BOOL, "0"),
410 : #endif /* defined(HAVE_MODULE_RELAY) || defined(TOR_UNIT_TESTS) */
411 : /* A DirAuthorityFallbackRate of 0.1 means that 0.5% of clients try an
412 : * authority when all fallbacks are up, and 2% try an authority when 25% of
413 : * fallbacks are down. (We rebuild the list when 25% of fallbacks are down).
414 : *
415 : * We want to reduce load on authorities, but keep these two figures within
416 : * an order of magnitude, so there isn't too much load shifting to
417 : * authorities when fallbacks go down. */
418 : V(DirAuthorityFallbackRate, DOUBLE, "0.1"),
419 : V_IMMUTABLE(DisableAllSwap, BOOL, "0"),
420 : V_IMMUTABLE(DisableDebuggerAttachment, BOOL, "1"),
421 : OBSOLETE("DisableIOCP"),
422 : OBSOLETE("DisableV2DirectoryInfo_"),
423 : OBSOLETE("DynamicDHGroups"),
424 : VPORT(DNSPort),
425 : OBSOLETE("DNSListenAddress"),
426 : V(DormantClientTimeout, INTERVAL, "24 hours"),
427 : V(DormantTimeoutEnabled, BOOL, "1"),
428 : V(DormantTimeoutDisabledByIdleStreams, BOOL, "1"),
429 : V(DormantOnFirstStartup, BOOL, "0"),
430 : V(DormantCanceledByStartup, BOOL, "0"),
431 : V(DownloadExtraInfo, BOOL, "0"),
432 : V(TestingEnableConnBwEvent, BOOL, "0"),
433 : V(TestingEnableCellStatsEvent, BOOL, "0"),
434 : OBSOLETE("TestingEnableTbEmptyEvent"),
435 : V(EnforceDistinctSubnets, BOOL, "1"),
436 : V_D(EntryNodes, ROUTERSET, NULL),
437 : V(EntryStatistics, BOOL, "0"),
438 : OBSOLETE("TestingEstimatedDescriptorPropagationTime"),
439 : V_D(ExcludeNodes, ROUTERSET, NULL),
440 : V_D(ExcludeExitNodes, ROUTERSET, NULL),
441 : OBSOLETE("ExcludeSingleHopRelays"),
442 : V_D(ExitNodes, ROUTERSET, NULL),
443 : /* Researchers need a way to tell their clients to use specific
444 : * middles that they also control, to allow safe live-network
445 : * experimentation with new padding machines. */
446 : V_D(MiddleNodes, ROUTERSET, NULL),
447 : V(ExitPolicy, LINELIST, NULL),
448 : V(ExitPolicyRejectPrivate, BOOL, "1"),
449 : V(ExitPolicyRejectLocalInterfaces, BOOL, "0"),
450 : V(ExitPortStatistics, BOOL, "0"),
451 : V(ExtendAllowPrivateAddresses, BOOL, "0"),
452 : V(ExitRelay, AUTOBOOL, "auto"),
453 : VPORT(ExtORPort),
454 : V(ExtORPortCookieAuthFile, FILENAME, NULL),
455 : V(ExtORPortCookieAuthFileGroupReadable, BOOL, "0"),
456 : V(ExtraInfoStatistics, BOOL, "1"),
457 : V(ExtendByEd25519ID, AUTOBOOL, "auto"),
458 : V(FallbackDir, LINELIST, NULL),
459 :
460 : V(UseDefaultFallbackDirs, BOOL, "1"),
461 :
462 : OBSOLETE("FallbackNetworkstatusFile"),
463 : V(FascistFirewall, BOOL, "0"),
464 : V(FirewallPorts, CSV, ""),
465 : OBSOLETE("FastFirstHopPK"),
466 : V(FetchDirInfoEarly, BOOL, "0"),
467 : V(FetchDirInfoExtraEarly, BOOL, "0"),
468 : V(FetchServerDescriptors, BOOL, "1"),
469 : V(FetchHidServDescriptors, BOOL, "1"),
470 : V(FetchUselessDescriptors, BOOL, "0"),
471 : OBSOLETE("FetchV2Networkstatus"),
472 : V(GeoIPExcludeUnknown, AUTOBOOL, "auto"),
473 : #ifdef _WIN32
474 : V(GeoIPFile, FILENAME, "<default>"),
475 : V(GeoIPv6File, FILENAME, "<default>"),
476 : #else
477 : V(GeoIPFile, FILENAME,
478 : SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "geoip"),
479 : V(GeoIPv6File, FILENAME,
480 : SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "geoip6"),
481 : #endif /* defined(_WIN32) */
482 : OBSOLETE("Group"),
483 : V(GuardLifetime, INTERVAL, "0 minutes"),
484 : V(HeartbeatPeriod, INTERVAL, "6 hours"),
485 : V(MainloopStats, BOOL, "0"),
486 : V(HashedControlPassword, LINELIST, NULL),
487 : OBSOLETE("HidServDirectoryV2"),
488 : OBSOLETE("HiddenServiceAuthorizeClient"),
489 : OBSOLETE("HidServAuth"),
490 : VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
491 : VAR("HiddenServiceDirGroupReadable", LINELIST_S, RendConfigLines, NULL),
492 : VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
493 : VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
494 : VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines, NULL),
495 : VAR("HiddenServiceAllowUnknownPorts",LINELIST_S, RendConfigLines, NULL),
496 : VAR("HiddenServiceMaxStreams",LINELIST_S, RendConfigLines, NULL),
497 : VAR("HiddenServiceMaxStreamsCloseCircuit",LINELIST_S, RendConfigLines, NULL),
498 : VAR("HiddenServiceNumIntroductionPoints", LINELIST_S, RendConfigLines, NULL),
499 : VAR("HiddenServiceExportCircuitID", LINELIST_S, RendConfigLines, NULL),
500 : VAR("HiddenServiceEnableIntroDoSDefense", LINELIST_S, RendConfigLines, NULL),
501 : VAR("HiddenServiceEnableIntroDoSRatePerSec",
502 : LINELIST_S, RendConfigLines, NULL),
503 : VAR("HiddenServiceEnableIntroDoSBurstPerSec",
504 : LINELIST_S, RendConfigLines, NULL),
505 : VAR("HiddenServiceOnionBalanceInstance",
506 : LINELIST_S, RendConfigLines, NULL),
507 : VAR("HiddenServiceStatistics", BOOL, HiddenServiceStatistics_option, "1"),
508 : V(ClientOnionAuthDir, FILENAME, NULL),
509 : OBSOLETE("CloseHSClientCircuitsImmediatelyOnTimeout"),
510 : OBSOLETE("CloseHSServiceRendCircuitsImmediatelyOnTimeout"),
511 : V_IMMUTABLE(HiddenServiceSingleHopMode, BOOL, "0"),
512 : V_IMMUTABLE(HiddenServiceNonAnonymousMode,BOOL, "0"),
513 : V(HTTPProxy, STRING, NULL),
514 : V(HTTPProxyAuthenticator, STRING, NULL),
515 : V(HTTPSProxy, STRING, NULL),
516 : V(HTTPSProxyAuthenticator, STRING, NULL),
517 : VPORT(HTTPTunnelPort),
518 : V(IPv6Exit, BOOL, "0"),
519 : VAR("ServerTransportPlugin", LINELIST, ServerTransportPlugin, NULL),
520 : V(ServerTransportListenAddr, LINELIST, NULL),
521 : V(ServerTransportOptions, LINELIST, NULL),
522 : V(SigningKeyLifetime, INTERVAL, "30 days"),
523 : V(Socks4Proxy, STRING, NULL),
524 : V(Socks5Proxy, STRING, NULL),
525 : V(Socks5ProxyUsername, STRING, NULL),
526 : V(Socks5ProxyPassword, STRING, NULL),
527 : V(TCPProxy, STRING, NULL),
528 : VAR_IMMUTABLE("KeyDirectory", FILENAME, KeyDirectory_option, NULL),
529 : V(KeyDirectoryGroupReadable, AUTOBOOL, "auto"),
530 : VAR_D("HSLayer2Nodes", ROUTERSET, HSLayer2Nodes, NULL),
531 : VAR_D("HSLayer3Nodes", ROUTERSET, HSLayer3Nodes, NULL),
532 : V(KeepalivePeriod, INTERVAL, "5 minutes"),
533 : V_IMMUTABLE(KeepBindCapabilities, AUTOBOOL, "auto"),
534 : VAR("Log", LINELIST, Logs, NULL),
535 : V(LogMessageDomains, BOOL, "0"),
536 : V(LogTimeGranularity, MSEC_INTERVAL, "1 second"),
537 : V(TruncateLogFile, BOOL, "0"),
538 : V_IMMUTABLE(SyslogIdentityTag, STRING, NULL),
539 : OBSOLETE("AndroidIdentityTag"),
540 : V(LongLivedPorts, CSV,
541 : "21,22,706,1863,5050,5190,5222,5223,6523,6667,6697,8300"),
542 : VAR("MapAddress", LINELIST, AddressMap, NULL),
543 : V(MaxAdvertisedBandwidth, MEMUNIT, "1 GB"),
544 : V(MaxCircuitDirtiness, INTERVAL, "10 minutes"),
545 : V(MaxClientCircuitsPending, POSINT, "32"),
546 : V(MaxConsensusAgeForDiffs, INTERVAL, "0 seconds"),
547 : VAR("MaxMemInQueues", MEMUNIT, MaxMemInQueues_raw, "0"),
548 : OBSOLETE("MaxOnionsPending"),
549 : V(MaxOnionQueueDelay, MSEC_INTERVAL, "1750 msec"),
550 : V(MaxUnparseableDescSizeToLog, MEMUNIT, "10 MB"),
551 : VPORT(MetricsPort),
552 : V(MetricsPortPolicy, LINELIST, NULL),
553 : VAR("MyFamily", LINELIST, MyFamily_lines, NULL),
554 : V(NewCircuitPeriod, INTERVAL, "30 seconds"),
555 : OBSOLETE("NamingAuthoritativeDirectory"),
556 : OBSOLETE("NATDListenAddress"),
557 : VPORT(NATDPort),
558 : V(Nickname, STRING, NULL),
559 : OBSOLETE("PredictedPortsRelevanceTime"),
560 : OBSOLETE("WarnUnsafeSocks"),
561 : VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
562 : V_IMMUTABLE(NoExec, BOOL, "0"),
563 : V(NumCPUs, POSINT, "0"),
564 : V(NumDirectoryGuards, POSINT, "0"),
565 : V(NumEntryGuards, POSINT, "0"),
566 : V(NumPrimaryGuards, POSINT, "0"),
567 : V(OfflineMasterKey, BOOL, "0"),
568 : OBSOLETE("ORListenAddress"),
569 : VPORT(ORPort),
570 : V(OutboundBindAddress, LINELIST, NULL),
571 : V(OutboundBindAddressOR, LINELIST, NULL),
572 : V(OutboundBindAddressExit, LINELIST, NULL),
573 : V(OutboundBindAddressPT, LINELIST, NULL),
574 :
575 : OBSOLETE("PathBiasDisableRate"),
576 : V(PathBiasCircThreshold, INT, "-1"),
577 : V(PathBiasNoticeRate, DOUBLE, "-1"),
578 : V(PathBiasWarnRate, DOUBLE, "-1"),
579 : V(PathBiasExtremeRate, DOUBLE, "-1"),
580 : V(PathBiasScaleThreshold, INT, "-1"),
581 : OBSOLETE("PathBiasScaleFactor"),
582 : OBSOLETE("PathBiasMultFactor"),
583 : V(PathBiasDropGuards, AUTOBOOL, "0"),
584 : OBSOLETE("PathBiasUseCloseCounts"),
585 :
586 : V(PathBiasUseThreshold, INT, "-1"),
587 : V(PathBiasNoticeUseRate, DOUBLE, "-1"),
588 : V(PathBiasExtremeUseRate, DOUBLE, "-1"),
589 : V(PathBiasScaleUseThreshold, INT, "-1"),
590 :
591 : V(PathsNeededToBuildCircuits, DOUBLE, "-1"),
592 : V(PerConnBWBurst, MEMUNIT, "0"),
593 : V(PerConnBWRate, MEMUNIT, "0"),
594 : V_IMMUTABLE(PidFile, FILENAME, NULL),
595 : V_IMMUTABLE(TestingTorNetwork, BOOL, "0"),
596 :
597 : V(TestingLinkCertLifetime, INTERVAL, "2 days"),
598 : V(TestingAuthKeyLifetime, INTERVAL, "2 days"),
599 : V(TestingLinkKeySlop, INTERVAL, "3 hours"),
600 : V(TestingAuthKeySlop, INTERVAL, "3 hours"),
601 : V(TestingSigningKeySlop, INTERVAL, "1 day"),
602 :
603 : OBSOLETE("OptimisticData"),
604 : OBSOLETE("PortForwarding"),
605 : OBSOLETE("PortForwardingHelper"),
606 : OBSOLETE("PreferTunneledDirConns"),
607 : V(ProtocolWarnings, BOOL, "0"),
608 : V(PublishServerDescriptor, CSV, "1"),
609 : V(PublishHidServDescriptors, BOOL, "1"),
610 : V(ReachableAddresses, LINELIST, NULL),
611 : V(ReachableDirAddresses, LINELIST, NULL),
612 : V(ReachableORAddresses, LINELIST, NULL),
613 : OBSOLETE("RecommendedPackages"),
614 : V(ReducedConnectionPadding, BOOL, "0"),
615 : V(ConnectionPadding, AUTOBOOL, "auto"),
616 : V(RefuseUnknownExits, AUTOBOOL, "auto"),
617 : V(CircuitPadding, BOOL, "1"),
618 : V(ReducedCircuitPadding, BOOL, "0"),
619 : V(RejectPlaintextPorts, CSV, ""),
620 : V(RelayBandwidthBurst, MEMUNIT, "0"),
621 : V(RelayBandwidthRate, MEMUNIT, "0"),
622 : V(RendPostPeriod, INTERVAL, "1 hour"), /* Used internally. */
623 : V(RephistTrackTime, INTERVAL, "24 hours"),
624 : V_IMMUTABLE(RunAsDaemon, BOOL, "0"),
625 : V(ReducedExitPolicy, BOOL, "0"),
626 : OBSOLETE("RunTesting"), // currently unused
627 : V_IMMUTABLE(Sandbox, BOOL, "0"),
628 : V(SafeLogging, STRING, "1"),
629 : V(SafeSocks, BOOL, "0"),
630 : V(ServerDNSAllowBrokenConfig, BOOL, "1"),
631 : V(ServerDNSAllowNonRFC953Hostnames, BOOL,"0"),
632 : V(ServerDNSDetectHijacking, BOOL, "1"),
633 : V(ServerDNSRandomizeCase, BOOL, "1"),
634 : V(ServerDNSResolvConfFile, FILENAME, NULL),
635 : V(ServerDNSSearchDomains, BOOL, "0"),
636 : V(ServerDNSTestAddresses, CSV,
637 : "www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"),
638 : OBSOLETE("SchedulerLowWaterMark__"),
639 : OBSOLETE("SchedulerHighWaterMark__"),
640 : OBSOLETE("SchedulerMaxFlushCells__"),
641 : V(KISTSchedRunInterval, MSEC_INTERVAL, "0 msec"),
642 : V(KISTSockBufSizeFactor, DOUBLE, "1.0"),
643 : V(Schedulers, CSV, "KIST,KISTLite,Vanilla"),
644 : V(ShutdownWaitLength, INTERVAL, "30 seconds"),
645 : OBSOLETE("SocksListenAddress"),
646 : V(SocksPolicy, LINELIST, NULL),
647 : VPORT(SocksPort),
648 : V(SocksTimeout, INTERVAL, "2 minutes"),
649 : V(SSLKeyLifetime, INTERVAL, "0"),
650 : OBSOLETE("StrictEntryNodes"),
651 : OBSOLETE("StrictExitNodes"),
652 : V(StrictNodes, BOOL, "0"),
653 : OBSOLETE("Support022HiddenServices"),
654 : V(TestSocks, BOOL, "0"),
655 : V_IMMUTABLE(TokenBucketRefillInterval, MSEC_INTERVAL, "100 msec"),
656 : OBSOLETE("Tor2webMode"),
657 : OBSOLETE("Tor2webRendezvousPoints"),
658 : OBSOLETE("TLSECGroup"),
659 : V(TrackHostExits, CSV, NULL),
660 : V(TrackHostExitsExpire, INTERVAL, "30 minutes"),
661 : OBSOLETE("TransListenAddress"),
662 : VPORT(TransPort),
663 : V(TransProxyType, STRING, "default"),
664 : OBSOLETE("TunnelDirConns"),
665 : V(UpdateBridgesFromAuthority, BOOL, "0"),
666 : V(UseBridges, BOOL, "0"),
667 : VAR("UseEntryGuards", BOOL, UseEntryGuards_option, "1"),
668 : OBSOLETE("UseEntryGuardsAsDirGuards"),
669 : V(UseGuardFraction, AUTOBOOL, "auto"),
670 : V(UseMicrodescriptors, AUTOBOOL, "auto"),
671 : OBSOLETE("UseNTorHandshake"),
672 : V_IMMUTABLE(User, STRING, NULL),
673 : OBSOLETE("UserspaceIOCPBuffers"),
674 : OBSOLETE("V1AuthoritativeDirectory"),
675 : OBSOLETE("V2AuthoritativeDirectory"),
676 : VAR("V3AuthoritativeDirectory",BOOL, V3AuthoritativeDir, "0"),
677 : V(TestingV3AuthInitialVotingInterval, INTERVAL, "30 minutes"),
678 : V(TestingV3AuthInitialVoteDelay, INTERVAL, "5 minutes"),
679 : V(TestingV3AuthInitialDistDelay, INTERVAL, "5 minutes"),
680 : V(TestingV3AuthVotingStartOffset, INTERVAL, "0"),
681 : V(V3AuthVotingInterval, INTERVAL, "1 hour"),
682 : V(V3AuthVoteDelay, INTERVAL, "5 minutes"),
683 : V(V3AuthDistDelay, INTERVAL, "5 minutes"),
684 : V(V3AuthNIntervalsValid, POSINT, "3"),
685 : V(V3AuthUseLegacyKey, BOOL, "0"),
686 : V(V3BandwidthsFile, FILENAME, NULL),
687 : V(GuardfractionFile, FILENAME, NULL),
688 : OBSOLETE("VoteOnHidServDirectoriesV2"),
689 : V(VirtualAddrNetworkIPv4, STRING, "127.192.0.0/10"),
690 : V(VirtualAddrNetworkIPv6, STRING, "[FE80::]/10"),
691 : V(WarnPlaintextPorts, CSV, "23,109,110,143"),
692 : OBSOLETE("UseFilteringSSLBufferevents"),
693 : OBSOLETE("__UseFilteringSSLBufferevents"),
694 : VAR_NODUMP("__ReloadTorrcOnSIGHUP", BOOL, ReloadTorrcOnSIGHUP, "1"),
695 : VAR_NODUMP("__AllDirActionsPrivate", BOOL, AllDirActionsPrivate, "0"),
696 : VAR_NODUMP("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits, "0"),
697 : VAR_NODUMP_IMMUTABLE("__DisableSignalHandlers", BOOL,
698 : DisableSignalHandlers, "0"),
699 : VAR_NODUMP("__LeaveStreamsUnattached",BOOL, LeaveStreamsUnattached, "0"),
700 : VAR_NODUMP("__HashedControlSessionPassword", LINELIST,
701 : HashedControlSessionPassword,
702 : NULL),
703 : VAR_NODUMP("__OwningControllerProcess",STRING,
704 : OwningControllerProcess, NULL),
705 : VAR_NODUMP_IMMUTABLE("__OwningControllerFD", UINT64, OwningControllerFD,
706 : UINT64_MAX_STRING),
707 : V(TestingServerDownloadInitialDelay, CSV_INTERVAL, "0"),
708 : V(TestingClientDownloadInitialDelay, CSV_INTERVAL, "0"),
709 : V(TestingServerConsensusDownloadInitialDelay, CSV_INTERVAL, "0"),
710 : V(TestingClientConsensusDownloadInitialDelay, CSV_INTERVAL, "0"),
711 : /* With the ClientBootstrapConsensus*Download* below:
712 : * Clients with only authorities will try:
713 : * - at least 3 authorities over 10 seconds, then exponentially backoff,
714 : * with the next attempt 3-21 seconds later,
715 : * Clients with authorities and fallbacks will try:
716 : * - at least 2 authorities and 4 fallbacks over 21 seconds, then
717 : * exponentially backoff, with the next attempts 4-33 seconds later,
718 : * Clients will also retry when an application request arrives.
719 : * After a number of failed requests, clients retry every 3 days + 1 hour.
720 : *
721 : * Clients used to try 2 authorities over 10 seconds, then wait for
722 : * 60 minutes or an application request.
723 : *
724 : * When clients have authorities and fallbacks available, they use these
725 : * schedules: (we stagger the times to avoid thundering herds) */
726 : V(ClientBootstrapConsensusAuthorityDownloadInitialDelay, CSV_INTERVAL, "6"),
727 : V(ClientBootstrapConsensusFallbackDownloadInitialDelay, CSV_INTERVAL, "0"),
728 : /* When clients only have authorities available, they use this schedule: */
729 : V(ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay, CSV_INTERVAL,
730 : "0"),
731 : /* We don't want to overwhelm slow networks (or mirrors whose replies are
732 : * blocked), but we also don't want to fail if only some mirrors are
733 : * blackholed. Clients will try 3 directories simultaneously.
734 : * (Relays never use simultaneous connections.) */
735 : V(ClientBootstrapConsensusMaxInProgressTries, POSINT, "3"),
736 : /* When a client has any running bridges, check each bridge occasionally,
737 : * whether or not that bridge is actually up. */
738 : V(TestingBridgeDownloadInitialDelay, CSV_INTERVAL,"10800"),
739 : /* When a client is just starting, or has no running bridges, check each
740 : * bridge a few times quickly, and then try again later. These schedules
741 : * are much longer than the other schedules, because we try each and every
742 : * configured bridge with this schedule. */
743 : V(TestingBridgeBootstrapDownloadInitialDelay, CSV_INTERVAL, "0"),
744 : V(TestingClientMaxIntervalWithoutRequest, INTERVAL, "10 minutes"),
745 : V(TestingDirConnectionMaxStall, INTERVAL, "5 minutes"),
746 : OBSOLETE("TestingConsensusMaxDownloadTries"),
747 : OBSOLETE("ClientBootstrapConsensusMaxDownloadTries"),
748 : OBSOLETE("ClientBootstrapConsensusAuthorityOnlyMaxDownloadTries"),
749 : OBSOLETE("TestingDescriptorMaxDownloadTries"),
750 : OBSOLETE("TestingMicrodescMaxDownloadTries"),
751 : OBSOLETE("TestingCertMaxDownloadTries"),
752 : VAR_INVIS("___UsingTestNetworkDefaults", BOOL, UsingTestNetworkDefaults_,
753 : "0"),
754 :
755 : END_OF_CONFIG_VARS
756 : };
757 :
758 : /** List of default directory authorities */
759 : static const char *default_authorities[] = {
760 : #ifndef COCCI
761 : #include "auth_dirs.inc"
762 : #endif
763 : NULL
764 : };
765 :
766 : /** List of fallback directory authorities. The list is generated by opt-in of
767 : * relays that meet certain stability criteria.
768 : */
769 : static const char *default_fallbacks[] = {
770 : #ifndef COCCI
771 : #include "fallback_dirs.inc"
772 : #endif
773 : NULL
774 : };
775 :
776 : /** Override default values with these if the user sets the TestingTorNetwork
777 : * option. */
778 : static const struct {
779 : const char *k;
780 : const char *v;
781 : } testing_tor_network_defaults[] = {
782 : #ifndef COCCI
783 : #include "testnet.inc"
784 : #endif
785 : { NULL, NULL }
786 : };
787 :
788 : #undef VAR
789 : #undef V
790 : #undef OBSOLETE
791 :
792 : static const config_deprecation_t option_deprecation_notes_[] = {
793 : /* Deprecated since 0.3.2.0-alpha. */
794 : { "HTTPProxy", "It only applies to direct unencrypted HTTP connections "
795 : "to your directory server, which your Tor probably wasn't using." },
796 : { "HTTPProxyAuthenticator", "HTTPProxy is deprecated in favor of HTTPSProxy "
797 : "which should be used with HTTPSProxyAuthenticator." },
798 : /* End of options deprecated since 0.3.2.1-alpha */
799 :
800 : /* Options deprecated since 0.3.2.2-alpha */
801 : { "ReachableDirAddresses", "It has no effect on relays, and has had no "
802 : "effect on clients since 0.2.8." },
803 : { "ClientPreferIPv6DirPort", "It has no effect on relays, and has had no "
804 : "effect on clients since 0.2.8." },
805 : /* End of options deprecated since 0.3.2.2-alpha. */
806 :
807 : /* Options deprecated since 0.4.3.1-alpha. */
808 : { "ClientAutoIPv6ORPort", "This option is unreliable if a connection isn't "
809 : "reliably dual-stack."},
810 : /* End of options deprecated since 0.4.3.1-alpha. */
811 :
812 : { NULL, NULL }
813 : };
814 :
815 : #ifdef _WIN32
816 : static char *get_windows_conf_root(void);
817 : #endif
818 :
819 : static int options_check_transition_cb(const void *old,
820 : const void *new,
821 : char **msg);
822 : static int validate_data_directories(or_options_t *options);
823 : static int write_configuration_file(const char *fname,
824 : const or_options_t *options);
825 :
826 : static void init_libevent(const or_options_t *options);
827 : static int opt_streq(const char *s1, const char *s2);
828 : static int parse_outbound_addresses(or_options_t *options, int validate_only,
829 : char **msg);
830 : static void config_maybe_load_geoip_files_(const or_options_t *options,
831 : const or_options_t *old_options);
832 : static int options_validate_cb(const void *old_options, void *options,
833 : char **msg);
834 : static void cleanup_protocol_warning_severity_level(void);
835 : static void set_protocol_warning_severity_level(int warning_severity);
836 : static void options_clear_cb(const config_mgr_t *mgr, void *opts);
837 : static setopt_err_t options_validate_and_set(const or_options_t *old_options,
838 : or_options_t *new_options,
839 : char **msg_out);
840 : struct listener_transaction_t;
841 : static void options_rollback_listener_transaction(
842 : struct listener_transaction_t *xn);
843 :
844 : /** Magic value for or_options_t. */
845 : #define OR_OPTIONS_MAGIC 9090909
846 :
847 : /** Configuration format for or_options_t. */
848 : static const config_format_t options_format = {
849 : .size = sizeof(or_options_t),
850 : .magic = {
851 : "or_options_t",
852 : OR_OPTIONS_MAGIC,
853 : offsetof(or_options_t, magic_),
854 : },
855 : .abbrevs = option_abbrevs_,
856 : .deprecations = option_deprecation_notes_,
857 : .vars = option_vars_,
858 : .legacy_validate_fn = options_validate_cb,
859 : .check_transition_fn = options_check_transition_cb,
860 : .clear_fn = options_clear_cb,
861 : .has_config_suite = true,
862 : .config_suite_offset = offsetof(or_options_t, subconfigs_),
863 : };
864 :
865 : /*
866 : * Functions to read and write the global options pointer.
867 : */
868 :
869 : /** Command-line and config-file options. */
870 : static or_options_t *global_options = NULL;
871 : /** The fallback options_t object; this is where we look for options not
872 : * in torrc before we fall back to Tor's defaults. */
873 : static or_options_t *global_default_options = NULL;
874 : /** Name of most recently read torrc file. */
875 : static char *torrc_fname = NULL;
876 : /** Name of the most recently read torrc-defaults file.*/
877 : static char *torrc_defaults_fname = NULL;
878 : /** Result of parsing the command line. */
879 : static parsed_cmdline_t *global_cmdline = NULL;
880 : /** List of port_cfg_t for all configured ports. */
881 : static smartlist_t *configured_ports = NULL;
882 : /** True iff we're currently validating options, and any calls to
883 : * get_options() are likely to be bugs. */
884 : static int in_option_validation = 0;
885 : /** True iff we have run options_act_once_on_startup() */
886 : static bool have_set_startup_options = false;
887 :
888 : /* A global configuration manager to handle all configuration objects. */
889 : static config_mgr_t *options_mgr = NULL;
890 :
891 : /** Return the global configuration manager object for torrc options. */
892 : STATIC const config_mgr_t *
893 32238 : get_options_mgr(void)
894 : {
895 32238 : if (PREDICT_UNLIKELY(options_mgr == NULL)) {
896 5553 : options_mgr = config_mgr_new(&options_format);
897 5553 : int rv = subsystems_register_options_formats(options_mgr);
898 5553 : tor_assert(rv == 0);
899 5553 : config_mgr_freeze(options_mgr);
900 : }
901 32238 : return options_mgr;
902 : }
903 :
904 : #define CHECK_OPTIONS_MAGIC(opt) STMT_BEGIN \
905 : config_check_toplevel_magic(get_options_mgr(), (opt)); \
906 : STMT_END
907 :
908 : /** Returns the currently configured options. */
909 272675 : MOCK_IMPL(or_options_t *,
910 : get_options_mutable, (void))
911 : {
912 272675 : tor_assert(global_options);
913 272675 : tor_assert_nonfatal(! in_option_validation);
914 272675 : return global_options;
915 : }
916 :
917 : /** Returns the currently configured options */
918 271777 : MOCK_IMPL(const or_options_t *,
919 : get_options,(void))
920 : {
921 271777 : return get_options_mutable();
922 : }
923 :
924 : /**
925 : * True iff we have noticed that this is a testing tor network, and we
926 : * should use the corresponding defaults.
927 : **/
928 : static bool testing_network_configured = false;
929 :
930 : /** Return a set of lines for any default options that we want to override
931 : * from those set in our config_var_t values. */
932 : static config_line_t *
933 956 : get_options_defaults(void)
934 : {
935 956 : int i;
936 956 : config_line_t *result = NULL, **next = &result;
937 :
938 956 : if (testing_network_configured) {
939 0 : for (i = 0; testing_tor_network_defaults[i].k; ++i) {
940 0 : config_line_append(next,
941 : testing_tor_network_defaults[i].k,
942 0 : testing_tor_network_defaults[i].v);
943 0 : next = &(*next)->next;
944 : }
945 : }
946 :
947 956 : return result;
948 : }
949 :
950 : /** Change the current global options to contain <b>new_val</b> instead of
951 : * their current value; take action based on the new value; free the old value
952 : * as necessary. Returns 0 on success, -1 on failure.
953 : */
954 : int
955 216 : set_options(or_options_t *new_val, char **msg)
956 : {
957 216 : or_options_t *old_options = global_options;
958 216 : global_options = new_val;
959 : /* Note that we pass the *old* options below, for comparison. It
960 : * pulls the new options directly out of global_options. */
961 216 : if (options_act_reversible(old_options, msg)<0) {
962 0 : tor_assert(*msg);
963 0 : global_options = old_options;
964 0 : return -1;
965 : }
966 431 : if (subsystems_set_options(get_options_mgr(), new_val) < 0 ||
967 215 : options_act(old_options) < 0) { /* acting on the options failed. die. */
968 1 : if (! tor_event_loop_shutdown_is_pending()) {
969 1 : log_err(LD_BUG,
970 : "Acting on config options left us in a broken state. Dying.");
971 1 : tor_shutdown_event_loop_and_exit(1);
972 : }
973 1 : global_options = old_options;
974 1 : return -1;
975 : }
976 : /* Issues a CONF_CHANGED event to notify controller of the change. If Tor is
977 : * just starting up then the old_options will be undefined. */
978 215 : if (old_options && old_options != global_options) {
979 5 : config_line_t *changes =
980 5 : config_get_changes(get_options_mgr(), old_options, new_val);
981 5 : control_event_conf_changed(changes);
982 5 : config_free_lines(changes);
983 : }
984 :
985 215 : if (old_options != global_options) {
986 215 : or_options_free(old_options);
987 : /* If we are here it means we've successfully applied the new options and
988 : * that the global options have been changed to the new values. We'll
989 : * check if we need to remove or add periodic events. */
990 215 : periodic_events_on_new_options(global_options);
991 : }
992 :
993 : return 0;
994 : }
995 :
996 : /** Release additional memory allocated in options
997 : */
998 : static void
999 6591 : options_clear_cb(const config_mgr_t *mgr, void *opts)
1000 : {
1001 6591 : (void)mgr;
1002 6591 : CHECK_OPTIONS_MAGIC(opts);
1003 6591 : or_options_t *options = opts;
1004 :
1005 6591 : routerset_free(options->ExcludeExitNodesUnion_);
1006 6591 : if (options->NodeFamilySets) {
1007 12 : SMARTLIST_FOREACH(options->NodeFamilySets, routerset_t *,
1008 : rs, routerset_free(rs));
1009 6 : smartlist_free(options->NodeFamilySets);
1010 : }
1011 6591 : if (options->SchedulerTypes_) {
1012 1528 : SMARTLIST_FOREACH(options->SchedulerTypes_, int *, i, tor_free(i));
1013 382 : smartlist_free(options->SchedulerTypes_);
1014 : }
1015 6591 : if (options->FilesOpenedByIncludes) {
1016 244 : SMARTLIST_FOREACH(options->FilesOpenedByIncludes, char *, f, tor_free(f));
1017 228 : smartlist_free(options->FilesOpenedByIncludes);
1018 : }
1019 6591 : tor_free(options->DataDirectory);
1020 6591 : tor_free(options->CacheDirectory);
1021 6591 : tor_free(options->KeyDirectory);
1022 6591 : tor_free(options->BridgePassword_AuthDigest_);
1023 6591 : tor_free(options->command_arg);
1024 6591 : tor_free(options->master_key_fname);
1025 6591 : config_free_lines(options->MyFamily);
1026 6591 : }
1027 :
1028 : /** Release all memory allocated in options
1029 : */
1030 : STATIC void
1031 7309 : or_options_free_(or_options_t *options)
1032 : {
1033 7309 : config_free(get_options_mgr(), options);
1034 7309 : }
1035 :
1036 : /** Release all memory and resources held by global configuration structures.
1037 : */
1038 : void
1039 241 : config_free_all(void)
1040 : {
1041 241 : or_options_free(global_options);
1042 241 : global_options = NULL;
1043 241 : or_options_free(global_default_options);
1044 241 : global_default_options = NULL;
1045 :
1046 241 : parsed_cmdline_free(global_cmdline);
1047 :
1048 241 : if (configured_ports) {
1049 32 : SMARTLIST_FOREACH(configured_ports,
1050 : port_cfg_t *, p, port_cfg_free(p));
1051 10 : smartlist_free(configured_ports);
1052 10 : configured_ports = NULL;
1053 : }
1054 :
1055 241 : tor_free(torrc_fname);
1056 241 : tor_free(torrc_defaults_fname);
1057 :
1058 241 : cleanup_protocol_warning_severity_level();
1059 :
1060 241 : have_set_startup_options = false;
1061 :
1062 241 : config_mgr_free(options_mgr);
1063 241 : }
1064 :
1065 : /** Make <b>address</b> -- a piece of information related to our operation as
1066 : * a client -- safe to log according to the settings in options->SafeLogging,
1067 : * and return it.
1068 : *
1069 : * (We return "[scrubbed]" if SafeLogging is "1", and address otherwise.)
1070 : */
1071 : const char *
1072 1488 : safe_str_client_opts(const or_options_t *options, const char *address)
1073 : {
1074 1488 : tor_assert(address);
1075 1488 : if (!options) {
1076 1488 : options = get_options();
1077 : }
1078 :
1079 1488 : if (options->SafeLogging_ == SAFELOG_SCRUB_ALL)
1080 : return "[scrubbed]";
1081 : else
1082 0 : return address;
1083 : }
1084 :
1085 : /** Make <b>address</b> -- a piece of information of unspecified sensitivity
1086 : * -- safe to log according to the settings in options->SafeLogging, and
1087 : * return it.
1088 : *
1089 : * (We return "[scrubbed]" if SafeLogging is anything besides "0", and address
1090 : * otherwise.)
1091 : */
1092 : const char *
1093 54 : safe_str_opts(const or_options_t *options, const char *address)
1094 : {
1095 54 : tor_assert(address);
1096 54 : if (!options) {
1097 54 : options = get_options();
1098 : }
1099 :
1100 54 : if (options->SafeLogging_ != SAFELOG_SCRUB_NONE)
1101 : return "[scrubbed]";
1102 : else
1103 16 : return address;
1104 : }
1105 :
1106 : /** Equivalent to escaped(safe_str_client(address)). See reentrancy note on
1107 : * escaped(): don't use this outside the main thread, or twice in the same
1108 : * log statement. */
1109 : const char *
1110 255 : escaped_safe_str_client(const char *address)
1111 : {
1112 255 : if (get_options()->SafeLogging_ == SAFELOG_SCRUB_ALL)
1113 : return "[scrubbed]";
1114 : else
1115 0 : return escaped(address);
1116 : }
1117 :
1118 : /** Equivalent to escaped(safe_str(address)). See reentrancy note on
1119 : * escaped(): don't use this outside the main thread, or twice in the same
1120 : * log statement. */
1121 : const char *
1122 14 : escaped_safe_str(const char *address)
1123 : {
1124 14 : if (get_options()->SafeLogging_ != SAFELOG_SCRUB_NONE)
1125 : return "[scrubbed]";
1126 : else
1127 0 : return escaped(address);
1128 : }
1129 :
1130 : /**
1131 : * The severity level that should be used for warnings of severity
1132 : * LOG_PROTOCOL_WARN.
1133 : *
1134 : * We keep this outside the options, and we use an atomic_counter_t, in case
1135 : * one thread needs to use LOG_PROTOCOL_WARN while an option transition is
1136 : * happening in the main thread.
1137 : */
1138 : static atomic_counter_t protocol_warning_severity_level;
1139 :
1140 : /** Return the severity level that should be used for warnings of severity
1141 : * LOG_PROTOCOL_WARN. */
1142 : int
1143 423 : get_protocol_warning_severity_level(void)
1144 : {
1145 423 : return (int) atomic_counter_get(&protocol_warning_severity_level);
1146 : }
1147 :
1148 : /** Set the protocol warning severity level to <b>severity</b>. */
1149 : static void
1150 5766 : set_protocol_warning_severity_level(int warning_severity)
1151 : {
1152 5766 : atomic_counter_exchange(&protocol_warning_severity_level,
1153 : warning_severity);
1154 5766 : }
1155 :
1156 : /**
1157 : * Initialize the log warning severity level for protocol warnings. Call
1158 : * only once at startup.
1159 : */
1160 : void
1161 5553 : init_protocol_warning_severity_level(void)
1162 : {
1163 5553 : atomic_counter_init(&protocol_warning_severity_level);
1164 5553 : set_protocol_warning_severity_level(LOG_WARN);
1165 5553 : }
1166 :
1167 : /**
1168 : * Tear down protocol_warning_severity_level.
1169 : */
1170 : static void
1171 : cleanup_protocol_warning_severity_level(void)
1172 : {
1173 : /* Destroying a locked mutex is undefined behaviour. This mutex may be
1174 : * locked, because multiple threads can access it. But we need to destroy
1175 : * it, otherwise re-initialisation will trigger undefined behaviour.
1176 : * See #31735 for details. */
1177 : atomic_counter_destroy(&protocol_warning_severity_level);
1178 : }
1179 :
1180 : /** Add the default directory authorities directly into the trusted dir list,
1181 : * but only add them insofar as they share bits with <b>type</b>.
1182 : * Each authority's bits are restricted to the bits shared with <b>type</b>.
1183 : * If <b>type</b> is ALL_DIRINFO or NO_DIRINFO (zero), add all authorities. */
1184 : STATIC void
1185 224 : add_default_trusted_dir_authorities(dirinfo_type_t type)
1186 : {
1187 224 : int i;
1188 2464 : for (i=0; default_authorities[i]; i++) {
1189 2240 : if (parse_dir_authority_line(default_authorities[i], type, 0)<0) {
1190 0 : log_err(LD_BUG, "Couldn't parse internal DirAuthority line %s",
1191 : default_authorities[i]);
1192 : }
1193 : }
1194 224 : }
1195 :
1196 : /** Add the default fallback directory servers into the fallback directory
1197 : * server list. */
1198 211 : MOCK_IMPL(void,
1199 : add_default_fallback_dir_servers,(void))
1200 : {
1201 211 : int i;
1202 42411 : for (i=0; default_fallbacks[i]; i++) {
1203 42200 : if (parse_dir_fallback_line(default_fallbacks[i], 0)<0) {
1204 0 : log_err(LD_BUG, "Couldn't parse internal FallbackDir line %s",
1205 : default_fallbacks[i]);
1206 : }
1207 : }
1208 211 : }
1209 :
1210 : /** Look at all the config options for using alternate directory
1211 : * authorities, and make sure none of them are broken. Also, warn the
1212 : * user if we changed any dangerous ones.
1213 : */
1214 : static int
1215 452 : validate_dir_servers(const or_options_t *options,
1216 : const or_options_t *old_options)
1217 : {
1218 452 : config_line_t *cl;
1219 :
1220 452 : if (options->DirAuthorities &&
1221 50 : (options->AlternateDirAuthority || options->AlternateBridgeAuthority)) {
1222 1 : log_warn(LD_CONFIG,
1223 : "You cannot set both DirAuthority and Alternate*Authority.");
1224 1 : return -1;
1225 : }
1226 :
1227 : /* do we want to complain to the user about being partitionable? */
1228 451 : if ((options->DirAuthorities &&
1229 0 : (!old_options ||
1230 0 : !config_lines_eq(options->DirAuthorities,
1231 0 : old_options->DirAuthorities))) ||
1232 402 : (options->AlternateDirAuthority &&
1233 0 : (!old_options ||
1234 0 : !config_lines_eq(options->AlternateDirAuthority,
1235 0 : old_options->AlternateDirAuthority)))) {
1236 51 : log_warn(LD_CONFIG,
1237 : "You have used DirAuthority or AlternateDirAuthority to "
1238 : "specify alternate directory authorities in "
1239 : "your configuration. This is potentially dangerous: it can "
1240 : "make you look different from all other Tor users, and hurt "
1241 : "your anonymity. Even if you've specified the same "
1242 : "authorities as Tor uses by default, the defaults could "
1243 : "change in the future. Be sure you know what you're doing.");
1244 : }
1245 :
1246 : /* Now go through the four ways you can configure an alternate
1247 : * set of directory authorities, and make sure none are broken. */
1248 500 : for (cl = options->DirAuthorities; cl; cl = cl->next)
1249 49 : if (parse_dir_authority_line(cl->value, NO_DIRINFO, 1)<0)
1250 : return -1;
1251 453 : for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
1252 2 : if (parse_dir_authority_line(cl->value, NO_DIRINFO, 1)<0)
1253 : return -1;
1254 453 : for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
1255 2 : if (parse_dir_authority_line(cl->value, NO_DIRINFO, 1)<0)
1256 : return -1;
1257 451 : for (cl = options->FallbackDir; cl; cl = cl->next)
1258 0 : if (parse_dir_fallback_line(cl->value, 1)<0)
1259 : return -1;
1260 : return 0;
1261 : }
1262 :
1263 : /** Look at all the config options and assign new dir authorities
1264 : * as appropriate.
1265 : */
1266 : int
1267 227 : consider_adding_dir_servers(const or_options_t *options,
1268 : const or_options_t *old_options)
1269 : {
1270 227 : config_line_t *cl;
1271 679 : int need_to_update =
1272 227 : !smartlist_len(router_get_trusted_dir_servers()) ||
1273 5 : !smartlist_len(router_get_fallback_dir_servers()) || !old_options ||
1274 4 : !config_lines_eq(options->DirAuthorities, old_options->DirAuthorities) ||
1275 2 : !config_lines_eq(options->FallbackDir, old_options->FallbackDir) ||
1276 4 : (options->UseDefaultFallbackDirs != old_options->UseDefaultFallbackDirs) ||
1277 2 : !config_lines_eq(options->AlternateBridgeAuthority,
1278 231 : old_options->AlternateBridgeAuthority) ||
1279 2 : !config_lines_eq(options->AlternateDirAuthority,
1280 2 : old_options->AlternateDirAuthority);
1281 :
1282 225 : if (!need_to_update)
1283 : return 0; /* all done */
1284 :
1285 : /* "You cannot set both DirAuthority and Alternate*Authority."
1286 : * Checking that this restriction holds allows us to simplify
1287 : * the unit tests. */
1288 225 : tor_assert(!(options->DirAuthorities &&
1289 : (options->AlternateDirAuthority
1290 : || options->AlternateBridgeAuthority)));
1291 :
1292 : /* Start from a clean slate. */
1293 225 : clear_dir_servers();
1294 :
1295 225 : if (!options->DirAuthorities) {
1296 : /* then we may want some of the defaults */
1297 223 : dirinfo_type_t type = NO_DIRINFO;
1298 223 : if (!options->AlternateBridgeAuthority) {
1299 219 : type |= BRIDGE_DIRINFO;
1300 : }
1301 223 : if (!options->AlternateDirAuthority) {
1302 219 : type |= V3_DIRINFO | EXTRAINFO_DIRINFO | MICRODESC_DIRINFO;
1303 : /* Only add the default fallback directories when the DirAuthorities,
1304 : * AlternateDirAuthority, and FallbackDir directory config options
1305 : * are set to their defaults, and when UseDefaultFallbackDirs is 1. */
1306 219 : if (!options->FallbackDir && options->UseDefaultFallbackDirs) {
1307 213 : add_default_fallback_dir_servers();
1308 : }
1309 : }
1310 : /* if type == NO_DIRINFO, we don't want to add any of the
1311 : * default authorities, because we've replaced them all */
1312 223 : if (type != NO_DIRINFO)
1313 221 : add_default_trusted_dir_authorities(type);
1314 : }
1315 :
1316 227 : for (cl = options->DirAuthorities; cl; cl = cl->next)
1317 2 : if (parse_dir_authority_line(cl->value, NO_DIRINFO, 0)<0)
1318 : return -1;
1319 229 : for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
1320 4 : if (parse_dir_authority_line(cl->value, NO_DIRINFO, 0)<0)
1321 : return -1;
1322 229 : for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
1323 4 : if (parse_dir_authority_line(cl->value, NO_DIRINFO, 0)<0)
1324 : return -1;
1325 230 : for (cl = options->FallbackDir; cl; cl = cl->next)
1326 5 : if (parse_dir_fallback_line(cl->value, 0)<0)
1327 : return -1;
1328 : return 0;
1329 : }
1330 :
1331 : /**
1332 : * Make sure that <b>directory</b> exists, with appropriate ownership and
1333 : * permissions (as modified by <b>group_readable</b>). If <b>create</b>,
1334 : * create the directory if it is missing. Return 0 on success.
1335 : * On failure, return -1 and set *<b>msg_out</b>.
1336 : */
1337 : static int
1338 657 : check_and_create_data_directory(int create,
1339 : const char *directory,
1340 : int group_readable,
1341 : const char *owner,
1342 : char **msg_out)
1343 : {
1344 657 : cpd_check_t cpd_opts = create ? CPD_CREATE : CPD_CHECK;
1345 657 : if (group_readable)
1346 6 : cpd_opts |= CPD_GROUP_READ;
1347 657 : if (check_private_dir(directory,
1348 : cpd_opts,
1349 : owner) < 0) {
1350 3 : tor_asprintf(msg_out,
1351 : "Couldn't %s private data directory \"%s\"",
1352 : create ? "create" : "access",
1353 : directory);
1354 3 : return -1;
1355 : }
1356 :
1357 : #ifndef _WIN32
1358 654 : if (group_readable) {
1359 : /* Only new dirs created get new opts, also enforce group read. */
1360 6 : if (chmod(directory, 0750)) {
1361 0 : log_warn(LD_FS,"Unable to make %s group-readable: %s",
1362 : directory, strerror(errno));
1363 : }
1364 : }
1365 : #endif /* !defined(_WIN32) */
1366 :
1367 : return 0;
1368 : }
1369 :
1370 : /**
1371 : * Ensure that our keys directory exists, with appropriate permissions.
1372 : * Return 0 on success, -1 on failure.
1373 : */
1374 : int
1375 70 : create_keys_directory(const or_options_t *options)
1376 : {
1377 : /* Make sure DataDirectory exists, and is private. */
1378 70 : cpd_check_t cpd_opts = CPD_CREATE;
1379 70 : if (options->DataDirectoryGroupReadable)
1380 0 : cpd_opts |= CPD_GROUP_READ;
1381 70 : if (check_private_dir(options->DataDirectory, cpd_opts, options->User)) {
1382 0 : log_err(LD_OR, "Can't create/check datadirectory %s",
1383 : options->DataDirectory);
1384 0 : return -1;
1385 : }
1386 :
1387 : /* Check the key directory. */
1388 70 : if (check_private_dir(options->KeyDirectory, CPD_CREATE, options->User)) {
1389 0 : return -1;
1390 : }
1391 : return 0;
1392 : }
1393 :
1394 : /* Helps determine flags to pass to switch_id. */
1395 : static int have_low_ports = -1;
1396 :
1397 : /** Take case of initial startup tasks that must occur before any of the
1398 : * transactional option-related changes are allowed. */
1399 : static int
1400 214 : options_act_once_on_startup(char **msg_out)
1401 : {
1402 214 : if (have_set_startup_options)
1403 : return 0;
1404 :
1405 214 : const or_options_t *options = get_options();
1406 214 : const bool running_tor = options->command == CMD_RUN_TOR;
1407 :
1408 214 : if (!running_tor)
1409 : return 0;
1410 :
1411 : /* Daemonize _first_, since we only want to open most of this stuff in
1412 : * the subprocess. Libevent bases can't be reliably inherited across
1413 : * processes. */
1414 4 : if (options->RunAsDaemon) {
1415 0 : if (! start_daemon_has_been_called())
1416 0 : subsystems_prefork();
1417 : /* No need to roll back, since you can't change the value. */
1418 0 : if (start_daemon())
1419 0 : subsystems_postfork();
1420 : }
1421 :
1422 : #ifdef HAVE_SYSTEMD
1423 : /* Our PID may have changed, inform supervisor */
1424 4 : sd_notifyf(0, "MAINPID=%ld\n", (long int)getpid());
1425 : #endif
1426 :
1427 : /* Set up libevent. (We need to do this before we can register the
1428 : * listeners as listeners.) */
1429 4 : init_libevent(options);
1430 :
1431 : /* This has to come up after libevent is initialized. */
1432 4 : control_initialize_event_queue();
1433 :
1434 : /*
1435 : * Initialize the scheduler - this has to come after
1436 : * options_init_from_torrc() sets up libevent - why yes, that seems
1437 : * completely sensible to hide the libevent setup in the option parsing
1438 : * code! It also needs to happen before init_keys(), so it needs to
1439 : * happen here too. How yucky. */
1440 4 : scheduler_init();
1441 :
1442 : /* Attempt to lock all current and future memory with mlockall() only once.
1443 : * This must happen before setuid. */
1444 4 : if (options->DisableAllSwap) {
1445 0 : if (tor_mlockall() == -1) {
1446 0 : *msg_out = tor_strdup("DisableAllSwap failure. Do you have proper "
1447 : "permissions?");
1448 0 : return -1;
1449 : }
1450 : }
1451 :
1452 4 : have_set_startup_options = true;
1453 4 : return 0;
1454 : }
1455 :
1456 : /**
1457 : * Change our user ID if we're configured to do so.
1458 : **/
1459 : static int
1460 214 : options_switch_id(char **msg_out)
1461 : {
1462 214 : const or_options_t *options = get_options();
1463 :
1464 : /* Setuid/setgid as appropriate */
1465 214 : if (options->User) {
1466 0 : tor_assert(have_low_ports != -1);
1467 0 : unsigned switch_id_flags = 0;
1468 0 : if (options->KeepBindCapabilities == 1) {
1469 0 : switch_id_flags |= SWITCH_ID_KEEP_BINDLOW;
1470 0 : switch_id_flags |= SWITCH_ID_WARN_IF_NO_CAPS;
1471 : }
1472 0 : if (options->KeepBindCapabilities == -1 && have_low_ports) {
1473 0 : switch_id_flags |= SWITCH_ID_KEEP_BINDLOW;
1474 : }
1475 0 : if (switch_id(options->User, switch_id_flags) != 0) {
1476 : /* No need to roll back, since you can't change the value. */
1477 0 : *msg_out = tor_strdup("Problem with User value. See logs for details.");
1478 0 : return -1;
1479 : }
1480 : }
1481 :
1482 : return 0;
1483 : }
1484 :
1485 : /**
1486 : * Helper. Given a data directory (<b>datadir</b>) and another directory
1487 : * (<b>subdir</b>) with respective group-writable permissions
1488 : * <b>datadir_gr</b> and <b>subdir_gr</b>, compute whether the subdir should
1489 : * be group-writeable.
1490 : **/
1491 : static int
1492 437 : compute_group_readable_flag(const char *datadir,
1493 : const char *subdir,
1494 : int datadir_gr,
1495 : int subdir_gr)
1496 : {
1497 437 : if (subdir_gr != -1) {
1498 : /* The user specified a default for "subdir", so we always obey it. */
1499 : return subdir_gr;
1500 : }
1501 :
1502 : /* The user left the subdir_gr option on "auto." */
1503 431 : if (0 == strcmp(subdir, datadir)) {
1504 : /* The directories are the same, so we use the group-readable flag from
1505 : * the datadirectory */
1506 : return datadir_gr;
1507 : } else {
1508 : /* The directories are different, so we default to "not group-readable" */
1509 217 : return 0;
1510 : }
1511 : }
1512 :
1513 : /**
1514 : * Create our DataDirectory, CacheDirectory, and KeyDirectory, and
1515 : * set their permissions correctly.
1516 : */
1517 : STATIC int
1518 220 : options_create_directories(char **msg_out)
1519 : {
1520 220 : const or_options_t *options = get_options();
1521 220 : const bool running_tor = options->command == CMD_RUN_TOR;
1522 :
1523 : /* Ensure data directory is private; create if possible. */
1524 : /* It's okay to do this in "options_act_reversible()" even though it isn't
1525 : * actually reversible, since you can't change the DataDirectory while
1526 : * Tor is running. */
1527 220 : if (check_and_create_data_directory(running_tor /* create */,
1528 220 : options->DataDirectory,
1529 220 : options->DataDirectoryGroupReadable,
1530 220 : options->User,
1531 : msg_out) < 0) {
1532 : return -1;
1533 : }
1534 :
1535 : /* We need to handle the group-readable flag for the cache directory and key
1536 : * directory specially, since they may be the same as the data directory */
1537 219 : const int key_dir_group_readable = compute_group_readable_flag(
1538 219 : options->DataDirectory,
1539 219 : options->KeyDirectory,
1540 219 : options->DataDirectoryGroupReadable,
1541 219 : options->KeyDirectoryGroupReadable);
1542 :
1543 219 : if (check_and_create_data_directory(running_tor /* create */,
1544 : options->KeyDirectory,
1545 : key_dir_group_readable,
1546 219 : options->User,
1547 : msg_out) < 0) {
1548 : return -1;
1549 : }
1550 :
1551 218 : const int cache_dir_group_readable = compute_group_readable_flag(
1552 218 : options->DataDirectory,
1553 218 : options->CacheDirectory,
1554 218 : options->DataDirectoryGroupReadable,
1555 218 : options->CacheDirectoryGroupReadable);
1556 :
1557 218 : if (check_and_create_data_directory(running_tor /* create */,
1558 : options->CacheDirectory,
1559 : cache_dir_group_readable,
1560 218 : options->User,
1561 : msg_out) < 0) {
1562 1 : return -1;
1563 : }
1564 :
1565 : return 0;
1566 : }
1567 :
1568 : /** Structure to represent an incomplete configuration of a set of
1569 : * listeners.
1570 : *
1571 : * This structure is generated by options_start_listener_transaction(), and is
1572 : * either committed by options_commit_listener_transaction() or rolled back by
1573 : * options_rollback_listener_transaction(). */
1574 : typedef struct listener_transaction_t {
1575 : bool set_conn_limit; /**< True if we've set the connection limit */
1576 : unsigned old_conn_limit; /**< If nonzero, previous connlimit value. */
1577 : smartlist_t *new_listeners; /**< List of new listeners that we opened. */
1578 : } listener_transaction_t;
1579 :
1580 : /**
1581 : * Start configuring our listeners based on the current value of
1582 : * get_options().
1583 : *
1584 : * The value <b>old_options</b> holds either the previous options object,
1585 : * or NULL if we're starting for the first time.
1586 : *
1587 : * On success, return a listener_transaction_t that we can either roll back or
1588 : * commit.
1589 : *
1590 : * On failure return NULL and write a message into a newly allocated string in
1591 : * *<b>msg_out</b>.
1592 : **/
1593 : static listener_transaction_t *
1594 214 : options_start_listener_transaction(const or_options_t *old_options,
1595 : char **msg_out)
1596 : {
1597 214 : listener_transaction_t *xn = tor_malloc_zero(sizeof(listener_transaction_t));
1598 214 : xn->new_listeners = smartlist_new();
1599 214 : or_options_t *options = get_options_mutable();
1600 214 : const bool running_tor = options->command == CMD_RUN_TOR;
1601 :
1602 214 : if (! running_tor) {
1603 : return xn;
1604 : }
1605 :
1606 4 : int n_ports=0;
1607 : /* We need to set the connection limit before we can open the listeners. */
1608 4 : if (! sandbox_is_active()) {
1609 4 : if (set_max_file_descriptors((unsigned)options->ConnLimit,
1610 : &options->ConnLimit_) < 0) {
1611 0 : *msg_out = tor_strdup("Problem with ConnLimit value. "
1612 : "See logs for details.");
1613 0 : goto rollback;
1614 : }
1615 4 : xn->set_conn_limit = true;
1616 4 : if (old_options)
1617 0 : xn->old_conn_limit = (unsigned)old_options->ConnLimit;
1618 : } else {
1619 0 : tor_assert(old_options);
1620 0 : options->ConnLimit_ = old_options->ConnLimit_;
1621 : }
1622 :
1623 : /* Adjust the port configuration so we can launch listeners. */
1624 : /* 31851: some ports are relay-only */
1625 4 : if (parse_ports(options, 0, msg_out, &n_ports, NULL)) {
1626 0 : if (!*msg_out)
1627 0 : *msg_out = tor_strdup("Unexpected problem parsing port config");
1628 0 : goto rollback;
1629 : }
1630 :
1631 : /* Set the hibernation state appropriately.*/
1632 4 : consider_hibernation(time(NULL));
1633 :
1634 : /* Launch the listeners. (We do this before we setuid, so we can bind to
1635 : * ports under 1024.) We don't want to rebind if we're hibernating or
1636 : * shutting down. If networking is disabled, this will close all but the
1637 : * control listeners, but disable those. */
1638 : /* 31851: some listeners are relay-only */
1639 4 : if (!we_are_hibernating()) {
1640 4 : if (retry_all_listeners(xn->new_listeners,
1641 : options->DisableNetwork) < 0) {
1642 0 : *msg_out = tor_strdup("Failed to bind one of the listener ports.");
1643 0 : goto rollback;
1644 : }
1645 : }
1646 4 : if (options->DisableNetwork) {
1647 : /* Aggressively close non-controller stuff, NOW */
1648 4 : log_notice(LD_NET, "DisableNetwork is set. Tor will not make or accept "
1649 : "non-control network connections. Shutting down all existing "
1650 : "connections.");
1651 4 : connection_mark_all_noncontrol_connections();
1652 : /* We can't complete circuits until the network is re-enabled. */
1653 4 : note_that_we_maybe_cant_complete_circuits();
1654 : }
1655 :
1656 : #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
1657 : /* Open /dev/pf before (possibly) dropping privileges. */
1658 : if (options->TransPort_set &&
1659 : options->TransProxyType_parsed == TPT_DEFAULT) {
1660 : if (get_pf_socket() < 0) {
1661 : *msg_out = tor_strdup("Unable to open /dev/pf for transparent proxy.");
1662 : goto rollback;
1663 : }
1664 : }
1665 : #endif /* defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H) */
1666 :
1667 : return xn;
1668 :
1669 0 : rollback:
1670 0 : options_rollback_listener_transaction(xn);
1671 0 : return NULL;
1672 : }
1673 :
1674 : /**
1675 : * Finish configuring the listeners that started to get configured with
1676 : * <b>xn</b>. Frees <b>xn</b>.
1677 : **/
1678 : static void
1679 214 : options_commit_listener_transaction(listener_transaction_t *xn)
1680 : {
1681 214 : tor_assert(xn);
1682 214 : if (xn->set_conn_limit) {
1683 4 : or_options_t *options = get_options_mutable();
1684 : /*
1685 : * If we adjusted the conn limit, recompute the OOS threshold too
1686 : *
1687 : * How many possible sockets to keep in reserve? If we have lots of
1688 : * possible sockets, keep this below a limit and set ConnLimit_high_thresh
1689 : * very close to ConnLimit_, but if ConnLimit_ is low, shrink it in
1690 : * proportion.
1691 : *
1692 : * Somewhat arbitrarily, set socks_in_reserve to 5% of ConnLimit_, but
1693 : * cap it at 64.
1694 : */
1695 4 : int socks_in_reserve = options->ConnLimit_ / 20;
1696 4 : if (socks_in_reserve > 64) socks_in_reserve = 64;
1697 :
1698 4 : options->ConnLimit_high_thresh = options->ConnLimit_ - socks_in_reserve;
1699 4 : options->ConnLimit_low_thresh = (options->ConnLimit_ / 4) * 3;
1700 4 : log_info(LD_GENERAL,
1701 : "Recomputed OOS thresholds: ConnLimit %d, ConnLimit_ %d, "
1702 : "ConnLimit_high_thresh %d, ConnLimit_low_thresh %d",
1703 : options->ConnLimit, options->ConnLimit_,
1704 : options->ConnLimit_high_thresh,
1705 : options->ConnLimit_low_thresh);
1706 :
1707 : /* Give the OOS handler a chance with the new thresholds */
1708 4 : connection_check_oos(get_n_open_sockets(), 0);
1709 : }
1710 :
1711 214 : smartlist_free(xn->new_listeners);
1712 214 : tor_free(xn);
1713 214 : }
1714 :
1715 : /**
1716 : * Revert the listener configuration changes that that started to get
1717 : * configured with <b>xn</b>. Frees <b>xn</b>.
1718 : **/
1719 : static void
1720 0 : options_rollback_listener_transaction(listener_transaction_t *xn)
1721 : {
1722 0 : if (! xn)
1723 : return;
1724 :
1725 0 : or_options_t *options = get_options_mutable();
1726 :
1727 0 : if (xn->set_conn_limit && xn->old_conn_limit)
1728 0 : set_max_file_descriptors(xn->old_conn_limit, &options->ConnLimit_);
1729 :
1730 0 : SMARTLIST_FOREACH(xn->new_listeners, connection_t *, conn,
1731 : {
1732 : log_notice(LD_NET, "Closing partially-constructed %s",
1733 : connection_describe(conn));
1734 : connection_close_immediate(conn);
1735 : connection_mark_for_close(conn);
1736 : });
1737 :
1738 0 : smartlist_free(xn->new_listeners);
1739 0 : tor_free(xn);
1740 : }
1741 :
1742 : /** Structure to represent an incomplete configuration of a set of logs.
1743 : *
1744 : * This structure is generated by options_start_log_transaction(), and is
1745 : * either committed by options_commit_log_transaction() or rolled back by
1746 : * options_rollback_log_transaction(). */
1747 : typedef struct log_transaction_t {
1748 : /** Previous lowest severity of any configured log. */
1749 : int old_min_log_level;
1750 : /** True if we have marked the previous logs to be closed */
1751 : bool logs_marked;
1752 : /** True if we initialized the new set of logs */
1753 : bool logs_initialized;
1754 : /** True if our safelogging configuration is different from what it was
1755 : * previously (or if we are starting for the first time). */
1756 : bool safelogging_changed;
1757 : } log_transaction_t;
1758 :
1759 : /**
1760 : * Start configuring our logs based on the current value of get_options().
1761 : *
1762 : * The value <b>old_options</b> holds either the previous options object,
1763 : * or NULL if we're starting for the first time.
1764 : *
1765 : * On success, return a log_transaction_t that we can either roll back or
1766 : * commit.
1767 : *
1768 : * On failure return NULL and write a message into a newly allocated string in
1769 : * *<b>msg_out</b>.
1770 : **/
1771 : STATIC log_transaction_t *
1772 219 : options_start_log_transaction(const or_options_t *old_options,
1773 : char **msg_out)
1774 : {
1775 219 : const or_options_t *options = get_options();
1776 219 : const bool running_tor = options->command == CMD_RUN_TOR;
1777 :
1778 219 : log_transaction_t *xn = tor_malloc_zero(sizeof(log_transaction_t));
1779 219 : xn->old_min_log_level = get_min_log_level();
1780 219 : xn->safelogging_changed = !old_options ||
1781 7 : old_options->SafeLogging_ != options->SafeLogging_;
1782 :
1783 219 : if (! running_tor)
1784 210 : goto done;
1785 :
1786 9 : mark_logs_temp(); /* Close current logs once new logs are open. */
1787 9 : xn->logs_marked = true;
1788 : /* Configure the tor_log(s) */
1789 9 : if (options_init_logs(old_options, options, 0)<0) {
1790 1 : *msg_out = tor_strdup("Failed to init Log options. See logs for details.");
1791 1 : options_rollback_log_transaction(xn);
1792 1 : xn = NULL;
1793 1 : goto done;
1794 : }
1795 :
1796 8 : xn->logs_initialized = true;
1797 :
1798 219 : done:
1799 219 : return xn;
1800 : }
1801 :
1802 : /**
1803 : * Finish configuring the logs that started to get configured with <b>xn</b>.
1804 : * Frees <b>xn</b>.
1805 : **/
1806 : STATIC void
1807 217 : options_commit_log_transaction(log_transaction_t *xn)
1808 : {
1809 217 : const or_options_t *options = get_options();
1810 217 : tor_assert(xn);
1811 :
1812 217 : if (xn->logs_marked) {
1813 14 : log_severity_list_t *severity =
1814 7 : tor_malloc_zero(sizeof(log_severity_list_t));
1815 7 : close_temp_logs();
1816 7 : add_callback_log(severity, control_event_logmsg);
1817 7 : logs_set_pending_callback_callback(control_event_logmsg_pending);
1818 7 : control_adjust_event_log_severity();
1819 7 : tor_free(severity);
1820 7 : tor_log_update_sigsafe_err_fds();
1821 : }
1822 :
1823 217 : if (xn->logs_initialized) {
1824 7 : flush_log_messages_from_startup();
1825 : }
1826 :
1827 : {
1828 217 : const char *badness = NULL;
1829 217 : int bad_safelog = 0, bad_severity = 0, new_badness = 0;
1830 217 : if (options->SafeLogging_ != SAFELOG_SCRUB_ALL) {
1831 4 : bad_safelog = 1;
1832 4 : if (xn->safelogging_changed)
1833 4 : new_badness = 1;
1834 : }
1835 217 : if (get_min_log_level() >= LOG_INFO) {
1836 2 : bad_severity = 1;
1837 2 : if (get_min_log_level() != xn->old_min_log_level)
1838 1 : new_badness = 1;
1839 : }
1840 217 : if (bad_safelog && bad_severity)
1841 : badness = "you disabled SafeLogging, and "
1842 : "you're logging more than \"notice\"";
1843 216 : else if (bad_safelog)
1844 : badness = "you disabled SafeLogging";
1845 : else
1846 213 : badness = "you're logging more than \"notice\"";
1847 217 : if (new_badness)
1848 5 : log_warn(LD_GENERAL, "Your log may contain sensitive information - %s. "
1849 : "Don't log unless it serves an important reason. "
1850 : "Overwrite the log afterwards.", badness);
1851 : }
1852 :
1853 217 : tor_free(xn);
1854 217 : }
1855 :
1856 : /**
1857 : * Revert the log configuration changes that that started to get configured
1858 : * with <b>xn</b>. Frees <b>xn</b>.
1859 : **/
1860 : STATIC void
1861 2 : options_rollback_log_transaction(log_transaction_t *xn)
1862 : {
1863 2 : if (!xn)
1864 : return;
1865 :
1866 2 : if (xn->logs_marked) {
1867 2 : rollback_log_changes();
1868 2 : control_adjust_event_log_severity();
1869 : }
1870 :
1871 2 : tor_free(xn);
1872 : }
1873 :
1874 : /**
1875 : * Fetch the active option list, and take actions based on it. All of
1876 : * the things we do in this function should survive being done
1877 : * repeatedly, OR be done only once when starting Tor. If present,
1878 : * <b>old_options</b> contains the previous value of the options.
1879 : *
1880 : * This function is only truly "reversible" _after_ the first time it
1881 : * is run. The first time that it runs, it performs some irreversible
1882 : * tasks in the correct sequence between the reversible option changes.
1883 : *
1884 : * Option changes should only be marked as "reversible" if they cannot
1885 : * be validated before switching them, but they can be switched back if
1886 : * some other validation fails.
1887 : *
1888 : * Return 0 if all goes well, return -1 if things went badly.
1889 : */
1890 214 : MOCK_IMPL(STATIC int,
1891 : options_act_reversible,(const or_options_t *old_options, char **msg))
1892 : {
1893 214 : const bool first_time = ! have_set_startup_options;
1894 214 : log_transaction_t *log_transaction = NULL;
1895 214 : listener_transaction_t *listener_transaction = NULL;
1896 214 : int r = -1;
1897 :
1898 : /* The ordering of actions in this function is not free, sadly.
1899 : *
1900 : * First of all, we _must_ daemonize before we take all kinds of
1901 : * initialization actions, since they need to happen in the
1902 : * subprocess.
1903 : */
1904 214 : if (options_act_once_on_startup(msg) < 0)
1905 0 : goto rollback;
1906 :
1907 : /* Once we've handled most of once-off initialization, we need to
1908 : * open our listeners before we switch IDs. (If we open listeners first,
1909 : * we might not be able to bind to low ports.)
1910 : */
1911 214 : listener_transaction = options_start_listener_transaction(old_options, msg);
1912 214 : if (listener_transaction == NULL)
1913 0 : goto rollback;
1914 :
1915 214 : if (first_time) {
1916 214 : if (options_switch_id(msg) < 0)
1917 0 : goto rollback;
1918 : }
1919 :
1920 : /* On the other hand, we need to touch the file system _after_ we
1921 : * switch IDs: otherwise, we'll be making directories and opening files
1922 : * with the wrong permissions.
1923 : */
1924 214 : if (first_time) {
1925 214 : if (options_create_directories(msg) < 0)
1926 0 : goto rollback;
1927 : }
1928 :
1929 : /* Bail out at this point if we're not going to be a client or server:
1930 : * we don't run Tor itself. */
1931 214 : log_transaction = options_start_log_transaction(old_options, msg);
1932 214 : if (log_transaction == NULL)
1933 0 : goto rollback;
1934 :
1935 : // Commit!
1936 214 : r = 0;
1937 :
1938 214 : options_commit_log_transaction(log_transaction);
1939 :
1940 214 : options_commit_listener_transaction(listener_transaction);
1941 :
1942 214 : goto done;
1943 :
1944 0 : rollback:
1945 0 : r = -1;
1946 0 : tor_assert(*msg);
1947 :
1948 0 : options_rollback_log_transaction(log_transaction);
1949 0 : options_rollback_listener_transaction(listener_transaction);
1950 :
1951 214 : done:
1952 214 : return r;
1953 : }
1954 :
1955 : /** If we need to have a GEOIP ip-to-country map to run with our configured
1956 : * options, return 1 and set *<b>reason_out</b> to a description of why. */
1957 : int
1958 8 : options_need_geoip_info(const or_options_t *options, const char **reason_out)
1959 : {
1960 8 : int bridge_usage = should_record_bridge_info(options);
1961 16 : int routerset_usage =
1962 16 : routerset_needs_geoip(options->EntryNodes) ||
1963 16 : routerset_needs_geoip(options->ExitNodes) ||
1964 16 : routerset_needs_geoip(options->MiddleNodes) ||
1965 16 : routerset_needs_geoip(options->ExcludeExitNodes) ||
1966 16 : routerset_needs_geoip(options->ExcludeNodes) ||
1967 24 : routerset_needs_geoip(options->HSLayer2Nodes) ||
1968 8 : routerset_needs_geoip(options->HSLayer3Nodes);
1969 :
1970 8 : if (routerset_usage && reason_out) {
1971 0 : *reason_out = "We've been configured to use (or avoid) nodes in certain "
1972 : "countries, and we need GEOIP information to figure out which ones they "
1973 : "are.";
1974 8 : } else if (bridge_usage && reason_out) {
1975 0 : *reason_out = "We've been configured to see which countries can access "
1976 : "us as a bridge, and we need GEOIP information to tell which countries "
1977 : "clients are in.";
1978 : }
1979 8 : return bridge_usage || routerset_usage;
1980 : }
1981 :
1982 : /* Used in the various options_transition_affects* functions. */
1983 : #define YES_IF_CHANGED_BOOL(opt) \
1984 : if (!CFG_EQ_BOOL(old_options, new_options, opt)) return 1;
1985 : #define YES_IF_CHANGED_INT(opt) \
1986 : if (!CFG_EQ_INT(old_options, new_options, opt)) return 1;
1987 : #define YES_IF_CHANGED_STRING(opt) \
1988 : if (!CFG_EQ_STRING(old_options, new_options, opt)) return 1;
1989 : #define YES_IF_CHANGED_LINELIST(opt) \
1990 : if (!CFG_EQ_LINELIST(old_options, new_options, opt)) return 1;
1991 : #define YES_IF_CHANGED_SMARTLIST(opt) \
1992 : if (!CFG_EQ_SMARTLIST(old_options, new_options, opt)) return 1;
1993 : #define YES_IF_CHANGED_ROUTERSET(opt) \
1994 : if (!CFG_EQ_ROUTERSET(old_options, new_options, opt)) return 1;
1995 :
1996 : /**
1997 : * Return true if changing the configuration from <b>old</b> to <b>new</b>
1998 : * affects the guard subsystem.
1999 : */
2000 : static int
2001 3 : options_transition_affects_guards(const or_options_t *old_options,
2002 : const or_options_t *new_options)
2003 : {
2004 : /* NOTE: Make sure this function stays in sync with
2005 : * node_passes_guard_filter */
2006 3 : tor_assert(old_options);
2007 3 : tor_assert(new_options);
2008 :
2009 3 : YES_IF_CHANGED_BOOL(UseEntryGuards);
2010 0 : YES_IF_CHANGED_BOOL(UseBridges);
2011 0 : YES_IF_CHANGED_BOOL(ClientUseIPv4);
2012 0 : YES_IF_CHANGED_BOOL(ClientUseIPv6);
2013 0 : YES_IF_CHANGED_BOOL(FascistFirewall);
2014 0 : YES_IF_CHANGED_ROUTERSET(ExcludeNodes);
2015 0 : YES_IF_CHANGED_ROUTERSET(EntryNodes);
2016 0 : YES_IF_CHANGED_SMARTLIST(FirewallPorts);
2017 0 : YES_IF_CHANGED_LINELIST(Bridges);
2018 0 : YES_IF_CHANGED_LINELIST(ReachableORAddresses);
2019 0 : YES_IF_CHANGED_LINELIST(ReachableDirAddresses);
2020 :
2021 : return 0;
2022 : }
2023 :
2024 : /** Fetch the active option list, and take actions based on it. All of the
2025 : * things we do should survive being done repeatedly. If present,
2026 : * <b>old_options</b> contains the previous value of the options.
2027 : *
2028 : * Return 0 if all goes well, return -1 if it's time to die.
2029 : *
2030 : * Note: We haven't moved all the "act on new configuration" logic
2031 : * the options_act* functions yet. Some is still in do_hup() and other
2032 : * places.
2033 : */
2034 213 : MOCK_IMPL(STATIC int,
2035 : options_act,(const or_options_t *old_options))
2036 : {
2037 213 : config_line_t *cl;
2038 213 : or_options_t *options = get_options_mutable();
2039 213 : int running_tor = options->command == CMD_RUN_TOR;
2040 213 : char *msg=NULL;
2041 426 : const int transition_affects_guards =
2042 213 : old_options && options_transition_affects_guards(old_options, options);
2043 :
2044 213 : if (options->NoExec || options->Sandbox) {
2045 0 : tor_disable_spawning_background_processes();
2046 : }
2047 :
2048 : /* disable ptrace and later, other basic debugging techniques */
2049 : {
2050 : /* Remember if we already disabled debugger attachment */
2051 213 : static int disabled_debugger_attach = 0;
2052 : /* Remember if we already warned about being configured not to disable
2053 : * debugger attachment */
2054 213 : static int warned_debugger_attach = 0;
2055 : /* Don't disable debugger attachment when we're running the unit tests. */
2056 213 : if (options->DisableDebuggerAttachment && !disabled_debugger_attach &&
2057 4 : running_tor) {
2058 4 : int ok = tor_disable_debugger_attach();
2059 : /* LCOV_EXCL_START the warned_debugger_attach is 0 can't reach inside. */
2060 : if (warned_debugger_attach && ok == 1) {
2061 : log_notice(LD_CONFIG, "Disabled attaching debuggers for unprivileged "
2062 : "users.");
2063 : }
2064 : /* LCOV_EXCL_STOP */
2065 4 : disabled_debugger_attach = (ok == 1);
2066 209 : } else if (!options->DisableDebuggerAttachment &&
2067 3 : !warned_debugger_attach) {
2068 3 : log_notice(LD_CONFIG, "Not disabling debugger attaching for "
2069 : "unprivileged users.");
2070 3 : warned_debugger_attach = 1;
2071 : }
2072 : }
2073 :
2074 : /* Write control ports to disk as appropriate */
2075 213 : control_ports_write_to_file();
2076 :
2077 213 : if (running_tor && !have_lockfile()) {
2078 4 : if (try_locking(options, 1) < 0)
2079 : return -1;
2080 : }
2081 :
2082 : {
2083 213 : int warning_severity = options->ProtocolWarnings ? LOG_WARN : LOG_INFO;
2084 213 : set_protocol_warning_severity_level(warning_severity);
2085 : }
2086 :
2087 213 : if (consider_adding_dir_servers(options, old_options) < 0) {
2088 : // XXXX This should get validated earlier, and committed here, to
2089 : // XXXX lower opportunities for reaching an error case.
2090 : return -1;
2091 : }
2092 :
2093 213 : if (hs_service_non_anonymous_mode_enabled(options)) {
2094 0 : log_warn(LD_GENERAL, "This copy of Tor was compiled or configured to run "
2095 : "in a non-anonymous mode. It will provide NO ANONYMITY.");
2096 : }
2097 :
2098 : /* 31851: OutboundBindAddressExit is relay-only */
2099 213 : if (parse_outbound_addresses(options, 0, &msg) < 0) {
2100 : // LCOV_EXCL_START
2101 : log_warn(LD_BUG, "Failed parsing previously validated outbound "
2102 : "bind addresses: %s", msg);
2103 : tor_free(msg);
2104 : return -1;
2105 : // LCOV_EXCL_STOP
2106 : }
2107 :
2108 213 : if (options->Bridges) {
2109 9 : mark_bridge_list();
2110 18 : for (cl = options->Bridges; cl; cl = cl->next) {
2111 9 : bridge_line_t *bridge_line = parse_bridge_line(cl->value);
2112 9 : if (!bridge_line) {
2113 : // LCOV_EXCL_START
2114 : log_warn(LD_BUG,
2115 : "Previously validated Bridge line could not be added!");
2116 : return -1;
2117 : // LCOV_EXCL_STOP
2118 : }
2119 9 : bridge_add_from_config(bridge_line);
2120 : }
2121 9 : sweep_bridge_list();
2122 : }
2123 :
2124 213 : if (running_tor && hs_config_service_all(options, 0)<0) {
2125 : // LCOV_EXCL_START
2126 : log_warn(LD_BUG,
2127 : "Previously validated hidden services line could not be added!");
2128 : return -1;
2129 : // LCOV_EXCL_STOP
2130 : }
2131 :
2132 213 : if (running_tor && hs_config_client_auth_all(options, 0) < 0) {
2133 : // LCOV_EXCL_START
2134 : log_warn(LD_BUG, "Previously validated client authorization for "
2135 : "hidden services could not be added!");
2136 : return -1;
2137 : // LCOV_EXCL_STOP
2138 : }
2139 :
2140 213 : if (running_tor && !old_options &&
2141 4 : options->OwningControllerFD != UINT64_MAX) {
2142 0 : const unsigned ctrl_flags =
2143 : CC_LOCAL_FD_IS_OWNER |
2144 : CC_LOCAL_FD_IS_AUTHENTICATED;
2145 0 : tor_socket_t ctrl_sock = (tor_socket_t)options->OwningControllerFD;
2146 0 : if (control_connection_add_local_fd(ctrl_sock, ctrl_flags) < 0) {
2147 0 : log_warn(LD_CONFIG, "Could not add local controller connection with "
2148 : "given FD.");
2149 0 : return -1;
2150 : }
2151 : }
2152 :
2153 : /* Load state */
2154 213 : if (! or_state_loaded() && running_tor) {
2155 4 : if (or_state_load())
2156 : return -1;
2157 4 : if (options_act_dirauth_mtbf(options) < 0)
2158 : return -1;
2159 : }
2160 :
2161 : /* 31851: some of the code in these functions is relay-only */
2162 213 : mark_transport_list();
2163 213 : pt_prepare_proxy_list_for_config_read();
2164 213 : if (!options->DisableNetwork) {
2165 175 : if (options->ClientTransportPlugin) {
2166 0 : for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
2167 0 : if (pt_parse_transport_line(options, cl->value, 0, 0) < 0) {
2168 : // LCOV_EXCL_START
2169 : log_warn(LD_BUG,
2170 : "Previously validated ClientTransportPlugin line "
2171 : "could not be added!");
2172 : return -1;
2173 : // LCOV_EXCL_STOP
2174 : }
2175 : }
2176 : }
2177 : }
2178 :
2179 213 : if (options_act_server_transport(old_options) < 0)
2180 : return -1;
2181 :
2182 213 : sweep_transport_list();
2183 213 : sweep_proxy_list();
2184 :
2185 : /* Start the PT proxy configuration. By doing this configuration
2186 : here, we also figure out which proxies need to be restarted and
2187 : which not. */
2188 213 : if (pt_proxies_configuration_pending() && !net_is_disabled())
2189 0 : pt_configure_remaining_proxies();
2190 :
2191 : /* Bail out at this point if we're not going to be a client or server:
2192 : * we want to not fork, and to log stuff to stderr. */
2193 213 : if (!running_tor)
2194 : return 0;
2195 :
2196 : /* Finish backgrounding the process */
2197 4 : if (options->RunAsDaemon) {
2198 : /* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
2199 0 : finish_daemon(options->DataDirectory);
2200 : }
2201 :
2202 4 : if (options_act_relay(old_options) < 0)
2203 : return -1;
2204 :
2205 : /* Write our PID to the PID file. If we do not have write permissions we
2206 : * will log a warning and exit. */
2207 4 : if (options->PidFile && !sandbox_is_active()) {
2208 0 : if (write_pidfile(options->PidFile) < 0) {
2209 0 : log_err(LD_CONFIG, "Unable to write PIDFile %s",
2210 : escaped(options->PidFile));
2211 0 : return -1;
2212 : }
2213 : }
2214 :
2215 : /* Register addressmap directives */
2216 4 : config_register_addressmaps(options);
2217 4 : parse_virtual_addr_network(options->VirtualAddrNetworkIPv4, AF_INET,0,NULL);
2218 4 : parse_virtual_addr_network(options->VirtualAddrNetworkIPv6, AF_INET6,0,NULL);
2219 :
2220 : /* Update address policies. */
2221 4 : if (policies_parse_from_options(options) < 0) {
2222 : /* This should be impossible, but let's be sure. */
2223 0 : log_warn(LD_BUG,"Error parsing already-validated policy options.");
2224 0 : return -1;
2225 : }
2226 :
2227 4 : if (init_control_cookie_authentication(options->CookieAuthentication) < 0) {
2228 0 : log_warn(LD_CONFIG,"Error creating control cookie authentication file.");
2229 0 : return -1;
2230 : }
2231 :
2232 4 : monitor_owning_controller_process(options->OwningControllerProcess);
2233 :
2234 : /* reload keys as needed for rendezvous services. */
2235 4 : if (hs_service_load_all_keys() < 0) {
2236 0 : log_warn(LD_GENERAL,"Error loading rendezvous service keys");
2237 0 : return -1;
2238 : }
2239 :
2240 : /* Inform the scheduler subsystem that a configuration changed happened. It
2241 : * might be a change of scheduler or parameter. */
2242 4 : scheduler_conf_changed();
2243 :
2244 4 : if (options_act_relay_accounting(old_options) < 0)
2245 : return -1;
2246 :
2247 : /* Change the cell EWMA settings */
2248 4 : cmux_ewma_set_options(options, networkstatus_get_latest_consensus());
2249 :
2250 : /* Update the BridgePassword's hashed version as needed. We store this as a
2251 : * digest so that we can do side-channel-proof comparisons on it.
2252 : */
2253 4 : if (options->BridgePassword) {
2254 0 : char *http_authenticator;
2255 0 : http_authenticator = alloc_http_authenticator(options->BridgePassword);
2256 0 : if (!http_authenticator) {
2257 : // XXXX This should get validated in options_validate().
2258 0 : log_warn(LD_BUG, "Unable to allocate HTTP authenticator. Not setting "
2259 : "BridgePassword.");
2260 0 : return -1;
2261 : }
2262 0 : options->BridgePassword_AuthDigest_ = tor_malloc(DIGEST256_LEN);
2263 0 : crypto_digest256(options->BridgePassword_AuthDigest_,
2264 : http_authenticator, strlen(http_authenticator),
2265 : DIGEST_SHA256);
2266 0 : tor_free(http_authenticator);
2267 : }
2268 :
2269 4 : config_maybe_load_geoip_files_(options, old_options);
2270 :
2271 4 : if (geoip_is_loaded(AF_INET) && options->GeoIPExcludeUnknown) {
2272 : /* ExcludeUnknown is true or "auto" */
2273 0 : const int is_auto = options->GeoIPExcludeUnknown == -1;
2274 0 : int changed;
2275 :
2276 0 : changed = routerset_add_unknown_ccs(&options->ExcludeNodes, is_auto);
2277 0 : changed += routerset_add_unknown_ccs(&options->ExcludeExitNodes, is_auto);
2278 :
2279 0 : if (changed)
2280 0 : routerset_add_unknown_ccs(&options->ExcludeExitNodesUnion_, is_auto);
2281 : }
2282 :
2283 : /* Check for transitions that need action. */
2284 4 : if (old_options) {
2285 0 : int revise_trackexithosts = 0;
2286 0 : int revise_automap_entries = 0;
2287 0 : int abandon_circuits = 0;
2288 0 : if ((options->UseEntryGuards && !old_options->UseEntryGuards) ||
2289 0 : options->UseBridges != old_options->UseBridges ||
2290 0 : (options->UseBridges &&
2291 0 : !config_lines_eq(options->Bridges, old_options->Bridges)) ||
2292 0 : !routerset_equal(old_options->ExcludeNodes,options->ExcludeNodes) ||
2293 0 : !routerset_equal(old_options->ExcludeExitNodes,
2294 0 : options->ExcludeExitNodes) ||
2295 0 : !routerset_equal(old_options->EntryNodes, options->EntryNodes) ||
2296 0 : !routerset_equal(old_options->ExitNodes, options->ExitNodes) ||
2297 0 : !routerset_equal(old_options->HSLayer2Nodes,
2298 0 : options->HSLayer2Nodes) ||
2299 0 : !routerset_equal(old_options->HSLayer3Nodes,
2300 0 : options->HSLayer3Nodes) ||
2301 0 : !routerset_equal(old_options->MiddleNodes, options->MiddleNodes) ||
2302 0 : options->StrictNodes != old_options->StrictNodes) {
2303 0 : log_info(LD_CIRC,
2304 : "Changed to using entry guards or bridges, or changed "
2305 : "preferred or excluded node lists. "
2306 : "Abandoning previous circuits.");
2307 0 : abandon_circuits = 1;
2308 : }
2309 :
2310 0 : if (transition_affects_guards) {
2311 0 : if (guards_update_all()) {
2312 : abandon_circuits = 1;
2313 : }
2314 : }
2315 :
2316 0 : if (abandon_circuits) {
2317 0 : circuit_mark_all_unused_circs();
2318 0 : circuit_mark_all_dirty_circs_as_unusable();
2319 0 : revise_trackexithosts = 1;
2320 : }
2321 :
2322 0 : if (!smartlist_strings_eq(old_options->TrackHostExits,
2323 0 : options->TrackHostExits))
2324 : revise_trackexithosts = 1;
2325 :
2326 0 : if (revise_trackexithosts)
2327 0 : addressmap_clear_excluded_trackexithosts(options);
2328 :
2329 0 : if (!options->AutomapHostsOnResolve &&
2330 0 : old_options->AutomapHostsOnResolve) {
2331 : revise_automap_entries = 1;
2332 : } else {
2333 0 : if (!smartlist_strings_eq(old_options->AutomapHostsSuffixes,
2334 0 : options->AutomapHostsSuffixes))
2335 : revise_automap_entries = 1;
2336 0 : else if (!opt_streq(old_options->VirtualAddrNetworkIPv4,
2337 0 : options->VirtualAddrNetworkIPv4) ||
2338 0 : !opt_streq(old_options->VirtualAddrNetworkIPv6,
2339 0 : options->VirtualAddrNetworkIPv6))
2340 : revise_automap_entries = 1;
2341 : }
2342 :
2343 : if (revise_automap_entries)
2344 0 : addressmap_clear_invalid_automaps(options);
2345 :
2346 0 : if (options_act_bridge_stats(old_options) < 0)
2347 : return -1;
2348 :
2349 0 : if (dns_reset())
2350 : return -1;
2351 :
2352 0 : if (options_act_relay_bandwidth(old_options) < 0)
2353 : return -1;
2354 :
2355 0 : if (options->BandwidthRate != old_options->BandwidthRate ||
2356 0 : options->BandwidthBurst != old_options->BandwidthBurst)
2357 0 : connection_bucket_adjust(options);
2358 :
2359 0 : if (options->MainloopStats != old_options->MainloopStats) {
2360 0 : reset_main_loop_counters();
2361 : }
2362 : }
2363 :
2364 : /* 31851: These options are relay-only, but we need to disable them if we
2365 : * are in client mode. In 29211, we will disable all relay options in
2366 : * client mode. */
2367 : /* Only collect directory-request statistics on relays and bridges. */
2368 8 : options->DirReqStatistics = options->DirReqStatistics_option &&
2369 4 : server_mode(options);
2370 8 : options->HiddenServiceStatistics =
2371 4 : options->HiddenServiceStatistics_option && server_mode(options);
2372 :
2373 : /* Only collect other relay-only statistics on relays. */
2374 4 : if (!public_server_mode(options)) {
2375 0 : options->CellStatistics = 0;
2376 0 : options->EntryStatistics = 0;
2377 0 : options->ConnDirectionStatistics = 0;
2378 0 : options->ExitPortStatistics = 0;
2379 : }
2380 :
2381 4 : bool print_notice = 0;
2382 4 : if (options_act_relay_stats(old_options, &print_notice) < 0)
2383 : return -1;
2384 4 : if (options_act_dirauth_stats(old_options, &print_notice) < 0)
2385 : return -1;
2386 4 : if (print_notice)
2387 0 : options_act_relay_stats_msg();
2388 :
2389 4 : if (options_act_relay_desc(old_options) < 0)
2390 : return -1;
2391 :
2392 4 : if (options_act_dirauth(old_options) < 0)
2393 : return -1;
2394 :
2395 : /* We may need to reschedule some directory stuff if our status changed. */
2396 4 : if (old_options) {
2397 0 : if (!bool_eq(dirclient_fetches_dir_info_early(options),
2398 0 : dirclient_fetches_dir_info_early(old_options)) ||
2399 0 : !bool_eq(dirclient_fetches_dir_info_later(options),
2400 0 : dirclient_fetches_dir_info_later(old_options)) ||
2401 0 : !config_lines_eq(old_options->Bridges, options->Bridges)) {
2402 : /* Make sure update_router_have_minimum_dir_info() gets called. */
2403 0 : router_dir_info_changed();
2404 : /* We might need to download a new consensus status later or sooner than
2405 : * we had expected. */
2406 0 : update_consensus_networkstatus_fetch_time(time(NULL));
2407 : }
2408 : }
2409 :
2410 4 : if (options_act_relay_dos(old_options) < 0)
2411 : return -1;
2412 4 : if (options_act_relay_dir(old_options) < 0)
2413 0 : return -1;
2414 :
2415 : return 0;
2416 : }
2417 :
2418 : /**
2419 : * Enumeration to describe the syntax for a command-line option.
2420 : **/
2421 : typedef enum {
2422 : /** Describe an option that does not take an argument. */
2423 : ARGUMENT_NONE = 0,
2424 : /** Describes an option that takes a single argument. */
2425 : ARGUMENT_NECESSARY = 1,
2426 : /** Describes an option that takes a single optional argument. */
2427 : ARGUMENT_OPTIONAL = 2
2428 : } takes_argument_t;
2429 :
2430 : /** Table describing arguments that Tor accepts on the command line,
2431 : * other than those that are the same as in torrc. */
2432 : static const struct {
2433 : /** The string that the user has to provide. */
2434 : const char *name;
2435 : /** Optional short name. */
2436 : const char *short_name;
2437 : /** Does this option accept an argument? */
2438 : takes_argument_t takes_argument;
2439 : /** If not CMD_RUN_TOR, what should Tor do when it starts? */
2440 : tor_cmdline_mode_t command;
2441 : /** If nonzero, set the quiet level to this. 1 is "hush", 2 is "quiet" */
2442 : int quiet;
2443 : } CMDLINE_ONLY_OPTIONS[] = {
2444 : { .name="--torrc-file",
2445 : .short_name="-f",
2446 : .takes_argument=ARGUMENT_NECESSARY },
2447 : { .name="--allow-missing-torrc" },
2448 : { .name="--defaults-torrc",
2449 : .takes_argument=ARGUMENT_NECESSARY },
2450 : { .name="--hash-password",
2451 : .takes_argument=ARGUMENT_NECESSARY,
2452 : .command=CMD_HASH_PASSWORD,
2453 : .quiet=QUIET_HUSH },
2454 : { .name="--dump-config",
2455 : .takes_argument=ARGUMENT_OPTIONAL,
2456 : .command=CMD_DUMP_CONFIG,
2457 : .quiet=QUIET_SILENT },
2458 : { .name="--list-fingerprint",
2459 : .takes_argument=ARGUMENT_OPTIONAL,
2460 : .command=CMD_LIST_FINGERPRINT },
2461 : { .name="--keygen",
2462 : .command=CMD_KEYGEN },
2463 : { .name="--key-expiration",
2464 : .takes_argument=ARGUMENT_OPTIONAL,
2465 : .command=CMD_KEY_EXPIRATION },
2466 : { .name="--format",
2467 : .takes_argument=ARGUMENT_NECESSARY },
2468 : { .name="--newpass" },
2469 : { .name="--no-passphrase" },
2470 : { .name="--passphrase-fd",
2471 : .takes_argument=ARGUMENT_NECESSARY },
2472 : { .name="--verify-config",
2473 : .command=CMD_VERIFY_CONFIG },
2474 : { .name="--ignore-missing-torrc" },
2475 : { .name="--quiet",
2476 : .quiet=QUIET_SILENT },
2477 : { .name="--hush",
2478 : .quiet=QUIET_HUSH },
2479 : { .name="--version",
2480 : .command=CMD_IMMEDIATE,
2481 : .quiet=QUIET_HUSH },
2482 : { .name="--list-modules",
2483 : .command=CMD_IMMEDIATE,
2484 : .quiet=QUIET_HUSH },
2485 : { .name="--library-versions",
2486 : .command=CMD_IMMEDIATE,
2487 : .quiet=QUIET_HUSH },
2488 : { .name="--help",
2489 : .short_name="-h",
2490 : .command=CMD_IMMEDIATE,
2491 : .quiet=QUIET_HUSH },
2492 : { .name="--list-torrc-options",
2493 : .command=CMD_IMMEDIATE,
2494 : .quiet=QUIET_HUSH },
2495 : { .name="--list-deprecated-options",
2496 : .command=CMD_IMMEDIATE },
2497 : { .name="--nt-service" },
2498 : { .name="-nt-service" },
2499 : { .name="--dbg-dump-subsystem-list",
2500 : .command=CMD_IMMEDIATE,
2501 : .quiet=QUIET_HUSH },
2502 : { .name=NULL },
2503 : };
2504 :
2505 : /** Helper: Read a list of configuration options from the command line. If
2506 : * successful, return a newly allocated parsed_cmdline_t; otherwise return
2507 : * NULL.
2508 : *
2509 : * If <b>ignore_errors</b> is set, try to recover from all recoverable
2510 : * errors and return the best command line we can.
2511 : */
2512 : parsed_cmdline_t *
2513 470 : config_parse_commandline(int argc, char **argv, int ignore_errors)
2514 : {
2515 470 : parsed_cmdline_t *result = tor_malloc_zero(sizeof(parsed_cmdline_t));
2516 470 : result->command = CMD_RUN_TOR;
2517 470 : config_line_t *param = NULL;
2518 :
2519 470 : config_line_t **new_cmdline = &result->cmdline_opts;
2520 470 : config_line_t **new = &result->other_opts;
2521 :
2522 470 : char *s, *arg;
2523 470 : int i = 1;
2524 :
2525 2350 : while (i < argc) {
2526 17462 : unsigned command = CONFIG_LINE_NORMAL;
2527 17462 : takes_argument_t want_arg = ARGUMENT_NECESSARY;
2528 17462 : int is_cmdline = 0;
2529 : int j;
2530 17462 : bool is_a_command = false;
2531 :
2532 17462 : for (j = 0; CMDLINE_ONLY_OPTIONS[j].name != NULL; ++j) {
2533 17070 : if (!strcmp(argv[i], CMDLINE_ONLY_OPTIONS[j].name) ||
2534 16040 : (CMDLINE_ONLY_OPTIONS[j].short_name &&
2535 2276 : !strcmp(argv[i], CMDLINE_ONLY_OPTIONS[j].short_name))) {
2536 1490 : is_cmdline = 1;
2537 1490 : want_arg = CMDLINE_ONLY_OPTIONS[j].takes_argument;
2538 1490 : if (CMDLINE_ONLY_OPTIONS[j].command != CMD_RUN_TOR) {
2539 464 : is_a_command = true;
2540 464 : result->command = CMDLINE_ONLY_OPTIONS[j].command;
2541 : }
2542 1490 : quiet_level_t quiet = CMDLINE_ONLY_OPTIONS[j].quiet;
2543 1490 : if (quiet > result->quiet_level)
2544 310 : result->quiet_level = quiet;
2545 : break;
2546 : }
2547 : }
2548 :
2549 1882 : s = argv[i];
2550 :
2551 : /* Each keyword may be prefixed with one or two dashes. */
2552 1882 : if (*s == '-')
2553 1854 : s++;
2554 1882 : if (*s == '-')
2555 1394 : s++;
2556 : /* Figure out the command, if any. */
2557 1882 : if (*s == '+') {
2558 8 : s++;
2559 8 : command = CONFIG_LINE_APPEND;
2560 1874 : } else if (*s == '/') {
2561 12 : s++;
2562 12 : command = CONFIG_LINE_CLEAR;
2563 : /* A 'clear' command has no argument. */
2564 12 : want_arg = 0;
2565 : }
2566 :
2567 1882 : const int is_last = (i == argc-1);
2568 :
2569 1882 : if (want_arg == ARGUMENT_NECESSARY && is_last) {
2570 4 : if (ignore_errors) {
2571 2 : arg = tor_strdup("");
2572 : } else {
2573 2 : log_warn(LD_CONFIG,"Command-line option '%s' with no value. Failing.",
2574 : argv[i]);
2575 2 : parsed_cmdline_free(result);
2576 2 : return NULL;
2577 : }
2578 1878 : } else if (want_arg == ARGUMENT_OPTIONAL &&
2579 : /* optional arguments may never start with '-'. */
2580 232 : (is_last || argv[i+1][0] == '-')) {
2581 40 : arg = tor_strdup("");
2582 40 : want_arg = ARGUMENT_NONE; // prevent skipping the next flag.
2583 : } else {
2584 1838 : arg = (want_arg != ARGUMENT_NONE) ? tor_strdup(argv[i+1]) :
2585 288 : tor_strdup("");
2586 : }
2587 :
2588 1880 : param = tor_malloc_zero(sizeof(config_line_t));
2589 1880 : param->key = is_cmdline ? tor_strdup(argv[i]) :
2590 392 : tor_strdup(config_expand_abbrev(get_options_mgr(), s, 1, 1));
2591 1880 : param->value = arg;
2592 1880 : param->command = command;
2593 1880 : param->next = NULL;
2594 1880 : log_debug(LD_CONFIG, "command line: parsed keyword '%s', value '%s'",
2595 : param->key, param->value);
2596 :
2597 1880 : if (is_a_command) {
2598 463 : result->command_arg = param->value;
2599 : }
2600 :
2601 1880 : if (is_cmdline) {
2602 1488 : *new_cmdline = param;
2603 1488 : new_cmdline = &((*new_cmdline)->next);
2604 : } else {
2605 392 : *new = param;
2606 392 : new = &((*new)->next);
2607 : }
2608 :
2609 2208 : i += want_arg ? 2 : 1;
2610 : }
2611 :
2612 : return result;
2613 : }
2614 :
2615 : /** Release all storage held by <b>cmdline</b>. */
2616 : void
2617 478 : parsed_cmdline_free_(parsed_cmdline_t *cmdline)
2618 : {
2619 478 : if (!cmdline)
2620 : return;
2621 470 : config_free_lines(cmdline->cmdline_opts);
2622 470 : config_free_lines(cmdline->other_opts);
2623 470 : tor_free(cmdline);
2624 : }
2625 :
2626 : /** Return true iff key is a valid configuration option. */
2627 : int
2628 8 : option_is_recognized(const char *key)
2629 : {
2630 8 : return config_find_option_name(get_options_mgr(), key) != NULL;
2631 : }
2632 :
2633 : /** Return the canonical name of a configuration option, or NULL
2634 : * if no such option exists. */
2635 : const char *
2636 1 : option_get_canonical_name(const char *key)
2637 : {
2638 1 : return config_find_option_name(get_options_mgr(), key);
2639 : }
2640 :
2641 : /** Return a canonical list of the options assigned for key.
2642 : */
2643 : config_line_t *
2644 4 : option_get_assignment(const or_options_t *options, const char *key)
2645 : {
2646 4 : return config_get_assigned_option(get_options_mgr(), options, key, 1);
2647 : }
2648 :
2649 : /** Try assigning <b>list</b> to the global options. You do this by duping
2650 : * options, assigning list to the new one, then validating it. If it's
2651 : * ok, then throw out the old one and stick with the new one. Else,
2652 : * revert to old and return failure. Return SETOPT_OK on success, or
2653 : * a setopt_err_t on failure.
2654 : *
2655 : * If not success, point *<b>msg</b> to a newly allocated string describing
2656 : * what went wrong.
2657 : */
2658 : setopt_err_t
2659 5 : options_trial_assign(config_line_t *list, unsigned flags, char **msg)
2660 : {
2661 5 : int r;
2662 5 : or_options_t *trial_options = config_dup(get_options_mgr(), get_options());
2663 :
2664 5 : if ((r=config_assign(get_options_mgr(), trial_options,
2665 : list, flags, msg)) < 0) {
2666 1 : or_options_free(trial_options);
2667 1 : return r;
2668 : }
2669 4 : const or_options_t *cur_options = get_options();
2670 :
2671 4 : return options_validate_and_set(cur_options, trial_options, msg);
2672 : }
2673 :
2674 : /** Print a usage message for tor. */
2675 : static void
2676 0 : print_usage(void)
2677 : {
2678 0 : printf(
2679 : "Copyright (c) 2001-2004, Roger Dingledine\n"
2680 : "Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson\n"
2681 : "Copyright (c) 2007-2021, The Tor Project, Inc.\n\n"
2682 : "tor -f <torrc> [args]\n"
2683 : "See man page for options, or https://www.torproject.org/ for "
2684 : "documentation.\n");
2685 0 : }
2686 :
2687 : /** Print all non-obsolete torrc options. */
2688 : static void
2689 1 : list_torrc_options(void)
2690 : {
2691 1 : smartlist_t *vars = config_mgr_list_vars(get_options_mgr());
2692 430 : SMARTLIST_FOREACH_BEGIN(vars, const config_var_t *, var) {
2693 : /* Possibly this should check listable, rather than (or in addition to)
2694 : * settable. See ticket 31654.
2695 : */
2696 429 : if (! config_var_is_settable(var)) {
2697 : /* This variable cannot be set, or cannot be set by this name. */
2698 85 : continue;
2699 : }
2700 344 : printf("%s\n", var->member.name);
2701 429 : } SMARTLIST_FOREACH_END(var);
2702 1 : smartlist_free(vars);
2703 1 : }
2704 :
2705 : /** Print all deprecated but non-obsolete torrc options. */
2706 : static void
2707 0 : list_deprecated_options(void)
2708 : {
2709 0 : smartlist_t *deps = config_mgr_list_deprecated_vars(get_options_mgr());
2710 : /* Possibly this should check whether the variables are listable,
2711 : * but currently it does not. See ticket 31654. */
2712 0 : SMARTLIST_FOREACH(deps, const char *, name,
2713 : printf("%s\n", name));
2714 0 : smartlist_free(deps);
2715 0 : }
2716 :
2717 : /** Print all compile-time modules and their enabled/disabled status. */
2718 : static void
2719 4 : list_enabled_modules(void)
2720 : {
2721 4 : printf("%s: %s\n", "relay", have_module_relay() ? "yes" : "no");
2722 4 : printf("%s: %s\n", "dirauth", have_module_dirauth() ? "yes" : "no");
2723 : // We don't list dircache, because it cannot be enabled or disabled
2724 : // independently from relay. Listing it here would proliferate
2725 : // test variants in test_parseconf.sh to no useful purpose.
2726 4 : }
2727 :
2728 : /** Prints compile-time and runtime library versions. */
2729 : static void
2730 0 : print_library_versions(void)
2731 : {
2732 0 : printf("Tor version %s. \n", get_version());
2733 0 : printf("Library versions\tCompiled\t\tRuntime\n");
2734 0 : printf("Libevent\t\t%-15s\t\t%s\n",
2735 : tor_libevent_get_header_version_str(),
2736 : tor_libevent_get_version_str());
2737 : #ifdef ENABLE_OPENSSL
2738 0 : printf("OpenSSL \t\t%-15s\t\t%s\n",
2739 : crypto_openssl_get_header_version_str(),
2740 : crypto_openssl_get_version_str());
2741 : #endif
2742 : #ifdef ENABLE_NSS
2743 : printf("NSS \t\t%-15s\t\t%s\n",
2744 : crypto_nss_get_header_version_str(),
2745 : crypto_nss_get_version_str());
2746 : #endif
2747 0 : if (tor_compress_supports_method(ZLIB_METHOD)) {
2748 0 : printf("Zlib \t\t%-15s\t\t%s\n",
2749 : tor_compress_version_str(ZLIB_METHOD),
2750 : tor_compress_header_version_str(ZLIB_METHOD));
2751 : }
2752 0 : if (tor_compress_supports_method(LZMA_METHOD)) {
2753 0 : printf("Liblzma \t\t%-15s\t\t%s\n",
2754 : tor_compress_version_str(LZMA_METHOD),
2755 : tor_compress_header_version_str(LZMA_METHOD));
2756 : }
2757 0 : if (tor_compress_supports_method(ZSTD_METHOD)) {
2758 0 : printf("Libzstd \t\t%-15s\t\t%s\n",
2759 : tor_compress_version_str(ZSTD_METHOD),
2760 : tor_compress_header_version_str(ZSTD_METHOD));
2761 : }
2762 0 : if (tor_libc_get_name()) {
2763 0 : printf("%-7s \t\t%-15s\t\t%s\n",
2764 : tor_libc_get_name(),
2765 : tor_libc_get_header_version_str(),
2766 : tor_libc_get_version_str());
2767 : }
2768 : //TODO: Hex versions?
2769 0 : }
2770 :
2771 : /** Handles the --no-passphrase command line option. */
2772 : static int
2773 3 : handle_cmdline_no_passphrase(tor_cmdline_mode_t command)
2774 : {
2775 3 : if (command == CMD_KEYGEN) {
2776 2 : get_options_mutable()->keygen_force_passphrase = FORCE_PASSPHRASE_OFF;
2777 2 : return 0;
2778 : } else {
2779 1 : log_err(LD_CONFIG, "--no-passphrase specified without --keygen!");
2780 1 : return -1;
2781 : }
2782 : }
2783 :
2784 : /** Handles the --format command line option. */
2785 : static int
2786 4 : handle_cmdline_format(tor_cmdline_mode_t command, const char *value)
2787 : {
2788 4 : if (command == CMD_KEY_EXPIRATION) {
2789 : // keep the same order as enum key_expiration_format
2790 3 : const char *formats[] = { "iso8601", "timestamp" };
2791 3 : int format = -1;
2792 6 : for (unsigned i = 0; i < ARRAY_LENGTH(formats); i++) {
2793 5 : if (!strcmp(value, formats[i])) {
2794 2 : format = i;
2795 2 : break;
2796 : }
2797 : }
2798 :
2799 3 : if (format < 0) {
2800 1 : log_err(LD_CONFIG, "Invalid --format value %s", escaped(value));
2801 1 : return -1;
2802 : } else {
2803 2 : get_options_mutable()->key_expiration_format = format;
2804 : }
2805 2 : return 0;
2806 : } else {
2807 1 : log_err(LD_CONFIG, "--format specified without --key-expiration!");
2808 1 : return -1;
2809 : }
2810 : }
2811 :
2812 : /** Handles the --newpass command line option. */
2813 : static int
2814 1 : handle_cmdline_newpass(tor_cmdline_mode_t command)
2815 : {
2816 1 : if (command == CMD_KEYGEN) {
2817 0 : get_options_mutable()->change_key_passphrase = 1;
2818 0 : return 0;
2819 : } else {
2820 1 : log_err(LD_CONFIG, "--newpass specified without --keygen!");
2821 1 : return -1;
2822 : }
2823 : }
2824 :
2825 : /** Handles the --passphrase-fd command line option. */
2826 : static int
2827 5 : handle_cmdline_passphrase_fd(tor_cmdline_mode_t command, const char *value)
2828 : {
2829 5 : if (get_options()->keygen_force_passphrase == FORCE_PASSPHRASE_OFF) {
2830 1 : log_err(LD_CONFIG, "--no-passphrase specified with --passphrase-fd!");
2831 1 : return -1;
2832 4 : } else if (command != CMD_KEYGEN) {
2833 1 : log_err(LD_CONFIG, "--passphrase-fd specified without --keygen!");
2834 1 : return -1;
2835 : } else {
2836 3 : int ok = 1;
2837 3 : long fd = tor_parse_long(value, 10, 0, INT_MAX, &ok, NULL);
2838 3 : if (fd < 0 || ok == 0) {
2839 1 : log_err(LD_CONFIG, "Invalid --passphrase-fd value %s", escaped(value));
2840 1 : return -1;
2841 : }
2842 2 : get_options_mutable()->keygen_passphrase_fd = (int)fd;
2843 2 : get_options_mutable()->use_keygen_passphrase_fd = 1;
2844 2 : get_options_mutable()->keygen_force_passphrase = FORCE_PASSPHRASE_ON;
2845 2 : return 0;
2846 : }
2847 : }
2848 :
2849 : /** Handles the --master-key command line option. */
2850 : static int
2851 0 : handle_cmdline_master_key(tor_cmdline_mode_t command, const char *value)
2852 : {
2853 0 : if (command != CMD_KEYGEN) {
2854 0 : log_err(LD_CONFIG, "--master-key without --keygen!");
2855 0 : return -1;
2856 : } else {
2857 0 : get_options_mutable()->master_key_fname = tor_strdup(value);
2858 0 : return 0;
2859 : }
2860 : }
2861 :
2862 : /* Return true if <b>options</b> is using the default authorities, and false
2863 : * if any authority-related option has been overridden. */
2864 : int
2865 11 : using_default_dir_authorities(const or_options_t *options)
2866 : {
2867 11 : return (!options->DirAuthorities && !options->AlternateDirAuthority);
2868 : }
2869 :
2870 : /** Return a new empty or_options_t. Used for testing. */
2871 : or_options_t *
2872 6358 : options_new(void)
2873 : {
2874 6358 : or_options_t *options = config_new(get_options_mgr());
2875 6358 : options->command = CMD_RUN_TOR;
2876 6358 : return options;
2877 : }
2878 :
2879 : /** Set <b>options</b> to hold reasonable defaults for most options.
2880 : * Each option defaults to zero. */
2881 : void
2882 956 : options_init(or_options_t *options)
2883 : {
2884 956 : config_init(get_options_mgr(), options);
2885 956 : config_line_t *dflts = get_options_defaults();
2886 956 : char *msg=NULL;
2887 956 : if (config_assign(get_options_mgr(), options, dflts,
2888 : CAL_WARN_DEPRECATIONS, &msg)<0) {
2889 0 : log_err(LD_BUG, "Unable to set default options: %s", msg);
2890 0 : tor_free(msg);
2891 0 : tor_assert_unreached();
2892 : }
2893 956 : config_free_lines(dflts);
2894 956 : tor_free(msg);
2895 956 : }
2896 :
2897 : /** Return a string containing a possible configuration file that would give
2898 : * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
2899 : * include options that are the same as Tor's defaults.
2900 : */
2901 : char *
2902 110 : options_dump(const or_options_t *options, int how_to_dump)
2903 : {
2904 110 : const or_options_t *use_defaults;
2905 110 : int minimal;
2906 110 : switch (how_to_dump) {
2907 110 : case OPTIONS_DUMP_MINIMAL:
2908 110 : use_defaults = global_default_options;
2909 110 : minimal = 1;
2910 110 : break;
2911 : case OPTIONS_DUMP_ALL:
2912 : use_defaults = NULL;
2913 : minimal = 0;
2914 : break;
2915 0 : default:
2916 0 : log_warn(LD_BUG, "Bogus value for how_to_dump==%d", how_to_dump);
2917 0 : return NULL;
2918 : }
2919 :
2920 110 : return config_dump(get_options_mgr(), use_defaults, options, minimal, 0);
2921 : }
2922 :
2923 : /** Return 0 if every element of sl is a string holding a decimal
2924 : * representation of a port number, or if sl is NULL.
2925 : * Otherwise set *msg and return -1. */
2926 : static int
2927 2142 : validate_ports_csv(smartlist_t *sl, const char *name, char **msg)
2928 : {
2929 2142 : int i;
2930 2142 : tor_assert(name);
2931 :
2932 2142 : if (!sl)
2933 : return 0;
2934 :
2935 10644 : SMARTLIST_FOREACH(sl, const char *, cp,
2936 : {
2937 : i = atoi(cp);
2938 : if (i < 1 || i > 65535) {
2939 : tor_asprintf(msg, "Port '%s' out of range in %s", cp, name);
2940 : return -1;
2941 : }
2942 : });
2943 : return 0;
2944 : }
2945 :
2946 : /** If <b>value</b> exceeds ROUTER_MAX_DECLARED_BANDWIDTH, write
2947 : * a complaint into *<b>msg</b> using string <b>desc</b>, and return -1.
2948 : * Else return 0.
2949 : */
2950 : int
2951 4610 : config_ensure_bandwidth_cap(uint64_t *value, const char *desc, char **msg)
2952 : {
2953 4610 : if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
2954 : /* This handles an understandable special case where somebody says "2gb"
2955 : * whereas our actual maximum is 2gb-1 (INT_MAX) */
2956 25 : --*value;
2957 : }
2958 4610 : if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) {
2959 23 : tor_asprintf(msg, "%s (%"PRIu64") must be at most %d",
2960 : desc, (*value),
2961 : ROUTER_MAX_DECLARED_BANDWIDTH);
2962 23 : return -1;
2963 : }
2964 : return 0;
2965 : }
2966 :
2967 : /** Lowest allowable value for RendPostPeriod; if this is too low, hidden
2968 : * services can overload the directory system. */
2969 : #define MIN_REND_POST_PERIOD (10*60)
2970 : #define MIN_REND_POST_PERIOD_TESTING (5)
2971 :
2972 : /** Highest allowable value for CircuitsAvailableTimeout.
2973 : * If this is too large, client connections will stay open for too long,
2974 : * incurring extra padding overhead. */
2975 : #define MAX_CIRCS_AVAILABLE_TIME (24*60*60)
2976 :
2977 : /** Highest allowable value for RendPostPeriod. */
2978 : #define MAX_DIR_PERIOD ((7*24*60*60)/2)
2979 :
2980 : /** Lowest allowable value for MaxCircuitDirtiness; if this is too low, Tor
2981 : * will generate too many circuits and potentially overload the network. */
2982 : #define MIN_MAX_CIRCUIT_DIRTINESS 10
2983 :
2984 : /** Highest allowable value for MaxCircuitDirtiness: prevents time_t
2985 : * overflows. */
2986 : #define MAX_MAX_CIRCUIT_DIRTINESS (30*24*60*60)
2987 :
2988 : /** Lowest allowable value for CircuitStreamTimeout; if this is too low, Tor
2989 : * will generate too many circuits and potentially overload the network. */
2990 : #define MIN_CIRCUIT_STREAM_TIMEOUT 10
2991 :
2992 : /** Lowest recommended value for CircuitBuildTimeout; if it is set too low
2993 : * and LearnCircuitBuildTimeout is off, the failure rate for circuit
2994 : * construction may be very high. In that case, if it is set below this
2995 : * threshold emit a warning.
2996 : * */
2997 : #define RECOMMENDED_MIN_CIRCUIT_BUILD_TIMEOUT (10)
2998 :
2999 : /**
3000 : * Validate <b>new_options</b>. If it is valid, and it is a reasonable
3001 : * replacement for <b>old_options</b>, replace the previous value of the
3002 : * global options, and return return SETOPT_OK.
3003 : *
3004 : * If it is not valid, then free <b>new_options</b>, set *<b>msg_out</b> to a
3005 : * newly allocated error message, and return an error code.
3006 : */
3007 : static setopt_err_t
3008 232 : options_validate_and_set(const or_options_t *old_options,
3009 : or_options_t *new_options,
3010 : char **msg_out)
3011 : {
3012 232 : setopt_err_t rv;
3013 232 : validation_status_t vs;
3014 :
3015 232 : in_option_validation = 1;
3016 232 : vs = config_validate(get_options_mgr(), old_options, new_options, msg_out);
3017 :
3018 232 : if (vs == VSTAT_TRANSITION_ERR) {
3019 1 : rv = SETOPT_ERR_TRANSITION;
3020 1 : goto err;
3021 231 : } else if (vs < 0) {
3022 24 : rv = SETOPT_ERR_PARSE;
3023 24 : goto err;
3024 : }
3025 207 : in_option_validation = 0;
3026 :
3027 207 : if (set_options(new_options, msg_out)) {
3028 1 : rv = SETOPT_ERR_SETTING;
3029 1 : goto err;
3030 : }
3031 :
3032 : rv = SETOPT_OK;
3033 : new_options = NULL; /* prevent free */
3034 232 : err:
3035 232 : in_option_validation = 0;
3036 232 : tor_assert(new_options == NULL || rv != SETOPT_OK);
3037 232 : or_options_free(new_options);
3038 232 : return rv;
3039 : }
3040 :
3041 : #ifdef TOR_UNIT_TESTS
3042 : /**
3043 : * Return 0 if every setting in <b>options</b> is reasonable, is a
3044 : * permissible transition from <b>old_options</b>, and none of the
3045 : * testing-only settings differ from <b>default_options</b> unless in
3046 : * testing mode. Else return -1. Should have no side effects, except for
3047 : * normalizing the contents of <b>options</b>.
3048 : *
3049 : * On error, tor_strdup an error explanation into *<b>msg</b>.
3050 : */
3051 : int
3052 349 : options_validate(const or_options_t *old_options, or_options_t *options,
3053 : char **msg)
3054 : {
3055 349 : validation_status_t vs;
3056 349 : vs = config_validate(get_options_mgr(), old_options, options, msg);
3057 349 : return vs < 0 ? -1 : 0;
3058 : }
3059 : #endif /* defined(TOR_UNIT_TESTS) */
3060 :
3061 : #define REJECT(arg) \
3062 : STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
3063 : #if defined(__GNUC__) && __GNUC__ <= 3
3064 : #define COMPLAIN(args...) \
3065 : STMT_BEGIN log_warn(LD_CONFIG, args); STMT_END
3066 : #else
3067 : #define COMPLAIN(args, ...) \
3068 : STMT_BEGIN log_warn(LD_CONFIG, args, ##__VA_ARGS__); STMT_END
3069 : #endif /* defined(__GNUC__) && __GNUC__ <= 3 */
3070 :
3071 : /** Log a warning message iff <b>filepath</b> is not absolute.
3072 : * Warning message must contain option name <b>option</b> and
3073 : * an absolute path that <b>filepath</b> will resolve to.
3074 : *
3075 : * In case <b>filepath</b> is absolute, do nothing.
3076 : *
3077 : * Return 1 if there were relative paths; 0 otherwise.
3078 : */
3079 : static int
3080 1214 : warn_if_option_path_is_relative(const char *option,
3081 : const char *filepath)
3082 : {
3083 1214 : if (filepath && path_is_relative(filepath)) {
3084 4 : char *abs_path = make_path_absolute(filepath);
3085 4 : COMPLAIN("Path for %s (%s) is relative and will resolve to %s."
3086 : " Is this what you wanted?", option, filepath, abs_path);
3087 4 : tor_free(abs_path);
3088 4 : return 1;
3089 : }
3090 : return 0;
3091 : }
3092 :
3093 : /** Scan <b>options</b> for occurrences of relative file/directory
3094 : * paths and log a warning whenever one is found.
3095 : *
3096 : * Return 1 if there were relative paths; 0 otherwise.
3097 : */
3098 : static int
3099 563 : warn_about_relative_paths(const or_options_t *options)
3100 : {
3101 563 : tor_assert(options);
3102 563 : int n = 0;
3103 563 : const config_mgr_t *mgr = get_options_mgr();
3104 :
3105 563 : smartlist_t *vars = config_mgr_list_vars(mgr);
3106 242090 : SMARTLIST_FOREACH_BEGIN(vars, const config_var_t *, cv) {
3107 241527 : config_line_t *line;
3108 241527 : if (cv->member.type != CONFIG_TYPE_FILENAME)
3109 233082 : continue;
3110 8445 : const char *name = cv->member.name;
3111 8445 : line = config_get_assigned_option(mgr, options, name, 0);
3112 8445 : if (line)
3113 1204 : n += warn_if_option_path_is_relative(name, line->value);
3114 8445 : config_free_lines(line);
3115 241527 : } SMARTLIST_FOREACH_END(cv);
3116 563 : smartlist_free(vars);
3117 :
3118 584 : for (config_line_t *hs_line = options->RendConfigLines; hs_line;
3119 21 : hs_line = hs_line->next) {
3120 21 : if (!strcasecmp(hs_line->key, "HiddenServiceDir"))
3121 10 : n += warn_if_option_path_is_relative("HiddenServiceDir",hs_line->value);
3122 : }
3123 563 : return n != 0;
3124 : }
3125 :
3126 : /* Validate options related to the scheduler. From the Schedulers list, the
3127 : * SchedulerTypes_ list is created with int values so once we select the
3128 : * scheduler, which can happen anytime at runtime, we don't have to parse
3129 : * strings and thus be quick.
3130 : *
3131 : * Return 0 on success else -1 and msg is set with an error message. */
3132 : static int
3133 386 : options_validate_scheduler(or_options_t *options, char **msg)
3134 : {
3135 386 : tor_assert(options);
3136 386 : tor_assert(msg);
3137 :
3138 386 : if (!options->Schedulers || smartlist_len(options->Schedulers) == 0) {
3139 0 : REJECT("Empty Schedulers list. Either remove the option so the defaults "
3140 : "can be used or set at least one value.");
3141 : }
3142 : /* Ok, we do have scheduler types, validate them. */
3143 386 : if (options->SchedulerTypes_) {
3144 12 : SMARTLIST_FOREACH(options->SchedulerTypes_, int *, iptr, tor_free(iptr));
3145 3 : smartlist_free(options->SchedulerTypes_);
3146 : }
3147 386 : options->SchedulerTypes_ = smartlist_new();
3148 1544 : SMARTLIST_FOREACH_BEGIN(options->Schedulers, const char *, type) {
3149 1158 : int *sched_type;
3150 1158 : if (!strcasecmp("KISTLite", type)) {
3151 386 : sched_type = tor_malloc_zero(sizeof(int));
3152 386 : *sched_type = SCHEDULER_KIST_LITE;
3153 386 : smartlist_add(options->SchedulerTypes_, sched_type);
3154 772 : } else if (!strcasecmp("KIST", type)) {
3155 386 : sched_type = tor_malloc_zero(sizeof(int));
3156 386 : *sched_type = SCHEDULER_KIST;
3157 386 : smartlist_add(options->SchedulerTypes_, sched_type);
3158 386 : } else if (!strcasecmp("Vanilla", type)) {
3159 386 : sched_type = tor_malloc_zero(sizeof(int));
3160 386 : *sched_type = SCHEDULER_VANILLA;
3161 386 : smartlist_add(options->SchedulerTypes_, sched_type);
3162 : } else {
3163 0 : tor_asprintf(msg, "Unknown type %s in option Schedulers. "
3164 : "Possible values are KIST, KISTLite and Vanilla.",
3165 : escaped(type));
3166 0 : return -1;
3167 : }
3168 1158 : } SMARTLIST_FOREACH_END(type);
3169 :
3170 386 : if (options->KISTSockBufSizeFactor < 0) {
3171 0 : REJECT("KISTSockBufSizeFactor must be at least 0");
3172 : }
3173 :
3174 : /* Don't need to validate that the Interval is less than anything because
3175 : * zero is valid and all negative values are valid. */
3176 386 : if (options->KISTSchedRunInterval > KIST_SCHED_RUN_INTERVAL_MAX) {
3177 0 : tor_asprintf(msg, "KISTSchedRunInterval must not be more than %d (ms)",
3178 : KIST_SCHED_RUN_INTERVAL_MAX);
3179 0 : return -1;
3180 : }
3181 :
3182 : return 0;
3183 : }
3184 :
3185 : /* Validate options related to single onion services.
3186 : * Modifies some options that are incompatible with single onion services.
3187 : * On failure returns -1, and sets *msg to an error string.
3188 : * Returns 0 on success. */
3189 : STATIC int
3190 513 : options_validate_single_onion(or_options_t *options, char **msg)
3191 : {
3192 : /* The two single onion service options must have matching values. */
3193 513 : if (options->HiddenServiceSingleHopMode &&
3194 6 : !options->HiddenServiceNonAnonymousMode) {
3195 2 : REJECT("HiddenServiceSingleHopMode does not provide any server anonymity. "
3196 : "It must be used with HiddenServiceNonAnonymousMode set to 1.");
3197 : }
3198 511 : if (options->HiddenServiceNonAnonymousMode &&
3199 : !options->HiddenServiceSingleHopMode) {
3200 2 : REJECT("HiddenServiceNonAnonymousMode does not provide any server "
3201 : "anonymity. It must be used with HiddenServiceSingleHopMode set to "
3202 : "1.");
3203 : }
3204 :
3205 : /* Now that we've checked that the two options are consistent, we can safely
3206 : * call the hs_service_* functions that abstract these options. */
3207 :
3208 : /* If you run an anonymous client with an active Single Onion service, the
3209 : * client loses anonymity. */
3210 509 : const int client_port_set = (options->SocksPort_set ||
3211 : options->TransPort_set ||
3212 : options->NATDPort_set ||
3213 509 : options->DNSPort_set ||
3214 : options->HTTPTunnelPort_set);
3215 509 : if (hs_service_non_anonymous_mode_enabled(options) && client_port_set) {
3216 1 : REJECT("HiddenServiceNonAnonymousMode is incompatible with using Tor as "
3217 : "an anonymous client. Please set Socks/Trans/NATD/DNSPort to 0, or "
3218 : "revert HiddenServiceNonAnonymousMode to 0.");
3219 : }
3220 :
3221 508 : if (hs_service_allow_non_anonymous_connection(options)
3222 3 : && options->UseEntryGuards) {
3223 : /* Single Onion services only use entry guards when uploading descriptors;
3224 : * all other connections are one-hop. Further, Single Onions causes the
3225 : * hidden service code to do things which break the path bias
3226 : * detector, and it's far easier to turn off entry guards (and
3227 : * thus the path bias detector with it) than to figure out how to
3228 : * make path bias compatible with single onions.
3229 : */
3230 3 : log_notice(LD_CONFIG,
3231 : "HiddenServiceSingleHopMode is enabled; disabling "
3232 : "UseEntryGuards.");
3233 3 : options->UseEntryGuards = 0;
3234 : }
3235 :
3236 : return 0;
3237 : }
3238 :
3239 : /**
3240 : * Legacy validation/normalization callback for or_options_t. See
3241 : * legacy_validate_fn_t for more information.
3242 : */
3243 : static int
3244 576 : options_validate_cb(const void *old_options_, void *options_, char **msg)
3245 : {
3246 576 : if (old_options_)
3247 8 : CHECK_OPTIONS_MAGIC(old_options_);
3248 576 : CHECK_OPTIONS_MAGIC(options_);
3249 576 : const or_options_t *old_options = old_options_;
3250 576 : or_options_t *options = options_;
3251 :
3252 576 : config_line_t *cl;
3253 576 : int n_ports=0;
3254 576 : int world_writable_control_socket=0;
3255 :
3256 576 : tor_assert(msg);
3257 576 : *msg = NULL;
3258 :
3259 576 : if (parse_ports(options, 1, msg, &n_ports,
3260 : &world_writable_control_socket) < 0)
3261 : return -1;
3262 :
3263 : #ifndef HAVE_SYS_UN_H
3264 : if (options->ControlSocket || options->ControlSocketsGroupWritable) {
3265 : *msg = tor_strdup("Unix domain sockets (ControlSocket) not supported "
3266 : "on this OS/with this build.");
3267 : return -1;
3268 : }
3269 : #else /* defined(HAVE_SYS_UN_H) */
3270 566 : if (options->ControlSocketsGroupWritable && !options->ControlSocket) {
3271 1 : *msg = tor_strdup("Setting ControlSocketsGroupWritable without setting "
3272 : "a ControlSocket makes no sense.");
3273 1 : return -1;
3274 : }
3275 : #endif /* !defined(HAVE_SYS_UN_H) */
3276 :
3277 : /* Set UseEntryGuards from the configured value, before we check it below.
3278 : * We change UseEntryGuards when it's incompatible with other options,
3279 : * but leave UseEntryGuards_option with the original value.
3280 : * Always use the value of UseEntryGuards, not UseEntryGuards_option. */
3281 565 : options->UseEntryGuards = options->UseEntryGuards_option;
3282 :
3283 565 : if (options_validate_relay_os(old_options, options, msg) < 0)
3284 : return -1;
3285 :
3286 : /* 31851: OutboundBindAddressExit is unused in client mode */
3287 565 : if (parse_outbound_addresses(options, 1, msg) < 0)
3288 : return -1;
3289 :
3290 564 : if (validate_data_directories(options)<0)
3291 1 : REJECT("Invalid DataDirectory");
3292 :
3293 : /* need to check for relative paths after we populate
3294 : * options->DataDirectory (just above). */
3295 563 : if (warn_about_relative_paths(options) && options->RunAsDaemon) {
3296 1 : REJECT("You have specified at least one relative path (see above) "
3297 : "with the RunAsDaemon option. RunAsDaemon is not compatible "
3298 : "with relative paths.");
3299 : }
3300 :
3301 562 : if (options_validate_relay_info(old_options, options, msg) < 0)
3302 : return -1;
3303 :
3304 : /* 31851: this function is currently a no-op in client mode */
3305 558 : check_network_configuration(server_mode(options));
3306 :
3307 : /* Validate the tor_log(s) */
3308 558 : if (options_init_logs(old_options, options, 1)<0)
3309 1 : REJECT("Failed to validate Log options. See logs for details.");
3310 :
3311 : /* XXXX require that the only port not be DirPort? */
3312 : /* XXXX require that at least one port be listened-upon. */
3313 557 : if (n_ports == 0 && !options->RendConfigLines)
3314 5 : log_warn(LD_CONFIG,
3315 : "SocksPort, TransPort, NATDPort, DNSPort, and ORPort are all "
3316 : "undefined, and there aren't any hidden services configured. "
3317 : "Tor will still run, but probably won't do anything.");
3318 :
3319 557 : options->TransProxyType_parsed = TPT_DEFAULT;
3320 : #ifdef USE_TRANSPARENT
3321 557 : if (options->TransProxyType) {
3322 557 : if (!strcasecmp(options->TransProxyType, "default")) {
3323 : options->TransProxyType_parsed = TPT_DEFAULT;
3324 5 : } else if (!strcasecmp(options->TransProxyType, "pf-divert")) {
3325 : #if !defined(OpenBSD) && !defined(DARWIN)
3326 : /* Later versions of OS X have pf */
3327 1 : REJECT("pf-divert is a OpenBSD-specific "
3328 : "and OS X/Darwin-specific feature.");
3329 : #else
3330 : options->TransProxyType_parsed = TPT_PF_DIVERT;
3331 : #endif /* !defined(OpenBSD) && !defined(DARWIN) */
3332 4 : } else if (!strcasecmp(options->TransProxyType, "tproxy")) {
3333 : #if !defined(__linux__)
3334 : REJECT("TPROXY is a Linux-specific feature.");
3335 : #else
3336 2 : options->TransProxyType_parsed = TPT_TPROXY;
3337 : #endif
3338 2 : } else if (!strcasecmp(options->TransProxyType, "ipfw")) {
3339 : #ifndef KERNEL_MAY_SUPPORT_IPFW
3340 : /* Earlier versions of OS X have ipfw */
3341 1 : REJECT("ipfw is a FreeBSD-specific "
3342 : "and OS X/Darwin-specific feature.");
3343 : #else
3344 : options->TransProxyType_parsed = TPT_IPFW;
3345 : #endif /* !defined(KERNEL_MAY_SUPPORT_IPFW) */
3346 : } else {
3347 1 : REJECT("Unrecognized value for TransProxyType");
3348 : }
3349 :
3350 554 : if (strcasecmp(options->TransProxyType, "default") &&
3351 2 : !options->TransPort_set) {
3352 1 : REJECT("Cannot use TransProxyType without any valid TransPort.");
3353 : }
3354 : }
3355 : #else /* !defined(USE_TRANSPARENT) */
3356 : if (options->TransPort_set)
3357 : REJECT("TransPort is disabled in this build.");
3358 : #endif /* defined(USE_TRANSPARENT) */
3359 :
3360 553 : if (options->TokenBucketRefillInterval <= 0
3361 553 : || options->TokenBucketRefillInterval > 1000) {
3362 2 : REJECT("TokenBucketRefillInterval must be between 1 and 1000 inclusive.");
3363 : }
3364 :
3365 551 : if (options->AssumeReachable && options->AssumeReachableIPv6 == 0) {
3366 0 : REJECT("Cannot set AssumeReachable 1 and AssumeReachableIPv6 0.");
3367 : }
3368 :
3369 551 : if (options->ExcludeExitNodes || options->ExcludeNodes) {
3370 8 : options->ExcludeExitNodesUnion_ = routerset_new();
3371 8 : routerset_union(options->ExcludeExitNodesUnion_,options->ExcludeExitNodes);
3372 8 : routerset_union(options->ExcludeExitNodesUnion_,options->ExcludeNodes);
3373 : }
3374 :
3375 551 : if (options->NodeFamilies) {
3376 6 : options->NodeFamilySets = smartlist_new();
3377 14 : for (cl = options->NodeFamilies; cl; cl = cl->next) {
3378 8 : routerset_t *rs = routerset_new();
3379 8 : if (routerset_parse(rs, cl->value, cl->key) == 0) {
3380 6 : smartlist_add(options->NodeFamilySets, rs);
3381 : } else {
3382 8 : routerset_free(rs);
3383 : }
3384 : }
3385 : }
3386 :
3387 551 : if (options->ExcludeNodes && options->StrictNodes) {
3388 4 : COMPLAIN("You have asked to exclude certain relays from all positions "
3389 : "in your circuits. Expect hidden services and other Tor "
3390 : "features to be broken in unpredictable ways.");
3391 : }
3392 :
3393 551 : if (options_validate_dirauth_mode(old_options, options, msg) < 0)
3394 : return -1;
3395 :
3396 541 : if (options->FetchDirInfoExtraEarly && !options->FetchDirInfoEarly)
3397 1 : REJECT("FetchDirInfoExtraEarly requires that you also set "
3398 : "FetchDirInfoEarly");
3399 :
3400 540 : if (options->ConnLimit <= 0) {
3401 1 : tor_asprintf(msg,
3402 : "ConnLimit must be greater than 0, but was set to %d",
3403 : options->ConnLimit);
3404 1 : return -1;
3405 : }
3406 :
3407 539 : if (options->PathsNeededToBuildCircuits >= 0.0) {
3408 3 : if (options->PathsNeededToBuildCircuits < 0.25) {
3409 1 : log_warn(LD_CONFIG, "PathsNeededToBuildCircuits is too low. Increasing "
3410 : "to 0.25");
3411 1 : options->PathsNeededToBuildCircuits = 0.25;
3412 2 : } else if (options->PathsNeededToBuildCircuits > 0.95) {
3413 1 : log_warn(LD_CONFIG, "PathsNeededToBuildCircuits is too high. Decreasing "
3414 : "to 0.95");
3415 1 : options->PathsNeededToBuildCircuits = 0.95;
3416 : }
3417 : }
3418 :
3419 539 : if (options->MaxClientCircuitsPending <= 0 ||
3420 : options->MaxClientCircuitsPending > MAX_MAX_CLIENT_CIRCUITS_PENDING) {
3421 2 : tor_asprintf(msg,
3422 : "MaxClientCircuitsPending must be between 1 and %d, but "
3423 : "was set to %d", MAX_MAX_CLIENT_CIRCUITS_PENDING,
3424 : options->MaxClientCircuitsPending);
3425 2 : return -1;
3426 : }
3427 :
3428 537 : if (validate_ports_csv(options->FirewallPorts, "FirewallPorts", msg) < 0)
3429 : return -1;
3430 :
3431 536 : if (validate_ports_csv(options->LongLivedPorts, "LongLivedPorts", msg) < 0)
3432 : return -1;
3433 :
3434 535 : if (validate_ports_csv(options->RejectPlaintextPorts,
3435 : "RejectPlaintextPorts", msg) < 0)
3436 : return -1;
3437 :
3438 534 : if (validate_ports_csv(options->WarnPlaintextPorts,
3439 : "WarnPlaintextPorts", msg) < 0)
3440 : return -1;
3441 :
3442 533 : if (options->FascistFirewall && !options->ReachableAddresses) {
3443 4 : if (options->FirewallPorts && smartlist_len(options->FirewallPorts)) {
3444 : /* We already have firewall ports set, so migrate them to
3445 : * ReachableAddresses, which will set ReachableORAddresses and
3446 : * ReachableDirAddresses if they aren't set explicitly. */
3447 1 : smartlist_t *instead = smartlist_new();
3448 1 : config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3449 1 : new_line->key = tor_strdup("ReachableAddresses");
3450 : /* If we're configured with the old format, we need to prepend some
3451 : * open ports. */
3452 2 : SMARTLIST_FOREACH(options->FirewallPorts, const char *, portno,
3453 : {
3454 : int p = atoi(portno);
3455 : if (p<0) continue;
3456 : smartlist_add_asprintf(instead, "*:%d", p);
3457 : });
3458 1 : new_line->value = smartlist_join_strings(instead,",",0,NULL);
3459 : /* These have been deprecated since 0.1.1.5-alpha-cvs */
3460 1 : log_notice(LD_CONFIG,
3461 : "Converting FascistFirewall and FirewallPorts "
3462 : "config options to new format: \"ReachableAddresses %s\"",
3463 : new_line->value);
3464 1 : options->ReachableAddresses = new_line;
3465 2 : SMARTLIST_FOREACH(instead, char *, cp, tor_free(cp));
3466 1 : smartlist_free(instead);
3467 : } else {
3468 : /* We do not have FirewallPorts set, so add 80 to
3469 : * ReachableDirAddresses, and 443 to ReachableORAddresses. */
3470 2 : if (!options->ReachableDirAddresses) {
3471 1 : config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3472 1 : new_line->key = tor_strdup("ReachableDirAddresses");
3473 1 : new_line->value = tor_strdup("*:80");
3474 1 : options->ReachableDirAddresses = new_line;
3475 1 : log_notice(LD_CONFIG, "Converting FascistFirewall config option "
3476 : "to new format: \"ReachableDirAddresses *:80\"");
3477 : }
3478 2 : if (!options->ReachableORAddresses) {
3479 1 : config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
3480 1 : new_line->key = tor_strdup("ReachableORAddresses");
3481 1 : new_line->value = tor_strdup("*:443");
3482 1 : options->ReachableORAddresses = new_line;
3483 1 : log_notice(LD_CONFIG, "Converting FascistFirewall config option "
3484 : "to new format: \"ReachableORAddresses *:443\"");
3485 : }
3486 : }
3487 : }
3488 :
3489 533 : if ((options->ReachableAddresses ||
3490 526 : options->ReachableORAddresses ||
3491 523 : options->ReachableDirAddresses ||
3492 535 : options->ClientUseIPv4 == 0) &&
3493 13 : server_mode(options))
3494 4 : REJECT("Servers must be able to freely connect to the rest "
3495 : "of the Internet, so they must not set Reachable*Addresses "
3496 : "or FascistFirewall or FirewallPorts or ClientUseIPv4 0.");
3497 :
3498 543 : if (options->UseBridges &&
3499 14 : server_mode(options))
3500 1 : REJECT("Servers must be able to freely connect to the rest "
3501 : "of the Internet, so they must not set UseBridges.");
3502 :
3503 : /* If both of these are set, we'll end up with funny behavior where we
3504 : * demand enough entrynodes be up and running else we won't build
3505 : * circuits, yet we never actually use them. */
3506 528 : if (options->UseBridges && options->EntryNodes)
3507 2 : REJECT("You cannot set both UseBridges and EntryNodes.");
3508 :
3509 : /* If we have UseBridges as 1 and UseEntryGuards as 0, we end up bypassing
3510 : * the use of bridges */
3511 526 : if (options->UseBridges && !options->UseEntryGuards)
3512 1 : REJECT("Setting UseBridges requires also setting UseEntryGuards.");
3513 :
3514 1050 : options->MaxMemInQueues =
3515 525 : compute_real_max_mem_in_queues(options->MaxMemInQueues_raw,
3516 525 : server_mode(options));
3517 525 : options->MaxMemInQueues_low_threshold = (options->MaxMemInQueues / 4) * 3;
3518 :
3519 525 : if (!options->SafeLogging ||
3520 525 : !strcasecmp(options->SafeLogging, "0")) {
3521 5 : options->SafeLogging_ = SAFELOG_SCRUB_NONE;
3522 520 : } else if (!strcasecmp(options->SafeLogging, "relay")) {
3523 1 : options->SafeLogging_ = SAFELOG_SCRUB_RELAY;
3524 519 : } else if (!strcasecmp(options->SafeLogging, "1")) {
3525 518 : options->SafeLogging_ = SAFELOG_SCRUB_ALL;
3526 : } else {
3527 1 : tor_asprintf(msg,
3528 : "Unrecognized value '%s' in SafeLogging",
3529 : escaped(options->SafeLogging));
3530 1 : return -1;
3531 : }
3532 :
3533 524 : if (options_validate_publish_server(old_options, options, msg) < 0)
3534 : return -1;
3535 :
3536 518 : if (options_validate_relay_padding(old_options, options, msg) < 0)
3537 : return -1;
3538 :
3539 1026 : const int min_rendpostperiod =
3540 513 : options->TestingTorNetwork ?
3541 513 : MIN_REND_POST_PERIOD_TESTING : MIN_REND_POST_PERIOD;
3542 513 : if (options->RendPostPeriod < min_rendpostperiod) {
3543 1 : log_warn(LD_CONFIG, "RendPostPeriod option is too short; "
3544 : "raising to %d seconds.", min_rendpostperiod);
3545 1 : options->RendPostPeriod = min_rendpostperiod;
3546 : }
3547 :
3548 513 : if (options->RendPostPeriod > MAX_DIR_PERIOD) {
3549 1 : log_warn(LD_CONFIG, "RendPostPeriod is too large; clipping to %ds.",
3550 : MAX_DIR_PERIOD);
3551 1 : options->RendPostPeriod = MAX_DIR_PERIOD;
3552 : }
3553 :
3554 : /* Check the Single Onion Service options */
3555 513 : if (options_validate_single_onion(options, msg) < 0)
3556 : return -1;
3557 :
3558 508 : if (options->CircuitsAvailableTimeout > MAX_CIRCS_AVAILABLE_TIME) {
3559 : // options_t is immutable for new code (the above code is older),
3560 : // so just make the user fix the value themselves rather than
3561 : // silently keep a shadow value lower than what they asked for.
3562 0 : REJECT("CircuitsAvailableTimeout is too large. Max is 24 hours.");
3563 : }
3564 :
3565 508 : if (options->EntryNodes && !options->UseEntryGuards) {
3566 1 : REJECT("If EntryNodes is set, UseEntryGuards must be enabled.");
3567 : }
3568 :
3569 507 : if (!(options->UseEntryGuards) &&
3570 65 : (options->RendConfigLines != NULL) &&
3571 2 : !hs_service_allow_non_anonymous_connection(options)) {
3572 1 : log_warn(LD_CONFIG,
3573 : "UseEntryGuards is disabled, but you have configured one or more "
3574 : "hidden services on this Tor instance. Your hidden services "
3575 : "will be very easy to locate using a well-known attack -- see "
3576 : "https://freehaven.net/anonbib/#hs-attack06 for details.");
3577 : }
3578 :
3579 507 : if (options->NumPrimaryGuards && options->NumEntryGuards &&
3580 : options->NumEntryGuards > options->NumPrimaryGuards) {
3581 0 : REJECT("NumEntryGuards must not be greater than NumPrimaryGuards.");
3582 : }
3583 :
3584 520 : if (options->EntryNodes &&
3585 16 : routerset_is_list(options->EntryNodes) &&
3586 3 : (routerset_len(options->EntryNodes) == 1) &&
3587 0 : (options->RendConfigLines != NULL)) {
3588 0 : tor_asprintf(msg,
3589 : "You have one single EntryNodes and at least one hidden service "
3590 : "configured. This is bad because it's very easy to locate your "
3591 : "entry guard which can then lead to the deanonymization of your "
3592 : "hidden service -- for more details, see "
3593 : "https://bugs.torproject.org/tpo/core/tor/14917. "
3594 : "For this reason, the use of one EntryNodes with an hidden "
3595 : "service is prohibited until a better solution is found.");
3596 0 : return -1;
3597 : }
3598 :
3599 : /* Inform the hidden service operator that pinning EntryNodes can possibly
3600 : * be harmful for the service anonymity. */
3601 520 : if (options->EntryNodes &&
3602 13 : routerset_is_list(options->EntryNodes) &&
3603 3 : (options->RendConfigLines != NULL)) {
3604 0 : log_warn(LD_CONFIG,
3605 : "EntryNodes is set with multiple entries and at least one "
3606 : "hidden service is configured. Pinning entry nodes can possibly "
3607 : "be harmful to the service anonymity. Because of this, we "
3608 : "recommend you either don't do that or make sure you know what "
3609 : "you are doing. For more details, please look at "
3610 : "https://bugs.torproject.org/tpo/core/tor/21155.");
3611 : }
3612 :
3613 : /* Single Onion Services: non-anonymous hidden services */
3614 507 : if (hs_service_non_anonymous_mode_enabled(options)) {
3615 3 : log_warn(LD_CONFIG,
3616 : "HiddenServiceNonAnonymousMode is set. Every hidden service on "
3617 : "this tor instance is NON-ANONYMOUS. If "
3618 : "the HiddenServiceNonAnonymousMode option is changed, Tor will "
3619 : "refuse to launch hidden services from the same directories, to "
3620 : "protect your anonymity against config errors. This setting is "
3621 : "for experimental use only.");
3622 : }
3623 :
3624 507 : if (!options->LearnCircuitBuildTimeout && options->CircuitBuildTimeout &&
3625 : options->CircuitBuildTimeout < RECOMMENDED_MIN_CIRCUIT_BUILD_TIMEOUT) {
3626 1 : log_warn(LD_CONFIG,
3627 : "CircuitBuildTimeout is shorter (%d seconds) than the recommended "
3628 : "minimum (%d seconds), and LearnCircuitBuildTimeout is disabled. "
3629 : "If tor isn't working, raise this value or enable "
3630 : "LearnCircuitBuildTimeout.",
3631 : options->CircuitBuildTimeout,
3632 : RECOMMENDED_MIN_CIRCUIT_BUILD_TIMEOUT );
3633 506 : } else if (!options->LearnCircuitBuildTimeout &&
3634 0 : !options->CircuitBuildTimeout) {
3635 0 : int severity = LOG_NOTICE;
3636 : /* Be a little quieter if we've deliberately disabled
3637 : * LearnCircuitBuildTimeout. */
3638 0 : if (circuit_build_times_disabled_(options, 1)) {
3639 0 : severity = LOG_INFO;
3640 : }
3641 0 : log_fn(severity, LD_CONFIG, "You disabled LearnCircuitBuildTimeout, but "
3642 : "didn't specify a CircuitBuildTimeout. I'll pick a plausible "
3643 : "default.");
3644 : }
3645 :
3646 507 : if (options->DormantClientTimeout < 10*60 && !options->TestingTorNetwork) {
3647 0 : REJECT("DormantClientTimeout is too low. It must be at least 10 minutes.");
3648 : }
3649 :
3650 507 : if (options->PathBiasNoticeRate > 1.0) {
3651 1 : tor_asprintf(msg,
3652 : "PathBiasNoticeRate is too high. "
3653 : "It must be between 0 and 1.0");
3654 1 : return -1;
3655 : }
3656 506 : if (options->PathBiasWarnRate > 1.0) {
3657 1 : tor_asprintf(msg,
3658 : "PathBiasWarnRate is too high. "
3659 : "It must be between 0 and 1.0");
3660 1 : return -1;
3661 : }
3662 505 : if (options->PathBiasExtremeRate > 1.0) {
3663 1 : tor_asprintf(msg,
3664 : "PathBiasExtremeRate is too high. "
3665 : "It must be between 0 and 1.0");
3666 1 : return -1;
3667 : }
3668 504 : if (options->PathBiasNoticeUseRate > 1.0) {
3669 1 : tor_asprintf(msg,
3670 : "PathBiasNoticeUseRate is too high. "
3671 : "It must be between 0 and 1.0");
3672 1 : return -1;
3673 : }
3674 503 : if (options->PathBiasExtremeUseRate > 1.0) {
3675 1 : tor_asprintf(msg,
3676 : "PathBiasExtremeUseRate is too high. "
3677 : "It must be between 0 and 1.0");
3678 1 : return -1;
3679 : }
3680 :
3681 502 : if (options->MaxCircuitDirtiness < MIN_MAX_CIRCUIT_DIRTINESS) {
3682 0 : log_warn(LD_CONFIG, "MaxCircuitDirtiness option is too short; "
3683 : "raising to %d seconds.", MIN_MAX_CIRCUIT_DIRTINESS);
3684 0 : options->MaxCircuitDirtiness = MIN_MAX_CIRCUIT_DIRTINESS;
3685 : }
3686 :
3687 502 : if (options->MaxCircuitDirtiness > MAX_MAX_CIRCUIT_DIRTINESS) {
3688 1 : log_warn(LD_CONFIG, "MaxCircuitDirtiness option is too high; "
3689 : "setting to %d days.", MAX_MAX_CIRCUIT_DIRTINESS/86400);
3690 1 : options->MaxCircuitDirtiness = MAX_MAX_CIRCUIT_DIRTINESS;
3691 : }
3692 :
3693 502 : if (options->CircuitStreamTimeout &&
3694 : options->CircuitStreamTimeout < MIN_CIRCUIT_STREAM_TIMEOUT) {
3695 1 : log_warn(LD_CONFIG, "CircuitStreamTimeout option is too short; "
3696 : "raising to %d seconds.", MIN_CIRCUIT_STREAM_TIMEOUT);
3697 1 : options->CircuitStreamTimeout = MIN_CIRCUIT_STREAM_TIMEOUT;
3698 : }
3699 :
3700 502 : if (options->HeartbeatPeriod &&
3701 1 : options->HeartbeatPeriod < MIN_HEARTBEAT_PERIOD &&
3702 1 : !options->TestingTorNetwork) {
3703 1 : log_warn(LD_CONFIG, "HeartbeatPeriod option is too short; "
3704 : "raising to %d seconds.", MIN_HEARTBEAT_PERIOD);
3705 1 : options->HeartbeatPeriod = MIN_HEARTBEAT_PERIOD;
3706 : }
3707 :
3708 502 : if (options->KeepalivePeriod < 1)
3709 0 : REJECT("KeepalivePeriod option must be positive.");
3710 :
3711 502 : if (config_ensure_bandwidth_cap(&options->BandwidthRate,
3712 : "BandwidthRate", msg) < 0)
3713 : return -1;
3714 499 : if (config_ensure_bandwidth_cap(&options->BandwidthBurst,
3715 : "BandwidthBurst", msg) < 0)
3716 : return -1;
3717 :
3718 496 : if (options_validate_relay_bandwidth(old_options, options, msg) < 0)
3719 : return -1;
3720 :
3721 477 : if (options->BandwidthRate > options->BandwidthBurst)
3722 1 : REJECT("BandwidthBurst must be at least equal to BandwidthRate.");
3723 :
3724 476 : if (options_validate_relay_accounting(old_options, options, msg) < 0)
3725 : return -1;
3726 :
3727 474 : if (options_validate_relay_mode(old_options, options, msg) < 0)
3728 : return -1;
3729 :
3730 471 : if (options->HTTPProxy) { /* parse it now */
3731 7 : if (tor_addr_port_lookup(options->HTTPProxy,
3732 7 : &options->HTTPProxyAddr, &options->HTTPProxyPort) < 0)
3733 1 : REJECT("HTTPProxy failed to parse or resolve. Please fix.");
3734 6 : if (options->HTTPProxyPort == 0) { /* give it a default */
3735 5 : options->HTTPProxyPort = 80;
3736 : }
3737 : }
3738 :
3739 470 : if (options->HTTPProxyAuthenticator) {
3740 2 : if (strlen(options->HTTPProxyAuthenticator) >= 512)
3741 1 : REJECT("HTTPProxyAuthenticator is too long (>= 512 chars).");
3742 : }
3743 :
3744 469 : if (options->HTTPSProxy) { /* parse it now */
3745 4 : if (tor_addr_port_lookup(options->HTTPSProxy,
3746 4 : &options->HTTPSProxyAddr, &options->HTTPSProxyPort) <0)
3747 1 : REJECT("HTTPSProxy failed to parse or resolve. Please fix.");
3748 3 : if (options->HTTPSProxyPort == 0) { /* give it a default */
3749 2 : options->HTTPSProxyPort = 443;
3750 : }
3751 : }
3752 :
3753 468 : if (options->HTTPSProxyAuthenticator) {
3754 2 : if (strlen(options->HTTPSProxyAuthenticator) >= 512)
3755 1 : REJECT("HTTPSProxyAuthenticator is too long (>= 512 chars).");
3756 : }
3757 :
3758 467 : if (options->Socks4Proxy) { /* parse it now */
3759 5 : if (tor_addr_port_lookup(options->Socks4Proxy,
3760 5 : &options->Socks4ProxyAddr,
3761 : &options->Socks4ProxyPort) <0)
3762 1 : REJECT("Socks4Proxy failed to parse or resolve. Please fix.");
3763 4 : if (options->Socks4ProxyPort == 0) { /* give it a default */
3764 3 : options->Socks4ProxyPort = 1080;
3765 : }
3766 : }
3767 :
3768 466 : if (options->Socks5Proxy) { /* parse it now */
3769 8 : if (tor_addr_port_lookup(options->Socks5Proxy,
3770 8 : &options->Socks5ProxyAddr,
3771 : &options->Socks5ProxyPort) <0)
3772 1 : REJECT("Socks5Proxy failed to parse or resolve. Please fix.");
3773 7 : if (options->Socks5ProxyPort == 0) { /* give it a default */
3774 3 : options->Socks5ProxyPort = 1080;
3775 : }
3776 : }
3777 :
3778 465 : if (options->TCPProxy) {
3779 0 : int res = parse_tcp_proxy_line(options->TCPProxy, options, msg);
3780 0 : if (res < 0) {
3781 : return res;
3782 : }
3783 : }
3784 :
3785 : /* Check if more than one exclusive proxy type has been enabled. */
3786 465 : if (!!options->Socks4Proxy + !!options->Socks5Proxy +
3787 465 : !!options->HTTPSProxy + !!options->TCPProxy > 1)
3788 1 : REJECT("You have configured more than one proxy type. "
3789 : "(Socks4Proxy|Socks5Proxy|HTTPSProxy|TCPProxy)");
3790 :
3791 : /* Check if the proxies will give surprising behavior. */
3792 467 : if (options->HTTPProxy && !(options->Socks4Proxy ||
3793 4 : options->Socks5Proxy ||
3794 : options->HTTPSProxy ||
3795 : options->TCPProxy)) {
3796 3 : log_warn(LD_CONFIG, "HTTPProxy configured, but no SOCKS proxy, "
3797 : "HTTPS proxy, or any other TCP proxy configured. Watch out: "
3798 : "this configuration will proxy unencrypted directory "
3799 : "connections only.");
3800 : }
3801 :
3802 464 : if (options->Socks5ProxyUsername) {
3803 9 : size_t len;
3804 :
3805 9 : len = strlen(options->Socks5ProxyUsername);
3806 9 : if (len < 1 || len > MAX_SOCKS5_AUTH_FIELD_SIZE)
3807 2 : REJECT("Socks5ProxyUsername must be between 1 and 255 characters.");
3808 :
3809 7 : if (!options->Socks5ProxyPassword)
3810 1 : REJECT("Socks5ProxyPassword must be included with Socks5ProxyUsername.");
3811 :
3812 6 : len = strlen(options->Socks5ProxyPassword);
3813 6 : if (len < 1 || len > MAX_SOCKS5_AUTH_FIELD_SIZE)
3814 2 : REJECT("Socks5ProxyPassword must be between 1 and 255 characters.");
3815 455 : } else if (options->Socks5ProxyPassword)
3816 1 : REJECT("Socks5ProxyPassword must be included with Socks5ProxyUsername.");
3817 :
3818 458 : if (options->HashedControlPassword) {
3819 4 : smartlist_t *sl = decode_hashed_passwords(options->HashedControlPassword);
3820 4 : if (!sl) {
3821 1 : REJECT("Bad HashedControlPassword: wrong length or bad encoding");
3822 : } else {
3823 6 : SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
3824 3 : smartlist_free(sl);
3825 : }
3826 : }
3827 :
3828 457 : if (options->HashedControlSessionPassword) {
3829 4 : smartlist_t *sl = decode_hashed_passwords(
3830 : options->HashedControlSessionPassword);
3831 4 : if (!sl) {
3832 1 : REJECT("Bad HashedControlSessionPassword: wrong length or bad encoding");
3833 : } else {
3834 6 : SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
3835 3 : smartlist_free(sl);
3836 : }
3837 : }
3838 :
3839 456 : if (options->OwningControllerProcess) {
3840 2 : const char *validate_pspec_msg = NULL;
3841 2 : if (tor_validate_process_specifier(options->OwningControllerProcess,
3842 : &validate_pspec_msg)) {
3843 1 : tor_asprintf(msg, "Bad OwningControllerProcess: %s",
3844 : validate_pspec_msg);
3845 1 : return -1;
3846 : }
3847 : }
3848 :
3849 455 : if ((options->ControlPort_set || world_writable_control_socket) &&
3850 11 : !options->HashedControlPassword &&
3851 9 : !options->HashedControlSessionPassword &&
3852 7 : !options->CookieAuthentication) {
3853 4 : log_warn(LD_CONFIG, "Control%s is %s, but no authentication method "
3854 : "has been configured. This means that any program on your "
3855 : "computer can reconfigure your Tor. That's bad! You should "
3856 : "upgrade your Tor controller as soon as possible.",
3857 : options->ControlPort_set ? "Port" : "Socket",
3858 : options->ControlPort_set ? "open" : "world writable");
3859 : }
3860 :
3861 455 : if (options->CookieAuthFileGroupReadable && !options->CookieAuthFile) {
3862 1 : log_warn(LD_CONFIG, "CookieAuthFileGroupReadable is set, but will have "
3863 : "no effect: you must specify an explicit CookieAuthFile to "
3864 : "have it group-readable.");
3865 : }
3866 :
3867 461 : for (cl = options->NodeFamilies; cl; cl = cl->next) {
3868 8 : routerset_t *rs = routerset_new();
3869 8 : if (routerset_parse(rs, cl->value, cl->key)) {
3870 2 : routerset_free(rs);
3871 2 : return -1;
3872 : }
3873 6 : routerset_free(rs);
3874 : }
3875 :
3876 453 : if (validate_addr_policies(options, msg) < 0)
3877 : return -1;
3878 :
3879 : /* If FallbackDir is set, we don't UseDefaultFallbackDirs */
3880 452 : if (options->UseDefaultFallbackDirs && options->FallbackDir) {
3881 0 : log_info(LD_CONFIG, "You have set UseDefaultFallbackDirs 1 and "
3882 : "FallbackDir(s). Ignoring UseDefaultFallbackDirs, and "
3883 : "using the FallbackDir(s) you have set.");
3884 : }
3885 :
3886 452 : if (validate_dir_servers(options, old_options) < 0)
3887 1 : REJECT("Directory authority/fallback line did not parse. See logs "
3888 : "for details.");
3889 :
3890 451 : if (options->UseBridges && !options->Bridges)
3891 2 : REJECT("If you set UseBridges, you must specify at least one bridge.");
3892 :
3893 460 : for (cl = options->Bridges; cl; cl = cl->next) {
3894 12 : bridge_line_t *bridge_line = parse_bridge_line(cl->value);
3895 12 : if (!bridge_line)
3896 1 : REJECT("Bridge line did not parse. See logs for details.");
3897 11 : bridge_line_free(bridge_line);
3898 : }
3899 :
3900 449 : for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
3901 2 : if (pt_parse_transport_line(options, cl->value, 1, 0) < 0)
3902 1 : REJECT("Invalid client transport line. See logs for details.");
3903 : }
3904 :
3905 447 : if (options_validate_server_transport(old_options, options, msg) < 0)
3906 : return -1;
3907 :
3908 442 : if (options->ConstrainedSockets) {
3909 : /* If the user wants to constrain socket buffer use, make sure the desired
3910 : * limit is between MIN|MAX_TCPSOCK_BUFFER in k increments. */
3911 6 : if (options->ConstrainedSockSize < MIN_CONSTRAINED_TCP_BUFFER ||
3912 3 : options->ConstrainedSockSize > MAX_CONSTRAINED_TCP_BUFFER ||
3913 3 : options->ConstrainedSockSize % 1024) {
3914 3 : tor_asprintf(msg,
3915 : "ConstrainedSockSize is invalid. Must be a value between %d and %d "
3916 : "in 1024 byte increments.",
3917 : MIN_CONSTRAINED_TCP_BUFFER, MAX_CONSTRAINED_TCP_BUFFER);
3918 3 : return -1;
3919 : }
3920 : }
3921 :
3922 439 : if (options_validate_dirauth_schedule(old_options, options, msg) < 0)
3923 : return -1;
3924 :
3925 430 : if (hs_config_service_all(options, 1) < 0)
3926 1 : REJECT("Failed to configure rendezvous options. See logs for details.");
3927 :
3928 : /* Parse client-side authorization for hidden services. */
3929 429 : if (hs_config_client_auth_all(options, 1) < 0)
3930 0 : REJECT("Failed to configure client authorization for hidden services. "
3931 : "See logs for details.");
3932 :
3933 429 : if (parse_virtual_addr_network(options->VirtualAddrNetworkIPv4,
3934 : AF_INET, 1, msg)<0)
3935 : return -1;
3936 428 : if (parse_virtual_addr_network(options->VirtualAddrNetworkIPv6,
3937 : AF_INET6, 1, msg)<0)
3938 : return -1;
3939 :
3940 427 : if (options->TestingTorNetwork &&
3941 49 : !(options->DirAuthorities ||
3942 4 : (options->AlternateDirAuthority &&
3943 2 : options->AlternateBridgeAuthority))) {
3944 3 : REJECT("TestingTorNetwork may only be configured in combination with "
3945 : "a non-default set of DirAuthority or both of "
3946 : "AlternateDirAuthority and AlternateBridgeAuthority configured.");
3947 : }
3948 :
3949 : #define CHECK_DEFAULT(arg) \
3950 : STMT_BEGIN \
3951 : if (!config_is_same(get_options_mgr(),options, \
3952 : dflt_options,#arg)) { \
3953 : or_options_free(dflt_options); \
3954 : REJECT(#arg " may only be changed in testing Tor " \
3955 : "networks!"); \
3956 : } \
3957 : STMT_END
3958 :
3959 : /* Check for options that can only be changed from the defaults in testing
3960 : networks. */
3961 424 : if (! options->TestingTorNetwork && !options->UsingTestNetworkDefaults_) {
3962 357 : or_options_t *dflt_options = options_new();
3963 357 : options_init(dflt_options);
3964 : /* 31851: some of these options are dirauth or relay only */
3965 357 : CHECK_DEFAULT(TestingV3AuthInitialVotingInterval);
3966 356 : CHECK_DEFAULT(TestingV3AuthInitialVoteDelay);
3967 355 : CHECK_DEFAULT(TestingV3AuthInitialDistDelay);
3968 354 : CHECK_DEFAULT(TestingV3AuthVotingStartOffset);
3969 353 : CHECK_DEFAULT(TestingAuthDirTimeToLearnReachability);
3970 352 : CHECK_DEFAULT(TestingServerDownloadInitialDelay);
3971 351 : CHECK_DEFAULT(TestingClientDownloadInitialDelay);
3972 350 : CHECK_DEFAULT(TestingServerConsensusDownloadInitialDelay);
3973 349 : CHECK_DEFAULT(TestingClientConsensusDownloadInitialDelay);
3974 348 : CHECK_DEFAULT(TestingBridgeDownloadInitialDelay);
3975 347 : CHECK_DEFAULT(TestingBridgeBootstrapDownloadInitialDelay);
3976 346 : CHECK_DEFAULT(TestingClientMaxIntervalWithoutRequest);
3977 345 : CHECK_DEFAULT(TestingDirConnectionMaxStall);
3978 344 : CHECK_DEFAULT(TestingAuthKeyLifetime);
3979 343 : CHECK_DEFAULT(TestingLinkCertLifetime);
3980 342 : CHECK_DEFAULT(TestingSigningKeySlop);
3981 341 : CHECK_DEFAULT(TestingAuthKeySlop);
3982 340 : CHECK_DEFAULT(TestingLinkKeySlop);
3983 339 : or_options_free(dflt_options);
3984 : }
3985 : #undef CHECK_DEFAULT
3986 :
3987 406 : if (!options->ClientDNSRejectInternalAddresses &&
3988 0 : !(options->DirAuthorities ||
3989 0 : (options->AlternateDirAuthority && options->AlternateBridgeAuthority)))
3990 0 : REJECT("ClientDNSRejectInternalAddresses used for default network.");
3991 :
3992 406 : if (options_validate_relay_testing(old_options, options, msg) < 0)
3993 : return -1;
3994 401 : if (options_validate_dirauth_testing(old_options, options, msg) < 0)
3995 : return -1;
3996 :
3997 394 : if (options->TestingClientMaxIntervalWithoutRequest < 1) {
3998 3 : REJECT("TestingClientMaxIntervalWithoutRequest is way too low.");
3999 391 : } else if (options->TestingClientMaxIntervalWithoutRequest > 3600) {
4000 3 : COMPLAIN("TestingClientMaxIntervalWithoutRequest is insanely high.");
4001 : }
4002 :
4003 391 : if (options->TestingDirConnectionMaxStall < 5) {
4004 3 : REJECT("TestingDirConnectionMaxStall is way too low.");
4005 388 : } else if (options->TestingDirConnectionMaxStall > 3600) {
4006 3 : COMPLAIN("TestingDirConnectionMaxStall is insanely high.");
4007 : }
4008 :
4009 388 : if (options->ClientBootstrapConsensusMaxInProgressTries < 1) {
4010 0 : REJECT("ClientBootstrapConsensusMaxInProgressTries must be greater "
4011 : "than 0.");
4012 388 : } else if (options->ClientBootstrapConsensusMaxInProgressTries
4013 : > 100) {
4014 0 : COMPLAIN("ClientBootstrapConsensusMaxInProgressTries is insanely "
4015 : "high.");
4016 : }
4017 :
4018 388 : if (options->TestingEnableConnBwEvent &&
4019 3 : !options->TestingTorNetwork && !options->UsingTestNetworkDefaults_) {
4020 1 : REJECT("TestingEnableConnBwEvent may only be changed in testing "
4021 : "Tor networks!");
4022 : }
4023 :
4024 387 : if (options->TestingEnableCellStatsEvent &&
4025 3 : !options->TestingTorNetwork && !options->UsingTestNetworkDefaults_) {
4026 1 : REJECT("TestingEnableCellStatsEvent may only be changed in testing "
4027 : "Tor networks!");
4028 : }
4029 :
4030 386 : if (options->TestingTorNetwork) {
4031 31 : log_warn(LD_CONFIG, "TestingTorNetwork is set. This will make your node "
4032 : "almost unusable in the public Tor network, and is "
4033 : "therefore only advised if you are building a "
4034 : "testing Tor network!");
4035 : }
4036 :
4037 386 : if (options_validate_scheduler(options, msg) < 0) {
4038 0 : return -1;
4039 : }
4040 :
4041 : return 0;
4042 : }
4043 :
4044 : #undef REJECT
4045 : #undef COMPLAIN
4046 :
4047 : /* Given the value that the user has set for MaxMemInQueues, compute the
4048 : * actual maximum value. We clip this value if it's too low, and autodetect
4049 : * it if it's set to 0. */
4050 : STATIC uint64_t
4051 531 : compute_real_max_mem_in_queues(const uint64_t val, bool is_server)
4052 : {
4053 : #define MIN_SERVER_MB 64
4054 : #define MIN_UNWARNED_SERVER_MB 256
4055 : #define MIN_UNWARNED_CLIENT_MB 64
4056 531 : uint64_t result;
4057 :
4058 531 : if (val == 0) {
4059 : #define ONE_GIGABYTE (UINT64_C(1) << 30)
4060 : #define ONE_MEGABYTE (UINT64_C(1) << 20)
4061 : /* The user didn't pick a memory limit. Choose a very large one
4062 : * that is still smaller than the system memory */
4063 528 : static int notice_sent = 0;
4064 528 : size_t ram = 0;
4065 528 : if (get_total_system_memory(&ram) < 0) {
4066 : /* We couldn't determine our total system memory! */
4067 : #if SIZEOF_VOID_P >= 8
4068 : /* 64-bit system. Let's hope for 8 GB. */
4069 : result = 8 * ONE_GIGABYTE;
4070 : #else
4071 : /* (presumably) 32-bit system. Let's hope for 1 GB. */
4072 : result = ONE_GIGABYTE;
4073 : #endif /* SIZEOF_VOID_P >= 8 */
4074 : } else {
4075 : /* We detected the amount of memory available. */
4076 527 : uint64_t avail = 0;
4077 :
4078 : #if SIZEOF_SIZE_T > 4
4079 : /* On a 64-bit platform, we consider 8GB "very large". */
4080 : #define RAM_IS_VERY_LARGE(x) ((x) >= (8 * ONE_GIGABYTE))
4081 : #else
4082 : /* On a 32-bit platform, we can't have 8GB of ram. */
4083 : #define RAM_IS_VERY_LARGE(x) (0)
4084 : #endif /* SIZEOF_SIZE_T > 4 */
4085 :
4086 527 : if (RAM_IS_VERY_LARGE(ram)) {
4087 : /* If we have 8 GB, or more, RAM available, we set the MaxMemInQueues
4088 : * to 0.4 * RAM. The idea behind this value is that the amount of RAM
4089 : * is more than enough for a single relay and should allow the relay
4090 : * operator to run two relays if they have additional bandwidth
4091 : * available.
4092 : */
4093 525 : avail = (ram / 5) * 2;
4094 : } else {
4095 : /* If we have less than 8 GB of RAM available, we use the "old" default
4096 : * for MaxMemInQueues of 0.75 * RAM.
4097 : */
4098 2 : avail = (ram / 4) * 3;
4099 : }
4100 :
4101 : /* Make sure it's in range from 0.25 GB to 8 GB for 64-bit and 0.25 to 2
4102 : * GB for 32-bit. */
4103 527 : if (avail > MAX_DEFAULT_MEMORY_QUEUE_SIZE) {
4104 : /* If you want to use more than this much RAM, you need to configure
4105 : it yourself */
4106 : result = MAX_DEFAULT_MEMORY_QUEUE_SIZE;
4107 : } else if (avail < ONE_GIGABYTE / 4) {
4108 : result = ONE_GIGABYTE / 4;
4109 : } else {
4110 : result = avail;
4111 : }
4112 : }
4113 528 : if (is_server && ! notice_sent) {
4114 135 : log_notice(LD_CONFIG, "%sMaxMemInQueues is set to %"PRIu64" MB. "
4115 : "You can override this by setting MaxMemInQueues by hand.",
4116 : ram ? "Based on detected system memory, " : "",
4117 : (result / ONE_MEGABYTE));
4118 135 : notice_sent = 1;
4119 : }
4120 528 : return result;
4121 3 : } else if (is_server && val < ONE_MEGABYTE * MIN_SERVER_MB) {
4122 : /* We can't configure less than this much on a server. */
4123 0 : log_warn(LD_CONFIG, "MaxMemInQueues must be at least %d MB on servers "
4124 : "for now. Ideally, have it as large as you can afford.",
4125 : MIN_SERVER_MB);
4126 0 : return MIN_SERVER_MB * ONE_MEGABYTE;
4127 3 : } else if (is_server && val < ONE_MEGABYTE * MIN_UNWARNED_SERVER_MB) {
4128 : /* On a server, if it's less than this much, we warn that things
4129 : * may go badly. */
4130 0 : log_warn(LD_CONFIG, "MaxMemInQueues is set to a low value; if your "
4131 : "relay doesn't work, this may be the reason why.");
4132 0 : return val;
4133 3 : } else if (! is_server && val < ONE_MEGABYTE * MIN_UNWARNED_CLIENT_MB) {
4134 : /* On a client, if it's less than this much, we warn that things
4135 : * may go badly. */
4136 0 : log_warn(LD_CONFIG, "MaxMemInQueues is set to a low value; if your "
4137 : "client doesn't work, this may be the reason why.");
4138 0 : return val;
4139 : } else {
4140 : /* The value was fine all along */
4141 : return val;
4142 : }
4143 : }
4144 :
4145 : /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
4146 : * equal strings. */
4147 : static int
4148 0 : opt_streq(const char *s1, const char *s2)
4149 : {
4150 0 : return 0 == strcmp_opt(s1, s2);
4151 : }
4152 :
4153 : /** Check if any config options have changed but aren't allowed to. */
4154 : static int
4155 5 : options_check_transition_cb(const void *old_,
4156 : const void *new_val_,
4157 : char **msg)
4158 : {
4159 5 : CHECK_OPTIONS_MAGIC(old_);
4160 5 : CHECK_OPTIONS_MAGIC(new_val_);
4161 :
4162 5 : const or_options_t *old = old_;
4163 5 : const or_options_t *new_val = new_val_;
4164 :
4165 5 : if (BUG(!old))
4166 0 : return 0;
4167 :
4168 : #define BAD_CHANGE_TO(opt, how) do { \
4169 : *msg = tor_strdup("While Tor is running"how", changing " #opt \
4170 : " is not allowed"); \
4171 : return -1; \
4172 : } while (0)
4173 :
4174 5 : if (sandbox_is_active()) {
4175 : #define SB_NOCHANGE_STR(opt) \
4176 : if (! CFG_EQ_STRING(old, new_val, opt)) \
4177 : BAD_CHANGE_TO(opt," with Sandbox active")
4178 : #define SB_NOCHANGE_LINELIST(opt) \
4179 : if (! CFG_EQ_LINELIST(old, new_val, opt)) \
4180 : BAD_CHANGE_TO(opt," with Sandbox active")
4181 : #define SB_NOCHANGE_INT(opt) \
4182 : if (! CFG_EQ_INT(old, new_val, opt)) \
4183 : BAD_CHANGE_TO(opt," with Sandbox active")
4184 :
4185 0 : SB_NOCHANGE_LINELIST(Address);
4186 0 : SB_NOCHANGE_STR(ServerDNSResolvConfFile);
4187 0 : SB_NOCHANGE_STR(DirPortFrontPage);
4188 0 : SB_NOCHANGE_STR(CookieAuthFile);
4189 0 : SB_NOCHANGE_STR(ExtORPortCookieAuthFile);
4190 0 : SB_NOCHANGE_LINELIST(Logs);
4191 0 : SB_NOCHANGE_INT(ConnLimit);
4192 :
4193 0 : if (server_mode(old) != server_mode(new_val)) {
4194 0 : *msg = tor_strdup("Can't start/stop being a server while "
4195 : "Sandbox is active");
4196 0 : return -1;
4197 : }
4198 : }
4199 :
4200 : #undef SB_NOCHANGE_LINELIST
4201 : #undef SB_NOCHANGE_STR
4202 : #undef SB_NOCHANGE_INT
4203 : #undef BAD_CHANGE_TO
4204 : #undef NO_CHANGE_BOOL
4205 : #undef NO_CHANGE_INT
4206 : #undef NO_CHANGE_STRING
4207 : return 0;
4208 : }
4209 :
4210 : #ifdef _WIN32
4211 : /** Return the directory on windows where we expect to find our application
4212 : * data. */
4213 : static char *
4214 : get_windows_conf_root(void)
4215 : {
4216 : static int is_set = 0;
4217 : static char path[MAX_PATH*2+1];
4218 : TCHAR tpath[MAX_PATH] = {0};
4219 :
4220 : LPITEMIDLIST idl;
4221 : IMalloc *m;
4222 : HRESULT result;
4223 :
4224 : if (is_set)
4225 : return path;
4226 :
4227 : /* Find X:\documents and settings\username\application data\ .
4228 : * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
4229 : */
4230 : #ifdef ENABLE_LOCAL_APPDATA
4231 : #define APPDATA_PATH CSIDL_LOCAL_APPDATA
4232 : #else
4233 : #define APPDATA_PATH CSIDL_APPDATA
4234 : #endif
4235 : if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, APPDATA_PATH, &idl))) {
4236 : getcwd(path,MAX_PATH);
4237 : is_set = 1;
4238 : log_warn(LD_CONFIG,
4239 : "I couldn't find your application data folder: are you "
4240 : "running an ancient version of Windows 95? Defaulting to \"%s\"",
4241 : path);
4242 : return path;
4243 : }
4244 : /* Convert the path from an "ID List" (whatever that is!) to a path. */
4245 : result = SHGetPathFromIDList(idl, tpath);
4246 : #ifdef UNICODE
4247 : wcstombs(path,tpath,sizeof(path));
4248 : path[sizeof(path)-1] = '\0';
4249 : #else
4250 : strlcpy(path,tpath,sizeof(path));
4251 : #endif /* defined(UNICODE) */
4252 :
4253 : /* Now we need to free the memory that the path-idl was stored in. In
4254 : * typical Windows fashion, we can't just call 'free()' on it. */
4255 : SHGetMalloc(&m);
4256 : if (m) {
4257 : m->lpVtbl->Free(m, idl);
4258 : m->lpVtbl->Release(m);
4259 : }
4260 : if (!SUCCEEDED(result)) {
4261 : return NULL;
4262 : }
4263 : strlcat(path,"\\tor",MAX_PATH);
4264 : is_set = 1;
4265 : return path;
4266 : }
4267 : #endif /* defined(_WIN32) */
4268 :
4269 : /** Return the default location for our torrc file (if <b>defaults_file</b> is
4270 : * false), or for the torrc-defaults file (if <b>defaults_file</b> is true). */
4271 : static const char *
4272 0 : get_default_conf_file(int defaults_file)
4273 : {
4274 : #ifdef DISABLE_SYSTEM_TORRC
4275 : (void) defaults_file;
4276 : return NULL;
4277 : #elif defined(_WIN32)
4278 : if (defaults_file) {
4279 : static char defaults_path[MAX_PATH+1];
4280 : tor_snprintf(defaults_path, MAX_PATH, "%s\\torrc-defaults",
4281 : get_windows_conf_root());
4282 : return defaults_path;
4283 : } else {
4284 : static char path[MAX_PATH+1];
4285 : tor_snprintf(path, MAX_PATH, "%s\\torrc",
4286 : get_windows_conf_root());
4287 : return path;
4288 : }
4289 : #else
4290 0 : return defaults_file ? CONFDIR "/torrc-defaults" : CONFDIR "/torrc";
4291 : #endif /* defined(DISABLE_SYSTEM_TORRC) || ... */
4292 : }
4293 :
4294 : /** Learn config file name from command line arguments, or use the default.
4295 : *
4296 : * If <b>defaults_file</b> is true, we're looking for torrc-defaults;
4297 : * otherwise, we're looking for the regular torrc_file.
4298 : *
4299 : * Set *<b>using_default_fname</b> to true if we're using the default
4300 : * configuration file name; or false if we've set it from the command line.
4301 : *
4302 : * Set *<b>ignore_missing_torrc</b> to true if we should ignore the resulting
4303 : * filename if it doesn't exist.
4304 : */
4305 : static char *
4306 456 : find_torrc_filename(const config_line_t *cmd_arg,
4307 : int defaults_file,
4308 : int *using_default_fname, int *ignore_missing_torrc)
4309 : {
4310 456 : char *fname=NULL;
4311 456 : const config_line_t *p_index;
4312 456 : const char *fname_opt = defaults_file ? "--defaults-torrc" : "-f";
4313 456 : const char *fname_long_opt = defaults_file ? "--defaults-torrc" :
4314 : "--torrc-file";
4315 456 : const char *ignore_opt = defaults_file ? NULL : "--ignore-missing-torrc";
4316 456 : const char *keygen_opt = "--keygen";
4317 :
4318 456 : if (defaults_file)
4319 228 : *ignore_missing_torrc = 1;
4320 :
4321 1920 : for (p_index = cmd_arg; p_index; p_index = p_index->next) {
4322 : // options_init_from_torrc ensures only the short or long name is present
4323 1464 : if (!strcmp(p_index->key, fname_opt) ||
4324 1008 : !strcmp(p_index->key, fname_long_opt)) {
4325 456 : if (fname) {
4326 0 : log_warn(LD_CONFIG, "Duplicate %s options on command line.",
4327 : p_index->key);
4328 0 : tor_free(fname);
4329 : }
4330 456 : fname = expand_filename(p_index->value);
4331 :
4332 : {
4333 456 : char *absfname;
4334 456 : absfname = make_path_absolute(fname);
4335 456 : tor_free(fname);
4336 456 : fname = absfname;
4337 : }
4338 :
4339 456 : *using_default_fname = 0;
4340 1008 : } else if ((ignore_opt && !strcmp(p_index->key, ignore_opt)) ||
4341 1008 : (keygen_opt && !strcmp(p_index->key, keygen_opt))) {
4342 12 : *ignore_missing_torrc = 1;
4343 : }
4344 : }
4345 :
4346 456 : if (*using_default_fname) {
4347 : /* didn't find one, try CONFDIR */
4348 0 : const char *dflt = get_default_conf_file(defaults_file);
4349 0 : file_status_t st = file_status(dflt);
4350 0 : if (dflt && (st == FN_FILE || st == FN_EMPTY)) {
4351 0 : fname = tor_strdup(dflt);
4352 : } else {
4353 : #ifndef _WIN32
4354 0 : char *fn = NULL;
4355 0 : if (!defaults_file) {
4356 0 : fn = expand_filename("~/.torrc");
4357 : }
4358 0 : if (fn) {
4359 0 : file_status_t hmst = file_status(fn);
4360 0 : if (hmst == FN_FILE || hmst == FN_EMPTY || dflt == NULL) {
4361 : fname = fn;
4362 : } else {
4363 0 : tor_free(fn);
4364 0 : fname = tor_strdup(dflt);
4365 : }
4366 : } else {
4367 0 : fname = dflt ? tor_strdup(dflt) : NULL;
4368 : }
4369 : #else /* defined(_WIN32) */
4370 : fname = dflt ? tor_strdup(dflt) : NULL;
4371 : #endif /* !defined(_WIN32) */
4372 : }
4373 : }
4374 456 : return fname;
4375 : }
4376 :
4377 : /** Read the torrc from standard input and return it as a string.
4378 : * Upon failure, return NULL.
4379 : */
4380 : static char *
4381 0 : load_torrc_from_stdin(void)
4382 : {
4383 0 : size_t sz_out;
4384 :
4385 0 : return read_file_to_str_until_eof(STDIN_FILENO,SIZE_MAX,&sz_out);
4386 : }
4387 :
4388 : /** Load a configuration file from disk, setting torrc_fname or
4389 : * torrc_defaults_fname if successful.
4390 : *
4391 : * If <b>defaults_file</b> is true, load torrc-defaults; otherwise load torrc.
4392 : *
4393 : * Return the contents of the file on success, and NULL on failure.
4394 : */
4395 : static char *
4396 456 : load_torrc_from_disk(const config_line_t *cmd_arg, int defaults_file)
4397 : {
4398 456 : char *fname=NULL;
4399 456 : char *cf = NULL;
4400 456 : int using_default_torrc = 1;
4401 456 : int ignore_missing_torrc = 0;
4402 456 : char **fname_var = defaults_file ? &torrc_defaults_fname : &torrc_fname;
4403 :
4404 456 : if (*fname_var == NULL) {
4405 456 : fname = find_torrc_filename(cmd_arg, defaults_file,
4406 : &using_default_torrc, &ignore_missing_torrc);
4407 456 : tor_free(*fname_var);
4408 456 : *fname_var = fname;
4409 : } else {
4410 : fname = *fname_var;
4411 : }
4412 912 : log_debug(LD_CONFIG, "Opening config file \"%s\"", fname?fname:"<NULL>");
4413 :
4414 : /* Open config file */
4415 456 : file_status_t st = fname ? file_status(fname) : FN_EMPTY;
4416 456 : if (fname == NULL ||
4417 456 : !(st == FN_FILE || st == FN_EMPTY) ||
4418 455 : !(cf = read_file_to_str(fname,0,NULL))) {
4419 1 : if (using_default_torrc == 1 || ignore_missing_torrc) {
4420 0 : if (!defaults_file)
4421 0 : log_notice(LD_CONFIG, "Configuration file \"%s\" not present, "
4422 : "using reasonable defaults.", fname);
4423 0 : tor_free(fname); /* sets fname to NULL */
4424 0 : *fname_var = NULL;
4425 0 : cf = tor_strdup("");
4426 : } else {
4427 1 : log_warn(LD_CONFIG,
4428 : "Unable to open configuration file \"%s\".", fname);
4429 1 : goto err;
4430 : }
4431 : } else {
4432 455 : log_notice(LD_CONFIG, "Read configuration file \"%s\".", fname);
4433 : }
4434 :
4435 : return cf;
4436 1 : err:
4437 1 : tor_free(fname);
4438 1 : *fname_var = NULL;
4439 1 : return NULL;
4440 : }
4441 :
4442 : /** Read a configuration file into <b>options</b>, finding the configuration
4443 : * file location based on the command line. After loading the file
4444 : * call options_init_from_string() to load the config.
4445 : * Return 0 if success, -1 if failure, and 1 if we succeeded but should exit
4446 : * anyway. */
4447 : int
4448 235 : options_init_from_torrc(int argc, char **argv)
4449 : {
4450 235 : char *cf=NULL, *cf_defaults=NULL;
4451 235 : int retval = -1;
4452 235 : char *errmsg=NULL;
4453 235 : const config_line_t *cmdline_only_options;
4454 :
4455 : /* Go through command-line variables */
4456 235 : if (global_cmdline == NULL) {
4457 : /* Or we could redo the list every time we pass this place.
4458 : * It does not really matter */
4459 235 : global_cmdline = config_parse_commandline(argc, argv, 0);
4460 235 : if (global_cmdline == NULL) {
4461 2 : goto err;
4462 : }
4463 : }
4464 233 : cmdline_only_options = global_cmdline->cmdline_opts;
4465 :
4466 466 : if (config_line_find(cmdline_only_options, "-h") ||
4467 233 : config_line_find(cmdline_only_options, "--help")) {
4468 0 : print_usage();
4469 0 : return 1;
4470 : }
4471 233 : if (config_line_find(cmdline_only_options, "--list-torrc-options")) {
4472 : /* For validating whether we've documented everything. */
4473 1 : list_torrc_options();
4474 1 : return 1;
4475 : }
4476 232 : if (config_line_find(cmdline_only_options, "--list-deprecated-options")) {
4477 : /* For validating whether what we have deprecated really exists. */
4478 0 : list_deprecated_options();
4479 0 : return 1;
4480 : }
4481 232 : if (config_line_find(cmdline_only_options, "--dbg-dump-subsystem-list")) {
4482 0 : subsystems_dump_list();
4483 0 : return 1;
4484 : }
4485 :
4486 232 : if (config_line_find(cmdline_only_options, "--version")) {
4487 0 : printf("Tor version %s.\n",get_version());
4488 0 : printf("Tor is running on %s with Libevent %s, "
4489 : "%s %s, Zlib %s, Liblzma %s, Libzstd %s and %s %s as libc.\n",
4490 : get_uname(),
4491 : tor_libevent_get_version_str(),
4492 : crypto_get_library_name(),
4493 : crypto_get_library_version_string(),
4494 0 : tor_compress_supports_method(ZLIB_METHOD) ?
4495 0 : tor_compress_version_str(ZLIB_METHOD) : "N/A",
4496 0 : tor_compress_supports_method(LZMA_METHOD) ?
4497 0 : tor_compress_version_str(LZMA_METHOD) : "N/A",
4498 0 : tor_compress_supports_method(ZSTD_METHOD) ?
4499 0 : tor_compress_version_str(ZSTD_METHOD) : "N/A",
4500 0 : tor_libc_get_name() ?
4501 0 : tor_libc_get_name() : "Unknown",
4502 : tor_libc_get_version_str());
4503 0 : printf("Tor compiled with %s version %s\n",
4504 : strcmp(COMPILER_VENDOR, "gnu") == 0?
4505 : COMPILER:COMPILER_VENDOR, COMPILER_VERSION);
4506 :
4507 0 : return 1;
4508 : }
4509 :
4510 232 : if (config_line_find(cmdline_only_options, "--list-modules")) {
4511 4 : list_enabled_modules();
4512 4 : return 1;
4513 : }
4514 :
4515 228 : if (config_line_find(cmdline_only_options, "--library-versions")) {
4516 0 : print_library_versions();
4517 0 : return 1;
4518 : }
4519 :
4520 228 : int command = global_cmdline->command;
4521 228 : const char *command_arg = global_cmdline->command_arg;
4522 : /* "immediate" has already been handled by this point. */
4523 228 : tor_assert(command != CMD_IMMEDIATE);
4524 :
4525 228 : if (command == CMD_HASH_PASSWORD) {
4526 0 : cf_defaults = tor_strdup("");
4527 0 : cf = tor_strdup("");
4528 : } else {
4529 228 : cf_defaults = load_torrc_from_disk(cmdline_only_options, 1);
4530 228 : const config_line_t *f_line = config_line_find(cmdline_only_options, "-f");
4531 228 : const config_line_t *f_line_long = config_line_find(cmdline_only_options,
4532 : "--torrc-file");
4533 228 : if (f_line && f_line_long) {
4534 0 : log_err(LD_CONFIG, "-f and --torrc-file cannot be used together.");
4535 0 : retval = -1;
4536 0 : goto err;
4537 228 : } else if (f_line_long) {
4538 0 : f_line = f_line_long;
4539 : }
4540 :
4541 456 : const int read_torrc_from_stdin =
4542 228 : (f_line != NULL && strcmp(f_line->value, "-") == 0);
4543 :
4544 228 : if (read_torrc_from_stdin) {
4545 0 : cf = load_torrc_from_stdin();
4546 : } else {
4547 228 : cf = load_torrc_from_disk(cmdline_only_options, 0);
4548 : }
4549 :
4550 228 : if (!cf) {
4551 1 : if (config_line_find(cmdline_only_options, "--allow-missing-torrc")) {
4552 0 : cf = tor_strdup("");
4553 : } else {
4554 1 : goto err;
4555 : }
4556 : }
4557 : }
4558 :
4559 227 : retval = options_init_from_string(cf_defaults, cf, command, command_arg,
4560 : &errmsg);
4561 227 : if (retval < 0)
4562 26 : goto err;
4563 :
4564 201 : if (config_line_find(cmdline_only_options, "--no-passphrase")) {
4565 3 : if (handle_cmdline_no_passphrase(command) < 0) {
4566 1 : retval = -1;
4567 1 : goto err;
4568 : }
4569 : }
4570 :
4571 200 : const config_line_t *format_line = config_line_find(cmdline_only_options,
4572 : "--format");
4573 200 : if (format_line) {
4574 4 : if (handle_cmdline_format(command, format_line->value) < 0) {
4575 2 : retval = -1;
4576 2 : goto err;
4577 : }
4578 : } else {
4579 196 : get_options_mutable()->key_expiration_format =
4580 : KEY_EXPIRATION_FORMAT_ISO8601;
4581 : }
4582 :
4583 198 : if (config_line_find(cmdline_only_options, "--newpass")) {
4584 1 : if (handle_cmdline_newpass(command) < 0) {
4585 1 : retval = -1;
4586 1 : goto err;
4587 : }
4588 : }
4589 :
4590 197 : const config_line_t *fd_line = config_line_find(cmdline_only_options,
4591 : "--passphrase-fd");
4592 197 : if (fd_line) {
4593 5 : if (handle_cmdline_passphrase_fd(command, fd_line->value) < 0) {
4594 3 : retval = -1;
4595 3 : goto err;
4596 : }
4597 : }
4598 :
4599 194 : const config_line_t *key_line = config_line_find(cmdline_only_options,
4600 : "--master-key");
4601 194 : if (key_line) {
4602 0 : if (handle_cmdline_master_key(command, key_line->value) < 0) {
4603 0 : retval = -1;
4604 0 : goto err;
4605 : }
4606 : }
4607 :
4608 194 : err:
4609 230 : tor_free(cf);
4610 230 : tor_free(cf_defaults);
4611 230 : if (errmsg) {
4612 25 : log_warn(LD_CONFIG,"%s", errmsg);
4613 25 : tor_free(errmsg);
4614 : }
4615 230 : return retval < 0 ? -1 : 0;
4616 : }
4617 :
4618 : /** Load the options from the configuration in <b>cf</b>, validate
4619 : * them for consistency and take actions based on them.
4620 : *
4621 : * Return 0 if success, negative on error:
4622 : * * -1 for general errors.
4623 : * * -2 for failure to parse/validate,
4624 : * * -3 for transition not allowed
4625 : * * -4 for error while setting the new options
4626 : */
4627 : setopt_err_t
4628 230 : options_init_from_string(const char *cf_defaults, const char *cf,
4629 : int command, const char *command_arg,
4630 : char **msg)
4631 : {
4632 230 : bool retry = false;
4633 230 : or_options_t *oldoptions, *newoptions, *newdefaultoptions=NULL;
4634 230 : config_line_t *cl;
4635 230 : int retval;
4636 230 : setopt_err_t err = SETOPT_ERR_MISC;
4637 230 : int cf_has_include = 0;
4638 230 : tor_assert(msg);
4639 :
4640 230 : oldoptions = global_options; /* get_options unfortunately asserts if
4641 : this is the first time we run*/
4642 :
4643 230 : newoptions = options_new();
4644 230 : options_init(newoptions);
4645 230 : newoptions->command = command;
4646 230 : newoptions->command_arg = command_arg ? tor_strdup(command_arg) : NULL;
4647 :
4648 230 : smartlist_t *opened_files = smartlist_new();
4649 688 : for (int i = 0; i < 2; ++i) {
4650 460 : const char *body = i==0 ? cf_defaults : cf;
4651 460 : if (!body)
4652 0 : continue;
4653 :
4654 : /* get config lines, assign them */
4655 689 : retval = config_get_lines_include(body, &cl, 1,
4656 : body == cf ? &cf_has_include : NULL,
4657 : opened_files);
4658 460 : if (retval < 0) {
4659 0 : err = SETOPT_ERR_PARSE;
4660 0 : goto err;
4661 : }
4662 460 : retval = config_assign(get_options_mgr(), newoptions, cl,
4663 : CAL_WARN_DEPRECATIONS, msg);
4664 460 : config_free_lines(cl);
4665 460 : if (retval < 0) {
4666 2 : err = SETOPT_ERR_PARSE;
4667 2 : goto err;
4668 : }
4669 458 : if (i==0)
4670 230 : newdefaultoptions = config_dup(get_options_mgr(), newoptions);
4671 : }
4672 :
4673 228 : if (newdefaultoptions == NULL) {
4674 0 : newdefaultoptions = config_dup(get_options_mgr(), global_default_options);
4675 : }
4676 :
4677 : /* Go through command-line variables too */
4678 : {
4679 228 : config_line_t *other_opts = NULL;
4680 228 : if (global_cmdline) {
4681 225 : other_opts = global_cmdline->other_opts;
4682 : }
4683 228 : retval = config_assign(get_options_mgr(), newoptions,
4684 : other_opts,
4685 : CAL_WARN_DEPRECATIONS, msg);
4686 : }
4687 228 : if (retval < 0) {
4688 0 : err = SETOPT_ERR_PARSE;
4689 0 : goto err;
4690 : }
4691 :
4692 228 : newoptions->IncludeUsed = cf_has_include;
4693 228 : newoptions->FilesOpenedByIncludes = opened_files;
4694 228 : opened_files = NULL; // prevent double-free.
4695 :
4696 : /* If this is a testing network configuration, change defaults
4697 : * for a list of dependent config options, and try this function again. */
4698 228 : if (newoptions->TestingTorNetwork && ! testing_network_configured) {
4699 : // retry with the testing defaults.
4700 0 : testing_network_configured = true;
4701 0 : retry = true;
4702 0 : goto err;
4703 : }
4704 :
4705 228 : err = options_validate_and_set(oldoptions, newoptions, msg);
4706 228 : if (err < 0) {
4707 24 : newoptions = NULL; // This was already freed in options_validate_and_set.
4708 24 : goto err;
4709 : }
4710 :
4711 204 : or_options_free(global_default_options);
4712 204 : global_default_options = newdefaultoptions;
4713 :
4714 204 : return SETOPT_OK;
4715 :
4716 26 : err:
4717 26 : in_option_validation = 0;
4718 26 : if (opened_files) {
4719 2 : SMARTLIST_FOREACH(opened_files, char *, f, tor_free(f));
4720 2 : smartlist_free(opened_files);
4721 : }
4722 26 : or_options_free(newdefaultoptions);
4723 26 : or_options_free(newoptions);
4724 26 : if (*msg) {
4725 25 : char *old_msg = *msg;
4726 25 : tor_asprintf(msg, "Failed to parse/validate config: %s", old_msg);
4727 25 : tor_free(old_msg);
4728 : }
4729 26 : if (retry)
4730 0 : return options_init_from_string(cf_defaults, cf, command, command_arg,
4731 : msg);
4732 : return err;
4733 : }
4734 :
4735 : /** Return the location for our configuration file. May return NULL.
4736 : */
4737 : const char *
4738 0 : get_torrc_fname(int defaults_fname)
4739 : {
4740 0 : const char *fname = defaults_fname ? torrc_defaults_fname : torrc_fname;
4741 :
4742 0 : if (fname)
4743 : return fname;
4744 : else
4745 0 : return get_default_conf_file(defaults_fname);
4746 : }
4747 :
4748 : /** Adjust the address map based on the MapAddress elements in the
4749 : * configuration <b>options</b>
4750 : */
4751 : void
4752 28 : config_register_addressmaps(const or_options_t *options)
4753 : {
4754 28 : smartlist_t *elts;
4755 28 : config_line_t *opt;
4756 28 : const char *from, *to, *msg;
4757 :
4758 28 : addressmap_clear_configured();
4759 28 : elts = smartlist_new();
4760 54 : for (opt = options->AddressMap; opt; opt = opt->next) {
4761 26 : smartlist_split_string(elts, opt->value, NULL,
4762 : SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
4763 26 : if (smartlist_len(elts) < 2) {
4764 0 : log_warn(LD_CONFIG,"MapAddress '%s' has too few arguments. Ignoring.",
4765 : opt->value);
4766 0 : goto cleanup;
4767 : }
4768 :
4769 26 : from = smartlist_get(elts,0);
4770 26 : to = smartlist_get(elts,1);
4771 :
4772 26 : if (to[0] == '.' || from[0] == '.') {
4773 1 : log_warn(LD_CONFIG,"MapAddress '%s' is ambiguous - address starts with a"
4774 : "'.'. Ignoring.",opt->value);
4775 1 : goto cleanup;
4776 : }
4777 :
4778 25 : if (addressmap_register_auto(from, to, 0, ADDRMAPSRC_TORRC, &msg) < 0) {
4779 3 : log_warn(LD_CONFIG,"MapAddress '%s' failed: %s. Ignoring.", opt->value,
4780 : msg);
4781 3 : goto cleanup;
4782 : }
4783 :
4784 22 : if (smartlist_len(elts) > 2)
4785 0 : log_warn(LD_CONFIG,"Ignoring extra arguments to MapAddress.");
4786 :
4787 22 : cleanup:
4788 78 : SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
4789 26 : smartlist_clear(elts);
4790 : }
4791 28 : smartlist_free(elts);
4792 28 : }
4793 :
4794 : /** As addressmap_register(), but detect the wildcarded status of "from" and
4795 : * "to", and do not steal a reference to <b>to</b>. */
4796 : /* XXXX move to connection_edge.c */
4797 : int
4798 25 : addressmap_register_auto(const char *from, const char *to,
4799 : time_t expires,
4800 : addressmap_entry_source_t addrmap_source,
4801 : const char **msg)
4802 : {
4803 25 : int from_wildcard = 0, to_wildcard = 0;
4804 :
4805 25 : *msg = "whoops, forgot the error message";
4806 :
4807 25 : if (!strcmp(to, "*") || !strcmp(from, "*")) {
4808 1 : *msg = "can't remap from or to *";
4809 1 : return -1;
4810 : }
4811 : /* Detect asterisks in expressions of type: '*.example.com' */
4812 24 : if (!strncmp(from,"*.",2)) {
4813 8 : from += 2;
4814 8 : from_wildcard = 1;
4815 : }
4816 24 : if (!strncmp(to,"*.",2)) {
4817 6 : to += 2;
4818 6 : to_wildcard = 1;
4819 : }
4820 :
4821 24 : if (to_wildcard && !from_wildcard) {
4822 2 : *msg = "can only use wildcard (i.e. '*.') if 'from' address "
4823 : "uses wildcard also";
4824 2 : return -1;
4825 : }
4826 :
4827 22 : if (address_is_invalid_destination(to, 1)) {
4828 0 : *msg = "destination is invalid";
4829 0 : return -1;
4830 : }
4831 :
4832 22 : addressmap_register(from, tor_strdup(to), expires, addrmap_source,
4833 : from_wildcard, to_wildcard, 0);
4834 :
4835 22 : return 0;
4836 : }
4837 :
4838 : /**
4839 : * As add_file_log, but open the file as appropriate.
4840 : */
4841 : STATIC int
4842 2 : open_and_add_file_log(const log_severity_list_t *severity,
4843 : const char *filename, int truncate_log)
4844 : {
4845 2 : int open_flags = O_WRONLY|O_CREAT;
4846 2 : open_flags |= truncate_log ? O_TRUNC : O_APPEND;
4847 :
4848 2 : int fd = tor_open_cloexec(filename, open_flags, 0640);
4849 2 : if (fd < 0)
4850 : return -1;
4851 :
4852 2 : return add_file_log(severity, filename, fd);
4853 : }
4854 :
4855 : /**
4856 : * Try to set our global log granularity from `options->LogGranularity`,
4857 : * adjusting it as needed so that we are an even divisor of a second, or an
4858 : * even multiple of seconds. Return 0 on success, -1 on failure.
4859 : **/
4860 : static int
4861 578 : options_init_log_granularity(const or_options_t *options,
4862 : int validate_only)
4863 : {
4864 578 : if (options->LogTimeGranularity <= 0) {
4865 1 : log_warn(LD_CONFIG, "Log time granularity '%d' has to be positive.",
4866 : options->LogTimeGranularity);
4867 1 : return -1;
4868 577 : } else if (1000 % options->LogTimeGranularity != 0 &&
4869 8 : options->LogTimeGranularity % 1000 != 0) {
4870 3 : int granularity = options->LogTimeGranularity;
4871 3 : if (granularity < 40) {
4872 1 : do granularity++;
4873 1 : while (1000 % granularity != 0);
4874 2 : } else if (granularity < 1000) {
4875 1 : granularity = 1000 / granularity;
4876 1 : while (1000 % granularity != 0)
4877 0 : granularity--;
4878 1 : granularity = 1000 / granularity;
4879 : } else {
4880 1 : granularity = 1000 * ((granularity / 1000) + 1);
4881 : }
4882 3 : log_warn(LD_CONFIG, "Log time granularity '%d' has to be either a "
4883 : "divisor or a multiple of 1 second. Changing to "
4884 : "'%d'.",
4885 : options->LogTimeGranularity, granularity);
4886 3 : if (!validate_only)
4887 3 : set_log_time_granularity(granularity);
4888 : } else {
4889 574 : if (!validate_only)
4890 16 : set_log_time_granularity(options->LogTimeGranularity);
4891 : }
4892 :
4893 : return 0;
4894 : }
4895 :
4896 : /**
4897 : * Initialize the logs based on the configuration file.
4898 : */
4899 : STATIC int
4900 578 : options_init_logs(const or_options_t *old_options, const or_options_t *options,
4901 : int validate_only)
4902 : {
4903 578 : config_line_t *opt;
4904 578 : int ok;
4905 578 : smartlist_t *elts;
4906 578 : int run_as_daemon =
4907 : #ifdef _WIN32
4908 : 0;
4909 : #else
4910 : options->RunAsDaemon;
4911 : #endif
4912 :
4913 578 : if (options_init_log_granularity(options, validate_only) < 0)
4914 : return -1;
4915 :
4916 577 : ok = 1;
4917 577 : elts = smartlist_new();
4918 :
4919 577 : if (options->Logs == NULL && !run_as_daemon && !validate_only) {
4920 : /* When no logs are given, the default behavior is to log nothing (if
4921 : RunAsDaemon is set) or to log based on the quiet level otherwise. */
4922 13 : add_default_log_for_quiet_level(quiet_level);
4923 : }
4924 :
4925 590 : for (opt = options->Logs; opt; opt = opt->next) {
4926 13 : log_severity_list_t *severity;
4927 13 : const char *cfg = opt->value;
4928 13 : severity = tor_malloc_zero(sizeof(log_severity_list_t));
4929 13 : if (parse_log_severity_config(&cfg, severity) < 0) {
4930 2 : log_warn(LD_CONFIG, "Couldn't parse log levels in Log option 'Log %s'",
4931 : opt->value);
4932 2 : ok = 0; goto cleanup;
4933 : }
4934 :
4935 11 : smartlist_split_string(elts, cfg, NULL,
4936 : SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
4937 :
4938 11 : if (smartlist_len(elts) == 0)
4939 0 : smartlist_add_strdup(elts, "stdout");
4940 :
4941 11 : if (smartlist_len(elts) == 1 &&
4942 4 : (!strcasecmp(smartlist_get(elts,0), "stdout") ||
4943 0 : !strcasecmp(smartlist_get(elts,0), "stderr"))) {
4944 8 : int err = smartlist_len(elts) &&
4945 4 : !strcasecmp(smartlist_get(elts,0), "stderr");
4946 4 : if (!validate_only) {
4947 4 : if (run_as_daemon) {
4948 0 : log_warn(LD_CONFIG,
4949 : "Can't log to %s with RunAsDaemon set; skipping stdout",
4950 : err?"stderr":"stdout");
4951 : } else {
4952 8 : add_stream_log(severity, err?"<stderr>":"<stdout>",
4953 : fileno(err?stderr:stdout));
4954 : }
4955 : }
4956 4 : goto cleanup;
4957 : }
4958 7 : if (smartlist_len(elts) == 1) {
4959 0 : if (!strcasecmp(smartlist_get(elts,0), "syslog")) {
4960 : #ifdef HAVE_SYSLOG_H
4961 0 : if (!validate_only) {
4962 0 : add_syslog_log(severity, options->SyslogIdentityTag);
4963 : }
4964 : #else
4965 : log_warn(LD_CONFIG, "Syslog is not supported on this system. Sorry.");
4966 : #endif /* defined(HAVE_SYSLOG_H) */
4967 0 : goto cleanup;
4968 : }
4969 :
4970 : /* We added this workaround in 0.4.5.x; we can remove it in 0.4.6 or
4971 : * later */
4972 0 : if (!strcasecmp(smartlist_get(elts, 0), "android")) {
4973 : #ifdef HAVE_SYSLOG_H
4974 0 : log_warn(LD_CONFIG, "The android logging API is no longer supported;"
4975 : " adding a syslog instead. The 'android' logging "
4976 : " type will no longer work in the future.");
4977 0 : if (!validate_only) {
4978 0 : add_syslog_log(severity, options->SyslogIdentityTag);
4979 : }
4980 : #else /* !defined(HAVE_SYSLOG_H) */
4981 : log_warn(LD_CONFIG, "The android logging API is no longer supported.");
4982 : #endif /* defined(HAVE_SYSLOG_H) */
4983 0 : goto cleanup;
4984 : }
4985 : }
4986 :
4987 7 : if (smartlist_len(elts) == 2 &&
4988 7 : !strcasecmp(smartlist_get(elts,0), "file")) {
4989 7 : if (!validate_only) {
4990 1 : char *fname = expand_filename(smartlist_get(elts, 1));
4991 : /* Truncate if TruncateLogFile is set and we haven't seen this option
4992 : line before. */
4993 1 : int truncate_log = 0;
4994 1 : if (options->TruncateLogFile) {
4995 0 : truncate_log = 1;
4996 0 : if (old_options) {
4997 0 : config_line_t *opt2;
4998 0 : for (opt2 = old_options->Logs; opt2; opt2 = opt2->next)
4999 0 : if (!strcmp(opt->value, opt2->value)) {
5000 : truncate_log = 0;
5001 : break;
5002 : }
5003 : }
5004 : }
5005 1 : if (open_and_add_file_log(severity, fname, truncate_log) < 0) {
5006 0 : log_warn(LD_CONFIG, "Couldn't open file for 'Log %s': %s",
5007 : opt->value, strerror(errno));
5008 0 : ok = 0;
5009 : }
5010 1 : tor_free(fname);
5011 : }
5012 7 : goto cleanup;
5013 : }
5014 :
5015 0 : log_warn(LD_CONFIG, "Bad syntax on file Log option 'Log %s'",
5016 : opt->value);
5017 0 : ok = 0; goto cleanup;
5018 :
5019 13 : cleanup:
5020 31 : SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
5021 13 : smartlist_clear(elts);
5022 13 : tor_free(severity);
5023 : }
5024 577 : smartlist_free(elts);
5025 :
5026 577 : if (ok && !validate_only)
5027 18 : logs_set_domain_logging(options->LogMessageDomains);
5028 :
5029 577 : return ok?0:-1;
5030 : }
5031 :
5032 : /** Given a smartlist of SOCKS arguments to be passed to a transport
5033 : * proxy in <b>args</b>, validate them and return -1 if they are
5034 : * corrupted. Return 0 if they seem OK. */
5035 : static int
5036 53 : validate_transport_socks_arguments(const smartlist_t *args)
5037 : {
5038 53 : char *socks_string = NULL;
5039 53 : size_t socks_string_len;
5040 :
5041 53 : tor_assert(args);
5042 53 : tor_assert(smartlist_len(args) > 0);
5043 :
5044 123 : SMARTLIST_FOREACH_BEGIN(args, const char *, s) {
5045 71 : if (!string_is_key_value(LOG_WARN, s)) { /* items should be k=v items */
5046 1 : log_warn(LD_CONFIG, "'%s' is not a k=v item.", s);
5047 1 : return -1;
5048 : }
5049 70 : } SMARTLIST_FOREACH_END(s);
5050 :
5051 52 : socks_string = pt_stringify_socks_args(args);
5052 52 : if (!socks_string)
5053 : return -1;
5054 :
5055 52 : socks_string_len = strlen(socks_string);
5056 52 : tor_free(socks_string);
5057 :
5058 52 : if (socks_string_len > MAX_SOCKS5_AUTH_SIZE_TOTAL) {
5059 1 : log_warn(LD_CONFIG, "SOCKS arguments can't be more than %u bytes (%lu).",
5060 : MAX_SOCKS5_AUTH_SIZE_TOTAL,
5061 : (unsigned long) socks_string_len);
5062 1 : return -1;
5063 : }
5064 :
5065 : return 0;
5066 : }
5067 :
5068 : /** Deallocate a bridge_line_t structure. */
5069 : /* private */ void
5070 34 : bridge_line_free_(bridge_line_t *bridge_line)
5071 : {
5072 34 : if (!bridge_line)
5073 : return;
5074 :
5075 27 : if (bridge_line->socks_args) {
5076 12 : SMARTLIST_FOREACH(bridge_line->socks_args, char*, s, tor_free(s));
5077 5 : smartlist_free(bridge_line->socks_args);
5078 : }
5079 27 : tor_free(bridge_line->transport_name);
5080 27 : tor_free(bridge_line);
5081 : }
5082 :
5083 : /** Parse the contents of a string, <b>line</b>, containing a Bridge line,
5084 : * into a bridge_line_t.
5085 : *
5086 : * Validates that the IP:PORT, fingerprint, and SOCKS arguments (given to the
5087 : * Pluggable Transport, if a one was specified) are well-formed.
5088 : *
5089 : * Returns NULL If the Bridge line could not be validated, and returns a
5090 : * bridge_line_t containing the parsed information otherwise.
5091 : *
5092 : * Bridge line format:
5093 : * Bridge [transport] IP:PORT [id-fingerprint] [k=v] [k=v] ...
5094 : */
5095 : /* private */ bridge_line_t *
5096 148 : parse_bridge_line(const char *line)
5097 : {
5098 148 : smartlist_t *items = NULL;
5099 148 : char *addrport=NULL, *fingerprint=NULL;
5100 148 : char *field=NULL;
5101 148 : bridge_line_t *bridge_line = tor_malloc_zero(sizeof(bridge_line_t));
5102 :
5103 148 : items = smartlist_new();
5104 148 : smartlist_split_string(items, line, NULL,
5105 : SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
5106 148 : if (smartlist_len(items) < 1) {
5107 1 : log_warn(LD_CONFIG, "Too few arguments to Bridge line.");
5108 1 : goto err;
5109 : }
5110 :
5111 : /* first field is either a transport name or addrport */
5112 147 : field = smartlist_get(items, 0);
5113 147 : smartlist_del_keeporder(items, 0);
5114 :
5115 147 : if (string_is_C_identifier(field)) {
5116 : /* It's a transport name. */
5117 72 : bridge_line->transport_name = field;
5118 72 : if (smartlist_len(items) < 1) {
5119 1 : log_warn(LD_CONFIG, "Too few items to Bridge line.");
5120 1 : goto err;
5121 : }
5122 71 : addrport = smartlist_get(items, 0); /* Next field is addrport then. */
5123 71 : smartlist_del_keeporder(items, 0);
5124 : } else {
5125 : addrport = field;
5126 : }
5127 :
5128 146 : if (tor_addr_port_parse(LOG_INFO, addrport,
5129 : &bridge_line->addr, &bridge_line->port, 443)<0) {
5130 3 : log_warn(LD_CONFIG, "Error parsing Bridge address '%s'", addrport);
5131 3 : goto err;
5132 : }
5133 :
5134 : /* If transports are enabled, next field could be a fingerprint or a
5135 : socks argument. If transports are disabled, next field must be
5136 : a fingerprint. */
5137 143 : if (smartlist_len(items)) {
5138 88 : if (bridge_line->transport_name) { /* transports enabled: */
5139 70 : field = smartlist_get(items, 0);
5140 70 : smartlist_del_keeporder(items, 0);
5141 :
5142 : /* If it's a key=value pair, then it's a SOCKS argument for the
5143 : transport proxy... */
5144 70 : if (string_is_key_value(LOG_DEBUG, field)) {
5145 18 : bridge_line->socks_args = smartlist_new();
5146 18 : smartlist_add(bridge_line->socks_args, field);
5147 : } else { /* ...otherwise, it's the bridge fingerprint. */
5148 : fingerprint = field;
5149 : }
5150 :
5151 : } else { /* transports disabled: */
5152 18 : fingerprint = smartlist_join_strings(items, "", 0, NULL);
5153 : }
5154 : }
5155 :
5156 : /* Handle fingerprint, if it was provided. */
5157 88 : if (fingerprint) {
5158 70 : if (strlen(fingerprint) != HEX_DIGEST_LEN) {
5159 1 : log_warn(LD_CONFIG, "Key digest for Bridge is wrong length.");
5160 1 : goto err;
5161 : }
5162 69 : if (base16_decode(bridge_line->digest, DIGEST_LEN,
5163 : fingerprint, HEX_DIGEST_LEN) != DIGEST_LEN) {
5164 0 : log_warn(LD_CONFIG, "Unable to decode Bridge key digest.");
5165 0 : goto err;
5166 : }
5167 : }
5168 :
5169 : /* If we are using transports, any remaining items in the smartlist
5170 : should be k=v values. */
5171 142 : if (bridge_line->transport_name && smartlist_len(items)) {
5172 36 : if (!bridge_line->socks_args)
5173 35 : bridge_line->socks_args = smartlist_new();
5174 :
5175 : /* append remaining items of 'items' to 'socks_args' */
5176 36 : smartlist_add_all(bridge_line->socks_args, items);
5177 36 : smartlist_clear(items);
5178 :
5179 36 : tor_assert(smartlist_len(bridge_line->socks_args) > 0);
5180 : }
5181 :
5182 142 : if (bridge_line->socks_args) {
5183 53 : if (validate_transport_socks_arguments(bridge_line->socks_args) < 0)
5184 2 : goto err;
5185 : }
5186 :
5187 140 : goto done;
5188 :
5189 8 : err:
5190 8 : bridge_line_free(bridge_line);
5191 8 : bridge_line = NULL;
5192 :
5193 148 : done:
5194 167 : SMARTLIST_FOREACH(items, char*, s, tor_free(s));
5195 148 : smartlist_free(items);
5196 148 : tor_free(addrport);
5197 148 : tor_free(fingerprint);
5198 :
5199 148 : return bridge_line;
5200 : }
5201 :
5202 : /** Parse the contents of a TCPProxy line from <b>line</b> and put it
5203 : * in <b>options</b>. Return 0 if the line is well-formed, and -1 if it
5204 : * isn't.
5205 : *
5206 : * This will mutate only options->TCPProxyProtocol, options->TCPProxyAddr,
5207 : * and options->TCPProxyPort.
5208 : *
5209 : * On error, tor_strdup an error explanation into *<b>msg</b>.
5210 : */
5211 : STATIC int
5212 4 : parse_tcp_proxy_line(const char *line, or_options_t *options, char **msg)
5213 : {
5214 4 : int ret = 0;
5215 4 : tor_assert(line);
5216 4 : tor_assert(options);
5217 4 : tor_assert(msg);
5218 :
5219 4 : smartlist_t *sl = smartlist_new();
5220 : /* Split between the protocol and the address/port. */
5221 4 : smartlist_split_string(sl, line, " ",
5222 : SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
5223 :
5224 : /* The address/port is not specified. */
5225 4 : if (smartlist_len(sl) < 2) {
5226 1 : *msg = tor_strdup("TCPProxy has no address/port. Please fix.");
5227 1 : goto err;
5228 : }
5229 :
5230 3 : char *protocol_string = smartlist_get(sl, 0);
5231 3 : char *addrport_string = smartlist_get(sl, 1);
5232 :
5233 : /* The only currently supported protocol is 'haproxy'. */
5234 3 : if (strcasecmp(protocol_string, "haproxy")) {
5235 1 : *msg = tor_strdup("TCPProxy protocol is not supported. Currently "
5236 : "the only supported protocol is 'haproxy'. "
5237 : "Please fix.");
5238 1 : goto err;
5239 : } else {
5240 : /* Otherwise, set the correct protocol. */
5241 2 : options->TCPProxyProtocol = TCP_PROXY_PROTOCOL_HAPROXY;
5242 : }
5243 :
5244 : /* Parse the address/port. */
5245 2 : if (tor_addr_port_lookup(addrport_string, &options->TCPProxyAddr,
5246 : &options->TCPProxyPort) < 0) {
5247 1 : *msg = tor_strdup("TCPProxy address/port failed to parse or resolve. "
5248 : "Please fix.");
5249 1 : goto err;
5250 : }
5251 :
5252 : /* Success. */
5253 1 : ret = 0;
5254 1 : goto end;
5255 :
5256 : err:
5257 : ret = -1;
5258 4 : end:
5259 11 : SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
5260 4 : smartlist_free(sl);
5261 4 : return ret;
5262 : }
5263 :
5264 : /** Read the contents of a ClientTransportPlugin or ServerTransportPlugin
5265 : * line from <b>line</b>, depending on the value of <b>server</b>. Return 0
5266 : * if the line is well-formed, and -1 if it isn't.
5267 : *
5268 : * If <b>validate_only</b> is 0, the line is well-formed, and the transport is
5269 : * needed by some bridge:
5270 : * - If it's an external proxy line, add the transport described in the line to
5271 : * our internal transport list.
5272 : * - If it's a managed proxy line, launch the managed proxy.
5273 : */
5274 : int
5275 65 : pt_parse_transport_line(const or_options_t *options,
5276 : const char *line, int validate_only,
5277 : int server)
5278 : {
5279 :
5280 65 : smartlist_t *items = NULL;
5281 65 : int r;
5282 65 : const char *transports = NULL;
5283 65 : smartlist_t *transport_list = NULL;
5284 65 : char *type = NULL;
5285 65 : char *addrport = NULL;
5286 65 : tor_addr_t addr;
5287 65 : uint16_t port = 0;
5288 65 : int socks_ver = PROXY_NONE;
5289 :
5290 : /* managed proxy options */
5291 65 : int is_managed = 0;
5292 65 : char **proxy_argv = NULL;
5293 65 : char **tmp = NULL;
5294 65 : int proxy_argc, i;
5295 65 : int is_useless_proxy = 1;
5296 :
5297 65 : int line_length;
5298 :
5299 : /* Split the line into space-separated tokens */
5300 65 : items = smartlist_new();
5301 65 : smartlist_split_string(items, line, NULL,
5302 : SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
5303 65 : line_length = smartlist_len(items);
5304 :
5305 65 : if (line_length < 3) {
5306 9 : log_warn(LD_CONFIG,
5307 : "Too few arguments on %sTransportPlugin line.",
5308 : server ? "Server" : "Client");
5309 6 : goto err;
5310 : }
5311 :
5312 : /* Get the first line element, split it to commas into
5313 : transport_list (in case it's multiple transports) and validate
5314 : the transport names. */
5315 59 : transports = smartlist_get(items, 0);
5316 59 : transport_list = smartlist_new();
5317 59 : smartlist_split_string(transport_list, transports, ",",
5318 : SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
5319 120 : SMARTLIST_FOREACH_BEGIN(transport_list, const char *, transport_name) {
5320 : /* validate transport names */
5321 63 : if (!string_is_C_identifier(transport_name)) {
5322 2 : log_warn(LD_CONFIG, "Transport name is not a C identifier (%s).",
5323 : transport_name);
5324 2 : goto err;
5325 : }
5326 :
5327 : /* see if we actually need the transports provided by this proxy */
5328 61 : if (!validate_only && transport_is_needed(transport_name))
5329 2 : is_useless_proxy = 0;
5330 61 : } SMARTLIST_FOREACH_END(transport_name);
5331 :
5332 57 : type = smartlist_get(items, 1);
5333 57 : if (!strcmp(type, "exec")) {
5334 : is_managed = 1;
5335 13 : } else if (server && !strcmp(type, "proxy")) {
5336 : /* 'proxy' syntax only with ServerTransportPlugin */
5337 : is_managed = 0;
5338 8 : } else if (!server && !strcmp(type, "socks4")) {
5339 : /* 'socks4' syntax only with ClientTransportPlugin */
5340 : is_managed = 0;
5341 : socks_ver = PROXY_SOCKS4;
5342 7 : } else if (!server && !strcmp(type, "socks5")) {
5343 : /* 'socks5' syntax only with ClientTransportPlugin */
5344 : is_managed = 0;
5345 : socks_ver = PROXY_SOCKS5;
5346 : } else {
5347 3 : log_warn(LD_CONFIG,
5348 : "Strange %sTransportPlugin type '%s'",
5349 : server ? "Server" : "Client", type);
5350 2 : goto err;
5351 : }
5352 :
5353 44 : if (is_managed && options->Sandbox) {
5354 3 : log_warn(LD_CONFIG,
5355 : "Managed proxies are not compatible with Sandbox mode."
5356 : "(%sTransportPlugin line was %s)",
5357 : server ? "Server" : "Client", escaped(line));
5358 2 : goto err;
5359 : }
5360 :
5361 53 : if (is_managed && options->NoExec) {
5362 0 : log_warn(LD_CONFIG,
5363 : "Managed proxies are not compatible with NoExec mode; ignoring."
5364 : "(%sTransportPlugin line was %s)",
5365 : server ? "Server" : "Client", escaped(line));
5366 0 : r = 0;
5367 0 : goto done;
5368 : }
5369 :
5370 53 : if (is_managed) {
5371 : /* managed */
5372 :
5373 42 : if (!server && !validate_only && is_useless_proxy) {
5374 1 : log_info(LD_GENERAL,
5375 : "Pluggable transport proxy (%s) does not provide "
5376 : "any needed transports and will not be launched.",
5377 : line);
5378 : }
5379 :
5380 : /*
5381 : * If we are not just validating, use the rest of the line as the
5382 : * argv of the proxy to be launched. Also, make sure that we are
5383 : * only launching proxies that contribute useful transports.
5384 : */
5385 :
5386 42 : if (!validate_only && (server || !is_useless_proxy)) {
5387 17 : proxy_argc = line_length - 2;
5388 17 : tor_assert(proxy_argc > 0);
5389 17 : proxy_argv = tor_calloc((proxy_argc + 1), sizeof(char *));
5390 17 : tmp = proxy_argv;
5391 :
5392 51 : for (i = 0; i < proxy_argc; i++) {
5393 : /* store arguments */
5394 17 : *tmp++ = smartlist_get(items, 2);
5395 17 : smartlist_del_keeporder(items, 2);
5396 : }
5397 17 : *tmp = NULL; /* terminated with NULL, just like execve() likes it */
5398 :
5399 : /* kickstart the thing */
5400 17 : if (server) {
5401 16 : pt_kickstart_server_proxy(transport_list, proxy_argv);
5402 : } else {
5403 1 : pt_kickstart_client_proxy(transport_list, proxy_argv);
5404 : }
5405 : }
5406 : } else {
5407 : /* external */
5408 :
5409 : /* ClientTransportPlugins connecting through a proxy is managed only. */
5410 11 : if (!server && (options->Socks4Proxy || options->Socks5Proxy ||
5411 6 : options->HTTPSProxy || options->TCPProxy)) {
5412 0 : log_warn(LD_CONFIG, "You have configured an external proxy with another "
5413 : "proxy type. (Socks4Proxy|Socks5Proxy|HTTPSProxy|"
5414 : "TCPProxy)");
5415 0 : goto err;
5416 : }
5417 :
5418 11 : if (smartlist_len(transport_list) != 1) {
5419 2 : log_warn(LD_CONFIG,
5420 : "You can't have an external proxy with more than "
5421 : "one transport.");
5422 2 : goto err;
5423 : }
5424 :
5425 9 : addrport = smartlist_get(items, 2);
5426 :
5427 9 : if (tor_addr_port_lookup(addrport, &addr, &port) < 0) {
5428 2 : log_warn(LD_CONFIG,
5429 : "Error parsing transport address '%s'", addrport);
5430 2 : goto err;
5431 : }
5432 :
5433 7 : if (!port) {
5434 2 : log_warn(LD_CONFIG,
5435 : "Transport address '%s' has no port.", addrport);
5436 2 : goto err;
5437 : }
5438 :
5439 5 : if (!validate_only) {
5440 3 : log_info(LD_DIR, "%s '%s' at %s.",
5441 : server ? "Server transport" : "Transport",
5442 : transports, fmt_addrport(&addr, port));
5443 :
5444 2 : if (!server) {
5445 1 : transport_add_from_config(&addr, port,
5446 1 : smartlist_get(transport_list, 0),
5447 : socks_ver);
5448 : }
5449 : }
5450 : }
5451 :
5452 47 : r = 0;
5453 47 : goto done;
5454 :
5455 : err:
5456 : r = -1;
5457 :
5458 65 : done:
5459 233 : SMARTLIST_FOREACH(items, char*, s, tor_free(s));
5460 65 : smartlist_free(items);
5461 65 : if (transport_list) {
5462 122 : SMARTLIST_FOREACH(transport_list, char*, s, tor_free(s));
5463 59 : smartlist_free(transport_list);
5464 : }
5465 :
5466 65 : return r;
5467 : }
5468 :
5469 : /**
5470 : * Parse a flag describing an extra dirport for a directory authority.
5471 : *
5472 : * Right now, the supported format is exactly:
5473 : * `{upload,download,voting}=http://[IP:PORT]/`.
5474 : * Other URL schemes, and other suffixes, might be supported in the future.
5475 : *
5476 : * Only call this function if `flag` starts with one of the above strings.
5477 : *
5478 : * Return 0 on success, and -1 on failure.
5479 : *
5480 : * If `ds` is provided, then add any parsed dirport to `ds`. If `ds` is NULL,
5481 : * take no action other than parsing.
5482 : **/
5483 : static int
5484 11 : parse_dirauth_dirport(dir_server_t *ds, const char *flag)
5485 : {
5486 11 : tor_assert(flag);
5487 :
5488 11 : auth_dirport_usage_t usage;
5489 :
5490 11 : if (!strcasecmpstart(flag, "upload=")) {
5491 : usage = AUTH_USAGE_UPLOAD;
5492 4 : } else if (!strcasecmpstart(flag, "download=")) {
5493 : usage = AUTH_USAGE_DOWNLOAD;
5494 2 : } else if (!strcasecmpstart(flag, "vote=")) {
5495 : usage = AUTH_USAGE_VOTING;
5496 : } else {
5497 : // We shouldn't get called with a flag that we don't recognize.
5498 0 : tor_assert_nonfatal_unreached();
5499 0 : return -1;
5500 : }
5501 :
5502 11 : const char *eq = strchr(flag, '=');
5503 11 : tor_assert(eq);
5504 11 : const char *target = eq + 1;
5505 :
5506 : // Find the part inside the http://{....}/
5507 11 : if (strcmpstart(target, "http://")) {
5508 1 : log_warn(LD_CONFIG, "Unsupported URL scheme in authority flag %s", flag);
5509 1 : return -1;
5510 : }
5511 10 : const char *addr = target + strlen("http://");
5512 :
5513 10 : const char *eos = strchr(addr, '/');
5514 10 : size_t addr_len;
5515 10 : if (eos && strcmp(eos, "/")) {
5516 1 : log_warn(LD_CONFIG, "Unsupported URL prefix in authority flag %s", flag);
5517 1 : return -1;
5518 9 : } else if (eos) {
5519 7 : addr_len = eos - addr;
5520 : } else {
5521 2 : addr_len = strlen(addr);
5522 : }
5523 :
5524 : // Finally, parse the addr:port part.
5525 9 : char *addr_string = tor_strndup(addr, addr_len);
5526 9 : tor_addr_port_t dirport;
5527 9 : memset(&dirport, 0, sizeof(dirport));
5528 9 : int rv = tor_addr_port_parse(LOG_WARN, addr_string,
5529 : &dirport.addr, &dirport.port, -1);
5530 9 : if (ds != NULL && rv == 0) {
5531 4 : trusted_dir_server_add_dirport(ds, usage, &dirport);
5532 5 : } else if (rv == -1) {
5533 2 : log_warn(LD_CONFIG, "Unable to parse address in authority flag %s",flag);
5534 : }
5535 :
5536 9 : tor_free(addr_string);
5537 9 : return rv;
5538 : }
5539 :
5540 : /** Read the contents of a DirAuthority line from <b>line</b>. If
5541 : * <b>validate_only</b> is 0, and the line is well-formed, and it
5542 : * shares any bits with <b>required_type</b> or <b>required_type</b>
5543 : * is NO_DIRINFO (zero), then add the dirserver described in the line
5544 : * (minus whatever bits it's missing) as a valid authority.
5545 : * Return 0 on success or filtering out by type,
5546 : * or -1 if the line isn't well-formed or if we can't add it. */
5547 : STATIC int
5548 2315 : parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
5549 : int validate_only)
5550 : {
5551 2315 : smartlist_t *items = NULL;
5552 2315 : int r;
5553 2315 : char *addrport=NULL, *address=NULL, *nickname=NULL, *fingerprint=NULL;
5554 2315 : tor_addr_port_t ipv6_addrport, *ipv6_addrport_ptr = NULL;
5555 2315 : uint16_t dir_port = 0, or_port = 0;
5556 2315 : char digest[DIGEST_LEN];
5557 2315 : char v3_digest[DIGEST_LEN];
5558 2315 : dirinfo_type_t type = 0;
5559 2315 : double weight = 1.0;
5560 2315 : smartlist_t *extra_dirports = smartlist_new();
5561 :
5562 2315 : memset(v3_digest, 0, sizeof(v3_digest));
5563 :
5564 2315 : items = smartlist_new();
5565 2315 : smartlist_split_string(items, line, NULL,
5566 : SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
5567 2315 : if (smartlist_len(items) < 1) {
5568 0 : log_warn(LD_CONFIG, "No arguments on DirAuthority line.");
5569 0 : goto err;
5570 : }
5571 :
5572 2315 : if (is_legal_nickname(smartlist_get(items, 0))) {
5573 2315 : nickname = smartlist_get(items, 0);
5574 2315 : smartlist_del_keeporder(items, 0);
5575 : }
5576 :
5577 8082 : while (smartlist_len(items)) {
5578 8082 : char *flag = smartlist_get(items, 0);
5579 8082 : if (TOR_ISDIGIT(flag[0]))
5580 : break;
5581 5767 : if (!strcasecmp(flag, "hs") ||
5582 5767 : !strcasecmp(flag, "no-hs")) {
5583 0 : log_warn(LD_CONFIG, "The DirAuthority options 'hs' and 'no-hs' are "
5584 : "obsolete; you don't need them any more.");
5585 5767 : } else if (!strcasecmp(flag, "bridge")) {
5586 228 : type |= BRIDGE_DIRINFO;
5587 5539 : } else if (!strcasecmp(flag, "no-v2")) {
5588 : /* obsolete, but may still be contained in DirAuthority lines generated
5589 : by various tools */;
5590 5539 : } else if (!strcasecmpstart(flag, "orport=")) {
5591 2315 : int ok;
5592 2315 : char *portstring = flag + strlen("orport=");
5593 2315 : or_port = (uint16_t) tor_parse_long(portstring, 10, 1, 65535, &ok, NULL);
5594 2315 : if (!ok)
5595 0 : log_warn(LD_CONFIG, "Invalid orport '%s' on DirAuthority line.",
5596 : portstring);
5597 3224 : } else if (!strcmpstart(flag, "weight=")) {
5598 0 : int ok;
5599 0 : const char *wstring = flag + strlen("weight=");
5600 0 : weight = tor_parse_double(wstring, 0, (double)UINT64_MAX, &ok, NULL);
5601 0 : if (!ok) {
5602 0 : log_warn(LD_CONFIG, "Invalid weight '%s' on DirAuthority line.",flag);
5603 0 : weight=1.0;
5604 : }
5605 3224 : } else if (!strcasecmpstart(flag, "v3ident=")) {
5606 2087 : char *idstr = flag + strlen("v3ident=");
5607 4174 : if (strlen(idstr) != HEX_DIGEST_LEN ||
5608 2087 : base16_decode(v3_digest, DIGEST_LEN,
5609 : idstr, HEX_DIGEST_LEN) != DIGEST_LEN) {
5610 0 : log_warn(LD_CONFIG, "Bad v3 identity digest '%s' on DirAuthority line",
5611 : flag);
5612 : } else {
5613 2087 : type |= V3_DIRINFO|EXTRAINFO_DIRINFO|MICRODESC_DIRINFO;
5614 : }
5615 1137 : } else if (!strcasecmpstart(flag, "ipv6=")) {
5616 1121 : if (ipv6_addrport_ptr) {
5617 0 : log_warn(LD_CONFIG, "Redundant ipv6 addr/port on DirAuthority line");
5618 : } else {
5619 1121 : if (tor_addr_port_parse(LOG_WARN, flag+strlen("ipv6="),
5620 : &ipv6_addrport.addr, &ipv6_addrport.port,
5621 : -1) < 0
5622 1121 : || tor_addr_family(&ipv6_addrport.addr) != AF_INET6) {
5623 0 : log_warn(LD_CONFIG, "Bad ipv6 addr/port %s on DirAuthority line",
5624 : escaped(flag));
5625 0 : goto err;
5626 : }
5627 : ipv6_addrport_ptr = &ipv6_addrport;
5628 : }
5629 25 : } else if (!strcasecmpstart(flag, "upload=") ||
5630 16 : !strcasecmpstart(flag, "download=") ||
5631 7 : !strcasecmpstart(flag, "vote=")) {
5632 : // We'll handle these after creating the authority object.
5633 11 : smartlist_add(extra_dirports, flag);
5634 11 : flag = NULL; // prevent double-free.
5635 : } else {
5636 5 : log_warn(LD_CONFIG, "Unrecognized flag '%s' on DirAuthority line",
5637 : flag);
5638 : }
5639 5767 : tor_free(flag);
5640 5767 : smartlist_del_keeporder(items, 0);
5641 : }
5642 :
5643 2315 : if (smartlist_len(items) < 2) {
5644 0 : log_warn(LD_CONFIG, "Too few arguments to DirAuthority line.");
5645 0 : goto err;
5646 : }
5647 2315 : addrport = smartlist_get(items, 0);
5648 2315 : smartlist_del_keeporder(items, 0);
5649 :
5650 2315 : if (tor_addr_port_split(LOG_WARN, addrport, &address, &dir_port) < 0) {
5651 0 : log_warn(LD_CONFIG, "Error parsing DirAuthority address '%s'.", addrport);
5652 0 : goto err;
5653 : }
5654 :
5655 2315 : if (!string_is_valid_ipv4_address(address)) {
5656 2 : log_warn(LD_CONFIG, "Error parsing DirAuthority address '%s' "
5657 : "(invalid IPv4 address)", address);
5658 2 : goto err;
5659 : }
5660 :
5661 2313 : if (!dir_port) {
5662 0 : log_warn(LD_CONFIG, "Missing port in DirAuthority address '%s'",addrport);
5663 0 : goto err;
5664 : }
5665 :
5666 2313 : fingerprint = smartlist_join_strings(items, "", 0, NULL);
5667 2313 : if (strlen(fingerprint) != HEX_DIGEST_LEN) {
5668 0 : log_warn(LD_CONFIG, "Key digest '%s' for DirAuthority is wrong length %d.",
5669 : fingerprint, (int)strlen(fingerprint));
5670 0 : goto err;
5671 : }
5672 2313 : if (base16_decode(digest, DIGEST_LEN,
5673 : fingerprint, HEX_DIGEST_LEN) != DIGEST_LEN) {
5674 0 : log_warn(LD_CONFIG, "Unable to decode DirAuthority key digest.");
5675 0 : goto err;
5676 : }
5677 :
5678 2313 : if (validate_only) {
5679 64 : SMARTLIST_FOREACH_BEGIN(extra_dirports, const char *, cp) {
5680 7 : if (parse_dirauth_dirport(NULL, cp) < 0)
5681 4 : goto err;
5682 3 : } SMARTLIST_FOREACH_END(cp);
5683 : }
5684 :
5685 2309 : if (!validate_only && (!required_type || required_type & type)) {
5686 2221 : dir_server_t *ds;
5687 2221 : if (required_type)
5688 2209 : type &= required_type; /* pare down what we think of them as an
5689 : * authority for. */
5690 2221 : log_debug(LD_DIR, "Trusted %d dirserver at %s:%d (%s)", (int)type,
5691 : address, (int)dir_port, (char*)smartlist_get(items,0));
5692 2221 : if (!(ds = trusted_dir_server_new(nickname, address, dir_port, or_port,
5693 : ipv6_addrport_ptr,
5694 : digest, v3_digest, type, weight)))
5695 0 : goto err;
5696 :
5697 2225 : SMARTLIST_FOREACH_BEGIN(extra_dirports, const char *, cp) {
5698 4 : if (parse_dirauth_dirport(ds, cp) < 0)
5699 0 : goto err;
5700 4 : } SMARTLIST_FOREACH_END(cp);
5701 2221 : dir_server_add(ds);
5702 : }
5703 :
5704 2309 : r = 0;
5705 2309 : goto done;
5706 :
5707 : err:
5708 : r = -1;
5709 :
5710 2315 : done:
5711 2326 : SMARTLIST_FOREACH(extra_dirports, char*, s, tor_free(s));
5712 2315 : smartlist_free(extra_dirports);
5713 25461 : SMARTLIST_FOREACH(items, char*, s, tor_free(s));
5714 2315 : smartlist_free(items);
5715 2315 : tor_free(addrport);
5716 2315 : tor_free(address);
5717 2315 : tor_free(nickname);
5718 2315 : tor_free(fingerprint);
5719 2315 : return r;
5720 : }
5721 :
5722 : /** Read the contents of a FallbackDir line from <b>line</b>. If
5723 : * <b>validate_only</b> is 0, and the line is well-formed, then add the
5724 : * dirserver described in the line as a fallback directory. Return 0 on
5725 : * success, or -1 if the line isn't well-formed or if we can't add it. */
5726 : int
5727 42210 : parse_dir_fallback_line(const char *line,
5728 : int validate_only)
5729 : {
5730 42210 : int r = -1;
5731 42210 : smartlist_t *items = smartlist_new(), *positional = smartlist_new();
5732 42210 : int orport = -1;
5733 42210 : uint16_t dirport;
5734 42210 : tor_addr_t addr;
5735 42210 : int ok;
5736 42210 : char id[DIGEST_LEN];
5737 42210 : char *address=NULL;
5738 42210 : tor_addr_port_t ipv6_addrport, *ipv6_addrport_ptr = NULL;
5739 42210 : double weight=1.0;
5740 :
5741 42210 : memset(id, 0, sizeof(id));
5742 42210 : smartlist_split_string(items, line, NULL,
5743 : SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
5744 183822 : SMARTLIST_FOREACH_BEGIN(items, const char *, cp) {
5745 141612 : const char *eq = strchr(cp, '=');
5746 141612 : ok = 1;
5747 141612 : if (! eq) {
5748 42210 : smartlist_add(positional, (char*)cp);
5749 42210 : continue;
5750 : }
5751 99402 : if (!strcmpstart(cp, "orport=")) {
5752 42210 : orport = (int)tor_parse_long(cp+strlen("orport="), 10,
5753 : 1, 65535, &ok, NULL);
5754 57192 : } else if (!strcmpstart(cp, "id=")) {
5755 84420 : ok = base16_decode(id, DIGEST_LEN, cp+strlen("id="),
5756 42210 : strlen(cp)-strlen("id=")) == DIGEST_LEN;
5757 14982 : } else if (!strcasecmpstart(cp, "ipv6=")) {
5758 14982 : if (ipv6_addrport_ptr) {
5759 0 : log_warn(LD_CONFIG, "Redundant ipv6 addr/port on FallbackDir line");
5760 : } else {
5761 14982 : if (tor_addr_port_parse(LOG_WARN, cp+strlen("ipv6="),
5762 : &ipv6_addrport.addr, &ipv6_addrport.port,
5763 : -1) < 0
5764 14982 : || tor_addr_family(&ipv6_addrport.addr) != AF_INET6) {
5765 0 : log_warn(LD_CONFIG, "Bad ipv6 addr/port %s on FallbackDir line",
5766 : escaped(cp));
5767 0 : goto end;
5768 : }
5769 : ipv6_addrport_ptr = &ipv6_addrport;
5770 : }
5771 0 : } else if (!strcmpstart(cp, "weight=")) {
5772 0 : int num_ok;
5773 0 : const char *wstring = cp + strlen("weight=");
5774 0 : weight = tor_parse_double(wstring, 0, (double)UINT64_MAX, &num_ok, NULL);
5775 0 : if (!num_ok) {
5776 0 : log_warn(LD_CONFIG, "Invalid weight '%s' on FallbackDir line.", cp);
5777 0 : weight=1.0;
5778 : }
5779 : }
5780 :
5781 99402 : if (!ok) {
5782 0 : log_warn(LD_CONFIG, "Bad FallbackDir option %s", escaped(cp));
5783 0 : goto end;
5784 : }
5785 141612 : } SMARTLIST_FOREACH_END(cp);
5786 :
5787 42210 : if (smartlist_len(positional) != 1) {
5788 0 : log_warn(LD_CONFIG, "Couldn't parse FallbackDir line %s", escaped(line));
5789 0 : goto end;
5790 : }
5791 :
5792 42210 : if (tor_digest_is_zero(id)) {
5793 0 : log_warn(LD_CONFIG, "Missing identity on FallbackDir line");
5794 0 : goto end;
5795 : }
5796 :
5797 42210 : if (orport <= 0) {
5798 0 : log_warn(LD_CONFIG, "Missing orport on FallbackDir line");
5799 0 : goto end;
5800 : }
5801 :
5802 42210 : if (tor_addr_port_split(LOG_INFO, smartlist_get(positional, 0),
5803 42210 : &address, &dirport) < 0 ||
5804 42210 : tor_addr_parse(&addr, address)<0) {
5805 0 : log_warn(LD_CONFIG, "Couldn't parse address:port %s on FallbackDir line",
5806 : (const char*)smartlist_get(positional, 0));
5807 0 : goto end;
5808 : }
5809 :
5810 42210 : if (!validate_only) {
5811 42208 : dir_server_t *ds;
5812 42208 : ds = fallback_dir_server_new(&addr, dirport, orport, ipv6_addrport_ptr,
5813 : id, weight);
5814 42208 : if (!ds) {
5815 0 : log_warn(LD_CONFIG, "Couldn't create FallbackDir %s", escaped(line));
5816 0 : goto end;
5817 : }
5818 42208 : dir_server_add(ds);
5819 : }
5820 :
5821 : r = 0;
5822 :
5823 42210 : end:
5824 183822 : SMARTLIST_FOREACH(items, char *, cp, tor_free(cp));
5825 42210 : smartlist_free(items);
5826 42210 : smartlist_free(positional);
5827 42210 : tor_free(address);
5828 42210 : return r;
5829 : }
5830 :
5831 : /** Allocate and return a new port_cfg_t with reasonable defaults.
5832 : *
5833 : * <b>namelen</b> is the length of the unix socket name
5834 : * (typically the filesystem path), not including the trailing NUL.
5835 : * It should be 0 for ports that are not zunix sockets. */
5836 : port_cfg_t *
5837 1272 : port_cfg_new(size_t namelen)
5838 : {
5839 1272 : tor_assert(namelen <= SIZE_T_CEILING - sizeof(port_cfg_t) - 1);
5840 1272 : port_cfg_t *cfg = tor_malloc_zero(sizeof(port_cfg_t) + namelen + 1);
5841 :
5842 : /* entry_cfg flags */
5843 1272 : cfg->entry_cfg.ipv4_traffic = 1;
5844 1272 : cfg->entry_cfg.ipv6_traffic = 1;
5845 1272 : cfg->entry_cfg.prefer_ipv6 = 0;
5846 1272 : cfg->entry_cfg.dns_request = 1;
5847 1272 : cfg->entry_cfg.onion_traffic = 1;
5848 1272 : cfg->entry_cfg.prefer_ipv6_virtaddr = 1;
5849 1272 : cfg->entry_cfg.session_group = SESSION_GROUP_UNSET;
5850 1272 : cfg->entry_cfg.isolation_flags = ISO_DEFAULT;
5851 :
5852 : /* Other flags default to 0 due to tor_malloc_zero */
5853 1272 : return cfg;
5854 : }
5855 :
5856 : /** Free all storage held in <b>port</b> */
5857 : void
5858 1231 : port_cfg_free_(port_cfg_t *port)
5859 : {
5860 1231 : tor_free(port);
5861 1231 : }
5862 :
5863 : /** Warn for every port in <b>ports</b> of type <b>listener_type</b> that is
5864 : * on a publicly routable address. */
5865 : static void
5866 5 : warn_nonlocal_client_ports(const smartlist_t *ports,
5867 : const char *portname,
5868 : const int listener_type)
5869 : {
5870 14 : SMARTLIST_FOREACH_BEGIN(ports, const port_cfg_t *, port) {
5871 9 : if (port->type != listener_type)
5872 4 : continue;
5873 5 : if (port->is_unix_addr) {
5874 : /* Unix sockets aren't accessible over a network. */
5875 5 : } else if (!tor_addr_is_internal(&port->addr, 1)) {
5876 0 : log_warn(LD_CONFIG, "You specified a public address '%s' for %sPort. "
5877 : "Other people on the Internet might find your computer and "
5878 : "use it as an open proxy. Please don't allow this unless you "
5879 : "have a good reason.",
5880 : fmt_addrport(&port->addr, port->port), portname);
5881 5 : } else if (!tor_addr_is_loopback(&port->addr)) {
5882 0 : log_notice(LD_CONFIG, "You configured a non-loopback address '%s' "
5883 : "for %sPort. This allows everybody on your local network to "
5884 : "use your machine as a proxy. Make sure this is what you "
5885 : "wanted.",
5886 : fmt_addrport(&port->addr, port->port), portname);
5887 : }
5888 9 : } SMARTLIST_FOREACH_END(port);
5889 5 : }
5890 :
5891 : /** Given a list of port_cfg_t in <b>ports</b>, warn if any controller port
5892 : * there is listening on any non-loopback address. If <b>forbid_nonlocal</b>
5893 : * is true, then emit a stronger warning and remove the port from the list.
5894 : */
5895 : static void
5896 15 : warn_nonlocal_controller_ports(smartlist_t *ports, unsigned forbid_nonlocal)
5897 : {
5898 15 : int warned = 0;
5899 47 : SMARTLIST_FOREACH_BEGIN(ports, port_cfg_t *, port) {
5900 32 : if (port->type != CONN_TYPE_CONTROL_LISTENER)
5901 17 : continue;
5902 15 : if (port->is_unix_addr)
5903 7 : continue;
5904 8 : if (!tor_addr_is_loopback(&port->addr)) {
5905 0 : if (forbid_nonlocal) {
5906 0 : if (!warned)
5907 0 : log_warn(LD_CONFIG,
5908 : "You have a ControlPort set to accept "
5909 : "unauthenticated connections from a non-local address. "
5910 : "This means that programs not running on your computer "
5911 : "can reconfigure your Tor, without even having to guess a "
5912 : "password. That's so bad that I'm closing your ControlPort "
5913 : "for you. If you need to control your Tor remotely, try "
5914 : "enabling authentication and using a tool like stunnel or "
5915 : "ssh to encrypt remote access.");
5916 0 : warned = 1;
5917 0 : port_cfg_free(port);
5918 0 : SMARTLIST_DEL_CURRENT(ports, port);
5919 : } else {
5920 0 : log_warn(LD_CONFIG, "You have a ControlPort set to accept "
5921 : "connections from a non-local address. This means that "
5922 : "programs not running on your computer can reconfigure your "
5923 : "Tor. That's pretty bad, since the controller "
5924 : "protocol isn't encrypted! Maybe you should just listen on "
5925 : "127.0.0.1 and use a tool like stunnel or ssh to encrypt "
5926 : "remote connections to your control port.");
5927 0 : return; /* No point in checking the rest */
5928 : }
5929 : }
5930 32 : } SMARTLIST_FOREACH_END(port);
5931 : }
5932 :
5933 : /**
5934 : * Take a string (<b>line</b>) that begins with either an address:port, a
5935 : * port, or an AF_UNIX address, optionally quoted, prefixed with
5936 : * "unix:". Parse that line, and on success, set <b>addrport_out</b> to a new
5937 : * string containing the beginning portion (without prefix). Iff there was a
5938 : * unix: prefix, set <b>is_unix_out</b> to true. On success, also set
5939 : * <b>rest_out</b> to point to the part of the line after the address portion.
5940 : *
5941 : * Return 0 on success, -1 on failure.
5942 : */
5943 : int
5944 759 : port_cfg_line_extract_addrport(const char *line,
5945 : char **addrport_out,
5946 : int *is_unix_out,
5947 : const char **rest_out)
5948 : {
5949 759 : tor_assert(line);
5950 759 : tor_assert(addrport_out);
5951 759 : tor_assert(is_unix_out);
5952 759 : tor_assert(rest_out);
5953 :
5954 759 : line = eat_whitespace(line);
5955 :
5956 759 : if (!strcmpstart(line, unix_q_socket_prefix)) {
5957 : // It starts with unix:"
5958 14 : size_t sz;
5959 14 : *is_unix_out = 1;
5960 14 : *addrport_out = NULL;
5961 14 : line += strlen(unix_socket_prefix); /* No 'unix:', but keep the quote */
5962 14 : *rest_out = unescape_string(line, addrport_out, &sz);
5963 14 : if (!*rest_out || (*addrport_out && sz != strlen(*addrport_out))) {
5964 4 : tor_free(*addrport_out);
5965 4 : return -1;
5966 : }
5967 10 : *rest_out = eat_whitespace(*rest_out);
5968 10 : return 0;
5969 : } else {
5970 : // Is there a unix: prefix?
5971 745 : if (!strcmpstart(line, unix_socket_prefix)) {
5972 21 : line += strlen(unix_socket_prefix);
5973 21 : *is_unix_out = 1;
5974 : } else {
5975 724 : *is_unix_out = 0;
5976 : }
5977 :
5978 745 : const char *end = find_whitespace(line);
5979 745 : if (BUG(!end)) {
5980 : end = strchr(line, '\0'); // LCOV_EXCL_LINE -- this can't be NULL
5981 : }
5982 745 : tor_assert(end && end >= line);
5983 745 : *addrport_out = tor_strndup(line, end - line);
5984 745 : *rest_out = eat_whitespace(end);
5985 745 : return 0;
5986 : }
5987 : }
5988 :
5989 : static void
5990 7 : warn_client_dns_cache(const char *option, int disabling)
5991 : {
5992 7 : if (disabling)
5993 : return;
5994 :
5995 6 : warn_deprecated_option(option,
5996 : "Client-side DNS caching enables a wide variety of route-"
5997 : "capture attacks. If a single bad exit node lies to you about "
5998 : "an IP address, caching that address would make you visit "
5999 : "an address of the attacker's choice every time you connected "
6000 : "to your destination.");
6001 : }
6002 :
6003 : /**
6004 : * Parse port configuration for a single port type.
6005 : *
6006 : * Read entries of the "FooPort" type from the list <b>ports</b>. Syntax is
6007 : * that FooPort can have any number of entries of the format
6008 : * "[Address:][Port] IsolationOptions".
6009 : *
6010 : * In log messages, describe the port type as <b>portname</b>.
6011 : *
6012 : * If no address is specified, default to <b>defaultaddr</b>. If no
6013 : * FooPort is given, default to defaultport (if 0, there is no default).
6014 : *
6015 : * If CL_PORT_NO_STREAM_OPTIONS is set in <b>flags</b>, do not allow stream
6016 : * isolation options in the FooPort entries.
6017 : *
6018 : * If CL_PORT_WARN_NONLOCAL is set in <b>flags</b>, warn if any of the
6019 : * ports are not on a local address. If CL_PORT_FORBID_NONLOCAL is set,
6020 : * this is a control port with no password set: don't even allow it.
6021 : *
6022 : * If CL_PORT_SERVER_OPTIONS is set in <b>flags</b>, do not allow stream
6023 : * isolation options in the FooPort entries; instead allow the
6024 : * server-port option set.
6025 : *
6026 : * If CL_PORT_TAKES_HOSTNAMES is set in <b>flags</b>, allow the options
6027 : * {No,}IPv{4,6}Traffic.
6028 : *
6029 : * On success, if <b>out</b> is given, add a new port_cfg_t entry to
6030 : * <b>out</b> for every port that the client should listen on. Return 0
6031 : * on success, -1 on failure.
6032 : */
6033 : int
6034 6537 : port_parse_config(smartlist_t *out,
6035 : const config_line_t *ports,
6036 : const char *portname,
6037 : int listener_type,
6038 : const char *defaultaddr,
6039 : int defaultport,
6040 : const unsigned flags)
6041 : {
6042 6537 : smartlist_t *elts;
6043 6537 : int retval = -1;
6044 6537 : const unsigned is_control = (listener_type == CONN_TYPE_CONTROL_LISTENER);
6045 6537 : const unsigned is_ext_orport = (listener_type == CONN_TYPE_EXT_OR_LISTENER);
6046 6537 : const unsigned allow_no_stream_options = flags & CL_PORT_NO_STREAM_OPTIONS;
6047 6537 : const unsigned use_server_options = flags & CL_PORT_SERVER_OPTIONS;
6048 6537 : const unsigned warn_nonlocal = flags & CL_PORT_WARN_NONLOCAL;
6049 6537 : const unsigned forbid_nonlocal = flags & CL_PORT_FORBID_NONLOCAL;
6050 6537 : const unsigned default_to_group_writable =
6051 : flags & CL_PORT_DFLT_GROUP_WRITABLE;
6052 6537 : const unsigned takes_hostnames = flags & CL_PORT_TAKES_HOSTNAMES;
6053 6537 : const unsigned is_unix_socket = flags & CL_PORT_IS_UNIXSOCKET;
6054 6537 : int got_zero_port=0, got_nonzero_port=0;
6055 6537 : char *unix_socket_path = NULL;
6056 6537 : port_cfg_t *cfg = NULL;
6057 6537 : bool addr_is_explicit = false;
6058 6537 : tor_addr_t default_addr = TOR_ADDR_NULL;
6059 :
6060 : /* Parse default address. This can fail for Unix socket so the default_addr
6061 : * will simply be made UNSPEC. */
6062 6537 : if (defaultaddr) {
6063 5920 : tor_addr_parse(&default_addr, defaultaddr);
6064 : }
6065 :
6066 : /* If there's no FooPort, then maybe make a default one. */
6067 6537 : if (! ports) {
6068 5887 : if (defaultport && defaultaddr && out) {
6069 573 : cfg = port_cfg_new(is_unix_socket ? strlen(defaultaddr) : 0);
6070 573 : cfg->type = listener_type;
6071 573 : if (is_unix_socket) {
6072 1 : tor_addr_make_unspec(&cfg->addr);
6073 1 : memcpy(cfg->unix_addr, defaultaddr, strlen(defaultaddr) + 1);
6074 1 : cfg->is_unix_addr = 1;
6075 : } else {
6076 572 : cfg->port = defaultport;
6077 572 : tor_addr_parse(&cfg->addr, defaultaddr);
6078 : }
6079 573 : smartlist_add(out, cfg);
6080 : }
6081 5887 : return 0;
6082 : }
6083 :
6084 : /* At last we can actually parse the FooPort lines. The syntax is:
6085 : * [Addr:](Port|auto) [Options].*/
6086 650 : elts = smartlist_new();
6087 650 : char *addrport = NULL;
6088 :
6089 1332 : for (; ports; ports = ports->next) {
6090 711 : tor_addr_t addr;
6091 711 : tor_addr_make_unspec(&addr);
6092 711 : int port, ok,
6093 711 : has_used_unix_socket_only_option = 0,
6094 711 : is_unix_tagged_addr = 0;
6095 711 : uint16_t ptmp=0;
6096 711 : const char *rest_of_line = NULL;
6097 :
6098 711 : if (port_cfg_line_extract_addrport(ports->value,
6099 : &addrport, &is_unix_tagged_addr, &rest_of_line)<0) {
6100 1 : log_warn(LD_CONFIG, "Invalid %sPort line with unparsable address",
6101 : portname);
6102 29 : goto err;
6103 : }
6104 710 : if (strlen(addrport) == 0) {
6105 4 : log_warn(LD_CONFIG, "Invalid %sPort line with no address", portname);
6106 4 : goto err;
6107 : }
6108 :
6109 : /* Split the remainder... */
6110 706 : smartlist_split_string(elts, rest_of_line, NULL,
6111 : SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
6112 :
6113 : /* Let's start to check if it's a Unix socket path. */
6114 706 : if (is_unix_tagged_addr) {
6115 : #ifndef HAVE_SYS_UN_H
6116 : log_warn(LD_CONFIG, "Unix sockets not supported on this system.");
6117 : goto err;
6118 : #endif
6119 14 : unix_socket_path = addrport;
6120 14 : addrport = NULL;
6121 : }
6122 :
6123 720 : if (unix_socket_path &&
6124 14 : ! conn_listener_type_supports_af_unix(listener_type)) {
6125 2 : log_warn(LD_CONFIG, "%sPort does not support unix sockets", portname);
6126 2 : goto err;
6127 : }
6128 :
6129 704 : if (unix_socket_path) {
6130 : port = 1;
6131 692 : } else if (is_unix_socket) {
6132 5 : if (BUG(!addrport))
6133 : goto err; // LCOV_EXCL_LINE unreachable, but coverity can't tell that
6134 5 : unix_socket_path = tor_strdup(addrport);
6135 5 : if (!strcmp(addrport, "0"))
6136 : port = 0;
6137 : else
6138 4 : port = 1;
6139 687 : } else if (!strcasecmp(addrport, "auto")) {
6140 23 : port = CFG_AUTO_PORT;
6141 23 : tor_addr_copy(&addr, &default_addr);
6142 664 : } else if (!strcasecmpend(addrport, ":auto")) {
6143 38 : char *addrtmp = tor_strndup(addrport, strlen(addrport)-5);
6144 38 : port = CFG_AUTO_PORT;
6145 38 : if (tor_addr_port_lookup(addrtmp, &addr, &ptmp)<0 || ptmp) {
6146 2 : log_warn(LD_CONFIG, "Invalid address '%s' for %sPort",
6147 : escaped(addrport), portname);
6148 2 : tor_free(addrtmp);
6149 2 : goto err;
6150 : }
6151 36 : tor_free(addrtmp);
6152 : } else {
6153 : /* Try parsing integer port before address, because, who knows?
6154 : * "9050" might be a valid address. */
6155 626 : port = (int) tor_parse_long(addrport, 10, 0, 65535, &ok, NULL);
6156 626 : if (ok) {
6157 506 : tor_addr_copy(&addr, &default_addr);
6158 506 : addr_is_explicit = false;
6159 120 : } else if (tor_addr_port_lookup(addrport, &addr, &ptmp) == 0) {
6160 114 : if (ptmp == 0) {
6161 0 : log_warn(LD_CONFIG, "%sPort line has address but no port", portname);
6162 0 : goto err;
6163 : }
6164 114 : port = ptmp;
6165 114 : addr_is_explicit = true;
6166 : } else {
6167 6 : log_warn(LD_CONFIG, "Couldn't parse address %s for %sPort",
6168 : escaped(addrport), portname);
6169 6 : goto err;
6170 : }
6171 : }
6172 :
6173 : /* Default port_cfg_t object initialization */
6174 696 : cfg = port_cfg_new(unix_socket_path ? strlen(unix_socket_path) : 0);
6175 :
6176 696 : cfg->explicit_addr = addr_is_explicit;
6177 696 : if (unix_socket_path && default_to_group_writable)
6178 1 : cfg->is_group_writable = 1;
6179 :
6180 : /* Now parse the rest of the options, if any. */
6181 696 : if (use_server_options) {
6182 : /* This is a server port; parse advertising options */
6183 637 : SMARTLIST_FOREACH_BEGIN(elts, char *, elt) {
6184 27 : if (!strcasecmp(elt, "NoAdvertise")) {
6185 9 : cfg->server_cfg.no_advertise = 1;
6186 18 : } else if (!strcasecmp(elt, "NoListen")) {
6187 7 : cfg->server_cfg.no_listen = 1;
6188 : #if 0
6189 : /* not implemented yet. */
6190 : } else if (!strcasecmp(elt, "AllAddrs")) {
6191 :
6192 : all_addrs = 1;
6193 : #endif /* 0 */
6194 11 : } else if (!strcasecmp(elt, "IPv4Only")) {
6195 5 : cfg->server_cfg.bind_ipv4_only = 1;
6196 6 : } else if (!strcasecmp(elt, "IPv6Only")) {
6197 5 : cfg->server_cfg.bind_ipv6_only = 1;
6198 : } else {
6199 1 : log_warn(LD_CONFIG, "Unrecognized %sPort option '%s'",
6200 : portname, escaped(elt));
6201 : }
6202 27 : } SMARTLIST_FOREACH_END(elt);
6203 :
6204 610 : if (cfg->server_cfg.no_advertise && cfg->server_cfg.no_listen) {
6205 1 : log_warn(LD_CONFIG, "Tried to set both NoListen and NoAdvertise "
6206 : "on %sPort line '%s'",
6207 : portname, escaped(ports->value));
6208 1 : goto err;
6209 : }
6210 609 : if (cfg->server_cfg.bind_ipv4_only &&
6211 : cfg->server_cfg.bind_ipv6_only) {
6212 1 : log_warn(LD_CONFIG, "Tried to set both IPv4Only and IPv6Only "
6213 : "on %sPort line '%s'",
6214 : portname, escaped(ports->value));
6215 1 : goto err;
6216 : }
6217 608 : if (cfg->server_cfg.bind_ipv4_only &&
6218 4 : tor_addr_family(&addr) != AF_INET) {
6219 3 : if (cfg->explicit_addr) {
6220 2 : log_warn(LD_CONFIG, "Could not interpret %sPort address as IPv4",
6221 : portname);
6222 2 : goto err;
6223 : }
6224 : /* This ORPort is IPv4Only but the default address is IPv6, ignore it
6225 : * since this will be configured with an IPv4 default address. */
6226 1 : goto ignore;
6227 : }
6228 605 : if (cfg->server_cfg.bind_ipv6_only &&
6229 4 : tor_addr_family(&addr) != AF_INET6) {
6230 3 : if (cfg->explicit_addr) {
6231 2 : log_warn(LD_CONFIG, "Could not interpret %sPort address as IPv6",
6232 : portname);
6233 2 : goto err;
6234 : }
6235 : /* This ORPort is IPv6Only but the default address is IPv4, ignore it
6236 : * since this will be configured with an IPv6 default address. */
6237 1 : goto ignore;
6238 : }
6239 : } else {
6240 : /* This is a client port; parse isolation options */
6241 134 : SMARTLIST_FOREACH_BEGIN(elts, char *, elt) {
6242 51 : int no = 0, isoflag = 0;
6243 51 : const char *elt_orig = elt;
6244 :
6245 51 : if (!strcasecmpstart(elt, "SessionGroup=")) {
6246 5 : int group = (int)tor_parse_long(elt+strlen("SessionGroup="),
6247 : 10, 0, INT_MAX, &ok, NULL);
6248 5 : if (!ok || allow_no_stream_options) {
6249 2 : log_warn(LD_CONFIG, "Invalid %sPort option '%s'",
6250 : portname, escaped(elt));
6251 2 : goto err;
6252 : }
6253 3 : if (cfg->entry_cfg.session_group >= 0) {
6254 1 : log_warn(LD_CONFIG, "Multiple SessionGroup options on %sPort",
6255 : portname);
6256 1 : goto err;
6257 : }
6258 2 : cfg->entry_cfg.session_group = group;
6259 2 : continue;
6260 : }
6261 :
6262 46 : if (!strcasecmpstart(elt, "No")) {
6263 18 : no = 1;
6264 18 : elt += 2;
6265 : }
6266 :
6267 46 : if (!strcasecmp(elt, "GroupWritable")) {
6268 1 : cfg->is_group_writable = !no;
6269 1 : has_used_unix_socket_only_option = 1;
6270 1 : continue;
6271 45 : } else if (!strcasecmp(elt, "WorldWritable")) {
6272 5 : cfg->is_world_writable = !no;
6273 5 : has_used_unix_socket_only_option = 1;
6274 5 : continue;
6275 40 : } else if (!strcasecmp(elt, "RelaxDirModeCheck")) {
6276 1 : cfg->relax_dirmode_check = !no;
6277 1 : has_used_unix_socket_only_option = 1;
6278 1 : continue;
6279 : }
6280 :
6281 39 : if (allow_no_stream_options) {
6282 2 : log_warn(LD_CONFIG, "Unrecognized %sPort option '%s'",
6283 : portname, escaped(elt));
6284 2 : continue;
6285 : }
6286 :
6287 37 : if (takes_hostnames) {
6288 21 : if (!strcasecmp(elt, "IPv4Traffic")) {
6289 6 : cfg->entry_cfg.ipv4_traffic = ! no;
6290 6 : continue;
6291 15 : } else if (!strcasecmp(elt, "IPv6Traffic")) {
6292 7 : cfg->entry_cfg.ipv6_traffic = ! no;
6293 7 : continue;
6294 8 : } else if (!strcasecmp(elt, "PreferIPv6")) {
6295 1 : cfg->entry_cfg.prefer_ipv6 = ! no;
6296 1 : continue;
6297 7 : } else if (!strcasecmp(elt, "DNSRequest")) {
6298 3 : cfg->entry_cfg.dns_request = ! no;
6299 3 : continue;
6300 4 : } else if (!strcasecmp(elt, "OnionTraffic")) {
6301 2 : cfg->entry_cfg.onion_traffic = ! no;
6302 2 : continue;
6303 2 : } else if (!strcasecmp(elt, "OnionTrafficOnly")) {
6304 : /* Only connect to .onion addresses. Equivalent to
6305 : * NoDNSRequest, NoIPv4Traffic, NoIPv6Traffic. The option
6306 : * NoOnionTrafficOnly is not supported, it's too confusing. */
6307 1 : if (no) {
6308 0 : log_warn(LD_CONFIG, "Unsupported %sPort option 'No%s'. Use "
6309 : "DNSRequest, IPv4Traffic, and/or IPv6Traffic instead.",
6310 : portname, escaped(elt));
6311 : } else {
6312 1 : cfg->entry_cfg.ipv4_traffic = 0;
6313 1 : cfg->entry_cfg.ipv6_traffic = 0;
6314 1 : cfg->entry_cfg.dns_request = 0;
6315 : }
6316 1 : continue;
6317 : }
6318 : }
6319 17 : if (!strcasecmp(elt, "CacheIPv4DNS")) {
6320 2 : warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
6321 2 : cfg->entry_cfg.cache_ipv4_answers = ! no;
6322 2 : continue;
6323 15 : } else if (!strcasecmp(elt, "CacheIPv6DNS")) {
6324 1 : warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
6325 1 : cfg->entry_cfg.cache_ipv6_answers = ! no;
6326 1 : continue;
6327 14 : } else if (!strcasecmp(elt, "CacheDNS")) {
6328 1 : warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
6329 1 : cfg->entry_cfg.cache_ipv4_answers = ! no;
6330 1 : cfg->entry_cfg.cache_ipv6_answers = ! no;
6331 1 : continue;
6332 13 : } else if (!strcasecmp(elt, "UseIPv4Cache")) {
6333 1 : warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
6334 1 : cfg->entry_cfg.use_cached_ipv4_answers = ! no;
6335 1 : continue;
6336 12 : } else if (!strcasecmp(elt, "UseIPv6Cache")) {
6337 1 : warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
6338 1 : cfg->entry_cfg.use_cached_ipv6_answers = ! no;
6339 1 : continue;
6340 11 : } else if (!strcasecmp(elt, "UseDNSCache")) {
6341 1 : warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
6342 1 : cfg->entry_cfg.use_cached_ipv4_answers = ! no;
6343 1 : cfg->entry_cfg.use_cached_ipv6_answers = ! no;
6344 1 : continue;
6345 10 : } else if (!strcasecmp(elt, "PreferIPv6Automap")) {
6346 1 : cfg->entry_cfg.prefer_ipv6_virtaddr = ! no;
6347 1 : continue;
6348 9 : } else if (!strcasecmp(elt, "PreferSOCKSNoAuth")) {
6349 1 : cfg->entry_cfg.socks_prefer_no_auth = ! no;
6350 1 : continue;
6351 8 : } else if (!strcasecmp(elt, "KeepAliveIsolateSOCKSAuth")) {
6352 0 : cfg->entry_cfg.socks_iso_keep_alive = ! no;
6353 0 : continue;
6354 8 : } else if (!strcasecmp(elt, "ExtendedErrors")) {
6355 0 : cfg->entry_cfg.extended_socks5_codes = ! no;
6356 0 : continue;
6357 : }
6358 :
6359 8 : if (!strcasecmpend(elt, "s"))
6360 1 : elt[strlen(elt)-1] = '\0'; /* kill plurals. */
6361 :
6362 8 : if (!strcasecmp(elt, "IsolateDestPort")) {
6363 : isoflag = ISO_DESTPORT;
6364 6 : } else if (!strcasecmp(elt, "IsolateDestAddr")) {
6365 : isoflag = ISO_DESTADDR;
6366 5 : } else if (!strcasecmp(elt, "IsolateSOCKSAuth")) {
6367 : isoflag = ISO_SOCKSAUTH;
6368 3 : } else if (!strcasecmp(elt, "IsolateClientProtocol")) {
6369 : isoflag = ISO_CLIENTPROTO;
6370 2 : } else if (!strcasecmp(elt, "IsolateClientAddr")) {
6371 : isoflag = ISO_CLIENTADDR;
6372 : } else {
6373 1 : log_warn(LD_CONFIG, "Unrecognized %sPort option '%s'",
6374 : portname, escaped(elt_orig));
6375 : }
6376 :
6377 8 : if (no) {
6378 2 : cfg->entry_cfg.isolation_flags &= ~isoflag;
6379 : } else {
6380 6 : cfg->entry_cfg.isolation_flags |= isoflag;
6381 : }
6382 48 : } SMARTLIST_FOREACH_END(elt);
6383 : }
6384 :
6385 685 : if (port)
6386 : got_nonzero_port = 1;
6387 : else
6388 14 : got_zero_port = 1;
6389 :
6390 685 : if (cfg->entry_cfg.dns_request == 0 &&
6391 : listener_type == CONN_TYPE_AP_DNS_LISTENER) {
6392 1 : log_warn(LD_CONFIG, "You have a %sPort entry with DNS disabled; that "
6393 : "won't work.", portname);
6394 1 : goto err;
6395 : }
6396 684 : if (cfg->entry_cfg.ipv4_traffic == 0 &&
6397 684 : cfg->entry_cfg.ipv6_traffic == 0 &&
6398 2 : cfg->entry_cfg.onion_traffic == 0 &&
6399 : listener_type != CONN_TYPE_AP_DNS_LISTENER) {
6400 1 : log_warn(LD_CONFIG, "You have a %sPort entry with all of IPv4 and "
6401 : "IPv6 and .onion disabled; that won't work.", portname);
6402 1 : goto err;
6403 : }
6404 683 : if (cfg->entry_cfg.dns_request == 1 &&
6405 683 : cfg->entry_cfg.ipv4_traffic == 0 &&
6406 1 : cfg->entry_cfg.ipv6_traffic == 0 &&
6407 : listener_type != CONN_TYPE_AP_DNS_LISTENER) {
6408 0 : log_warn(LD_CONFIG, "You have a %sPort entry with DNSRequest enabled, "
6409 : "but IPv4 and IPv6 disabled; DNS-based sites won't work.",
6410 : portname);
6411 0 : goto err;
6412 : }
6413 683 : if (has_used_unix_socket_only_option && !unix_socket_path) {
6414 3 : log_warn(LD_CONFIG, "You have a %sPort entry with GroupWritable, "
6415 : "WorldWritable, or RelaxDirModeCheck, but it is not a "
6416 : "unix socket.", portname);
6417 3 : goto err;
6418 : }
6419 680 : if (!(cfg->entry_cfg.isolation_flags & ISO_SOCKSAUTH) &&
6420 : cfg->entry_cfg.socks_iso_keep_alive) {
6421 0 : log_warn(LD_CONFIG, "You have a %sPort entry with both "
6422 : "NoIsolateSOCKSAuth and KeepAliveIsolateSOCKSAuth set.",
6423 : portname);
6424 0 : goto err;
6425 : }
6426 680 : if (unix_socket_path &&
6427 : (cfg->entry_cfg.isolation_flags & ISO_CLIENTADDR)) {
6428 : /* `IsolateClientAddr` is nonsensical in the context of AF_LOCAL.
6429 : * just silently remove the isolation flag.
6430 : */
6431 16 : cfg->entry_cfg.isolation_flags &= ~ISO_CLIENTADDR;
6432 : }
6433 680 : if (out && port) {
6434 663 : size_t namelen = unix_socket_path ? strlen(unix_socket_path) : 0;
6435 663 : if (unix_socket_path) {
6436 15 : tor_addr_make_unspec(&cfg->addr);
6437 15 : memcpy(cfg->unix_addr, unix_socket_path, namelen + 1);
6438 15 : cfg->is_unix_addr = 1;
6439 15 : tor_free(unix_socket_path);
6440 : } else {
6441 648 : tor_addr_copy(&cfg->addr, &addr);
6442 648 : cfg->port = port;
6443 : }
6444 663 : cfg->type = listener_type;
6445 663 : if (! (cfg->entry_cfg.isolation_flags & ISO_SOCKSAUTH))
6446 1 : cfg->entry_cfg.socks_prefer_no_auth = 1;
6447 663 : smartlist_add(out, cfg);
6448 : /* out owns cfg now, don't re-use or free it */
6449 663 : cfg = NULL;
6450 : }
6451 :
6452 17 : ignore:
6453 682 : tor_free(cfg);
6454 741 : SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
6455 682 : smartlist_clear(elts);
6456 682 : tor_free(addrport);
6457 682 : tor_free(unix_socket_path);
6458 : }
6459 :
6460 621 : if (warn_nonlocal && out) {
6461 34 : if (is_control)
6462 15 : warn_nonlocal_controller_ports(out, forbid_nonlocal);
6463 19 : else if (is_ext_orport)
6464 14 : port_warn_nonlocal_ext_orports(out, portname);
6465 : else
6466 5 : warn_nonlocal_client_ports(out, portname, listener_type);
6467 : }
6468 :
6469 621 : if (got_zero_port && got_nonzero_port) {
6470 1 : log_warn(LD_CONFIG, "You specified a nonzero %sPort along with '%sPort 0' "
6471 : "in the same configuration. Did you mean to disable %sPort or "
6472 : "not?", portname, portname, portname);
6473 1 : goto err;
6474 : }
6475 :
6476 : retval = 0;
6477 650 : err:
6478 : /* There are two ways we can error out:
6479 : * 1. part way through the loop: cfg needs to be freed;
6480 : * 2. ending the loop normally: cfg is always NULL.
6481 : * In this case, cfg has either been:
6482 : * - added to out, then set to NULL, or
6483 : * - freed and set to NULL (because out is NULL, or port is 0).
6484 : */
6485 650 : tor_free(cfg);
6486 :
6487 : /* Free the other variables from the loop.
6488 : * elts is always non-NULL here, but it may or may not be empty. */
6489 673 : SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
6490 650 : smartlist_free(elts);
6491 650 : tor_free(unix_socket_path);
6492 650 : tor_free(addrport);
6493 :
6494 650 : return retval;
6495 : }
6496 :
6497 : /** Return the number of ports which are actually going to listen with type
6498 : * <b>listenertype</b>. Do not count no_listen ports. Only count unix
6499 : * sockets if count_sockets is true. */
6500 : int
6501 5193 : port_count_real_listeners(const smartlist_t *ports, int listenertype,
6502 : int count_sockets)
6503 : {
6504 5193 : int n = 0;
6505 15057 : SMARTLIST_FOREACH_BEGIN(ports, port_cfg_t *, port) {
6506 9864 : if (port->server_cfg.no_listen)
6507 9 : continue;
6508 9855 : if (!count_sockets && port->is_unix_addr)
6509 28 : continue;
6510 9827 : if (port->type != listenertype)
6511 8736 : continue;
6512 1091 : ++n;
6513 9864 : } SMARTLIST_FOREACH_END(port);
6514 5193 : return n;
6515 : }
6516 :
6517 : /** Parse all ports from <b>options</b>. On success, set *<b>n_ports_out</b>
6518 : * to the number of ports that are listed, update the *Port_set values in
6519 : * <b>options</b>, and return 0. On failure, set *<b>msg</b> to a
6520 : * description of the problem and return -1.
6521 : *
6522 : * If <b>validate_only</b> is false, set configured_client_ports to the
6523 : * new list of ports parsed from <b>options</b>.
6524 : **/
6525 : STATIC int
6526 588 : parse_ports(or_options_t *options, int validate_only,
6527 : char **msg, int *n_ports_out,
6528 : int *world_writable_control_socket)
6529 : {
6530 588 : smartlist_t *ports;
6531 588 : int retval = -1;
6532 :
6533 588 : ports = smartlist_new();
6534 :
6535 588 : *n_ports_out = 0;
6536 :
6537 1176 : const unsigned gw_flag = options->UnixSocksGroupWritable ?
6538 588 : CL_PORT_DFLT_GROUP_WRITABLE : 0;
6539 588 : if (port_parse_config(ports,
6540 588 : options->SocksPort_lines,
6541 : "Socks", CONN_TYPE_AP_LISTENER,
6542 : "127.0.0.1", 9050,
6543 : ((validate_only ? 0 : CL_PORT_WARN_NONLOCAL)
6544 588 : | CL_PORT_TAKES_HOSTNAMES | gw_flag)) < 0) {
6545 0 : *msg = tor_strdup("Invalid SocksPort configuration");
6546 0 : goto err;
6547 : }
6548 588 : if (port_parse_config(ports,
6549 588 : options->DNSPort_lines,
6550 : "DNS", CONN_TYPE_AP_DNS_LISTENER,
6551 : "127.0.0.1", 0,
6552 : CL_PORT_WARN_NONLOCAL|CL_PORT_TAKES_HOSTNAMES) < 0) {
6553 0 : *msg = tor_strdup("Invalid DNSPort configuration");
6554 0 : goto err;
6555 : }
6556 588 : if (port_parse_config(ports,
6557 588 : options->TransPort_lines,
6558 : "Trans", CONN_TYPE_AP_TRANS_LISTENER,
6559 : "127.0.0.1", 0,
6560 : CL_PORT_WARN_NONLOCAL) < 0) {
6561 0 : *msg = tor_strdup("Invalid TransPort configuration");
6562 0 : goto err;
6563 : }
6564 588 : if (port_parse_config(ports,
6565 588 : options->NATDPort_lines,
6566 : "NATD", CONN_TYPE_AP_NATD_LISTENER,
6567 : "127.0.0.1", 0,
6568 : CL_PORT_WARN_NONLOCAL) < 0) {
6569 0 : *msg = tor_strdup("Invalid NatdPort configuration");
6570 0 : goto err;
6571 : }
6572 588 : if (port_parse_config(ports,
6573 588 : options->HTTPTunnelPort_lines,
6574 : "HTTP Tunnel", CONN_TYPE_AP_HTTP_CONNECT_LISTENER,
6575 : "127.0.0.1", 0,
6576 : ((validate_only ? 0 : CL_PORT_WARN_NONLOCAL)
6577 : | CL_PORT_TAKES_HOSTNAMES | gw_flag)) < 0) {
6578 0 : *msg = tor_strdup("Invalid HTTPTunnelPort configuration");
6579 0 : goto err;
6580 : }
6581 588 : if (metrics_parse_ports(options, ports, msg) < 0) {
6582 0 : goto err;
6583 : }
6584 :
6585 : {
6586 588 : unsigned control_port_flags = CL_PORT_NO_STREAM_OPTIONS |
6587 : CL_PORT_WARN_NONLOCAL;
6588 2335 : const int any_passwords = (options->HashedControlPassword ||
6589 588 : options->HashedControlSessionPassword ||
6590 580 : options->CookieAuthentication);
6591 575 : if (! any_passwords)
6592 : control_port_flags |= CL_PORT_FORBID_NONLOCAL;
6593 588 : if (options->ControlSocketsGroupWritable)
6594 1 : control_port_flags |= CL_PORT_DFLT_GROUP_WRITABLE;
6595 :
6596 588 : if (port_parse_config(ports,
6597 588 : options->ControlPort_lines,
6598 : "Control", CONN_TYPE_CONTROL_LISTENER,
6599 : "127.0.0.1", 0,
6600 : control_port_flags) < 0) {
6601 0 : *msg = tor_strdup("Invalid ControlPort configuration");
6602 0 : goto err;
6603 : }
6604 :
6605 588 : if (port_parse_config(ports, options->ControlSocket,
6606 : "ControlSocket",
6607 : CONN_TYPE_CONTROL_LISTENER, NULL, 0,
6608 : control_port_flags | CL_PORT_IS_UNIXSOCKET) < 0) {
6609 0 : *msg = tor_strdup("Invalid ControlSocket configuration");
6610 0 : goto err;
6611 : }
6612 : }
6613 :
6614 588 : if (port_parse_ports_relay(options, msg, ports, &have_low_ports) < 0)
6615 10 : goto err;
6616 :
6617 578 : *n_ports_out = smartlist_len(ports);
6618 :
6619 578 : retval = 0;
6620 :
6621 : /* Update the *Port_set options. The !! here is to force a boolean out of
6622 : an integer. */
6623 578 : port_update_port_set_relay(options, ports);
6624 578 : options->SocksPort_set =
6625 578 : !! port_count_real_listeners(ports, CONN_TYPE_AP_LISTENER, 1);
6626 578 : options->TransPort_set =
6627 578 : !! port_count_real_listeners(ports, CONN_TYPE_AP_TRANS_LISTENER, 1);
6628 578 : options->NATDPort_set =
6629 578 : !! port_count_real_listeners(ports, CONN_TYPE_AP_NATD_LISTENER, 1);
6630 578 : options->HTTPTunnelPort_set =
6631 578 : !! port_count_real_listeners(ports, CONN_TYPE_AP_HTTP_CONNECT_LISTENER, 1);
6632 : /* Use options->ControlSocket to test if a control socket is set */
6633 578 : options->ControlPort_set =
6634 578 : !! port_count_real_listeners(ports, CONN_TYPE_CONTROL_LISTENER, 0);
6635 578 : options->DNSPort_set =
6636 578 : !! port_count_real_listeners(ports, CONN_TYPE_AP_DNS_LISTENER, 1);
6637 :
6638 578 : if (world_writable_control_socket) {
6639 1657 : SMARTLIST_FOREACH(ports, port_cfg_t *, p,
6640 : if (p->type == CONN_TYPE_CONTROL_LISTENER &&
6641 : p->is_unix_addr &&
6642 : p->is_world_writable) {
6643 : *world_writable_control_socket = 1;
6644 : break;
6645 : });
6646 : }
6647 :
6648 578 : if (!validate_only) {
6649 12 : if (configured_ports) {
6650 9 : SMARTLIST_FOREACH(configured_ports,
6651 : port_cfg_t *, p, port_cfg_free(p));
6652 4 : smartlist_free(configured_ports);
6653 : }
6654 12 : configured_ports = ports;
6655 12 : ports = NULL; /* prevent free below. */
6656 : }
6657 :
6658 566 : err:
6659 588 : if (ports) {
6660 1650 : SMARTLIST_FOREACH(ports, port_cfg_t *, p, port_cfg_free(p));
6661 576 : smartlist_free(ports);
6662 : }
6663 588 : return retval;
6664 : }
6665 :
6666 : /* Does port bind to IPv4? */
6667 : int
6668 471 : port_binds_ipv4(const port_cfg_t *port)
6669 : {
6670 471 : return tor_addr_family(&port->addr) == AF_INET ||
6671 : (tor_addr_family(&port->addr) == AF_UNSPEC
6672 0 : && !port->server_cfg.bind_ipv6_only);
6673 : }
6674 :
6675 : /* Does port bind to IPv6? */
6676 : int
6677 56 : port_binds_ipv6(const port_cfg_t *port)
6678 : {
6679 56 : return tor_addr_family(&port->addr) == AF_INET6 ||
6680 : (tor_addr_family(&port->addr) == AF_UNSPEC
6681 0 : && !port->server_cfg.bind_ipv4_only);
6682 : }
6683 :
6684 : /** Return a list of port_cfg_t for client ports parsed from the
6685 : * options. */
6686 76 : MOCK_IMPL(const smartlist_t *,
6687 : get_configured_ports,(void))
6688 : {
6689 76 : if (!configured_ports)
6690 7 : configured_ports = smartlist_new();
6691 76 : return configured_ports;
6692 : }
6693 :
6694 : /** Return an address:port string representation of the address
6695 : * where the first <b>listener_type</b> listener waits for
6696 : * connections. Return NULL if we couldn't find a listener. The
6697 : * string is allocated on the heap and it's the responsibility of the
6698 : * caller to free it after use.
6699 : *
6700 : * This function is meant to be used by the pluggable transport proxy
6701 : * spawning code, please make sure that it fits your purposes before
6702 : * using it. */
6703 : char *
6704 0 : get_first_listener_addrport_string(int listener_type)
6705 : {
6706 0 : static const char *ipv4_localhost = "127.0.0.1";
6707 0 : static const char *ipv6_localhost = "[::1]";
6708 0 : const char *address;
6709 0 : uint16_t port;
6710 0 : char *string = NULL;
6711 :
6712 0 : if (!configured_ports)
6713 : return NULL;
6714 :
6715 0 : SMARTLIST_FOREACH_BEGIN(configured_ports, const port_cfg_t *, cfg) {
6716 0 : if (cfg->server_cfg.no_listen)
6717 0 : continue;
6718 :
6719 0 : if (cfg->type == listener_type &&
6720 0 : tor_addr_family(&cfg->addr) != AF_UNSPEC) {
6721 :
6722 : /* We found the first listener of the type we are interested in! */
6723 :
6724 : /* If a listener is listening on INADDR_ANY, assume that it's
6725 : also listening on 127.0.0.1, and point the transport proxy
6726 : there: */
6727 0 : if (tor_addr_is_null(&cfg->addr))
6728 0 : address = tor_addr_is_v4(&cfg->addr) ? ipv4_localhost : ipv6_localhost;
6729 : else
6730 0 : address = fmt_and_decorate_addr(&cfg->addr);
6731 :
6732 : /* If a listener is configured with port 'auto', we are forced
6733 : to iterate all listener connections and find out in which
6734 : port it ended up listening: */
6735 0 : if (cfg->port == CFG_AUTO_PORT) {
6736 0 : port = router_get_active_listener_port_by_type_af(listener_type,
6737 0 : tor_addr_family(&cfg->addr));
6738 0 : if (!port)
6739 : return NULL;
6740 : } else {
6741 0 : port = cfg->port;
6742 : }
6743 :
6744 0 : tor_asprintf(&string, "%s:%u", address, port);
6745 :
6746 0 : return string;
6747 : }
6748 :
6749 0 : } SMARTLIST_FOREACH_END(cfg);
6750 :
6751 : return NULL;
6752 : }
6753 :
6754 : /** Find and return the first configured advertised `port_cfg_t` of type @a
6755 : * listener_type in @a address_family. */
6756 : static const port_cfg_t *
6757 87 : portconf_get_first_advertised(int listener_type, int address_family)
6758 : {
6759 87 : const port_cfg_t *first_port = NULL;
6760 87 : const port_cfg_t *first_port_explicit_addr = NULL;
6761 :
6762 87 : if (address_family == AF_UNSPEC)
6763 : return NULL;
6764 :
6765 85 : const smartlist_t *conf_ports = get_configured_ports();
6766 273 : SMARTLIST_FOREACH_BEGIN(conf_ports, const port_cfg_t *, cfg) {
6767 188 : if (cfg->type == listener_type && !cfg->server_cfg.no_advertise) {
6768 112 : if ((address_family == AF_INET && port_binds_ipv4(cfg)) ||
6769 56 : (address_family == AF_INET6 && port_binds_ipv6(cfg))) {
6770 66 : if (cfg->explicit_addr && !first_port_explicit_addr) {
6771 : first_port_explicit_addr = cfg;
6772 48 : } else if (!first_port) {
6773 48 : first_port = cfg;
6774 : }
6775 : }
6776 : }
6777 188 : } SMARTLIST_FOREACH_END(cfg);
6778 :
6779 : /* Prefer the port with the explicit address if any. */
6780 85 : return (first_port_explicit_addr) ? first_port_explicit_addr : first_port;
6781 : }
6782 :
6783 : /** Return the first advertised port of type <b>listener_type</b> in
6784 : * <b>address_family</b>. Returns 0 when no port is found, and when passed
6785 : * AF_UNSPEC. */
6786 : int
6787 71 : portconf_get_first_advertised_port(int listener_type, int address_family)
6788 : {
6789 71 : const port_cfg_t *cfg;
6790 71 : cfg = portconf_get_first_advertised(listener_type, address_family);
6791 :
6792 71 : return cfg ? cfg->port : 0;
6793 : }
6794 :
6795 : /** Return the first advertised address of type <b>listener_type</b> in
6796 : * <b>address_family</b>. Returns NULL if there is no advertised address,
6797 : * and when passed AF_UNSPEC. */
6798 : const tor_addr_t *
6799 16 : portconf_get_first_advertised_addr(int listener_type, int address_family)
6800 : {
6801 16 : const port_cfg_t *cfg;
6802 16 : cfg = portconf_get_first_advertised(listener_type, address_family);
6803 :
6804 16 : return cfg ? &cfg->addr : NULL;
6805 : }
6806 :
6807 : /** Return 1 if a port exists of type <b>listener_type</b> on <b>addr</b> and
6808 : * <b>port</b>. If <b>check_wildcard</b> is true, INADDR[6]_ANY and AF_UNSPEC
6809 : * addresses match any address of the appropriate family; and port -1 matches
6810 : * any port.
6811 : * To match auto ports, pass CFG_PORT_AUTO. (Does not match on the actual
6812 : * automatically chosen listener ports.) */
6813 : int
6814 0 : port_exists_by_type_addr_port(int listener_type, const tor_addr_t *addr,
6815 : int port, int check_wildcard)
6816 : {
6817 0 : if (!configured_ports || !addr)
6818 : return 0;
6819 0 : SMARTLIST_FOREACH_BEGIN(configured_ports, const port_cfg_t *, cfg) {
6820 0 : if (cfg->type == listener_type) {
6821 0 : if (cfg->port == port || (check_wildcard && port == -1)) {
6822 : /* Exact match */
6823 0 : if (tor_addr_eq(&cfg->addr, addr)) {
6824 : return 1;
6825 : }
6826 : /* Skip wildcard matches if we're not doing them */
6827 0 : if (!check_wildcard) {
6828 0 : continue;
6829 : }
6830 : /* Wildcard matches IPv4 */
6831 0 : const int cfg_v4 = port_binds_ipv4(cfg);
6832 0 : const int cfg_any_v4 = tor_addr_is_null(&cfg->addr) && cfg_v4;
6833 0 : const int addr_v4 = tor_addr_family(addr) == AF_INET ||
6834 : tor_addr_family(addr) == AF_UNSPEC;
6835 0 : const int addr_any_v4 = tor_addr_is_null(&cfg->addr) && addr_v4;
6836 0 : if ((cfg_any_v4 && addr_v4) || (cfg_v4 && addr_any_v4)) {
6837 : return 1;
6838 : }
6839 : /* Wildcard matches IPv6 */
6840 0 : const int cfg_v6 = port_binds_ipv6(cfg);
6841 0 : const int cfg_any_v6 = tor_addr_is_null(&cfg->addr) && cfg_v6;
6842 0 : const int addr_v6 = tor_addr_family(addr) == AF_INET6 ||
6843 : tor_addr_family(addr) == AF_UNSPEC;
6844 0 : const int addr_any_v6 = tor_addr_is_null(&cfg->addr) && addr_v6;
6845 0 : if ((cfg_any_v6 && addr_v6) || (cfg_v6 && addr_any_v6)) {
6846 : return 1;
6847 : }
6848 : }
6849 : }
6850 0 : } SMARTLIST_FOREACH_END(cfg);
6851 : return 0;
6852 : }
6853 :
6854 : /* Like port_exists_by_type_addr_port, but accepts a host-order IPv4 address
6855 : * instead. */
6856 : int
6857 0 : port_exists_by_type_addr32h_port(int listener_type, uint32_t addr_ipv4h,
6858 : int port, int check_wildcard)
6859 : {
6860 0 : tor_addr_t ipv4;
6861 0 : tor_addr_from_ipv4h(&ipv4, addr_ipv4h);
6862 0 : return port_exists_by_type_addr_port(listener_type, &ipv4, port,
6863 : check_wildcard);
6864 : }
6865 :
6866 : /** Allocate and return a good value for the DataDirectory based on
6867 : * <b>val</b>, which may be NULL. Return NULL on failure. */
6868 : static char *
6869 570 : get_data_directory(const char *val)
6870 : {
6871 : #ifdef _WIN32
6872 : if (val) {
6873 : return tor_strdup(val);
6874 : } else {
6875 : return tor_strdup(get_windows_conf_root());
6876 : }
6877 : #else /* !defined(_WIN32) */
6878 570 : const char *d = val;
6879 570 : if (!d)
6880 516 : d = "~/.tor";
6881 :
6882 570 : if (!strcmpstart(d, "~/")) {
6883 516 : char *fn = expand_filename(d);
6884 516 : if (!fn) {
6885 0 : log_warn(LD_CONFIG,"Failed to expand filename \"%s\".", d);
6886 0 : return NULL;
6887 : }
6888 516 : if (!val && !strcmp(fn,"/.tor")) {
6889 : /* If our homedir is /, we probably don't want to use it. */
6890 : /* Default to LOCALSTATEDIR/tor which is probably closer to what we
6891 : * want. */
6892 0 : log_warn(LD_CONFIG,
6893 : "Default DataDirectory is \"~/.tor\". This expands to "
6894 : "\"%s\", which is probably not what you want. Using "
6895 : "\"%s"PATH_SEPARATOR"tor\" instead", fn, LOCALSTATEDIR);
6896 0 : tor_free(fn);
6897 0 : fn = tor_strdup(LOCALSTATEDIR PATH_SEPARATOR "tor");
6898 : }
6899 516 : return fn;
6900 : }
6901 54 : return tor_strdup(d);
6902 : #endif /* defined(_WIN32) */
6903 : }
6904 :
6905 : /** Check and normalize the values of options->{Key,Data,Cache}Directory;
6906 : * return 0 if it is sane, -1 otherwise. */
6907 : static int
6908 564 : validate_data_directories(or_options_t *options)
6909 : {
6910 564 : tor_free(options->DataDirectory);
6911 564 : options->DataDirectory = get_data_directory(options->DataDirectory_option);
6912 564 : if (!options->DataDirectory)
6913 : return -1;
6914 564 : if (strlen(options->DataDirectory) > (512-128)) {
6915 1 : log_warn(LD_CONFIG, "DataDirectory is too long.");
6916 1 : return -1;
6917 : }
6918 :
6919 563 : tor_free(options->KeyDirectory);
6920 563 : if (options->KeyDirectory_option) {
6921 3 : options->KeyDirectory = get_data_directory(options->KeyDirectory_option);
6922 3 : if (!options->KeyDirectory)
6923 : return -1;
6924 : } else {
6925 : /* Default to the data directory's keys subdir */
6926 560 : tor_asprintf(&options->KeyDirectory, "%s"PATH_SEPARATOR"keys",
6927 : options->DataDirectory);
6928 : }
6929 :
6930 563 : tor_free(options->CacheDirectory);
6931 563 : if (options->CacheDirectory_option) {
6932 3 : options->CacheDirectory = get_data_directory(
6933 : options->CacheDirectory_option);
6934 3 : if (!options->CacheDirectory)
6935 0 : return -1;
6936 : } else {
6937 : /* Default to the data directory. */
6938 560 : options->CacheDirectory = tor_strdup(options->DataDirectory);
6939 : }
6940 :
6941 : return 0;
6942 : }
6943 :
6944 : /** This string must remain the same forevermore. It is how we
6945 : * recognize that the torrc file doesn't need to be backed up. */
6946 : #define GENERATED_FILE_PREFIX "# This file was generated by Tor; " \
6947 : "if you edit it, comments will not be preserved"
6948 : /** This string can change; it tries to give the reader an idea
6949 : * that editing this file by hand is not a good plan. */
6950 : #define GENERATED_FILE_COMMENT "# The old torrc file was renamed " \
6951 : "to torrc.orig.1, and Tor will ignore it"
6952 :
6953 : /** Save a configuration file for the configuration in <b>options</b>
6954 : * into the file <b>fname</b>. If the file already exists, and
6955 : * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
6956 : * replace it. Return 0 on success, -1 on failure. */
6957 : static int
6958 0 : write_configuration_file(const char *fname, const or_options_t *options)
6959 : {
6960 0 : char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
6961 0 : int rename_old = 0, r;
6962 :
6963 0 : if (!fname)
6964 : return -1;
6965 :
6966 0 : switch (file_status(fname)) {
6967 : /* create backups of old config files, even if they're empty */
6968 0 : case FN_FILE:
6969 : case FN_EMPTY:
6970 0 : old_val = read_file_to_str(fname, 0, NULL);
6971 0 : if (!old_val || strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
6972 : rename_old = 1;
6973 : }
6974 0 : tor_free(old_val);
6975 0 : break;
6976 : case FN_NOENT:
6977 : break;
6978 0 : case FN_ERROR:
6979 : case FN_DIR:
6980 : default:
6981 0 : log_warn(LD_CONFIG,
6982 : "Config file \"%s\" is not a file? Failing.", fname);
6983 0 : return -1;
6984 : }
6985 :
6986 0 : if (!(new_conf = options_dump(options, OPTIONS_DUMP_MINIMAL))) {
6987 0 : log_warn(LD_BUG, "Couldn't get configuration string");
6988 0 : goto err;
6989 : }
6990 :
6991 0 : tor_asprintf(&new_val, "%s\n%s\n\n%s",
6992 : GENERATED_FILE_PREFIX, GENERATED_FILE_COMMENT, new_conf);
6993 :
6994 0 : if (rename_old) {
6995 0 : char *fn_tmp = NULL;
6996 0 : tor_asprintf(&fn_tmp, CONFIG_BACKUP_PATTERN, fname);
6997 0 : file_status_t fn_tmp_status = file_status(fn_tmp);
6998 0 : if (fn_tmp_status == FN_DIR || fn_tmp_status == FN_ERROR) {
6999 0 : log_warn(LD_CONFIG,
7000 : "Config backup file \"%s\" is not a file? Failing.", fn_tmp);
7001 0 : tor_free(fn_tmp);
7002 0 : goto err;
7003 : }
7004 :
7005 0 : log_notice(LD_CONFIG, "Renaming old configuration file to \"%s\"", fn_tmp);
7006 0 : if (replace_file(fname, fn_tmp) < 0) {
7007 0 : log_warn(LD_FS,
7008 : "Couldn't rename configuration file \"%s\" to \"%s\": %s",
7009 : fname, fn_tmp, strerror(errno));
7010 0 : tor_free(fn_tmp);
7011 0 : goto err;
7012 : }
7013 0 : tor_free(fn_tmp);
7014 : }
7015 :
7016 0 : if (write_str_to_file(fname, new_val, 0) < 0)
7017 0 : goto err;
7018 :
7019 0 : r = 0;
7020 0 : goto done;
7021 : err:
7022 : r = -1;
7023 0 : done:
7024 0 : tor_free(new_val);
7025 0 : tor_free(new_conf);
7026 0 : return r;
7027 : }
7028 :
7029 : /**
7030 : * Save the current configuration file value to disk. Return 0 on
7031 : * success, -1 on failure.
7032 : **/
7033 : int
7034 0 : options_save_current(void)
7035 : {
7036 : /* This fails if we can't write to our configuration file.
7037 : *
7038 : * If we try falling back to datadirectory or something, we have a better
7039 : * chance of saving the configuration, but a better chance of doing
7040 : * something the user never expected. */
7041 0 : return write_configuration_file(get_torrc_fname(0), get_options());
7042 : }
7043 :
7044 : /** Return the number of cpus configured in <b>options</b>. If we are
7045 : * told to auto-detect the number of cpus, return the auto-detected number. */
7046 : int
7047 4 : get_num_cpus(const or_options_t *options)
7048 : {
7049 4 : if (options->NumCPUs == 0) {
7050 4 : int n = compute_num_cpus();
7051 4 : return (n >= 1) ? n : 1;
7052 : } else {
7053 : return options->NumCPUs;
7054 : }
7055 : }
7056 :
7057 : /**
7058 : * Initialize the libevent library.
7059 : */
7060 : static void
7061 4 : init_libevent(const or_options_t *options)
7062 : {
7063 4 : tor_libevent_cfg_t cfg;
7064 :
7065 4 : tor_assert(options);
7066 :
7067 4 : configure_libevent_logging();
7068 : /* If the kernel complains that some method (say, epoll) doesn't
7069 : * exist, we don't care about it, since libevent will cope.
7070 : */
7071 4 : suppress_libevent_log_msg("Function not implemented");
7072 :
7073 4 : memset(&cfg, 0, sizeof(cfg));
7074 4 : cfg.num_cpus = get_num_cpus(options);
7075 4 : cfg.msec_per_tick = options->TokenBucketRefillInterval;
7076 :
7077 4 : tor_libevent_initialize(&cfg);
7078 :
7079 4 : suppress_libevent_log_msg(NULL);
7080 4 : }
7081 :
7082 : /** Return a newly allocated string holding a filename relative to the
7083 : * directory in <b>options</b> specified by <b>roottype</b>.
7084 : * If <b>sub1</b> is present, it is the first path component after
7085 : * the data directory. If <b>sub2</b> is also present, it is the second path
7086 : * component after the data directory. If <b>suffix</b> is present, it
7087 : * is appended to the filename.
7088 : *
7089 : * Note: Consider using macros in config.h that wrap this function;
7090 : * you should probably never need to call it as-is.
7091 : */
7092 995 : MOCK_IMPL(char *,
7093 : options_get_dir_fname2_suffix,(const or_options_t *options,
7094 : directory_root_t roottype,
7095 : const char *sub1, const char *sub2,
7096 : const char *suffix))
7097 : {
7098 995 : tor_assert(options);
7099 :
7100 995 : const char *rootdir = NULL;
7101 995 : switch (roottype) {
7102 587 : case DIRROOT_DATADIR:
7103 587 : rootdir = options->DataDirectory;
7104 587 : break;
7105 195 : case DIRROOT_CACHEDIR:
7106 195 : rootdir = options->CacheDirectory;
7107 195 : break;
7108 213 : case DIRROOT_KEYDIR:
7109 213 : rootdir = options->KeyDirectory;
7110 213 : break;
7111 0 : default:
7112 0 : tor_assert_unreached();
7113 995 : break;
7114 : }
7115 995 : tor_assert(rootdir);
7116 :
7117 995 : if (!suffix)
7118 884 : suffix = "";
7119 :
7120 995 : char *fname = NULL;
7121 :
7122 995 : if (sub1 == NULL) {
7123 1 : tor_asprintf(&fname, "%s%s", rootdir, suffix);
7124 1 : tor_assert(!sub2); /* If sub2 is present, sub1 must be present. */
7125 994 : } else if (sub2 == NULL) {
7126 923 : tor_asprintf(&fname, "%s"PATH_SEPARATOR"%s%s", rootdir, sub1, suffix);
7127 : } else {
7128 71 : tor_asprintf(&fname, "%s"PATH_SEPARATOR"%s"PATH_SEPARATOR"%s%s",
7129 : rootdir, sub1, sub2, suffix);
7130 : }
7131 :
7132 995 : return fname;
7133 : }
7134 :
7135 : /** Check whether the data directory has a private subdirectory
7136 : * <b>subdir</b>. If not, try to create it. Return 0 on success,
7137 : * -1 otherwise. */
7138 : int
7139 4 : check_or_create_data_subdir(const char *subdir)
7140 : {
7141 4 : char *statsdir = get_datadir_fname(subdir);
7142 4 : int return_val = 0;
7143 :
7144 4 : if (check_private_dir(statsdir, CPD_CREATE, get_options()->User) < 0) {
7145 0 : log_warn(LD_HIST, "Unable to create %s/ directory!", subdir);
7146 0 : return_val = -1;
7147 : }
7148 4 : tor_free(statsdir);
7149 4 : return return_val;
7150 : }
7151 :
7152 : /** Create a file named <b>fname</b> with contents <b>str</b> in the
7153 : * subdirectory <b>subdir</b> of the data directory. <b>descr</b>
7154 : * should be a short description of the file's content and will be
7155 : * used for the warning message, if it's present and the write process
7156 : * fails. Return 0 on success, -1 otherwise.*/
7157 : int
7158 3 : write_to_data_subdir(const char* subdir, const char* fname,
7159 : const char* str, const char* descr)
7160 : {
7161 3 : char *filename = get_datadir_fname2(subdir, fname);
7162 3 : int return_val = 0;
7163 :
7164 3 : if (write_str_to_file(filename, str, 0) < 0) {
7165 1 : log_warn(LD_HIST, "Unable to write %s to disk!", descr ? descr : fname);
7166 1 : return_val = -1;
7167 : }
7168 3 : tor_free(filename);
7169 3 : return return_val;
7170 : }
7171 :
7172 : /** Helper to implement GETINFO functions about configuration variables (not
7173 : * their values). Given a "config/names" question, set *<b>answer</b> to a
7174 : * new string describing the supported configuration variables and their
7175 : * types. */
7176 : int
7177 1 : getinfo_helper_config(control_connection_t *conn,
7178 : const char *question, char **answer,
7179 : const char **errmsg)
7180 : {
7181 1 : (void) conn;
7182 1 : (void) errmsg;
7183 1 : if (!strcmp(question, "config/names")) {
7184 1 : smartlist_t *sl = smartlist_new();
7185 1 : smartlist_t *vars = config_mgr_list_vars(get_options_mgr());
7186 430 : SMARTLIST_FOREACH_BEGIN(vars, const config_var_t *, var) {
7187 : /* don't tell controller about invisible options */
7188 429 : if (! config_var_is_listable(var))
7189 74 : continue;
7190 355 : const char *type = struct_var_get_typename(&var->member);
7191 355 : if (!type)
7192 0 : continue;
7193 355 : smartlist_add_asprintf(sl, "%s %s\n",var->member.name,type);
7194 429 : } SMARTLIST_FOREACH_END(var);
7195 1 : *answer = smartlist_join_strings(sl, "", 0, NULL);
7196 356 : SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
7197 1 : smartlist_free(sl);
7198 1 : smartlist_free(vars);
7199 0 : } else if (!strcmp(question, "config/defaults")) {
7200 0 : smartlist_t *sl = smartlist_new();
7201 0 : int dirauth_lines_seen = 0, fallback_lines_seen = 0;
7202 : /* Possibly this should check whether the variables are listable,
7203 : * but currently it does not. See ticket 31654. */
7204 0 : smartlist_t *vars = config_mgr_list_vars(get_options_mgr());
7205 0 : SMARTLIST_FOREACH_BEGIN(vars, const config_var_t *, var) {
7206 0 : if (var->initvalue != NULL) {
7207 0 : if (strcmp(var->member.name, "DirAuthority") == 0) {
7208 : /*
7209 : * Count dirauth lines we have a default for; we'll use the
7210 : * count later to decide whether to add the defaults manually
7211 : */
7212 0 : ++dirauth_lines_seen;
7213 : }
7214 0 : if (strcmp(var->member.name, "FallbackDir") == 0) {
7215 : /*
7216 : * Similarly count fallback lines, so that we can decide later
7217 : * to add the defaults manually.
7218 : */
7219 0 : ++fallback_lines_seen;
7220 : }
7221 0 : char *val = esc_for_log(var->initvalue);
7222 0 : smartlist_add_asprintf(sl, "%s %s\n",var->member.name,val);
7223 0 : tor_free(val);
7224 : }
7225 0 : } SMARTLIST_FOREACH_END(var);
7226 0 : smartlist_free(vars);
7227 :
7228 0 : if (dirauth_lines_seen == 0) {
7229 : /*
7230 : * We didn't see any directory authorities with default values,
7231 : * so add the list of default authorities manually.
7232 : */
7233 :
7234 : /*
7235 : * default_authorities is defined earlier in this file and
7236 : * is a const char ** NULL-terminated array of dirauth config
7237 : * lines.
7238 : */
7239 0 : for (const char **i = default_authorities; *i != NULL; ++i) {
7240 0 : char *val = esc_for_log(*i);
7241 0 : smartlist_add_asprintf(sl, "DirAuthority %s\n", val);
7242 0 : tor_free(val);
7243 : }
7244 : }
7245 :
7246 0 : if (fallback_lines_seen == 0 &&
7247 0 : get_options()->UseDefaultFallbackDirs == 1) {
7248 : /*
7249 : * We didn't see any explicitly configured fallback mirrors,
7250 : * so add the defaults to the list manually.
7251 : *
7252 : * default_fallbacks is included earlier in this file and
7253 : * is a const char ** NULL-terminated array of fallback config lines.
7254 : */
7255 : const char **i;
7256 :
7257 0 : for (i = default_fallbacks; *i != NULL; ++i) {
7258 0 : char *val = esc_for_log(*i);
7259 0 : smartlist_add_asprintf(sl, "FallbackDir %s\n", val);
7260 0 : tor_free(val);
7261 : }
7262 : }
7263 :
7264 0 : *answer = smartlist_join_strings(sl, "", 0, NULL);
7265 0 : SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
7266 0 : smartlist_free(sl);
7267 : }
7268 1 : return 0;
7269 : }
7270 :
7271 : /* Check whether an address has already been set against the options
7272 : * depending on address family and destination type. Any exsting
7273 : * value will lead to a fail, even if it is the same value. If not
7274 : * set and not only validating, copy it into this location too.
7275 : * Returns 0 on success or -1 if this address is already set.
7276 : */
7277 : static int
7278 19 : verify_and_store_outbound_address(sa_family_t family, tor_addr_t *addr,
7279 : outbound_addr_t type, or_options_t *options, int validate_only)
7280 : {
7281 19 : if (type>=OUTBOUND_ADDR_MAX || (family!=AF_INET && family!=AF_INET6)) {
7282 : return -1;
7283 : }
7284 18 : int fam_index=0;
7285 18 : if (family==AF_INET6) {
7286 0 : fam_index=1;
7287 : }
7288 18 : tor_addr_t *dest=&options->OutboundBindAddresses[type][fam_index];
7289 18 : if (!tor_addr_is_null(dest)) {
7290 : return -1;
7291 : }
7292 18 : if (!validate_only) {
7293 9 : tor_addr_copy(dest, addr);
7294 : }
7295 : return 0;
7296 : }
7297 :
7298 : /* Parse a list of address lines for a specific destination type.
7299 : * Will store them into the options if not validate_only. If a
7300 : * problem occurs, a suitable error message is store in msg.
7301 : * Returns 0 on success or -1 if any address is already set.
7302 : */
7303 : static int
7304 3109 : parse_outbound_address_lines(const config_line_t *lines, outbound_addr_t type,
7305 : or_options_t *options, int validate_only, char **msg)
7306 : {
7307 3109 : tor_addr_t addr;
7308 3109 : sa_family_t family;
7309 3127 : while (lines) {
7310 19 : family = tor_addr_parse(&addr, lines->value);
7311 19 : if (verify_and_store_outbound_address(family, &addr, type,
7312 : options, validate_only)) {
7313 1 : if (msg)
7314 2 : tor_asprintf(msg, "Multiple%s%s outbound bind addresses "
7315 : "configured: %s",
7316 1 : family==AF_INET?" IPv4":(family==AF_INET6?" IPv6":""),
7317 : type==OUTBOUND_ADDR_OR?" OR":
7318 1 : (type==OUTBOUND_ADDR_EXIT?" exit":
7319 2 : (type==OUTBOUND_ADDR_PT?" PT":"")), lines->value);
7320 1 : return -1;
7321 : }
7322 18 : lines = lines->next;
7323 : }
7324 : return 0;
7325 : }
7326 :
7327 : /** Parse outbound bind address option lines. If <b>validate_only</b>
7328 : * is not 0 update OutboundBindAddresses in <b>options</b>.
7329 : * Only one address can be set for any of these values.
7330 : * On failure, set <b>msg</b> (if provided) to a newly allocated string
7331 : * containing a description of the problem and return -1.
7332 : */
7333 : static int
7334 778 : parse_outbound_addresses(or_options_t *options, int validate_only, char **msg)
7335 : {
7336 778 : if (!validate_only) {
7337 213 : memset(&options->OutboundBindAddresses, 0,
7338 : sizeof(options->OutboundBindAddresses));
7339 : }
7340 :
7341 778 : if (parse_outbound_address_lines(options->OutboundBindAddress,
7342 : OUTBOUND_ADDR_ANY, options,
7343 : validate_only, msg) < 0) {
7344 1 : goto err;
7345 : }
7346 :
7347 777 : if (parse_outbound_address_lines(options->OutboundBindAddressOR,
7348 : OUTBOUND_ADDR_OR, options, validate_only,
7349 : msg) < 0) {
7350 0 : goto err;
7351 : }
7352 :
7353 777 : if (parse_outbound_address_lines(options->OutboundBindAddressExit,
7354 : OUTBOUND_ADDR_EXIT, options, validate_only,
7355 : msg) < 0) {
7356 0 : goto err;
7357 : }
7358 :
7359 777 : if (parse_outbound_address_lines(options->OutboundBindAddressPT,
7360 : OUTBOUND_ADDR_PT, options, validate_only,
7361 : msg) < 0) {
7362 0 : goto err;
7363 : }
7364 :
7365 : return 0;
7366 : err:
7367 : return -1;
7368 : }
7369 :
7370 : /** Load one of the geoip files, <a>family</a> determining which
7371 : * one. <a>default_fname</a> is used if on Windows and
7372 : * <a>fname</a> equals "<default>". */
7373 : static void
7374 8 : config_load_geoip_file_(sa_family_t family,
7375 : const char *fname,
7376 : const char *default_fname)
7377 : {
7378 8 : const or_options_t *options = get_options();
7379 8 : const char *msg = "";
7380 8 : int severity = options_need_geoip_info(options, &msg) ? LOG_WARN : LOG_INFO;
7381 8 : int r;
7382 :
7383 : #ifdef _WIN32
7384 : char *free_fname = NULL; /* Used to hold any temporary-allocated value */
7385 : /* XXXX Don't use this "<default>" junk; make our filename options
7386 : * understand prefixes somehow. -NM */
7387 : if (!strcmp(fname, "<default>")) {
7388 : const char *conf_root = get_windows_conf_root();
7389 : tor_asprintf(&free_fname, "%s\\%s", conf_root, default_fname);
7390 : fname = free_fname;
7391 : }
7392 : r = geoip_load_file(family, fname, severity);
7393 : tor_free(free_fname);
7394 : #else /* !defined(_WIN32) */
7395 8 : (void)default_fname;
7396 8 : r = geoip_load_file(family, fname, severity);
7397 : #endif /* defined(_WIN32) */
7398 :
7399 8 : if (r < 0 && severity == LOG_WARN) {
7400 0 : log_warn(LD_GENERAL, "%s", msg);
7401 : }
7402 8 : }
7403 :
7404 : /** Load geoip files for IPv4 and IPv6 if <a>options</a> and
7405 : * <a>old_options</a> indicate we should. */
7406 : static void
7407 4 : config_maybe_load_geoip_files_(const or_options_t *options,
7408 : const or_options_t *old_options)
7409 : {
7410 : /* XXXX Reload GeoIPFile on SIGHUP. -NM */
7411 :
7412 4 : if (options->GeoIPFile &&
7413 0 : ((!old_options || !opt_streq(old_options->GeoIPFile,
7414 : options->GeoIPFile))
7415 0 : || !geoip_is_loaded(AF_INET))) {
7416 4 : config_load_geoip_file_(AF_INET, options->GeoIPFile, "geoip");
7417 : /* Okay, now we need to maybe change our mind about what is in
7418 : * which country. We do this for IPv4 only since that's what we
7419 : * store in node->country. */
7420 4 : refresh_all_country_info();
7421 : }
7422 4 : if (options->GeoIPv6File &&
7423 0 : ((!old_options || !opt_streq(old_options->GeoIPv6File,
7424 : options->GeoIPv6File))
7425 0 : || !geoip_is_loaded(AF_INET6))) {
7426 4 : config_load_geoip_file_(AF_INET6, options->GeoIPv6File, "geoip6");
7427 : }
7428 4 : }
7429 :
7430 : /** Initialize cookie authentication (used so far by the ControlPort
7431 : * and Extended ORPort).
7432 : *
7433 : * Allocate memory and create a cookie (of length <b>cookie_len</b>)
7434 : * in <b>cookie_out</b>.
7435 : * Then write it down to <b>fname</b> and prepend it with <b>header</b>.
7436 : *
7437 : * If <b>group_readable</b> is set, set <b>fname</b> to be readable
7438 : * by the default GID.
7439 : *
7440 : * If the whole procedure was successful, set
7441 : * <b>cookie_is_set_out</b> to True. */
7442 : int
7443 3 : init_cookie_authentication(const char *fname, const char *header,
7444 : int cookie_len, int group_readable,
7445 : uint8_t **cookie_out, int *cookie_is_set_out)
7446 : {
7447 3 : char cookie_file_str_len = strlen(header) + cookie_len;
7448 3 : char *cookie_file_str = tor_malloc(cookie_file_str_len);
7449 3 : int retval = -1;
7450 :
7451 : /* We don't want to generate a new cookie every time we call
7452 : * options_act(). One should be enough. */
7453 3 : if (*cookie_is_set_out) {
7454 1 : retval = 0; /* we are all set */
7455 1 : goto done;
7456 : }
7457 :
7458 : /* If we've already set the cookie, free it before re-setting
7459 : it. This can happen if we previously generated a cookie, but
7460 : couldn't write it to a disk. */
7461 2 : if (*cookie_out)
7462 2 : tor_free(*cookie_out);
7463 :
7464 : /* Generate the cookie */
7465 2 : *cookie_out = tor_malloc(cookie_len);
7466 2 : crypto_rand((char *)*cookie_out, cookie_len);
7467 :
7468 : /* Create the string that should be written on the file. */
7469 2 : memcpy(cookie_file_str, header, strlen(header));
7470 2 : memcpy(cookie_file_str+strlen(header), *cookie_out, cookie_len);
7471 2 : if (write_bytes_to_file(fname, cookie_file_str, cookie_file_str_len, 1)) {
7472 1 : log_warn(LD_FS,"Error writing auth cookie to %s.", escaped(fname));
7473 1 : goto done;
7474 : }
7475 :
7476 : #ifndef _WIN32
7477 1 : if (group_readable) {
7478 0 : if (chmod(fname, 0640)) {
7479 0 : log_warn(LD_FS,"Unable to make %s group-readable.", escaped(fname));
7480 : }
7481 : }
7482 : #else /* defined(_WIN32) */
7483 : (void) group_readable;
7484 : #endif /* !defined(_WIN32) */
7485 :
7486 : /* Success! */
7487 1 : log_info(LD_GENERAL, "Generated auth cookie file in '%s'.", escaped(fname));
7488 1 : *cookie_is_set_out = 1;
7489 1 : retval = 0;
7490 :
7491 3 : done:
7492 3 : memwipe(cookie_file_str, 0, cookie_file_str_len);
7493 3 : tor_free(cookie_file_str);
7494 3 : return retval;
7495 : }
7496 :
7497 : /**
7498 : * Return true if any option is set in <b>options</b> to make us behave
7499 : * as a client.
7500 : */
7501 : int
7502 313 : options_any_client_port_set(const or_options_t *options)
7503 : {
7504 313 : return (options->SocksPort_set ||
7505 : options->TransPort_set ||
7506 : options->NATDPort_set ||
7507 313 : options->DNSPort_set ||
7508 : options->HTTPTunnelPort_set);
7509 : }
|