[tor-dev] TOR socket for P2P in Python

Dear Tor Developers,

in my application, a client connects to a server via:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(ip,port)

I want to replace these two lines to create a client_socket whose IP address cannot be seen by the server. The application is e-polling.

I looked into

  • torpy (too many timeouts),
  • socks (requires too much external configuration),
  • and I have tor installed (unknown how to use from within python).

I just need a replacement for the two-liner code above.

The ideal solution: is device & OS agnostic, portable, uses no peripherals or configuration (i.e., just one pip package to install), and works reliably.
Thus, the below torpy solution would have been ideal if it had worked reliably:

from torpy import TorClient # pip install torpy

class Torsocket:

def init(self,ip,port):
self.mgr1 = TorClient()
self.tor = type(self.mgr1).enter(self.mgr1)
self.mgr2 = self.tor.create_circuit(3)
self.circuit = type(self.mgr2).enter(self.mgr2)
self.mgr3 = self.circuit.create_stream((ip,port))
self.socket = type(self.mgr3).enter(self.mgr3)
def send(self,data):
self.socket.send(data)
def recv(self,size):
return self.socket.recv(size)
def del(self):
for bla in [self.mgr3,self.mgr2,self.mgr1]: type(bla).exit(bla, None, None, None)

It replaces the two-liner from the beginning with the below one-liner
client_socket = Torsocket(*server_data.server_address)

My questions/requests:

  • Is torpy connected to the real tor network (or is it a little toy twin)? If it is the real tor network then I will close this issue and open another one.

  • Are practical solutions available to my problem already?, and which of them works best for user-friendliness?

  • Can a pip package for a torsocket be made, as described above? i.e., something like torpy, but connecting to the real network?

  • Can I offer anything so that the ideal solution would be crafted and packaged?*

*) If it helps, I could tell a lot about my project and how I believe it is significant and will be for the greater good of people. It is a fully implemented 1000LOC LSAG+WOT decentral P2P e-polling program with GUI that shall return trust and sovereignty into the people’s hands. The only missing bit is a reliable tor connection.

Sorry to bother again.

An equally good solution to replacing
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(ip,port)
with a TOR solution could be via a command line interface: os.system(“torsocketprogram -send 123.45.67.89 9000 filename.bytes”) and os.system(“torsocketprogram -recv 123.45.67.89 9000 filename.bytes”).

···

Am Do., 11. Aug. 2022 um 11:27 Uhr schrieb Martin Neuenhofen <martinneuenhofen@googlemail.com>:

Dear Tor Developers,

in my application, a client connects to a server via:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(ip,port)

I want to replace these two lines to create a client_socket whose IP address cannot be seen by the server. The application is e-polling.

I looked into

  • torpy (too many timeouts),
  • socks (requires too much external configuration),
  • and I have tor installed (unknown how to use from within python).

I just need a replacement for the two-liner code above.

The ideal solution: is device & OS agnostic, portable, uses no peripherals or configuration (i.e., just one pip package to install), and works reliably.
Thus, the below torpy solution would have been ideal if it had worked reliably:

from torpy import TorClient # pip install torpy

class Torsocket:

def init(self,ip,port):
self.mgr1 = TorClient()
self.tor = type(self.mgr1).enter(self.mgr1)
self.mgr2 = self.tor.create_circuit(3)
self.circuit = type(self.mgr2).enter(self.mgr2)
self.mgr3 = self.circuit.create_stream((ip,port))
self.socket = type(self.mgr3).enter(self.mgr3)
def send(self,data):
self.socket.send(data)
def recv(self,size):
return self.socket.recv(size)
def del(self):
for bla in [self.mgr3,self.mgr2,self.mgr1]: type(bla).exit(bla, None, None, None)

It replaces the two-liner from the beginning with the below one-liner
client_socket = Torsocket(*server_data.server_address)

My questions/requests:

  • Is torpy connected to the real tor network (or is it a little toy twin)? If it is the real tor network then I will close this issue and open another one.

  • Are practical solutions available to my problem already?, and which of them works best for user-friendliness?

  • Can a pip package for a torsocket be made, as described above? i.e., something like torpy, but connecting to the real network?

  • Can I offer anything so that the ideal solution would be crafted and packaged?*

*) If it helps, I could tell a lot about my project and how I believe it is significant and will be for the greater good of people. It is a fully implemented 1000LOC LSAG+WOT decentral P2P e-polling program with GUI that shall return trust and sovereignty into the people’s hands. The only missing bit is a reliable tor connection.

Some assorted responses to your messages:

- torpy[0] looks like a bad thing to base a revolutionary p2p tor-based thing on. No commits since last year. Not maintained by Tor Project or anyone associated with it. Touts v2 onion support as a positive when (1) the network has dropped support such that v2 onions will not work, even with torpy, and (2) it doesn't mention v3 onion support, which is the new thing. If your thing uses onion services, it needs v3 onion support

- You can get pretty far by "guessing" where a Tor client is going to be. E.g. try 127.0.0.1:9050, then :9150, then look for common control port and socket paths and if found, hope no auth is required and you can query tor this way to ask it where its SocksPort is. This is what nyx does (guess common ControlPort/Socket paths while allowing the user to specify it directly). This is what I'd do.

- Stem[1] is *the* tool to use to interact with a tor client from Python. Carml[2] and txtorcon[3] are great tools maintained by a well-known Tor person. I am most familiar with stem. All the things mentioned in this bullet point require the standard tor client to be available. I know stem can launch it if it isn't already running. AFAIK this is still the recommended route for integrating Python things with Tor. (1) If necessary, bundle a tor executable with your thing, and (2) launch it from your thing with the parameters you want. This is how I've done all the Python + Tor stuff I've ever written. Once you've determined the host:port of Tor's SocksPort, you can simply use PySocks:

     s = socks.sockssocket()
     socks_host = "something"
     socks_port = an_int
     s.set_proxy(socks.SOCKS5, socks_host, socks_port)

