Ejemplo n.º 1
0
class TUNReader(object):
	"""TUN device"""

	def __init__(self, tun_dev, tun_addr, tun_remote_addr, tun_nm, tun_mtu, wsfactory):
		self.wsfactory = wsfactory

		self.tun = TunTapDevice(name=tun_dev, flags=(IFF_TUN|IFF_NO_PI))
		self.tun.addr = tun_addr
		self.tun.dstaddr = tun_remote_addr
		self.tun.netmask = tun_nm
		self.tun.mtu = int(tun_mtu)
		self.tun.up()

		reactor.addReader(self)

		logstr = ("Opened TUN device on %s") % (self.tun.name)
		log.msg(logstr, logLevel=logging.INFO)


	def fileno(self):
		return self.tun.fileno()


	def connectionLost(self, reason):
		log.msg("Connection lost", logLevel=logging.WARN)


	def doRead(self):
		data = self.tun.read(self.tun.mtu)
		self.wsfactory.tunnel_write(data)


	def logPrefix(self):
		return "TUNReader"
Ejemplo n.º 2
0
class TunThread(threading.Thread):
    def __init__(self, *args, **kwargs):
        super(TunThread, self).__init__(*args, **kwargs)
        self.running = True
        self.tun = TunTapDevice(flags=(IFF_TAP | IFF_NO_PI))
        self.tun.addr = '10.5.0.1'
        self.tun.netmask = '255.255.0.0'
        self.tun.mtu = 1500
        self.tun.up()

    def run(self):
        p = poll()
        p.register(self.tun, POLLIN)
        try:
            while (self.running):
                #TODO: log IP headers in the future
                pollret = p.poll(1000)
                for (f, e) in pollret:
                    if f == self.tun.fileno() and (e & POLLIN):
                        buf = self.tun.read(
                            self.tun.mtu +
                            18)  #MTU doesn't include header or CRC32
                        if len(buf):
                            mac = buf[0:6]
                            if mac == BROADCAST or (ord(mac[0]) & 0x1) == 1:
                                #print 'sending broadcast frame:'
                                #print ':'.join('{0:02x}'.format(ord(c)) for c in buf)
                                for socket in macmap.values():

                                    def send_message():
                                        try:
                                            socket.write_message(str(buf),
                                                                 binary=True)
                                        except:
                                            pass

                                    loop.add_callback(send_message)

                            elif macmap.get(mac, False):

                                def send_message():
                                    try:
                                        macmap[mac].write_message(str(buf),
                                                                  binary=True)
                                    except:
                                        pass

                                loop.add_callback(send_message)
                            else:
                                print(
                                    "couldn't find recipient for mac %s from %s "
                                    % (':'.join('{0:02x}'.format(ord(c))
                                                for c in mac), ':'.join(
                                                    '{0:02x}'.format(ord(c))
                                                    for c in buf[6:12])))
        except:
            print 'closing due to tun error'
        finally:
            self.tun.close()
Ejemplo n.º 3
0
class TunThread(threading.Thread):
    def __init__(self, *args, **kwargs):
        super(TunThread, self).__init__(*args, **kwargs)
        self.running = True
        self.tun = TunTapDevice(flags=(IFF_TAP | IFF_NO_PI))
        self.tun.addr = '10.5.0.1'
        self.tun.netmask = '255.255.0.0'
        self.tun.mtu = 1500
        self.tun.up()

    def write(self, message):
        self.tun.write(message)

    def run(self):
        p = poll()
        p.register(self.tun, POLLIN)
        try:
            while (self.running):
                #TODO: log IP headers in the future
                pollret = p.poll(1000)
                for (f, e) in pollret:
                    if f == self.tun.fileno() and (e & POLLIN):
                        buf = self.tun.read(
                            self.tun.mtu +
                            18)  #MTU doesn't include header or CRC32
                        if len(buf):
                            mac = buf[0:6]
                            if mac == BROADCAST or (ord(mac[0]) & 0x1) == 1:
                                for socket in macmap.values():

                                    def send_message():
                                        try:
                                            socket.rate_limited_downstream(
                                                str(buf))
                                        except:
                                            pass

                                    loop.add_callback(send_message)

                            elif macmap.get(mac, False):

                                def send_message():
                                    try:
                                        macmap[mac].rate_limited_downstream(
                                            str(buf))
                                    except:
                                        pass

                                loop.add_callback(send_message)
        except:
            logger.error('closing due to tun error')
        finally:
            self.tun.close()
Ejemplo n.º 4
0
class TunThread(threading.Thread):
    def __init__(self, *args, **kwargs):
        super(TunThread, self).__init__(*args, **kwargs)
        self.running = True
        self.tun = TunTapDevice(flags= (IFF_TAP | IFF_NO_PI))
        self.tun.addr = '10.5.0.1'
        self.tun.netmask = '255.255.0.0'
        self.tun.mtu = 1500
        self.tun.up()

    def run(self):
        p = poll()
        p.register(self.tun, POLLIN)
        try:
            while(self.running):
                #TODO: log IP headers in the future
                pollret = p.poll(1000)
                for (f,e) in pollret:
                    if f == self.tun.fileno() and (e & POLLIN):
                        buf = self.tun.read(self.tun.mtu+18) #MTU doesn't include header or CRC32
                        if len(buf):
                            mac = buf[0:6]
                            if mac == BROADCAST or (ord(mac[0]) & 0x1) == 1:
                                #print 'sending broadcast frame:'
                                #print ':'.join('{0:02x}'.format(ord(c)) for c in buf)
                                for socket in macmap.values():
                                    def send_message():
                                        try:
                                            socket.write_message(str(buf),binary=True)
                                        except:
                                            pass

                                    loop.add_callback(send_message)

                            elif macmap.get(mac, False):
                                def send_message():
                                    try:
                                        macmap[mac].write_message(str(buf),binary=True)
                                    except:
                                        pass

                                loop.add_callback(send_message)
                            else:
                                print("couldn't find recipient for mac %s from %s " % (':'.join('{0:02x}'.format(ord(c)) for c in mac), ':'.join('{0:02x}'.format(ord(c)) for c in buf[6:12])))
        except:
            print 'closing due to tun error'
        finally:
            self.tun.close()
