Controller Connection¶
Functions for connecting and authenticating to the tor process.
The connect()
function give an easy, one line
method for getting an authenticated control connection. This is handy for CLI
applications and the python interactive interpreter, but does several things
that makes it undesirable for applications (uses stdin/stdout, suppresses
exceptions, etc).
import sys
from stem.connection import connect
if __name__ == '__main__':
controller = connect()
if not controller:
sys.exit(1) # unable to get a connection
print 'Tor is running version %s' % controller.get_version()
controller.close()
% python example.py
Tor is running version 0.2.4.10-alpha-dev (git-8be6058d8f31e578)
… or if Tor isn’t running…
% python example.py
[Errno 111] Connection refused
The authenticate()
function, however, gives easy but
fine-grained control over the authentication process. For instance…
import sys
import getpass
import stem.connection
import stem.socket
try:
control_socket = stem.socket.ControlPort(port = 9051)
except stem.SocketError as exc:
print 'Unable to connect to port 9051 (%s)' % exc
sys.exit(1)
try:
stem.connection.authenticate(control_socket)
except stem.connection.IncorrectSocketType:
print 'Please check in your torrc that 9051 is the ControlPort.'
print 'Maybe you configured it to be the ORPort or SocksPort instead?'
sys.exit(1)
except stem.connection.MissingPassword:
controller_password = getpass.getpass('Controller password: ')
try:
stem.connection.authenticate_password(control_socket, controller_password)
except stem.connection.PasswordAuthFailed:
print 'Unable to authenticate, password is incorrect'
sys.exit(1)
except stem.connection.AuthenticationFailure as exc:
print 'Unable to authenticate: %s' % exc
sys.exit(1)
Module Overview:
connect - Simple method for getting authenticated control connection
authenticate - Main method for authenticating to a control socket
authenticate_none - Authenticates to an open control socket
authenticate_password - Authenticates to a socket supporting password auth
authenticate_cookie - Authenticates to a socket supporting cookie auth
authenticate_safecookie - Authenticates to a socket supporting safecookie auth
get_protocolinfo - Issues a PROTOCOLINFO query
AuthenticationFailure - Base exception raised for authentication failures
|- UnrecognizedAuthMethods - Authentication methods are unsupported
|- IncorrectSocketType - Socket does not speak the tor control protocol
|
|- OpenAuthFailed - Failure when authenticating by an open socket
| +- OpenAuthRejected - Tor rejected this method of authentication
|
|- PasswordAuthFailed - Failure when authenticating by a password
| |- PasswordAuthRejected - Tor rejected this method of authentication
| |- IncorrectPassword - Password was rejected
| +- MissingPassword - Socket supports password auth but wasn't attempted
|
|- CookieAuthFailed - Failure when authenticating by a cookie
| |- CookieAuthRejected - Tor rejected this method of authentication
| |- IncorrectCookieValue - Authentication cookie was rejected
| |- IncorrectCookieSize - Size of the cookie file is incorrect
| |- UnreadableCookieFile - Unable to read the contents of the auth cookie
| +- AuthChallengeFailed - Failure completing the authchallenge request
| |- AuthChallengeUnsupported - Tor doesn't recognize the AUTHCHALLENGE command
| |- AuthSecurityFailure - Server provided the wrong nonce credentials
| |- InvalidClientNonce - The client nonce is invalid
| +- UnrecognizedAuthChallengeMethod - AUTHCHALLENGE does not support the given methods.
|
+- MissingAuthInfo - Unexpected PROTOCOLINFO response, missing auth info
|- NoAuthMethods - Missing any methods for authenticating
+- NoAuthCookie - Supports cookie auth but doesn't have its path
-
stem.connection.
AuthMethod
(enum)¶ Enumeration of PROTOCOLINFO responses for supported authentication methods.
AuthMethod Description NONE No authentication required. PASSWORD Password required, see tor’s HashedControlPassword option. COOKIE Contents of the cookie file required, see tor’s CookieAuthentication option. SAFECOOKIE Need to reply to a hmac challenge using the contents of the cookie file. UNKNOWN Tor provided one or more authentication methods that we don’t recognize, probably something new.
-
stem.connection.
connect
(control_port=('127.0.0.1', 'default'), control_socket='/var/run/tor/control', password=None, password_prompt=False, chroot_path=None, controller=<class 'stem.control.Controller'>)[source]¶ Convenience function for quickly getting a control connection. This is very handy for debugging or CLI setup, handling setup and prompting for a password if necessary (and none is provided). If any issues arise this prints a description of the problem and returns None.
If both a control_port and control_socket are provided then the control_socket is tried first, and this provides a generic error message if they’re both unavailable.
In much the same vein as git porcelain commands, users should not rely on details of how this works. Messages and details of this function’s behavior could change in the future.
If the port is ‘default’ then this checks on both 9051 (default for relays) and 9151 (default for the Tor Browser). This default may change in the future.
New in version 1.2.0.
Changed in version 1.5.0: Use both port 9051 and 9151 by default.
Parameters: - contol_port (tuple) – address and port tuple, for instance (‘127.0.0.1’, 9051)
- path (str) – path where the control socket is located
- password (str) – passphrase to authenticate to the socket
- password_prompt (bool) – prompt for the controller password if it wasn’t supplied
- chroot_path (str) – path prefix if in a chroot environment
- controller (Class) –
BaseController
subclass to be returned, this provides aControlSocket
if None
Returns: authenticated control connection, the type based on the controller argument
Raises: ValueError if given an invalid control_port, or both control_port and control_socket are None
-
stem.connection.
connect_port
(address='127.0.0.1', port=9051, password=None, chroot_path=None, controller=<class 'stem.control.Controller'>)[source]¶ Convenience function for quickly getting a control connection. This is very handy for debugging or CLI setup, handling setup and prompting for a password if necessary (and none is provided). If any issues arise this prints a description of the problem and returns None.
Deprecated since version 1.2.0: Use
connect()
instead.Parameters: - address (str) – ip address of the controller
- port (int) – port number of the controller
- password (str) – passphrase to authenticate to the socket
- chroot_path (str) – path prefix if in a chroot environment
- controller (Class) –
BaseController
subclass to be returned, this provides aControlSocket
if None
Returns: authenticated control connection, the type based on the controller argument
-
stem.connection.
connect_socket_file
(path='/var/run/tor/control', password=None, chroot_path=None, controller=<class 'stem.control.Controller'>)[source]¶ Convenience function for quickly getting a control connection. For more information see the
connect_port()
function.In much the same vein as git porcelain commands, users should not rely on details of how this works. Messages or details of this function’s behavior might change in the future.
Deprecated since version 1.2.0: Use
connect()
instead.Parameters: - path (str) – path where the control socket is located
- password (str) – passphrase to authenticate to the socket
- chroot_path (str) – path prefix if in a chroot environment
- controller (Class) –
BaseController
subclass to be returned, this provides aControlSocket
if None
Returns: authenticated control connection, the type based on the controller argument
-
stem.connection.
authenticate
(controller, password=None, chroot_path=None, protocolinfo_response=None)[source]¶ Authenticates to a control socket using the information provided by a PROTOCOLINFO response. In practice this will often be all we need to authenticate, raising an exception if all attempts to authenticate fail.
All exceptions are subclasses of AuthenticationFailure so, in practice, callers should catch the types of authentication failure that they care about, then have a
AuthenticationFailure
catch-all at the end.This can authenticate to either a
BaseController
orControlSocket
.Parameters: - controller – tor controller or socket to be authenticated
- password (str) – passphrase to present to the socket if it uses password authentication (skips password auth if None)
- chroot_path (str) – path prefix if in a chroot environment
- protocolinfo_response (stem.response.protocolinfo.ProtocolInfoResponse) – tor protocolinfo response, this is retrieved on our own if None
Raises: If all attempts to authenticate fails then this will raise a
AuthenticationFailure
subclass. Since this may try multiple authentication methods it may encounter multiple exceptions. If so then the exception this raises is prioritized as follows…stem.connection.IncorrectSocketType
The controller does not speak the tor control protocol. Most often this happened because the user confused the SocksPort or ORPort with the ControlPort.
stem.connection.UnrecognizedAuthMethods
All of the authentication methods tor will accept are new and unrecognized. Please upgrade stem and, if that doesn’t work, file a ticket on ‘trac.torproject.org’ and I’d be happy to add support.
stem.connection.MissingPassword
We were unable to authenticate but didn’t attempt password authentication because none was provided. You should prompt the user for a password and try again via ‘authenticate_password’.
stem.connection.IncorrectPassword
We were provided with a password but it was incorrect.
stem.connection.IncorrectCookieSize
Tor allows for authentication by reading it a cookie file, but that file is the wrong size to be an authentication cookie.
stem.connection.UnreadableCookieFile
Tor allows for authentication by reading it a cookie file, but we can’t read that file (probably due to permissions).
*
stem.connection.IncorrectCookieValue
Tor allows for authentication by reading it a cookie file, but rejected the contents of that file.
*
stem.connection.AuthChallengeUnsupported
Tor doesn’t recognize the AUTHCHALLENGE command. This is probably a Tor version prior to SAFECOOKIE being implement, but this exception shouldn’t arise because we won’t attempt SAFECOOKIE auth unless Tor claims to support it.
*
stem.connection.UnrecognizedAuthChallengeMethod
Tor couldn’t recognize the AUTHCHALLENGE method Stem sent to it. This shouldn’t happen at all.
*
stem.connection.InvalidClientNonce
Tor says that the client nonce provided by Stem during the AUTHCHALLENGE process is invalid.
*
stem.connection.AuthSecurityFailure
Nonce value provided by the server was invalid.
*
stem.connection.OpenAuthRejected
Tor says that it allows for authentication without any credentials, but then rejected our authentication attempt.
*
stem.connection.MissingAuthInfo
Tor provided us with a PROTOCOLINFO reply that is technically valid, but missing the information we need to authenticate.
*
stem.connection.AuthenticationFailure
There are numerous other ways that authentication could have failed including socket failures, malformed controller responses, etc. These mostly constitute transient failures or bugs.
* In practice it is highly unusual for this to occur, being more of a theoretical possibility rather than something you should expect. It’s fine to treat these as errors. If you have a use case where this commonly happens, please file a ticket on ‘trac.torproject.org’.
In the future new
AuthenticationFailure
subclasses may be added to allow for better error handling.
-
stem.connection.
authenticate_none
(controller, suppress_ctl_errors=True)[source]¶ Authenticates to an open control socket. All control connections need to authenticate before they can be used, even if tor hasn’t been configured to use any authentication.
If authentication fails tor will disconnect and we’ll make a best effort attempt to re-establish the connection. This may not succeed, so check
is_alive()
before using the socket further.This can authenticate to either a
BaseController
orControlSocket
.For general usage use the
authenticate()
function instead.Parameters: - controller – tor controller or socket to be authenticated
- suppress_ctl_errors (bool) – reports raised
ControllerError
as authentication rejection if True, otherwise they’re re-raised
Raises: stem.connection.OpenAuthRejected
if the empty authentication credentials aren’t accepted
-
stem.connection.
authenticate_password
(controller, password, suppress_ctl_errors=True)[source]¶ Authenticates to a control socket that uses a password (via the HashedControlPassword torrc option). Quotes in the password are escaped.
If authentication fails tor will disconnect and we’ll make a best effort attempt to re-establish the connection. This may not succeed, so check
is_alive()
before using the socket further.If you use this function directly, rather than
authenticate()
, we may mistakenly raise a PasswordAuthRejected rather than IncorrectPassword. This is because we rely on tor’s error messaging which is liable to change in future versions (ticket 4817).This can authenticate to either a
BaseController
orControlSocket
.For general usage use the
authenticate()
function instead.Parameters: - controller – tor controller or socket to be authenticated
- password (str) – passphrase to present to the socket
- suppress_ctl_errors (bool) – reports raised
ControllerError
as authentication rejection if True, otherwise they’re re-raised
Raises: stem.connection.PasswordAuthRejected
if the socket doesn’t accept password authenticationstem.connection.IncorrectPassword
if the authentication credentials aren’t accepted
Authenticates to a control socket that uses the contents of an authentication cookie (generated via the CookieAuthentication torrc option). This does basic validation that this is a cookie before presenting the contents to the socket.
The
IncorrectCookieSize
andUnreadableCookieFile
exceptions take precedence over the other types.If authentication fails tor will disconnect and we’ll make a best effort attempt to re-establish the connection. This may not succeed, so check
is_alive()
before using the socket further.If you use this function directly, rather than
authenticate()
, we may mistakenly raise aCookieAuthRejected
rather thanIncorrectCookieValue
. This is because we rely on tor’s error messaging which is liable to change in future versions (ticket 4817).This can authenticate to either a
BaseController
orControlSocket
.For general usage use the
authenticate()
function instead.Parameters: - controller – tor controller or socket to be authenticated
- cookie_path (str) – path of the authentication cookie to send to tor
- suppress_ctl_errors (bool) – reports raised
ControllerError
as authentication rejection if True, otherwise they’re re-raised
Raises: stem.connection.IncorrectCookieSize
if the cookie file’s size is wrongstem.connection.UnreadableCookieFile
if the cookie file doesn’t exist or we’re unable to read itstem.connection.CookieAuthRejected
if cookie authentication is attempted but the socket doesn’t accept itstem.connection.IncorrectCookieValue
if the cookie file’s value is rejected
Authenticates to a control socket using the safe cookie method, which is enabled by setting the CookieAuthentication torrc option on Tor client’s which support it.
Authentication with this is a two-step process…
- send a nonce to the server and receives a challenge from the server for the cookie’s contents
- generate a hash digest using the challenge received in the first step, and use it to authenticate the controller
The
IncorrectCookieSize
andUnreadableCookieFile
exceptions take precedence over the other exception types.The
AuthChallengeUnsupported
,UnrecognizedAuthChallengeMethod
,InvalidClientNonce
andCookieAuthRejected
exceptions are next in the order of precedence. Depending on the reason, one of these is raised if the first (AUTHCHALLENGE) step fails.In the second (AUTHENTICATE) step,
IncorrectCookieValue
orCookieAuthRejected
maybe raised.If authentication fails tor will disconnect and we’ll make a best effort attempt to re-establish the connection. This may not succeed, so check
is_alive()
before using the socket further.For general usage use the
authenticate()
function instead.Parameters: - controller – tor controller or socket to be authenticated
- cookie_path (str) – path of the authentication cookie to send to tor
- suppress_ctl_errors (bool) – reports raised
ControllerError
as authentication rejection if True, otherwise they’re re-raised
Raises: stem.connection.IncorrectCookieSize
if the cookie file’s size is wrongstem.connection.UnreadableCookieFile
if the cookie file doesn’t exist or we’re unable to read itstem.connection.CookieAuthRejected
if cookie authentication is attempted but the socket doesn’t accept itstem.connection.IncorrectCookieValue
if the cookie file’s value is rejectedstem.connection.UnrecognizedAuthChallengeMethod
if the Tor client fails to recognize the AuthChallenge methodstem.connection.AuthChallengeUnsupported
if AUTHCHALLENGE is unimplemented, or if unable to parse AUTHCHALLENGE responsestem.connection.AuthSecurityFailure
if AUTHCHALLENGE’s response looks like a security attackstem.connection.InvalidClientNonce
if stem’s AUTHCHALLENGE client nonce is rejected for being invalid
-
stem.connection.
get_protocolinfo
(controller)[source]¶ Issues a PROTOCOLINFO query to a control socket, getting information about the tor process running on it. If the socket is already closed then it is first reconnected.
This can authenticate to either a
BaseController
orControlSocket
.Parameters: controller – tor controller or socket to be queried
Returns: ProtocolInfoResponse
provided by torRaises: stem.ProtocolError
if the PROTOCOLINFO response is malformedstem.SocketError
if problems arise in establishing or using the socket
-
exception
stem.connection.
AuthenticationFailure
(message, auth_response=None)[source]¶ Bases:
Exception
Base error for authentication failures.
Variables: auth_response (stem.socket.ControlMessage) – AUTHENTICATE response from the control socket, None if one wasn’t received
-
exception
stem.connection.
UnrecognizedAuthMethods
(message, unknown_auth_methods)[source]¶ Bases:
stem.connection.AuthenticationFailure
All methods for authenticating aren’t recognized.
Variables: unknown_auth_methods (list) – authentication methods that weren’t recognized
-
exception
stem.connection.
IncorrectSocketType
(message, auth_response=None)[source]¶ Bases:
stem.connection.AuthenticationFailure
Socket does not speak the control protocol.
-
exception
stem.connection.
OpenAuthFailed
(message, auth_response=None)[source]¶ Bases:
stem.connection.AuthenticationFailure
Failure to authenticate to an open socket.
-
exception
stem.connection.
OpenAuthRejected
(message, auth_response=None)[source]¶ Bases:
stem.connection.OpenAuthFailed
Attempt to connect to an open control socket was rejected.
-
exception
stem.connection.
PasswordAuthFailed
(message, auth_response=None)[source]¶ Bases:
stem.connection.AuthenticationFailure
Failure to authenticate with a password.
-
exception
stem.connection.
PasswordAuthRejected
(message, auth_response=None)[source]¶ Bases:
stem.connection.PasswordAuthFailed
Socket does not support password authentication.
-
exception
stem.connection.
IncorrectPassword
(message, auth_response=None)[source]¶ Bases:
stem.connection.PasswordAuthFailed
Authentication password incorrect.
-
exception
stem.connection.
MissingPassword
(message, auth_response=None)[source]¶ Bases:
stem.connection.PasswordAuthFailed
Password authentication is supported but we weren’t provided with one.
-
exception
stem.connection.
CookieAuthFailed
(message, cookie_path, is_safecookie, auth_response=None)[source]¶ Bases:
stem.connection.AuthenticationFailure
Failure to authenticate with an authentication cookie.
Parameters: - cookie_path (str) – location of the authentication cookie we attempted
- is_safecookie (bool) – True if this was for SAFECOOKIE authentication, False if for COOKIE
- auth_response (stem.response.ControlMessage) – reply to our authentication attempt
-
exception
stem.connection.
CookieAuthRejected
(message, cookie_path, is_safecookie, auth_response=None)[source]¶ Bases:
stem.connection.CookieAuthFailed
Socket does not support password authentication.
-
exception
stem.connection.
IncorrectCookieValue
(message, cookie_path, is_safecookie, auth_response=None)[source]¶ Bases:
stem.connection.CookieAuthFailed
Authentication cookie value was rejected.
-
exception
stem.connection.
IncorrectCookieSize
(message, cookie_path, is_safecookie, auth_response=None)[source]¶ Bases:
stem.connection.CookieAuthFailed
Aborted because the cookie file is the wrong size.
-
exception
stem.connection.
UnreadableCookieFile
(message, cookie_path, is_safecookie, auth_response=None)[source]¶ Bases:
stem.connection.CookieAuthFailed
Error arose in reading the authentication cookie.
-
exception
stem.connection.
AuthChallengeFailed
(message, cookie_path)[source]¶ Bases:
stem.connection.CookieAuthFailed
AUTHCHALLENGE command has failed.
-
exception
stem.connection.
AuthChallengeUnsupported
(message, cookie_path)[source]¶ Bases:
stem.connection.AuthChallengeFailed
AUTHCHALLENGE isn’t implemented.
-
exception
stem.connection.
UnrecognizedAuthChallengeMethod
(message, cookie_path, authchallenge_method)[source]¶ Bases:
stem.connection.AuthChallengeFailed
Tor couldn’t recognize our AUTHCHALLENGE method.
Variables: authchallenge_method (str) – AUTHCHALLENGE method that Tor couldn’t recognize
-
exception
stem.connection.
AuthSecurityFailure
(message, cookie_path)[source]¶ Bases:
stem.connection.AuthChallengeFailed
AUTHCHALLENGE response is invalid.
-
exception
stem.connection.
InvalidClientNonce
(message, cookie_path)[source]¶ Bases:
stem.connection.AuthChallengeFailed
AUTHCHALLENGE request contains an invalid client nonce.
-
exception
stem.connection.
MissingAuthInfo
(message, auth_response=None)[source]¶ Bases:
stem.connection.AuthenticationFailure
The PROTOCOLINFO response didn’t have enough information to authenticate. These are valid control responses but really shouldn’t happen in practice.
-
exception
stem.connection.
NoAuthMethods
(message, auth_response=None)[source]¶ Bases:
stem.connection.MissingAuthInfo
PROTOCOLINFO response didn’t have any methods for authenticating.
-
exception
stem.connection.
NoAuthCookie
(message, is_safecookie)[source]¶ Bases:
stem.connection.MissingAuthInfo
PROTOCOLINFO response supports cookie auth but doesn’t have its path.
Parameters: is_safecookie (bool) – True if this was for SAFECOOKIE authentication, False if for COOKIE