Hacking exitmap modules
=======================

So, you are interested in hacking new `exitmap` modules?  Modules are Python
files in the directory src/modules/.  When invoked, a module engages in some
sort of TCP-based network interaction.  Examples are logging into a remote
machine, requesting a web page, or downloading a file over FTP.  The module is
then run over (a subset of) all Tor exit relays whose exit policy works for the
module.  To get an idea of what a module looks like in practice, have a look at
the existing files in src/modules/.

From an implementation point of view, there are two types of modules:

1. There are modules that are implemented in pure Python.  They don't use any
   external programs such as `wget`.  As a result, you are limited to whatever
   Python offers, e.g., `urllib2` for web interaction.  The network traffic
   generated by these modules is transparently tunneled over SOCKS using the
   code in torsocks.py.

2. Modules can invoke external tools such `gnutls-cli`, e.g., to fetch X.509
   certificates.  Similarly, a patched version of `torsocks` is used to
   transparently tunnel this type of network traffic over Tor's SOCKS port.

The function signature of modules is:

    def probe(exit_desc, run_python_over_tor, run_cmd_over_tor)

The arguments are:

1. `exit_desc`: An object of type
    `stem.descriptor.server_descriptor.RelayDescriptor`.

2. `run_python_over_tor`: Expects a function (as first argument) and its
   arguments (as subsequent arguments).  The function's network interaction is
   then routed over Tor.

3. `run_cmd_over_tor`: Expects a command (as first argument) and its parameters
   (as subsequent arguments).  The command's network interaction is then routed
   over Tor using `torsocks`.

Finally, you must define the global variable `destinations` in your module.  It
determines the destinations---as tuples---your module will connect to.
`Exitmap` must know this to select exit relays whose exit policy matches your
module.  Here's an example:

    destinations = [("www.example.com", 80), ("smtp.example.com", 25)]
