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) –
BaseControllersubclass to be returned, this provides aControlSocketif 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) –
BaseControllersubclass to be returned, this provides aControlSocketif 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) –
BaseControllersubclass to be returned, this provides aControlSocketif 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
AuthenticationFailurecatch-all at the end.This can authenticate to either a
BaseControllerorControlSocket.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
AuthenticationFailuresubclass. 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.IncorrectSocketTypeThe 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.UnrecognizedAuthMethodsAll 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.MissingPasswordWe 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.IncorrectPasswordWe were provided with a password but it was incorrect.
stem.connection.IncorrectCookieSizeTor allows for authentication by reading it a cookie file, but that file is the wrong size to be an authentication cookie.
stem.connection.UnreadableCookieFileTor allows for authentication by reading it a cookie file, but we can’t read that file (probably due to permissions).
*
stem.connection.IncorrectCookieValueTor allows for authentication by reading it a cookie file, but rejected the contents of that file.
*
stem.connection.AuthChallengeUnsupportedTor 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.UnrecognizedAuthChallengeMethodTor couldn’t recognize the AUTHCHALLENGE method Stem sent to it. This shouldn’t happen at all.
*
stem.connection.InvalidClientNonceTor says that the client nonce provided by Stem during the AUTHCHALLENGE process is invalid.
*
stem.connection.AuthSecurityFailureNonce value provided by the server was invalid.
*
stem.connection.OpenAuthRejectedTor says that it allows for authentication without any credentials, but then rejected our authentication attempt.
*
stem.connection.MissingAuthInfoTor provided us with a PROTOCOLINFO reply that is technically valid, but missing the information we need to authenticate.
*
stem.connection.AuthenticationFailureThere 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
AuthenticationFailuresubclasses 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
BaseControllerorControlSocket.For general usage use the
authenticate()function instead.Parameters: - controller – tor controller or socket to be authenticated
- suppress_ctl_errors (bool) – reports raised
ControllerErroras authentication rejection if True, otherwise they’re re-raised
Raises: stem.connection.OpenAuthRejectedif 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
BaseControllerorControlSocket.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
ControllerErroras authentication rejection if True, otherwise they’re re-raised
Raises: stem.connection.PasswordAuthRejectedif the socket doesn’t accept password authenticationstem.connection.IncorrectPasswordif 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
IncorrectCookieSizeandUnreadableCookieFileexceptions 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 aCookieAuthRejectedrather 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
BaseControllerorControlSocket.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
ControllerErroras authentication rejection if True, otherwise they’re re-raised
Raises: stem.connection.IncorrectCookieSizeif the cookie file’s size is wrongstem.connection.UnreadableCookieFileif the cookie file doesn’t exist or we’re unable to read itstem.connection.CookieAuthRejectedif cookie authentication is attempted but the socket doesn’t accept itstem.connection.IncorrectCookieValueif 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
IncorrectCookieSizeandUnreadableCookieFileexceptions take precedence over the other exception types.The
AuthChallengeUnsupported,UnrecognizedAuthChallengeMethod,InvalidClientNonceandCookieAuthRejectedexceptions 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,
IncorrectCookieValueorCookieAuthRejectedmaybe 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
ControllerErroras authentication rejection if True, otherwise they’re re-raised
Raises: stem.connection.IncorrectCookieSizeif the cookie file’s size is wrongstem.connection.UnreadableCookieFileif the cookie file doesn’t exist or we’re unable to read itstem.connection.CookieAuthRejectedif cookie authentication is attempted but the socket doesn’t accept itstem.connection.IncorrectCookieValueif the cookie file’s value is rejectedstem.connection.UnrecognizedAuthChallengeMethodif the Tor client fails to recognize the AuthChallenge methodstem.connection.AuthChallengeUnsupportedif AUTHCHALLENGE is unimplemented, or if unable to parse AUTHCHALLENGE responsestem.connection.AuthSecurityFailureif AUTHCHALLENGE’s response looks like a security attackstem.connection.InvalidClientNonceif 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
BaseControllerorControlSocket.Parameters: controller – tor controller or socket to be queried
Returns: ProtocolInfoResponseprovided by torRaises: stem.ProtocolErrorif the PROTOCOLINFO response is malformedstem.SocketErrorif problems arise in establishing or using the socket
-
exception
stem.connection.AuthenticationFailure(message, auth_response=None)[source]¶ Bases:
ExceptionBase 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.AuthenticationFailureAll 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.AuthenticationFailureSocket does not speak the control protocol.
-
exception
stem.connection.OpenAuthFailed(message, auth_response=None)[source]¶ Bases:
stem.connection.AuthenticationFailureFailure to authenticate to an open socket.
-
exception
stem.connection.OpenAuthRejected(message, auth_response=None)[source]¶ Bases:
stem.connection.OpenAuthFailedAttempt to connect to an open control socket was rejected.
-
exception
stem.connection.PasswordAuthFailed(message, auth_response=None)[source]¶ Bases:
stem.connection.AuthenticationFailureFailure to authenticate with a password.
-
exception
stem.connection.PasswordAuthRejected(message, auth_response=None)[source]¶ Bases:
stem.connection.PasswordAuthFailedSocket does not support password authentication.
-
exception
stem.connection.IncorrectPassword(message, auth_response=None)[source]¶ Bases:
stem.connection.PasswordAuthFailedAuthentication password incorrect.
-
exception
stem.connection.MissingPassword(message, auth_response=None)[source]¶ Bases:
stem.connection.PasswordAuthFailedPassword 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.AuthenticationFailureFailure 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.CookieAuthFailedSocket does not support password authentication.
-
exception
stem.connection.IncorrectCookieValue(message, cookie_path, is_safecookie, auth_response=None)[source]¶ Bases:
stem.connection.CookieAuthFailedAuthentication cookie value was rejected.
-
exception
stem.connection.IncorrectCookieSize(message, cookie_path, is_safecookie, auth_response=None)[source]¶ Bases:
stem.connection.CookieAuthFailedAborted because the cookie file is the wrong size.
-
exception
stem.connection.UnreadableCookieFile(message, cookie_path, is_safecookie, auth_response=None)[source]¶ Bases:
stem.connection.CookieAuthFailedError arose in reading the authentication cookie.
-
exception
stem.connection.AuthChallengeFailed(message, cookie_path)[source]¶ Bases:
stem.connection.CookieAuthFailedAUTHCHALLENGE command has failed.
-
exception
stem.connection.AuthChallengeUnsupported(message, cookie_path)[source]¶ Bases:
stem.connection.AuthChallengeFailedAUTHCHALLENGE isn’t implemented.
-
exception
stem.connection.UnrecognizedAuthChallengeMethod(message, cookie_path, authchallenge_method)[source]¶ Bases:
stem.connection.AuthChallengeFailedTor 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.AuthChallengeFailedAUTHCHALLENGE response is invalid.
-
exception
stem.connection.InvalidClientNonce(message, cookie_path)[source]¶ Bases:
stem.connection.AuthChallengeFailedAUTHCHALLENGE request contains an invalid client nonce.
-
exception
stem.connection.MissingAuthInfo(message, auth_response=None)[source]¶ Bases:
stem.connection.AuthenticationFailureThe 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.MissingAuthInfoPROTOCOLINFO response didn’t have any methods for authenticating.
-
exception
stem.connection.NoAuthCookie(message, is_safecookie)[source]¶ Bases:
stem.connection.MissingAuthInfoPROTOCOLINFO 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