Ejemplo n.º 5
0
class TunThread(threading.Thread):
    def __init__(self, *args, **kwargs):
        super(TunThread, self).__init__(*args, **kwargs)
        self.running = True
        self.tun = TunTapDevice(flags= (IFF_TAP | IFF_NO_PI))
        self.tun.addr = '10.5.0.1'
        self.tun.netmask = '255.255.0.0'
        self.tun.mtu = 1500
        self.tun.up()

    def write(self, message):
        self.tun.write(message)

    def run(self):
        p = poll()
        p.register(self.tun, POLLIN)
        try:
            while(self.running):
                #TODO: log IP headers in the future
                pollret = p.poll(1000)
                for (f,e) in pollret:
                    if f == self.tun.fileno() and (e & POLLIN):
                        buf = self.tun.read(self.tun.mtu+18) #MTU doesn't include header or CRC32
                        if len(buf):
                            mac = buf[0:6]
                            if mac == BROADCAST or (ord(mac[0]) & 0x1) == 1:
                                for socket in macmap.values():
                                    def send_message():
                                        try:
                                            socket.rate_limited_downstream(str(buf))
                                        except:
                                            pass

                                    loop.add_callback(send_message)

                            elif macmap.get(mac, False):
                                def send_message():
                                    try:
                                        macmap[mac].rate_limited_downstream(str(buf))
                                    except:
                                        pass

                                loop.add_callback(send_message)
        except:
            logger.error('closing due to tun error')
        finally:
            self.tun.close()
Ejemplo n.º 6
0
class TUNReader(object):
    """TUN device"""

    def __init__(self, tun_dev, tun_addr, tun_remote_addr, tun_nm, tun_mtu, wsfactory):
        self.wsfactory = wsfactory

        try:
            self.tun = TunTapDevice(name=tun_dev, flags=(IFF_TUN|IFF_NO_PI))
        except:
            log.msg("Couldn't open the TUN device.  Are you root?  Is the interface already in use?", logLevel=logging.WARN)
            sys.exit(ERR)

        self.tun.addr = tun_addr
        self.addr = tun_addr # used by mtcrypt
        self.tun.dstaddr = tun_remote_addr
        self.tun.netmask = tun_nm
        self.tun.mtu = int(tun_mtu)
        self.tun.up()

        reactor.addReader(self)

        logstr = ("Opened TUN device on %s") % (self.tun.name)
        log.msg(logstr, logLevel=logging.INFO)


    def fileno(self):
        return self.tun.fileno()


    def connectionLost(self, reason):
        log.msg("Connection lost", logLevel=logging.INFO)


    def doRead(self):
        """Read from host, send to WS to be sent to distant end"""
        data = self.tun.read(self.tun.mtu)
        self.wsfactory.tunnel_write(data)

    def doWrite(self, data):
        self.tun.write(data)


    def logPrefix(self):
        return "TUNReader"
Ejemplo n.º 7
0
from tornado import ioloop
from ws4py.client.tornadoclient import TornadoWebSocketClient
from pytun import TunTapDevice, IFF_TAP, IFF_NO_PI
import sys

io_loop = ioloop.IOLoop.instance()

tap = TunTapDevice(flags=IFF_TAP|IFF_NO_PI, name='vpn-ws%d')

class VpnWSClient(TornadoWebSocketClient):

    def received_message(self, m):
        tap.write(str(m))

    def closed(self, code, reason=None):
        print "ooops"


ws = VpnWSClient(sys.argv[1])
ws.connect()

def tap_callback(fd, event):
    ws.send(tap.read(tap.mtu), binary=True)

io_loop.add_handler(tap.fileno(), tap_callback, io_loop.READ)
io_loop.start()
Ejemplo n.º 8
0
from tornado import ioloop
from ws4py.client.tornadoclient import TornadoWebSocketClient
from pytun import TunTapDevice, IFF_TAP, IFF_NO_PI
import sys

io_loop = ioloop.IOLoop.instance()

tap = TunTapDevice(flags=IFF_TAP | IFF_NO_PI, name='vpn-ws%d')


class VpnWSClient(TornadoWebSocketClient):
    def received_message(self, m):
        tap.write(str(m))

    def closed(self, code, reason=None):
        print "ooops"


ws = VpnWSClient(sys.argv[1])
ws.connect()


def tap_callback(fd, event):
    ws.send(tap.read(tap.mtu), binary=True)


