mikie
mikie

Reputation: 95

twisted portforward proxy send back data to client

Here is some code I have come up with so far...

   from twisted.internet import protocol,reactor
   from twisted.internet.protocol import Protocol,ClientFactory

   class serverprotocol(Protocol):

       def dataReceived(self,data):
            print "[+] got \n" + data
            factory = protocol.ClientFactory()
            factory.protocol = Clientp
            global xx
            xx=data
            print xx
            reactor.connectTCP("127.0.0.1",80,factory)

   class Clientp(Protocol):
       def connectionMade(self):
            print "sending " + xx
            self.transport.write(xx)

       def dataReceived(self,data):
            print "+ got reply" + data

   factory = protocol.ServerFactory()
   factory.protocol = serverprotocol
   reactor.listenTCP(3333, factory)
   reactor.run()

I am wondering how I can send the data received in the client class back the client that connects on port 3333.

If there is a better way to code this please do let Me know.

Upvotes: 2

Views: 1646

Answers (3)

mikie
mikie

Reputation: 95

from twisted.internet import protocol,reactor
from twisted.internet.protocol import Protocol,ClientFactory

clients=[]

class serverprotocol(Protocol):
    def connectionMade(self):
        g.append(self)

    def dataReceived(self,data):

        factory = protocol.ClientFactory()
        factory.protocol = Clientp
        global xx
        xx=data
        reactor.connectTCP("127.0.0.1",80,factory)

class Clientp(Protocol):
    def connectionMade(self):
        print "sending "
        self.transport.write(xx)

    def dataReceived(self,data):
        print "+ got reply"

        for x in clients:
          x.transport.write(data)

factory = protocol.ServerFactory()
factory.protocol = serverprotocol
reactor.listenTCP(8080, factory)
reactor.run()

Upvotes: 0

Glyph
Glyph

Reputation: 31860

This is a Twisted FAQ: "How do I make input on one connection result in output on another"?

But it's not really a Twisted question. It's more of a basic Python programming question.

What you're asking is, given the class Clientp, how do you pass an argument to it so that it knows what to do later?

The answer is very simply "give it an __init__, pass it an argument"

from twisted.internet.protocol import Protocol, Factory
from twisted.internet.endpoints import TCP4ClientEndpoint
from twisted.internet import reactor

class serverprotocol(Protocol):

    def dataReceived(self,data):
        print "[+] got \n" + data
        def clientProtocol():
            return Clientp(data)
        endpoint = TCP4ClientEndpoint(reactor, "127.0.0.1", 80)
        endpoint.connect(Factory.forProtocol(clientProtocol))

class Clientp(Protocol):
    def __init__(self, dataToSend):
        self.dataToSend = dataToSend

    def connectionMade(self):
        self.transport.write(self.dataToSend)

    def dataReceived(self,data):
        print "+ got reply" + data

reactor.listenTCP(3333,
                  Factory.forProtocol(serverprotocol))
reactor.run()

If what you want is a full port forwarder, you could instead simply use twistd portforward or look at the code in twisted.protocols.portforward.

Upvotes: 2

James Mills
James Mills

Reputation: 19030

Because I'm biased I'm going to present a non-Twisted solution:

#!/usr/bin/env python

from uuid import uuid4 as uuid

from circuits import Component
from circuits.net.events import close, connect, write
from circuits.net.sockets import TCPClient, TCPServer


class Client(Component):

    channel = "client"

    def init(self, sock, host, port, channel=channel):
        self.sock = sock
        self.host = host
        self.port = port

        TCPClient(channel=self.channel).register(self)

    def ready(self, *args):
        self.fire(connect(self.host, self.port))

    def disconnect(self, *args):
        self.fire(close(self.sock), self.parent.channel)

    def read(self, data):
        self.fire(write(self.sock, data), self.parent.channel)


