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'>)

   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 a "ControlSocket" 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'>)

   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 a "ControlSocket" 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'>)

   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 a "ControlSocket" 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)

   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" or
   "ControlSocket".

   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)

   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" or
   "ControlSocket".

   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)

   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" or
   "ControlSocket".

   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 authentication

      * "stem.connection.IncorrectPassword" if the authentication
        credentials aren’t accepted

stem.connection.authenticate_cookie(controller, cookie_path, suppress_ctl_errors=True)

   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" and "UnreadableCookieFile" 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 a "CookieAuthRejected" rather than
   "IncorrectCookieValue". 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" or
   "ControlSocket".

   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 wrong

      * "stem.connection.UnreadableCookieFile" if the cookie file
        doesn’t exist or we’re unable to read it

      * "stem.connection.CookieAuthRejected" if cookie
        authentication is attempted but the socket doesn’t accept it

      * "stem.connection.IncorrectCookieValue" if the cookie file’s
        value is rejected

stem.connection.authenticate_safecookie(controller, cookie_path, suppress_ctl_errors=True)

   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…

   1. send a nonce to the server and receives a challenge from the
      server for the cookie’s contents

   2. generate a hash digest using the challenge received in the
      first step, and use it to authenticate the controller

   The "IncorrectCookieSize" and "UnreadableCookieFile" exceptions
   take precedence over the other exception types.

   The "AuthChallengeUnsupported", "UnrecognizedAuthChallengeMethod",
   "InvalidClientNonce" and "CookieAuthRejected" 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" or
   "CookieAuthRejected" 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 wrong

      * "stem.connection.UnreadableCookieFile" if the cookie file
        doesn’t exist or we’re unable to read it

      * "stem.connection.CookieAuthRejected" if cookie
        authentication is attempted but the socket doesn’t accept it

      * "stem.connection.IncorrectCookieValue" if the cookie file’s
        value is rejected

      * "stem.connection.UnrecognizedAuthChallengeMethod" if the Tor
        client fails to recognize the AuthChallenge method

      * "stem.connection.AuthChallengeUnsupported" if AUTHCHALLENGE
        is unimplemented, or if unable to parse AUTHCHALLENGE response

      * "stem.connection.AuthSecurityFailure" if AUTHCHALLENGE’s
        response looks like a security attack

      * "stem.connection.InvalidClientNonce" if stem’s AUTHCHALLENGE
        client nonce is rejected for being invalid

stem.connection.get_protocolinfo(controller)

   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" or
   "ControlSocket".

   Parameters:
      **controller** – tor controller or socket to be queried

   Returns:
      "ProtocolInfoResponse" provided by tor

   Raises:
      * "stem.ProtocolError" if the PROTOCOLINFO response is
        malformed

      * "stem.SocketError" if problems arise in establishing or
        using the socket

exception stem.connection.AuthenticationFailure(message, auth_response=None)

   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)

   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)

   Bases: "stem.connection.AuthenticationFailure"

   Socket does not speak the control protocol.

exception stem.connection.OpenAuthFailed(message, auth_response=None)

   Bases: "stem.connection.AuthenticationFailure"

   Failure to authenticate to an open socket.

exception stem.connection.OpenAuthRejected(message, auth_response=None)

   Bases: "stem.connection.OpenAuthFailed"

   Attempt to connect to an open control socket was rejected.

exception stem.connection.PasswordAuthFailed(message, auth_response=None)

   Bases: "stem.connection.AuthenticationFailure"

   Failure to authenticate with a password.

exception stem.connection.PasswordAuthRejected(message, auth_response=None)

   Bases: "stem.connection.PasswordAuthFailed"

   Socket does not support password authentication.

exception stem.connection.IncorrectPassword(message, auth_response=None)

   Bases: "stem.connection.PasswordAuthFailed"

   Authentication password incorrect.

exception stem.connection.MissingPassword(message, auth_response=None)

   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)

   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)

   Bases: "stem.connection.CookieAuthFailed"

   Socket does not support password authentication.

exception stem.connection.IncorrectCookieValue(message, cookie_path, is_safecookie, auth_response=None)

   Bases: "stem.connection.CookieAuthFailed"

   Authentication cookie value was rejected.

exception stem.connection.IncorrectCookieSize(message, cookie_path, is_safecookie, auth_response=None)

   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)

   Bases: "stem.connection.CookieAuthFailed"

   Error arose in reading the authentication cookie.

exception stem.connection.AuthChallengeFailed(message, cookie_path)

   Bases: "stem.connection.CookieAuthFailed"

   AUTHCHALLENGE command has failed.

exception stem.connection.AuthChallengeUnsupported(message, cookie_path)

   Bases: "stem.connection.AuthChallengeFailed"

   AUTHCHALLENGE isn’t implemented.

exception stem.connection.UnrecognizedAuthChallengeMethod(message, cookie_path, authchallenge_method)

   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)

   Bases: "stem.connection.AuthChallengeFailed"

   AUTHCHALLENGE response is invalid.

exception stem.connection.InvalidClientNonce(message, cookie_path)

   Bases: "stem.connection.AuthChallengeFailed"

   AUTHCHALLENGE request contains an invalid client nonce.

exception stem.connection.MissingAuthInfo(message, auth_response=None)

   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)

   Bases: "stem.connection.MissingAuthInfo"

   PROTOCOLINFO response didn’t have any methods for authenticating.

exception stem.connection.NoAuthCookie(message, is_safecookie)

   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
