Safe Haskell | None |
---|---|
Language | Haskell2010 |
This module provides the main interface for establishing secure and anonymous connections with other hosts on the interface using the Tor project. For more information about the Tor network, see: torproject.org
- connect :: MonadIO m => Integer -> SocksAddress -> (Socket -> IO a) -> m a
- connect' :: MonadIO m => Socket -> SocksAddress -> (Socket -> IO a) -> m a
- mapOnion :: MonadIO m => Socket -> Integer -> Integer -> Bool -> Maybe ByteString -> m Base32String
- accept :: MonadIO m => Socket -> Integer -> Maybe ByteString -> (Socket -> IO ()) -> m Base32String
- data Availability
- isAvailable :: MonadIO m => Integer -> m Availability
- socksPort :: MonadIO m => Socket -> m Integer
- withSession :: Integer -> (Socket -> IO a) -> IO a
Introduction to Tor
This module is a (partial) implementation of the Tor control protocol. Tor is an internet anonimization network. Whereas historically, Tor is primarily intended for privately browsing the world wide web, the service also supports application oriented P2P communication, to implement communication between applications.
The general idea of the Tor control interface to Tor is that you establish a master connection with the Tor control port, and create new, short-lived connections with the Tor bridge for the communication with the individual peers.
Client side
Connect through Tor with explicit port
Connect through Tor on using a specified SOCKS port. Note that you do not need to authorize with the Tor control port for this functionality.
main =connect
9050 constructDestination worker where constructDestination =SocksAddress
(SocksT.SocksAddrDomainName (BS8.pack "www.google.com")) 80 worker sock = -- Now you may use sock to communicate with the remote. return ()
Connect through Tor using control port
Connect through Tor and derive the SOCKS port from the Tor configuration. This function will query the Tor control service to find out which SOCKS port the Tor daemon listens at.
main =withSession
withinSession where constructDestination =SocksAddress
(SocksT.SocksAddrDomainName (BS8.pack "2a3b4c.onion")) 80 withinSession ::Socket
-> IO () withinSession sock = doconnect'
sock constructDestination worker worker sock = -- Now you may use sock to communicate with the remote. return ()
:: MonadIO m | |
=> Integer | Port our tor SOCKS server listens at. |
-> SocksAddress | Address we wish to connect to |
-> (Socket -> IO a) | Computation to execute once connection has been establised |
-> m a |
Connect through a remote using the Tor SOCKS proxy. The remote might me a a normal host/ip or a hidden service address. When you provide a FQDN to resolve, it will be resolved by the Tor service, and as such is secure.
This function is provided as a convenience, since it doesn't actually use the Tor control protocol, and can be used to talk with any Socks5 compatible proxy server.
:: MonadIO m | |
=> Socket | Our connection with the Tor control port |
-> SocksAddress | Address we wish to connect to |
-> (Socket -> IO a) | Computation to execute once connection has been establised |
-> m a |
Server side
Mapping
Create a new hidden service, and map remote port 80 to local port 8080.
main =withSession
withinSession where withinSession ::Socket
-> IO () withinSession sock = do onion <-mapOnion
sock 80 8080 -- At this point,onion
contains the base32 representation of -- our hidden service, without the trailing '.onion' part. -- -- Remember that, once we leave this function, the connection with -- the Tor control service will be lost and any mappings will be -- cleaned up.
Server
Convenience function which creates a hidden service on port 80 that is mapped to a server we create on the fly. Note that because we are mapping the hidden service's port 1:1 with our local port, port 80 must still be available.
main =withSession
withinSession where withinSession ::Socket
-> IO () withinSession sock = do onion <-accept
sock 80 worker -- At this point,onion
contains the base32 representation of -- our hidden service, without the trailing '.onion' part, and any -- incoming connections will be redirected to ourworker
function. -- -- Once again, when we leave this function, all registered mappings -- will be lost. worker sock = do -- Now you may use sock to communicate with the remote. return ()
:: MonadIO m | |
=> Socket | Connection with tor Control port |
-> Integer | Remote point of hidden service to listen at |
-> Integer | Local port to map onion service to |
-> Bool | Wether to detach the hidden service from the current session |
-> Maybe ByteString | Optional private key to use to set up the hidden service |
-> m Base32String | The address/service id of the Onion without the .onion part |
Creates a new hidden service and maps a public port to a local port. Useful for bridging a local service (e.g. a webserver or irc daemon) as a Tor hidden service. If a private key is supplied, it is used to instantiate the service.
:: MonadIO m | |
=> Socket | Connection with Tor control server |
-> Integer | Port to listen at |
-> Maybe ByteString | Optional private key to use to set up the hidden service |
-> (Socket -> IO ()) | Callback function called for each incoming connection |
-> m Base32String | Returns the hidden service descriptor created without the '.onion' part |
Convenience function that creates a new hidden service and starts accepting connections for it. Note that this creates a new local server at the same port as the public port, so ensure that the port is not yet in use.
Probing Tor configuration information
data Availability Source
Represents the availability status of Tor for a specific port.
Available | There is a Tor control service listening at the port |
ConnectionRefused | There is no service listening at the port |
IncorrectPort | There is a non-Tor control service listening at the port |
:: MonadIO m | |
=> Integer | The ports we wish to probe |
-> m Availability | The status of all the ports |
Probes a port to see if there is a service at the remote that behaves like the Tor controller daemon. Will return the status of the probed port.
Setting up the context
:: Integer | Port the Tor control server is listening at. Use
|
-> (Socket -> IO a) | Callback function called after a session has been established succesfully. |
-> IO a | Returns the value returned by the callback. |
Establishes a connection and authenticates with the Tor control socket. After authorization has been succesfully completed it executes the callback provided.
Note that when the session completes, the connection with the Tor control port is dropped, which means that any port mappings, connections and hidden services you have registered within the session will be cleaned up. This is by design, to prevent stale mappings when an application crashes.