class Proxy(Component):

    channel = "server"

    def init(self, bind, host, port):
        self.bind = bind
        self.host = host
        self.port = port

        self.clients = dict()

        TCPServer(self.bind).register(self)

    def connect(self, sock, host, port):
        channel = uuid()

        client = Client(
            sock, self.host, self.port, channel=channel
        ).register(self)

        self.clients[sock] = client

    def disconnect(self, sock):
        client = self.clients.get(sock)
        if client is not None:
            client.unregister()
            del self.clients[sock]

    def read(self, sock, data):
        client = self.clients[sock]
        self.fire(write(data), client.channel)


app = Proxy(("0.0.0.0", 3333), "127.0.0.1", 22)

from circuits import Debugger
Debugger().register(app)

app.run()

This works as expected as a full tcp port forwarding proxy using the circuits framework.

Here's an example run:

Terminal 1 (server):

Fri May 23 14:05:02
~/circuits
$ ./proxy.py
<registered[server] (<TCPServer/server 48541:MainThread (queued=0) [S]>, <Proxy/server 48541:MainThread (queued=3) [R]> )>
<registered[*] (<Debugger/* 48541:MainThread (queued=0) [S]>, <Proxy/server 48541:MainThread (queued=4) [R]> )>
<started[server] (<Proxy/server 48541:MainThread (queued=3) [R]> )>
<registered[select] (<Select/select 48541:MainThread (queued=0) [S]>, <TCPServer/server 48541:MainThread (queued=0) [S]> )>
<ready[server] (<TCPServer/server 48541:MainThread (queued=0) [S]>, ('0.0.0.0', 3333) )>
<_read[server] (<socket._socketobject object at 0x100ff57c0> )>
<connect[server] (<socket._socketobject object at 0x100ff5980>, '127.0.0.1', 52911 )>
<_read[server] (<socket._socketobject object at 0x100ff5980> )>
<registered[ee1c155f-d2de-4f09-b05d-5b5e6f4de1d6] (<TCPClient/ee1c155f-d2de-4f09-b05d-5b5e6f4de1d6 48541:MainThread (queued=0) [S]>, <Client/ee1c155f-d2de-4f09-b05d-5b5e6f4de1d6 48541:MainThread (queued=0) [S]> )>
<registered[ee1c155f-d2de-4f09-b05d-5b5e6f4de1d6] (<Client/ee1c155f-d2de-4f09-b05d-5b5e6f4de1d6 48541:MainThread (queued=0) [S]>, <Proxy/server 48541:MainThread (queued=3) [R]> )>
<read[server] (<socket._socketobject object at 0x100ff5980>, 'SSH-2.0-OpenSSH_6.2\r\n' )>
<ready[ee1c155f-d2de-4f09-b05d-5b5e6f4de1d6] (<TCPClient/ee1c155f-d2de-4f09-b05d-5b5e6f4de1d6 48541:MainThread (queued=0) [S]> )>
<write[ee1c155f-d2de-4f09-b05d-5b5e6f4de1d6] ('SSH-2.0-OpenSSH_6.2\r\n' )>
<connect[ee1c155f-d2de-4f09-b05d-5b5e6f4de1d6] ('127.0.0.1', 22 )>
<connected[ee1c155f-d2de-4f09-b05d-5b5e6f4de1d6] ('127.0.0.1', 22 )>
<_write[ee1c155f-d2de-4f09-b05d-5b5e6f4de1d6] (<socket._socketobject object at 0x100ff5830> )>
<_read[ee1c155f-d2de-4f09-b05d-5b5e6f4de1d6] (<socket._socketobject object at 0x100ff5830> )>
<read[ee1c155f-d2de-4f09-b05d-5b5e6f4de1d6] ('SSH-2.0-OpenSSH_6.2\r\n' )>
<write[server] (<socket._socketobject object at 0x100ff5980>, 'SSH-2.0-OpenSSH_6.2\r\n' )>
<_write[server] (<socket._socketobject object at 0x100ff5980> )>
<_read[server] (<socket._socketobject object at 0x100ff5980> )>

Terminal 2 (client):

Fri May 23 14:06:26
~
$ ssh -p 3333 localhost
Last login: Fri May 23 14:04:51 2014 from localhost

Fri May 23 14:06:31
~
$ logout
Connection to localhost closed.

Upvotes: -1

Related Questions