io_loop.add_handler(tap.fileno(), tap_callback, io_loop.READ)
io_loop.start()
Ejemplo n.º 9
0
class QRTun(object):
    def __init__(self, side):
        self.side = int(side)
        if self.side not in [1, 2]:
            print("Side must be 1 or 2")
            raise Exception("Invalid Side")
        self.tun = TunTapDevice(flags=IFF_TUN | IFF_NO_PI,
                                name='qrtun%d' % self.side)
        self.tun.addr = '10.0.8.%d' % (self.side)
        if self.side == 1:
            self.other_side = 2
        else:
            self.other_side = 1
        self.tun.netmask = '255.255.255.0'
        #MTU must be set low enough to fit in a single qrcode
        self.tun.mtu = 500
        self.epoll = select.epoll()
        self.epoll.register(self.tun.fileno(), select.EPOLLIN)
        self.tun.up()
        #self.outfile = 'resources/toscreen%d.png'%(self.side)
        self.outfile = None
        self.infile = 'resources/toscreen%d.png' % (self.other_side)
        self.indata = None
        self.olddata = ""
        self.outdata = ""
        self.running = False
        self.qr = qrtools.QR()
        self.vc = cv2.VideoCapture(0)
        self.vc.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 720)
        self.vc.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 1280)
        pygame.init()
        pygame.event.set_allowed(None)
        pygame.event.set_allowed([pygame.KEYDOWN, pygame.QUIT])
        self.screen = pygame.display.set_mode((SIZE, SIZE))
        self.scale = 12
        pygame.display.set_caption("qrtun - QR Code scale %d" % (self.scale))

    def read_tun(self):
        events = self.epoll.poll(0)
        if events:
            self.outdata = self.tun.read(self.tun.mtu)
            return True
        return False

    def write_qrcode(self):

        p = subprocess.Popen(
            ['qrencode', '-o', '-', '-s',
             str(self.scale), '-8'],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE)
        std_out, std_err = p.communicate(input=self.outdata)
        if std_err:
            raise Exception("qrencodeError", std_err.strip())

        self.outfile = StringIO.StringIO(std_out)
        #code.png(self.outfile, scale=self.scale)
        self.outfile.seek(0)

        if self.outfile and not self.outfile.closed:
            pimg = pygame.image.load(self.outfile)
            if pimg.get_width() > self.screen.get_width() or pimg.get_height(
            ) > self.screen.get_height():
                pygame.display.set_mode((pimg.get_width(), pimg.get_height()))
            self.screen.fill((0, 0, 0))
            self.screen.blit(pimg, (0, 0))
            pygame.display.flip()

        self.msg_read = False

    def write_tun(self):
        try:
            if len(self.indata.get('body')) > 0:
                data = self.indata.get('body')
                if data != self.olddata:
                    self.tun.write(data)
                    #This is a hacky way to avoid dup packets...
                    #surely a better way to do this...
                    self.olddata = data
        except:
            print("Failed to write to tun!")

    def read_qrcode(self):
        qr = qrtools.QR()
        try:
            if not qr.decode(self.infile):
                return False
            #Hack to convert unicde to python string
            body = qr.data.encode('latin-1')
            self.indata = {'body': body}
            self.write_tun()
        except:
            pass

    def run(self):
        self.running = True
        while self.running:
            if self.read_tun():
                self.write_qrcode()

            rval, frame = self.vc.read()
            if not rval:
                running = False
                break
            scipy.misc.toimage(frame).save(self.infile)
            self.read_qrcode()

            event = pygame.event.poll()
            if event.type == pygame.QUIT:
                self.running = False
                pygame.quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.running = False
                    pygame.quit()
                elif event.key == pygame.K_UP:
                    self.scale += 1
                    pygame.display.set_caption("qrtun - QR Code scale %d" %
                                               (self.scale))
                    self.write_qrcode()
                elif event.key == pygame.K_DOWN:
                    self.scale -= 1
                    pygame.display.set_caption("qrtun - QR Code scale %d" %
                                               (self.scale))
                    self.write_qrcode()

        try:
            #os.unlink(self.outfile)
            os.unlink(self.infile)
        except:
            pass
Ejemplo n.º 10
0
#	'socket' : conn,
#	'kill_signal' : False,
#	'CN' : 'client'
# }
active_connections = []

rate_per_key = 10  # frames per second
max_capacity = 20  # token capacity - defines burst size

buckets = token_bucket.Limiter(rate_per_key, max_capacity,
                               token_bucket.MemoryStorage())

# Initialize a TAP interface and make it non-blocking
tap = TunTapDevice(flags=IFF_TAP | IFF_NO_PI, name='tap0')
tap.up()
fcntl.fcntl(tap.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)

tap_thread = threading.Thread(target=ThreadTapFunction,
                              args=(
                                  tap,
                                  active_connections,
                              ))
tap_thread.daemon = True
tap_thread.start()

t = threading.Thread(target=ServerFunction,
                     args=(
                         listen_addr,
                         listen_port,
                         active_connections,
                         buckets,
Ejemplo n.º 11
0
class QRTun(object):
    def __init__(self, side):
        self.side = int(side)
        if self.side not in [1, 2]:
            print("Side must be 1 or 2")
            raise Exception("Invalid Side")
        self.tun = TunTapDevice(flags=IFF_TUN | IFF_NO_PI,
                                name='qrtun%d' % self.side)
        self.tun.addr = '10.0.8.%d' % (self.side)
        if self.side == 1:
            self.other_side = 2
        else:
            self.other_side = 1
        self.tun.netmask = '255.255.255.0'
        #MTU must be set low enough to fit in a single qrcode
        self.tun.mtu = 500
        self.epoll = select.epoll()
        self.epoll.register(self.tun.fileno(), select.EPOLLIN)
        self.tun.up()
        self.seq = 0
        self.ack = 0
        self.outfile = 'resources/toscreen%d.png' % (self.side)
        self.infile = 'resources/toscreen%d.png' % (self.other_side)
        self.indata = None
        self.olddata = ""
        self.outdata = ""
        self.msg_read = True
        self.sent_time = None
        self.running = False
        self.qr = qrtools.QR()
        self.vc = cv2.VideoCapture(0)
        self.vc.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 720)
        self.vc.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 1280)

    def read_tun(self):
        events = self.epoll.poll(0)
        if events:
            self.outdata = self.tun.read(self.tun.mtu)

    def write_qrcode(self):

        #Have a header with seq/ack format
        header = '%03d/%03d' % (self.seq, self.ack)
        #Base32 encode since alphanumeic qr code only allows A-Z, 0-9 and some
        # symbols, but base64 uses lowercase as well....
        body = base64.b32encode(self.outdata).replace('=', '/')
        qr = qrtools.QR()
        qrb = qrtools.QR()
        qrb.data = "  "
        qr.data = header + body

        #Had an issue where decoded data did not match encoded data...
        #So I just add plus symbols as padding until they match, then strip
        # on the other side....
        while qr.data != qrb.data:
            qr.pixel_size = 12
            qr.encode(self.outfile)

            qrb.decode(self.outfile)
            if qrb.data != qr.data:
                print("EncodingFailure", qr.data)
                qr.data += '+'

        self.msg_read = False

    def write_tun(self):
        try:
            if len(self.indata.get('body')) > 0:
                data = self.indata.get('body')
                if data != self.olddata:
                    self.tun.write(data)
                    #This is a hacky way to avoid dup packets...
                    #Didn't think my seq/ack through very well, there is
                    #surely a better way to do this...
                    self.olddata = data
        except:
            print("Failed to write to tun!")

    def read_qrcode(self):
        qr = qrtools.QR()
        try:
            if not qr.decode(self.infile):
                return False

            header = map(int, qr.data[:7].split('/'))
            body = base64.b32decode(qr.data[7:].replace('/',
                                                        '=').replace('+', ''))
            self.indata = {'header': header, 'body': body}
            #We read their message, need to ack that, unless we already saw it
            if self.ack != header[0]:
                # print("New Message")
                self.ack = header[0]
                self.write_tun()
            #Have they ready my message already?
            if header[1] == self.seq:

                print("Acked %d" % self.seq)
                self.msg_read = True
                self.seq += 1
                if self.seq == 1000:
                    self.seq = 0
        except:
            pass

    def run(self):
        self.running = True
        while self.running:
            if self.msg_read:
                self.read_tun()
            #Very inefficient right now, constantly rewriting qr code,
            # even if nothing has changed....
            self.write_qrcode()

            rval, frame = self.vc.read()
            if not rval:
                running = False
                break
            scipy.misc.toimage(frame).save(self.infile)
            self.read_qrcode()

            sprite = factory.from_image(self.outfile)
            #cam = factory.from_image(self.infile)

            # spriterenderer.render(cam)
            spriterenderer.render(sprite)

            event = SDL_Event()
            while SDL_PollEvent(ctypes.byref(event)) != 0:
                if event.type == SDL_QUIT:
                    self.running = False
                    break
                elif event.type == SDL_KEYDOWN and event.key.keysym.sym == SDLK_ESCAPE:
                    self.running = False
                    break

        try:
            os.unlink(self.outfile)
            os.unlink(self.infile)
        except:
            pass