As an example, here's a simplified/censored function from code I wrote. It is naive and may not be suitable for your purposes. Adapt it and make it better if you want to use it.

     def function(
             dest: Tuple[str, int],
             socks_addrport: Tuple[str, int]) -> \
             Tuple[bool, str]:
         msg = 'some bytes to send'
         resp = ''
         s = socks.socksocket()
         s.set_proxy(socks.SOCKS5, *socks_addrport)
         s.settimeout(15)
         try:
             s.connect(dest)
             s.sendall(msg.encode('utf-8'))
             while True:
                 new = s.recv(4096).decode('utf-8')
                 if not new:
                     break
                 resp += new
         except Exception as e:
             return False, f'{type(e).__name__} {e}'
         return True, resp

The Python + Tor stuff I write tends to be pretty big/complex. It's probably not the best for explaining the basics, but I'll point you towards how flashflow configures and launches a tor client in case you will find it more useful than confusing[5]. Remember, this requires the standard tor binary to exist on the host.

Matt

[0]: GitHub - torpyorg/torpy: Pure python Tor client implementation
[1]: https://stem.torproject.org/
[2]: GitHub - meejah/carml: Command-line utility to control Tor.
[3]: txtorcon — timaq4ygg2iegci7.onion: txtorcon documentation
[4]: PySocks · PyPI
[5]: flashflow/tor_client.py at master · pastly/flashflow · GitHub

···

On 8/11/22 11:13, Martin Neuenhofen via tor-dev wrote:

Sorry to bother again.
An equally good solution to replacing
/client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(ip,port)/
with a TOR solution could be via a command line interface: os.system("torsocketprogram -send 123.45.67.89 9000 filename.bytes") and os.system("torsocketprogram -recv 123.45.67.89 9000 filename.bytes").

Am Do., 11. Aug. 2022 um 11:27 Uhr schrieb Martin Neuenhofen <martinneuenhofen@googlemail.com <mailto:martinneuenhofen@googlemail.com>>:

    *The ideal solution:* is device & OS agnostic, portable, uses no
    peripherals or configuration (i.e., just one pip package to
    install), and works reliably.
    Thus, the below torpy solution would have been ideal if it had
    worked reliably:

_______________________________________________
tor-dev mailing list
tor-dev@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev

Dear Matt Traudt,

Thank you for your answer.

Three remarks:

  1. I only found your answer coincidentally when I googled for LSAG + WOT. It would have been very nice if you had let me know that you answered.
  2. Your answer sort of only repeats what is already written on Overflow. Since that was unhelpful to me, I had asked the question your answer refers to.
  3. Your answer leaves out all the critical bits. Just to name the very first, which caused the beginning of this conversation: The proxy did not work because in windows the command “tor.exe” does nothing unless using the expert bundle. Now, play a game and try to find the download link for the expert bundle. I have lots of other things that leave me puzzled but it would be unsuitable to post them publicly. Please feel invited to get in touch if you want to have a discussion on certain things that appear to me as dramatic design flaws.
···

Am Do., 11. Aug. 2022 um 17:13 Uhr schrieb Martin Neuenhofen <martinneuenhofen@googlemail.com>:

Sorry to bother again.

An equally good solution to replacing
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(ip,port)
with a TOR solution could be via a command line interface: os.system(“torsocketprogram -send 123.45.67.89 9000 filename.bytes”) and os.system(“torsocketprogram -recv 123.45.67.89 9000 filename.bytes”).

Am Do., 11. Aug. 2022 um 11:27 Uhr schrieb Martin Neuenhofen <martinneuenhofen@googlemail.com>:

Dear Tor Developers,

in my application, a client connects to a server via:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(ip,port)

I want to replace these two lines to create a client_socket whose IP address cannot be seen by the server. The application is e-polling.

I looked into

  • torpy (too many timeouts),
  • socks (requires too much external configuration),
  • and I have tor installed (unknown how to use from within python).

I just need a replacement for the two-liner code above.

The ideal solution: is device & OS agnostic, portable, uses no peripherals or configuration (i.e., just one pip package to install), and works reliably.
Thus, the below torpy solution would have been ideal if it had worked reliably:

from torpy import TorClient # pip install torpy

class Torsocket:

def init(self,ip,port):
self.mgr1 = TorClient()
self.tor = type(self.mgr1).enter(self.mgr1)
self.mgr2 = self.tor.create_circuit(3)
self.circuit = type(self.mgr2).enter(self.mgr2)
self.mgr3 = self.circuit.create_stream((ip,port))
self.socket = type(self.mgr3).enter(self.mgr3)
def send(self,data):
self.socket.send(data)
def recv(self,size):
return self.socket.recv(size)
def del(self):
for bla in [self.mgr3,self.mgr2,self.mgr1]: type(bla).exit(bla, None, None, None)

It replaces the two-liner from the beginning with the below one-liner
client_socket = Torsocket(*server_data.server_address)

My questions/requests:

  • Is torpy connected to the real tor network (or is it a little toy twin)? If it is the real tor network then I will close this issue and open another one.

  • Are practical solutions available to my problem already?, and which of them works best for user-friendliness?

  • Can a pip package for a torsocket be made, as described above? i.e., something like torpy, but connecting to the real network?

  • Can I offer anything so that the ideal solution would be crafted and packaged?*

*) If it helps, I could tell a lot about my project and how I believe it is significant and will be for the greater good of people. It is a fully implemented 1000LOC LSAG+WOT decentral P2P e-polling program with GUI that shall return trust and sovereignty into the people’s hands. The only missing bit is a reliable tor connection.