Authenticating a Controller with a Tor subprocess using Stem
Question: I am trying to launch a new tor process (no tor processes currently running on
the system) using a 'custom' config by using stems `launch_tor_with_config`.

I wrote a function that will successfully generate and capture a new hashed
password. I then use that new password in the config, launch tor and try to
authenticate using the same exact passhash and it fails.

Here is the code:

    
    
    from stem.process import launch_tor_with_config
    from stem.control import Controller
    
    from subprocess import Popen, PIPE
    import logging
    
    def genTorPassHash(password):
        """ Launches a subprocess of tor to generate a hashed <password>"""
        logging.info("Generating a hashed password")
        torP = Popen(['tor', '--hush', '--hash-password', str(password)], stdout=PIPE, bufsize=1)
        try:
            with torP.stdout:
                for line in iter(torP.stdout.readline, b''):
                    line = line.strip('\n')
                    if not "16:" in line: 
                        logging.debug(line)
                    else:
                        passhash = line
            torP.wait()
            logging.info("Got hashed password")
            logging.debug(passhash)
            return passhash
        except Exception as e:
            logging.exception(e)
    
    
    
    def startTor(config):
        """ Starts a tor subprocess using a custom <config>
        returns Popen and controller
        """
        try:
            # start tor
            logging.info("Starting tor")
            torProcess = launch_tor_with_config( 
                config=config, # use our custom config
                tor_cmd='tor', # start tor normally
                completion_percent=100, # blocks until tor is 100%
                timeout=90, # wait 90 sec for tor to start
                take_ownership=True # subprocess will close with parent
                )
            # connect a controller
            logging.info("Connecting controller")
            torControl = Controller.from_port(address="127.0.0.1", port=int(config['ControlPort']))
            # auth controller
            torControl.authenticate(password=config['HashedControlPassword'])
            logging.info("Connected to tor process")
            return torProcess, torControl
    
        except Exception as e:
            logging.exception(e)
    
    
    if __name__ == "__main__":
        logging.basicConfig(format='[%(asctime)s] %(message)s', datefmt="%H:%M:%S", level=logging.DEBUG)
        password =  genTorPassHash(raw_input("Type something: "))
    
        config = { 
            'ClientOnly': '1',
            'ControlPort': '9051',
            'DataDirectory': '~/.tor/temp',
            'Log': ['DEBUG stdout', 'ERR stderr' ],
            'HashedControlPassword' : password }
    
        torProcess, torControl = startTor(config)
    

This is what happens when I run the above code:

    
    
    s4w3d0ff@FooManChoo ~ $ python stackOverflowTest.py
    Type something: foo
    [13:33:55] Generating a hashed password
    [13:33:55] Got hashed password
    [13:33:55] 16:84DE3F93CAFD3B0660BD6EC303A8A7C65B6BD0AC7E9454B3B130881A57
    [13:33:55] Starting tor
    [13:33:56] System call: tor --version (runtime: 0.01)
    [13:33:56] Received from system (tor --version), stdout:
    Tor version 0.2.4.27 (git-412e3f7dc9c6c01a).
    [13:34:00] Connecting controller
    [13:34:00] Sent to tor:
    PROTOCOLINFO 1
    [13:34:00] Received from tor:
    250-PROTOCOLINFO 1
    250-AUTH METHODS=HASHEDPASSWORD
    250-VERSION Tor="0.2.4.27"
    250 OK
    [13:34:00] Sent to tor:
    AUTHENTICATE "16:84DE3F93CAFD3B0660BD6EC303A8A7C65B6BD0AC7E9454B3B130881A57"
    [13:34:00] Received from tor:
    515 Authentication failed: Password did not match HashedControlPassword value from configuration
    [13:34:00] Error while receiving a control message (SocketClosed): empty socket content
    [13:34:00] Sent to tor:
    SETEVENTS SIGNAL CONF_CHANGED
    [13:34:00] Error while receiving a control message (SocketClosed): empty socket content
    [13:34:00] Failed to send message: [Errno 32] Broken pipe
    [13:34:00] Error while receiving a control message (SocketClosed): empty socket content
    [13:34:00] Received empty socket content.
    Traceback (most recent call last):
      File "stackOverflowTest.py", line 46, in startTor
        torControl.authenticate(password=config['HashedControlPassword'])
      File "/usr/local/lib/python2.7/dist-packages/stem/control.py", line 991, in authenticate
        stem.connection.authenticate(self, *args, **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/stem/connection.py", line 608, in authenticate
        raise auth_exc
    AuthenticationFailure: Received empty socket content.
    Traceback (most recent call last):
      File "stackOverflowTest.py", line 65, in <module>
        torProcess, torControl = startTor(config)
    TypeError: 'NoneType' object is not iterable
    

Am I missing something?


Answer: The trouble is that you're authenticating with the password hash rather than
the password itself. Try...

    
    
    password = raw_input('password: ')
    password_hash = genTorPassHash(password)
    
    ... then use the password_hash in the config and password for authentication
    