Ejemplo n.º 12
0
desire_time = 1

#################################################################

import select
import time
from scapy.all import IP, ICMP
from pytun import TunTapDevice, IFF_TAP, IFF_TUN, IFF_NO_PI

tun = TunTapDevice(flags=IFF_TUN | IFF_NO_PI, name="FakePing")
tun.addr = "10.10.10.1"
tun.netmask = '255.255.255.0'
tun.up()

epoll = select.epoll()
epoll.register(tun.fileno(), select.EPOLLIN)

while True:
    while epoll.poll(0):
        data = tun.read(tun.mtu)
        packet = IP(data)

        icmp_part = packet.getlayer(ICMP)
        if icmp_part is not None:
            time.sleep(desire_time)
            respacket = IP(src=packet.dst, dst=packet.src, ttl=desire_ttl)
            respacket /= ICMP(type=0, seq=icmp_part.seq, id=icmp_part.id)
            respacket /= icmp_part.payload
            tun.write(bytes(respacket))

            packet.show()
Ejemplo n.º 13
0
class QRTun(object):
    def __init__(self, side):
        self.side = int(side)
        if self.side not in [1,2]:
            print("Side must be 1 or 2")
            raise Exception("Invalid Side")
        self.tun = TunTapDevice(flags=IFF_TUN|IFF_NO_PI, name='qrtun%d'%self.side)
        self.tun.addr = '10.0.8.%d'%(self.side)
        if self.side == 1:
            self.other_side = 2
        else:
            self.other_side = 1
        self.tun.netmask = '255.255.255.0'
        #MTU must be set low enough to fit in a single qrcode
        self.tun.mtu = 300
        self.epoll = select.epoll()
        self.epoll.register(self.tun.fileno(), select.EPOLLIN)
        self.tun.up()
        #self.outfile = 'resources/toscreen%d.png'%(self.side)
        self.outfile = None
        self.infile = 'resources/toscreen%d.png'%(self.other_side)
        self.indata = None
        self.olddata = ""
        self.outdata = ""
        self.running = False
        self.vc = cv2.VideoCapture(0)
        self.vc.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 720)
        self.vc.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 1280)
        self.scanner = zbar.ImageScanner()
        self.scanner.parse_config('enable')
        pygame.init()
        pygame.event.set_allowed(None)
        pygame.event.set_allowed([pygame.KEYDOWN, pygame.QUIT])
        self.screen = pygame.display.set_mode((SIZE, SIZE))
        self.scale = 12
        pygame.display.set_caption("qrtun - QR Code scale %d"%(self.scale))
    def read_tun(self):
        events = self.epoll.poll(0)
        if events:
            self.outdata = self.tun.read(self.tun.mtu)
            return True
        return False
    def write_qrcode(self):


        #Sadly qrencode does not support \0 in binary mode!!! So I had to disable it and use the slower pyqrtools instead!

        #p = subprocess.Popen(['qrencode', '-o', '-', '-s', str(self.scale), '-8'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        #std_out, std_err = p.communicate(input=self.outdata)
        #if std_err:
        #    raise Exception("qrencodeError", std_err.strip())

        code = pyqrcode.create(b32encode(self.outdata).replace('=', '/'), mode='alphanumeric')

        self.outfile = StringIO.StringIO()
        code.png(self.outfile, scale=self.scale)
        self.outfile.seek(0)

        if self.outfile and not self.outfile.closed:
            pimg = pygame.image.load(self.outfile)
            if pimg.get_width() > self.screen.get_width() or pimg.get_height() > self.screen.get_height():
                pygame.display.set_mode((pimg.get_width(), pimg.get_height()))
            self.screen.fill((0,0,0))
            self.screen.blit(pimg, (0,0))
            pygame.display.flip()


        self.msg_read = False
    def write_tun(self):
        try:
            if len(self.indata.get('body')) > 0:
                data = self.indata.get('body')
                if data != self.olddata:
                    self.tun.write(data)
                    #This is a hacky way to avoid dup packets...
                    #surely a better way to do this...
                    self.olddata = data
        except:
            print("Failed to write to tun!")
    def read_qrcode(self):
        width, height = self.inframe.size
        raw = self.inframe.tobytes()
        image = zbar.Image(width, height, 'Y800', raw)
        result = self.scanner.scan(image)
        if result == 0:
            return False
        else:
            print "QR!"
            for symbol in image:
                pass
            # clean up
            del(image)
            # Assuming data is encoded in utf8
            try:
                self.indata = {'body': b32decode(symbol.data.replace('/', '='))}
                self.write_tun()
                return True
            except:
                return False


    def read_cam(self):
        rval, frame = self.vc.read()
        if not rval:
            return False
        self.inframe = scipy.misc.toimage(frame).convert('L')
        return True
    def run(self):
        self.running = True
        while self.running:
            if self.read_tun():
                self.write_qrcode()
            
            if not self.read_cam():
                running = False
                break
            
            self.read_qrcode()

               

            event = pygame.event.poll()
            if event.type == pygame.QUIT:
                self.running = False
                pygame.quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.running = False 
                    pygame.quit()
                elif event.key == pygame.K_UP:
                    self.scale += 1
                    pygame.display.set_caption("qrtun - QR Code scale %d"%(self.scale))
                    self.write_qrcode()
                elif event.key == pygame.K_DOWN:
                    self.scale -= 1
                    pygame.display.set_caption("qrtun - QR Code scale %d"%(self.scale))
                    self.write_qrcode()
 
        try:
            #os.unlink(self.outfile)
            os.unlink(self.infile)
        except:
            pass
