Search code examples
pythontor

Python script Exception with Tor


I have the following script which uses SocksiPY

and Tor:

from TorCtl import TorCtl

import socks
import socket
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)
socket.socket = socks.socksocket

import urllib2
import sqlite3
from BeautifulSoup import BeautifulSoup

def newId():
    conn = TorCtl.connect(controlAddr="127.0.0.1", controlPort=9051, passphrase="123")
    TorCtl.Connection.send_signal(conn, "NEWNYM")

newId()

print(urllib2.urlopen("http://www.ifconfig.me/ip").read())

This code should change Tor identity but it waits for some time and gives the following error:

tuple index out of range
Traceback (most recent call last):
  File "template.py", line 16, in <module>
    newId()
  File "template.py", line 14, in newId
    TorCtl.Connection.send_signal(conn, "NEWNYM")
TypeError: unbound method send_signal() must be called with Connection instance as first argument (got NoneType instance instead)

But above script is divided into 2 separate scripts:

import socks
import socket
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)
socket.socket = socks.socksocket

import urllib2
import sqlite3
from BeautifulSoup import BeautifulSoup

print(urllib2.urlopen("http://www.ifconfig.me/ip").read())

AND:

from TorCtl import TorCtl
def newId():
    conn = TorCtl.connect(controlAddr="127.0.0.1", controlPort=9051, passphrase="123")
    TorCtl.Connection.send_signal(conn, "NEWNYM")

newId()

When second script is called then first is called it is ok. Can anyone explain what is the problem and how to fix?


Solution

  • Anonymous explained very well this socket overwrite, answer is almost perfect except you have to close the control socket. It is safer because of the TorCtl event loop, but I have to look deeper in the TorCtl code to understand this event loop.

    To summarize your code becomes:

    from TorCtl import TorCtl
    
    import socks
    import socket
    socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)
    
    import urllib2
    import sqlite3
    from BeautifulSoup import BeautifulSoup
    
    __originalSocket = socket.socket
    
    def newId():
        ''' Clean circuit switcher
    
        Restores socket to original system value.
        Calls TOR control socket and closes it
        Replaces system socket with socksified socket
        '''
        socket.socket = __originalSocket
        conn = TorCtl.connect(controlAddr="127.0.0.1", controlPort=9051, passphrase="123")
        TorCtl.Connection.send_signal(conn, "NEWNYM")
        conn.close()
        socket.socket = socks.socksocket
    
    newId()
    
    print(urllib2.urlopen("http://www.ifconfig.me/ip").read())