Reading and Writing Live Tor Configuration

TorConfig

class txtorcon.TorConfig(control=None)

Bases: object

This class abstracts out Tor’s config, and can be used both to create torrc files from nothing and track live configuration of a Tor instance.

Also, it gives easy access to all the configuration options present. This is initialized at “bootstrap” time, providing attribute-based access thereafter. Note that after you set some number of items, you need to do a save() before these are sent to Tor (and then they will be done as one SETCONF).

You may also use this class to construct a configuration from scratch (e.g. to give to txtorcon.launch_tor()). In this case, values are reflected right away. (If we’re not bootstrapped to a Tor, this is the mode).

Note that you do not need to call save() if you’re just using TorConfig to create a .torrc file or for input to launch_tor().

This class also listens for CONF_CHANGED events to update the cached data in the event other controllers (etc) changed it.

There is a lot of magic attribute stuff going on in here (which might be a bad idea, overall) but the intent is that you can just set Tor options and it will all Just Work. For config items that take multiple values, set that to a list. For example:

conf = TorConfig(...)
conf.SOCKSPort = [9050, 1337]
conf.HiddenServices.append(HiddenService(...))

(Incoming objects, like lists, are intercepted and wrapped).

FIXME: when is CONF_CHANGED introduced in Tor? Can we do anything like it for prior versions?

FIXME:

  • HiddenServiceOptions is special: GETCONF on it returns several (well, two) values. Besides adding the two keys ‘by hand’ do we need to do anything special? Can’t we just depend on users doing ‘conf.hiddenservicedir = foo’ AND ‘conf.hiddenserviceport = bar’ before a save() ?
  • once I determine a value is default, is there any way to actually get what this value is?
static from_protocol(*args, **kwargs)

This creates and returns a ready-to-go TorConfig instance from the given protocol, which should be an instance of TorControlProtocol.

config = None

Current configuration, by keys.

unsaved = None

Configuration that has been changed since last save().

parsers = None

Instances of the parser classes, subclasses of TorConfigType

list_parsers = None

All the names (keys from .parsers) that are a List of something.

socks_endpoint(reactor, port=None)

Returns a TorSocksEndpoint configured to use an already-configured SOCKSPort from the Tor we’re connected to. By default, this will be the very first SOCKSPort.

Parameters:port – a str, the first part of the SOCKSPort line (that is, a port like “9151” or a Unix socket config like “unix:/path”. You may also specify a port as an int.

If you need to use a particular port that may or may not already be configured, see the async method txtorcon.TorConfig.create_socks_endpoint()

create_socks_endpoint(*args, **kwargs)

Creates a new TorSocksEndpoint instance given a valid configuration line for SocksPort; if this configuration isn’t already in the underlying tor, we add it. Note that this method may call txtorcon.TorConfig.save() on this instance.

Note that calling this with socks_config=None is equivalent to calling .socks_endpoint (which is not async).

XXX socks_config should be .. i dunno, but there’s fucking options and craziness, e.g. default Tor Browser Bundle is: [‘9150 IPv6Traffic PreferIPv6 KeepAliveIsolateSOCKSAuth’, ‘9155’]

XXX maybe we should say “socks_port” as the 3rd arg, insist it’s an int, and then allow/support all the other options (e.g. via kwargs)

XXX we could avoid the “maybe call .save()” thing; worth it? (actually, no we can’t or the Tor won’t have it config’d)

protocol
tor_protocol
attach_protocol(proto)

returns a Deferred that fires once we’ve set this object up to track the protocol. Fails if we already have a protocol.

get_type(name)

return the type of a config key.

Param:name the key

FIXME can we do something more-clever than this for client code to determine what sort of thing a key is?

bootstrap(arg=None)

This only takes args so it can be used as a callback. Don’t pass an arg, it is ignored.

do_post_errback(f)
do_post_bootstrap(arg)
needs_save()
mark_unsaved(name)
save()

Save any outstanding items. This returns a Deferred which will errback if Tor was unhappy with anything, or callback with this TorConfig object on success.

config_args()

Returns an iterator of 2-tuples (config_name, value), one for each configuration option in this config. This is more-or-less an internal method, but see, e.g., launch_tor()’s implementation if you think you need to use this for something.

See txtorcon.TorConfig.create_torrc() which returns a string which is also a valid torrc file

create_torrc()

HiddenService

class txtorcon.HiddenService(config, thedir, ports, auth=[], ver=2, group_readable=0)

Bases: object

Because hidden service configuration is handled specially by Tor, we wrap the config in this class. This corresponds to the HiddenServiceDir, HiddenServicePort, HiddenServiceVersion and HiddenServiceAuthorizeClient lines from the config. If you want multiple HiddenServicePort lines, simply append more strings to the ports member.

To create an additional hidden service, append a new instance of this class to the config (ignore the conf argument):

state.hiddenservices.append(HiddenService(‘/path/to/dir’, [‘80 127.0.0.1:1234’]))

config is the TorConfig to which this will belong, thedir corresponds to ‘HiddenServiceDir’ and will ultimately contain a ‘hostname’ and ‘private_key’ file, ports is a list of lines corresponding to HiddenServicePort (like ‘80 127.0.0.1:1234’ to advertise a hidden service at port 80 and redirect it internally on 127.0.0.1:1234). auth corresponds to the HiddenServiceAuthenticateClient lines and can be either a string or a list of strings (like ‘basic client0,client1’ or ‘stealth client5,client6’) and ver corresponds to HiddenServiceVersion and is always 2 right now.

XXX FIXME can we avoid having to pass the config object somehow? Like provide a factory-function on TorConfig for users instead?

config_attributes()

Helper method used by TorConfig when generating a torrc file.