Ejemplo n.º 14
0
class TLSTunnel():

	def initialize (self):

		# parse arguments
		parser = argparse.ArgumentParser(description='TLS tunnel client')
		parser.add_argument('--mode', dest='mode', type=str, default="server")
		parser.add_argument('--priv_net_addr', dest='priv_net_addr', type=str, default='')
		parser.add_argument('--tap_mtu', dest='tap_mtu', type=int, default=1500)
		# server
		parser.add_argument('--listen_addr', dest='listen_addr', default = '0.0.0.0')
		parser.add_argument('--listen_port', dest='listen_port', type=int, default= 8082)
		parser.add_argument('--tb_rate', dest='tb_rate', type=int, default= 100)
		parser.add_argument('--tb_burst', dest='tb_burst', type=int, default= 1000)
		# client
		parser.add_argument('--server_addr', dest='server_addr', default = 'localhost')
		parser.add_argument('--server_port', dest='server_port', type=int, default= 8082)
		parser.add_argument('--server_sni_hostname', dest='server_sni_hostname', default = 'tunnel-server')
		self.args = parser.parse_args()

		self.tap_mtu = self.args.tap_mtu
		if self.args.mode == 'client':
			print("**Client**")
			self.server_port = self.args.server_port
			self.server_sni_hostname = self.args.server_sni_hostname

			self.server_cert = '/root/environments/tls/certs/server.crt'
			self.client_cert = '/root/environments/tls/certs/client.crt'
			self.client_key  = '/root/environments/tls/certs/client.key'

			self.pkts_rcvd  = [0]
			self.pkts_sent = 0
		elif self.args.mode == 'server':
			print("**Server**")
			self.server_cert = '/root/environments/tls/certs/server.crt'
			self.server_key  = '/root/environments/tls/certs/server.key'
			self.client_certs_path = '/root/environments/tls/certs/'
			
			self.tb_rate = self.args.tb_rate
			self.tb_burst = self.args.tb_burst

			self.context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
			self.context.verify_mode = ssl.CERT_REQUIRED
			self.context.load_cert_chain(certfile=self.server_cert, keyfile=self.server_key)
			self.context.load_verify_locations(capath=self.client_certs_path)

			# List of active connections - dicts, with IP, port, socket object,
			# thread signal (to kill corresponding thread), and Common Name
			# example_connection = {
			#	'ip' : '10.0.0.2',
			#	'port' : 2000,
			#	'socket' : conn,
			#	'kill_signal' : False,
			#	'CN' : 'client'
			# }
			self.active_connections = []
		else:
			print("Unnown mode -- choose between client and server")


	def create_tap(self):

		# identify interface for bridging, will may take some time to be created

		def get_interface_for_ip(addr):
			mon_if_name = ''
			addrs = psutil.net_if_addrs()
			for netif in addrs:
				for iface in addrs[netif]:
					#print (str(iface.family))
					if str(iface.family) == 'AddressFamily.AF_INET':
						ip_addr = ipaddress.IPv4Network((addrs[netif][0].address, addrs[netif][0].netmask), strict=False)
						print(ip_addr.network_address)
						if self.args.priv_net_addr.split('/')[0] == str(addrs[netif][0].address):
							mon_if_name = netif
							break
			return mon_if_name

		mon_if_name = get_interface_for_ip (self.args.priv_net_addr)

		while mon_if_name == '' or mon_if_name is None:
			print("waiting for interface to be active " + self.args.priv_net_addr)
			r("/bin/sleep 2s")
			mon_if_name = get_interface_for_ip (self.args.priv_net_addr)

		# create tap
		self.tap_interface = 'tap0'

		addrs = psutil.net_if_addrs()
		if mon_if_name == '':
			print ('No interface specified')
		elif self.tap_interface not in addrs:
			print('Creating tap ' + self.tap_interface + ' for ' + mon_if_name)
			#os.system("/root/environments/tls/start-tap.sh " + mon_if_name + " 10.0.2.2/24")
			r("mkdir /dev/net")
			r("mknod /dev/net/tun c 10 200")
			r("ip tuntap add tap0 mode tap")
			r("brctl addbr br0")
			r("ip link set tap0 up")
			r("ip link set br0 up")
			r("brctl addif br0 tap0")
			r("brctl addif br0 " + mon_if_name)
			r("ip addr del " + self.args.priv_net_addr + " dev " + mon_if_name)
			r("ip addr add " + self.args.priv_net_addr + " dev br0")
		else:
			print('Tap already created')

		# Initialize a TAP interface and make it non-blocking
		self.tap = TunTapDevice(flags = IFF_TAP|IFF_NO_PI, name=self.tap_interface); self.tap.up()
		fcntl.fcntl(self.tap.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
		self.tap.mtu = self.tap_mtu


	def srvThreadTapReadFunction(tap,conn_list):
		# Check for packets in tap interface and send them to every active connection
		print("Tap thread started")
		while True:
			try:
				# +20 for ethernet headear
				packet = tap.read(tap.mtu + 20)
				# Insert first 3 bytes with 0 and 2 byte big endian int with actual size.
				l = len(packet)
				b_packet_length = l.to_bytes(2, byteorder='big')
				bb1 = bytearray(b'\x00')
				bb2 = bytearray(b_packet_length)
				bb3 = bytearray(packet)
				buf = bytes(bb1+bb2+bb3)
			except Exception as e:
				if e.args[0] == errno.EAGAIN or e.args[0] == errno.EWOULDBLOCK:
					# Not an actual error, just no data to read yet
					# (this is expected, wait some more)
					sleep(0.1)
					# If we wish to insert a "fake packet", fill 'buf'
					# Otherwise, "continue", forcing a new tap read 
					continue
				else:
					# Actual error - raise!
					print(e)
					raise

			for conn in conn_list:
				# Do not send when client is not the destination? / Apply some filtering here.
				# Decide if we should add padding to a given packet.
				if conn['kill_signal'] == False:
					try:
						conn['socket'].send(buf)
					except OSError as exc:
						print("Error while sending data to {}:{} ({})".format(conn['ip'], conn['port'], conn['CN']))
						if exc.errno == errno.EPIPE:
							print("Broken pipe. Sending kill signal...")
							conn['kill_signal'] = True


	# per client read from ssl and write into tap
	def srvThreadTapWrite(self, clientsocket, addr, clienttap, conn_list, buckets):
		print("New TCP Connection: {}:{}".format(addr[0], addr[1]))
		try:
			conn = self.context.wrap_socket(clientsocket, server_side=True)
		except Exception as e:
			print("SSL connection not established.")
			print(e)
			print("")
			return
		
		print("SSL established.")
		print("Peer: {}".format(conn.getpeercert()))
		
		new_conn = {
			'ip' : addr[0],
			'port' : addr[1],
			'socket' : conn,
			'kill_signal' : False,
			'CN' : [cn for ((n,cn),) in conn.getpeercert()['subject'] if n == 'commonName'][0]
		}

		conn_list.append(new_conn)
		conn.setblocking(0)
		while new_conn['kill_signal'] == False:
			try:
				# timestamp and add tokens to bucket
				ready = select.select([conn], [], [], 0.1)
				if ready[0]:
					data = self.get_packet_from_tls(conn)
					# data = conn.recv(clienttap.mtu)
					if data:
						if buckets.consume(new_conn['CN']):
							#print("tb OK", new_conn['CN'], buckets._storage.get_token_count(new_conn['CN']))
							# Remove padding or fake packets. First bytes 2 dictate real size.
							# Also, apply a firewall here! (decide if a packet coming
							# from the TLS tunnel should go to the network interface)
							clienttap.write(data)
						else:
							#print("tb XX", new_conn['CN'], buckets._storage.get_token_count(new_conn['CN']))
							pass

					else:
						sleep(0.05)
			except OSError as exc:
				if exc.errno == errno.ENOTCONN:
					print("Connection to {} closed by remote host.".format(addr[0]))
					break
		conn_list.remove(new_conn)

		try:
			conn.shutdown(socket.SHUT_RDWR)
			conn.close()
			print("Connection to {}:{} ({}) closed.".format(new_conn['ip'], new_conn['port'], new_conn['CN']))
		except:
			pass


	def srvThreadServerFunction(self, listen_addr, listen_port, conn_list, buckets):
		bindsocket = socket.socket()
		bindsocket.bind((listen_addr, listen_port))
		bindsocket.listen(5)

		print("Waiting for clients")
		# Wait for new connections and serve them, creating a thread for each client
		while True:
			newsocket, fromaddr = bindsocket.accept() # blocking call
			client_thread = threading.Thread(target=self.srvThreadTapWrite, args=(newsocket,fromaddr,self.tap,conn_list,buckets,))
			client_thread.daemon = True; client_thread.start()



	def srvThreadCLI(clientsocket, addr, clienttap, conn_list):
		print("Available commands: close, block, list, exit")
		while True:
			try:
				inp = input('>> ')
				if inp == "close":
					print("\nActive connections:")
					for i, connection in enumerate(active_connections):
						print("{} - {}:{} ({})".format(i, connection['ip'], connection['port'], connection['CN']))
					
					chosen_connection = input("Which connection to close? [0-{}] >> ".format(len(active_connections)-1))
					try:
						c = active_connections[int(chosen_connection)]
					except:
						pass
					else:
						confirmation = input("Terminate connection to {}:{} ({})? (Y/n) >> ".format(c['ip'], c['port'], c['CN']))
						if confirmation != "N" and confirmation != "n":
							c['kill_signal'] = True
							print("Kill signal sent.")
				
				elif inp == "block":
					print("\nActive clients:")
					cn_list = list(set([conn['CN'] for conn in active_connections]))
					for i, client in enumerate(cn_list):
						print("{} - {}".format(i, client))
					
					chosen_connection = input("Which certificate to block? [0-{}] >> ".format(len(cn_list)-1))
					try:
						chosen_cn = cn_list[int(chosen_connection)]
					except:
						pass
					else:
						confirmation = input("Terminate every connection from client [{}]? (Y/n) >> ".format(chosen_cn))
						if confirmation != "N" and confirmation != "n":
							for conn in active_connections:
								if conn['CN'] == chosen_cn:
									conn['kill_signal'] = True
									print("Kill signal sent to {}:{}.".format(conn['ip'], conn['port']))
				
				elif inp == "list":
					print("\nActive connections:")
					for i, connection in enumerate(active_connections):
						print("{} - {}:{} ({})".format(i, connection['ip'], connection['port'], connection['CN']))
					print("\nActive clients:")
					cn_list = list(set([conn['CN'] for conn in active_connections]))
					for i, client in enumerate(cn_list):
						print("{} - {}".format(i, client))
				
				elif inp == "update":
					context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
					context.verify_mode = ssl.CERT_REQUIRED
					context.load_cert_chain(certfile=server_cert, keyfile=server_key)
					context.load_verify_locations(capath=client_certs_path)
					print("Updating client certificates...")
				
				elif inp == "exit":
					print("Terminating server. Closing connections...")
					for connection in active_connections:
						connection['kill_signal'] = True
					sleep(3)
					break

			except KeyboardInterrupt as e:
				print("\nKeyboard interrupt detected. Aborting.")
				for connection in active_connections:
					connection['kill_signal'] = True
				sleep(3)
				break



	def cliThreadTapReadFunction(self, conn):
		# Check for packets in tap interface and send them to every active connection
		print("Tap thread started")
		while True:
			try:
				# +20 for ethernet headear
				packet = self.tap.read(self.tap.mtu+20)
				# Insert first 3 bytes with 0 and 2 byte big endian int with actual size.
				l = len(packet)
				b_packet_length = l.to_bytes(2, byteorder='big')
				bb1 = bytearray(b'\x00')
				bb2 = bytearray(b_packet_length)
				bb3 = bytearray(packet)
				buf = bytes(bb1+bb2+bb3)
			except Exception as e:
				if e.args[0] == errno.EAGAIN or e.args[0] == errno.EWOULDBLOCK:
					# Not an actual error, just no data to read yet
					# (this is expected, wait some more)
					sleep(0.1)
					# If we wish to insert a "fake packet", fill 'buf'
					# Otherwise, "continue", forcing a new tap read 
					continue
				else:
					# Actual error - raise!
					print(e)
					raise
			try:
				conn.send(buf)
				self.pkts_rcvd[0] = self.pkts_rcvd[0]+1
			except OSError as exc:
				print("Error while sending data".format())
				if exc.errno == errno.EPIPE:
					print("Broken pipe. Sending kill signal...")

	# assume connection is blocking
	def get_packet_from_tls(self, conn):
		# get first 3 bytes with '\x00' and 2 byte big endian int
		data = conn.recv(3)
		if data and len(data) == 3:
			check = data[0]
			if check == 0:
				packet_length = int.from_bytes(data[1:3], "big")
				packet = conn.recv(packet_length)
				return packet
			else:
				return False
		return False
				
	def cliTapWriteFunction(self, conn):
		while True:
			try:
				data = self.get_packet_from_tls(conn)
				if data:
					self.tap.write(data)
					self.pkts_sent+=1
					#print("\rPackets sent:\t{:7d} | Packets received:\t{:7d}".format(self.pkts_sent, self.pkts_rcvd[0]), end='')
			except Exception as e:
				print("Exception occurred " + str(e))
				raise
				break


	def cli_start_new_client(self):
			self.server_addr = resolve_hostname(self.args.server_addr)
			print("Connecting to TLS server at " + self.server_addr)
			context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=self.server_cert)
			context.load_cert_chain(certfile=self.client_cert, keyfile=self.client_key)
			s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			conn = context.wrap_socket(s, server_side=False, server_hostname=self.server_sni_hostname)
			conn.connect((self.server_addr, self.server_port))
			print("SSL Connection Established.")
			t = threading.Thread(target=self.cliThreadTapReadFunction, args=(conn,))
			t.daemon = True
			t.start()
			self.cliTapWriteFunction(conn)
Ejemplo n.º 15
0
class QRTun(object):
    def __init__(self, side):
        self.side = int(side)
        if self.side not in [1,2]:
            print("Side must be 1 or 2")
            raise Exception("Invalid Side")
        self.tun = TunTapDevice(flags=IFF_TUN|IFF_NO_PI, name='qrtun%d'%self.side)
        self.tun.addr = '10.0.8.%d'%(self.side)
        if self.side == 1:
            self.other_side = 2
        else:
            self.other_side = 1
        self.tun.netmask = '255.255.255.0'
        #MTU must be set low enough to fit in a single qrcode
        self.tun.mtu = 300
        self.epoll = select.epoll()
        self.epoll.register(self.tun.fileno(), select.EPOLLIN)
        self.tun.up()
        #self.outfile = 'resources/toscreen%d.png'%(self.side)
        self.outfile = None
        self.infile = 'resources/toscreen%d.png'%(self.other_side)
        self.indata = None
        self.olddata = ""
        self.outdata = ""
        self.running = False
        self.vc = cv2.VideoCapture(0)
        self.vc.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 720)
        self.vc.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 1280)
        self.scanner = zbar.ImageScanner()
        self.scanner.parse_config('enable')
        pygame.init()
        pygame.event.set_allowed(None)
        pygame.event.set_allowed([pygame.KEYDOWN, pygame.QUIT])
        self.screen = pygame.display.set_mode((SIZE, SIZE))
        self.scale = 12
        self.display_cam = False
        pygame.display.set_caption("qrtun - QR Code scale %d"%(self.scale))
    def read_tun(self):
        events = self.epoll.poll(0)
        if events:
            self.outdata = self.tun.read(self.tun.mtu)
            return True
        return False
    def write_qrcode(self):


        p = subprocess.Popen(['qrencode', '-o', '-', '-s', str(self.scale)], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        std_out, std_err = p.communicate(input=b32encode(self.outdata).replace('=', '/'))
        if std_err:
            raise Exception("qrencodeError", std_err.strip())


        self.outfile = StringIO.StringIO(std_out)
        if self.display_cam:
            cimg = StringIO.StringIO()
            self.inframe.save(cimg, 'png')
            cimg.seek(0)
            cpimg = pygame.image.load(cimg)
            self.screen.blit(cpimg, (0,0))
            pygame.display.flip()
        else:
            if self.outfile and not self.outfile.closed:
                pimg = pygame.image.load(self.outfile)
                if pimg.get_width() > self.screen.get_width() or pimg.get_height() > self.screen.get_height():
                    pygame.display.set_mode((pimg.get_width(), pimg.get_height()))
                self.screen.fill((0,0,0))
                self.screen.blit(pimg, (0,0))
                pygame.display.flip()


        self.msg_read = False
    def write_tun(self):
        try:
            if len(self.indata.get('body')) > 0:
                data = self.indata.get('body')
                if data != self.olddata:
                    self.tun.write(data)
                    #This is a hacky way to avoid dup packets...
                    #surely a better way to do this...
                    self.olddata = data
        except:
            print("Failed to write to tun!")
    def read_qrcode(self):
        p = subprocess.Popen(['zbarimg', '-q', '--raw', 'PNG:-'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        temp_png = StringIO.StringIO()
        self.inframe.save(temp_png, 'png')
        std_out, std_err = p.communicate(input=temp_png.getvalue())
        if len(std_out) == 0:
            return False

        if std_err:
            raise Exception("zbarimg", std_err.strip())
        #p = subprocess.Popen(['iconv', '-f', 'UTF-8', '-t', 'ISO-8859-1'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        #std_out, std_err = p.communicate(input=std_out)
        #if std_err:
        #    raise Exception("iconv", std_err.strip())
        try:
            self.indata = {'body': b32decode(std_out.rstrip().replace('/', '='))}
            self.write_tun()
        except:
            pass


    def read_cam(self):
        rval, frame = self.vc.read()
        if not rval:
            return False
        self.inframe = scipy.misc.toimage(frame).convert('L')
        print "CAM"
        return True
    def run(self):
        self.running = True
        while self.running:
            if self.read_tun() or self.display_cam:
                self.write_qrcode()
            
            if not self.read_cam():
                running = False
                break
            
            self.read_qrcode()

               

            event = pygame.event.poll()
            if event.type == pygame.QUIT:
                self.running = False
                pygame.quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.running = False 
                    pygame.quit()
                elif event.key == pygame.K_UP:
                    self.scale += 1
                    pygame.display.set_caption("qrtun - QR Code scale %d"%(self.scale))
                    self.write_qrcode()
                elif event.key == pygame.K_DOWN:
                    self.scale -= 1
                    pygame.display.set_caption("qrtun - QR Code scale %d"%(self.scale))
                    self.write_qrcode()
                elif event.key == pygame.K_SPACE:
                    self.display_cam = not self.display_cam
                    self.write_qrcode()
 
        try:
            #os.unlink(self.outfile)
            os.unlink(self.infile)
        except:
            pass
Ejemplo n.º 16
0
class QRTun(object):
    def __init__(self, side):
        self.side = int(side)
        if self.side not in [1, 2]:
            print("Side must be 1 or 2")
            raise Exception("Invalid Side")
        self.tun = TunTapDevice(flags=IFF_TUN | IFF_NO_PI,
                                name='qrtun%d' % self.side)
        self.tun.addr = '10.0.8.%d' % (self.side)
        if self.side == 1:
            self.other_side = 2
        else:
            self.other_side = 1
        self.tun.netmask = '255.255.255.0'
        #MTU must be set low enough to fit in a single qrcode
        self.tun.mtu = 500
        self.epoll = select.epoll()
        self.epoll.register(self.tun.fileno(), select.EPOLLIN)
        self.tun.up()
        self.outfile = 'resources/toscreen%d.png' % (self.side)
        self.infile = 'resources/toscreen%d.png' % (self.other_side)
        self.indata = None
        self.olddata = ""
        self.outdata = ""
        self.running = False
        self.qr = qrtools.QR()
        self.vc = cv2.VideoCapture(0)
        self.vc.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 720)
        self.vc.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 1280)

    def read_tun(self):
        events = self.epoll.poll(0)
        if events:
            self.outdata = self.tun.read(self.tun.mtu)
            return True
        return False

    def write_qrcode(self):

        #Base32 encode since alphanumeic qr code only allows A-Z, 0-9 and some
        # symbols, but base64 uses lowercase as well....
        body = base64.b32encode(self.outdata).replace('=', '/')
        qr = qrtools.QR()
        qrb = qrtools.QR()
        qrb.data = "  "
        qr.data = body

        #Had an issue where decoded data did not match encoded data...
        #So I just add plus symbols as padding until they match, then strip
        # on the other side....
        while qr.data != qrb.data:
            qr.pixel_size = 12
            qr.encode(self.outfile)

            qrb.decode(self.outfile)
            if qrb.data != qr.data:
                print("EncodingFailure", qr.data)
                qr.data += '+'

        self.msg_read = False

    def write_tun(self):
        try:
            if len(self.indata.get('body')) > 0:
                data = self.indata.get('body')
                if data != self.olddata:
                    self.tun.write(data)
                    #This is a hacky way to avoid dup packets...
                    #surely a better way to do this...
                    self.olddata = data
        except:
            print("Failed to write to tun!")

    def read_qrcode(self):
        qr = qrtools.QR()
        try:
            if not qr.decode(self.infile):
                return False

            body = base64.b32decode(qr.data.replace('/', '=').replace('+', ''))
            self.indata = {'body': body}
            self.write_tun()
        except:
            pass

    def run(self):
        self.running = True
        while self.running:
            if self.read_tun():
                self.write_qrcode()

            rval, frame = self.vc.read()
            if not rval:
                running = False
                break
            scipy.misc.toimage(frame).save(self.infile)
            self.read_qrcode()

            if os.path.isfile(self.outfile):
                sprite = factory.from_image(self.outfile)
                spriterenderer.render(sprite)

            event = SDL_Event()
            while SDL_PollEvent(ctypes.byref(event)) != 0:
                if event.type == SDL_QUIT:
                    self.running = False
                    break
                elif event.type == SDL_KEYDOWN and event.key.keysym.sym == SDLK_ESCAPE:
                    self.running = False
                    break

        try:
            os.unlink(self.outfile)
            os.unlink(self.infile)
        except:
            pass