class Tun():
    """
	Initializes the tun device
	"""
    def __init__(self, name, address, netmask, mtu):
        self.name = name
        self.tun = TunTapDevice(self.name)
        self.tun.addr = address
        self.tun.netmask = netmask
        self.tun.mtu = mtu
        self.tun.up()

    """
	Reads data from device
	"""

    def read(self, nbytes):
        return self.tun.read(nbytes + PSEUDO_HEADER_SIZE)

    """
	Writes buffer to device
	"""

    def write(self, buf):
        return self.tun.write(buf)
Beispiel #2
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"
Beispiel #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 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()
Beispiel #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 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()
Beispiel #5
0
class TapNode(object):
    def __init__(self):
        os.system('sudo ip tuntap add dev esp32 mode tap user ds')
        time.sleep(1)
        self.tap = TunTapDevice(name='esp32', flags=IFF_TAP)

    def write(self, pkt):
        self.tap.write('\x00\x00\x00\x00' + pkt)
        print 'Wrote %d WIFI bytes to host' % len(pkt)
        #hexdump.hexdump(pkt)
    def read(self):
        data = self.tap.read(2000)[4:]
        print 'Read %d bytes from TAP interface' % len(data)
        return (PktType.WIFI, data)
class backend:
    def __init__(self):
        self.tun = TunTapDevice(name='strangenet',
                                flags=pytun.IFF_TUN | pytun.IFF_NO_PI)
        logging.debug('Created Linux tun device ' + self.tun.name)
        self.tun.addr = os.getenv('STRANGENET_IP', '10.0.0.1')
        logging.info('Assigned Linux tun device IP: ' + self.tun.addr)
        self.tun.netmask = os.getenv('STRANGENET_NETMASK', '255.255.255.0')
        logging.info('Configured Linux tun device netmask: ' +
                     self.tun.netmask)
        self.tun.persist(
            True)  # TODO figure out what this does and if we need it
        self.tun.mtu = 256
        self.tun.up()
        logging.info('Linux tun device is up!')

        # setup polling

        self.poller = select.poll()
        self.poller.register(self.tun, select.POLLIN)

    def set_mtu(self, mtu):
        self.tun.mtu = mtu

    # called by main code when data is recieved from XBee
    def tx(self, payload):
        logging.info('Writing payload')
        print(payload)
        self.tun.write(payload)

    def poll(self, timeout):
        logging.debug('Checking for packets on TUN...')

        events = self.poller.poll(timeout)
        if events:  # lists are true iff. they are non-empty
            # FIXME properly read the (fd, event) tuple, iterate list
            logging.debug("Select poller reports TUN is readable...")
            data = self.tun.read(self.tun.mtu)
            logging.debug("Incoming packets on TUN...")
            #sys.stdout.buffer.write(data)
            pack = ip.IP(data)
            return {"IP": pack.dst, "payload": data}
        else:
            logging.debug("No packets from TUN.")
            return None

    def phy_noroute(self, invalidip, datastart):
        pass
Beispiel #7
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()
Beispiel #8
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()
Beispiel #9
0
class TunTap(object):
    def __init__(self, name, ip, netmask):
        self.tun = TunTapDevice(name=name,
                                flags=pytun.IFF_TUN | pytun.IFF_NO_PI)
        self.tun.addr = ip
        self.tun.netmask = netmask
        self.mtu = 1500
        # self.tun.persist(True)
        self.tun.up()

    def getfd(self):
        return self.tun

    def recv(self):
        return self.tun.read(self.mtu)

    def send(self, buf):
        self.tun.write(buf)
Beispiel #10
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"
Beispiel #11
0
    def run(self):
        """
        Method called when starting the daemon. 
        """
        try:
            logger.info("TapDaemon has started")
            tap0 = TunTapDevice(name="tap0", flags=IFF_TAP)
            tap0.hwaddr = '\x00\x11\x22\x33\x44\x55'
            tap0.addr = '192.168.0.1'
            tap0.dstaddr = '192.168.0.2'
            tap0.netmask = '255.255.255.0'
            tap0.mtu = 1500
            tap0.persist(True)
            tap0.up()
            logger.info("tap0 interface created")
        except:
            logger.exception("exception: ")
            
        try:
            tap1 = TunTapDevice(name="tap1", flags=IFF_TAP)
            tap1.hwaddr = '\x00\x11\x22\x33\x44\x66'
            tap1.addr = '192.168.1.1'
            tap1.dstaddr = '192.168.1.2'
            tap1.netmask = '255.255.255.0'
            tap1.mtu = 1500
            tap1.persist(True)
            tap1.up()
            logger.info("tap1 interface created")
        except:
            logger.exception("exception: ")
            
        try:
            while True:
                time.sleep(2)
                frame = Ethernet(dst="\x01\x02\x03\x04\x05\x06", src="\x0A\x0B\x0C\x0D\x0E\x0F", type = 0x9100, data = "\x02\x55\x44\x00\x11\x00\x00\x00\x33\x22\x00\x00" + "\x61"*40) # "\x11\x00\x00\x00\x33\x22\x00\x00" #"\x00\x03\x08\x00"
                tap0.write("\x11\x22\x33\x44" + str(frame)) 
                logger.info("Frame send to tap0")

                logger.info("Waiting for frame in tap1...")
                buf = tap1.read(tap1.mtu)
                logger.info("Received %s", hexlify(buf))
                logger.info("\n\n ---------------------------------------------------")
        except:
            logger.exception("exception: ")
Beispiel #12
0
def start_main(rec, loc, dst, passwd,ifname):
    tunnel = WhatsAppMessageTunnel()
    # Create TUN device for network capture and injections
    tun = TunTapDevice(name='socialtun')

    print(tun.name + ' has been created, information follows:')

    tun.addr = loc
    tun.dstaddr = dst
    tun.netmask = '255.255.255.0'
    tun.mtu = 40000
    password = passwd

    print('Address: ' + tun.addr)
    print('Dest.-Address: ' + tun.dstaddr)
    print('Netmask: ' + tun.netmask)
    print('MTU: ' + str(tun.mtu))


    # Start TUN device
    tun.up()
    up = True

    print('TUN is up')


    # Create the receive thread via our helper method
    # thread = threading.Thread(target=main_loop_starter)
    thread = threading.Thread(target=recv_loop, args=(tunnel, rec, password, tun))
    thread.start()
    thread = threading.Thread(target=ping_server, args=(loc,))
    thread.start()
    while True:
        # Continually read from the tunnel and write data in base64
        buf = tun.read(tun.mtu)
        rc4obj = ARC4.new(password)
        tunnel.send(rec+"@s.whatsapp.net", base64.b64encode(rc4obj.encrypt(buf)))
        #print (buf)

    # Cleanup and stop application
    up = False
    tun.down()
    receiver.stop()
Beispiel #13
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-s', '--source-addr', default='10.8.0.1')
    parser.add_argument('-d', '--dest-addr', default='10.8.0.2')
    parser.add_argument('-m', '--netmask', default='255.255.255.0')
    parser.add_argument('-l', '--mtu', default=1500, type=int)
    args = parser.parse_args()

    tun = TunTapDevice()
    try:
        tun.addr = args.source_addr
        tun.dstaddr = args.dest_addr
        tun.netmask = args.netmask
        tun.mtu = args.mtu
        while True:
            buf = tun.read(tun.mtu)
            print(buf)
            tun.write(buf)
    finally:
        tun.close()
Beispiel #14
0
import hexdump
from pytun import TunTapDevice, IFF_TAP

tun = TunTapDevice(name='rfc6214')

with open("captured_in.hex", "r") as the_file:
    hex = the_file.readline()

buf = hexdump.dehex(hex)

tun.write(buf)

buf = tun.read(tun.mtu)
hex = hexdump.dump(buf, 2, '')

print(hex)

with open('captured_out.hex', 'w') as the_file:
    the_file.write(hex)
Beispiel #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 = 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
Beispiel #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 = 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
Beispiel #17
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)
Beispiel #18
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
Beispiel #19
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
Beispiel #20
0
def main():
    global sent, received, up, tun, encrypted, args

    # Process arguments
    parser = argparse.ArgumentParser(description='Teletun - IP over Telegram')
    parser.add_argument('peer_id', help='peer id (list for contact list)')
    parser.add_argument('-r', '--server', help='server', action='store_true')
    parser.add_argument('-e',
                        '--encrypted',
                        help='secret chat',
                        action='store_true')
    parser.add_argument('-p', '--src', help='peer address', default='10.8.0.2')
    parser.add_argument('-s',
                        '--dst',
                        help='server address',
                        default='10.8.0.1')
    parser.add_argument('-m', '--mask', help='mask', default='255.255.255.0')
    parser.add_argument('-n', '--mtu', help='MTU', default=1500)
    parser.add_argument('-H',
                        '--host',
                        help='Telegram host address',
                        default='localhost')
    parser.add_argument('-P', '--port', help='Telegram port', default=4458)
    parser.add_argument('-a',
                        '--auto',
                        help='autoconfig from server',
                        action='store_true')
    args = parser.parse_args()
    peer_id = None

    # Connect to telegram
    print('Connecting to Telegram...', file=sys.stderr)
    receiver = Receiver(host=args.host, port=args.port)
    sender = Sender(host=args.host, port=args.port)

    # Retrieve contact list

    try:
        contacts = [c for c in sender.dialog_list()]
        for i, user in enumerate(contacts):
            if args.peer_id == 'list':
                print('{:16s} {}'.format(str(user['peer_id']),
                                         str(user['print_name'])))
            elif str(user['peer_id']) == args.peer_id:
                peer_id = args.peer_id
                username = str(user['print_name'])
        if args.peer_id == 'list':
            sys.exit(0)
    except ConnectionError:
        print(
            'Could not connect to telegram-cli. Start it by issuing "telegram-cli --json -P 4458" in a separate console.',
            file=sys.stderr)
        sys.exit(1)

    if peer_id is None:
        print('Could not find peer_id in contact list.', file=sys.stderr)
        sys.exit(1)

    print('Connecting to partner: ' + username, file=sys.stderr)

    # Helper function that can be executed in a thread
    def main_loop_starter():
        receiver.start()
        # Start the receive loop
        receiver.message(main_loop())

    @coroutine
    def main_loop():
        global args, received, tun, encrypted
        while up:
            # Receive message from telegram, this includes ALL messages
            msg = (yield)
            # Check if it is an actual "message" message and if the sender is our peer
            if (msg is not None and msg.event == str('message') and not msg.own
                    and str(msg.sender.peer_id) == peer_id):
                print('Msg: ' + msg.text, file=sys.stderr)
                if msg.text[0] == '-' and msg.text[1] == '-':
                    if args.server:
                        if msg.text == '--encrypted':
                            print('Requested encyption for: ' + username,
                                  file=sys.stderr)
                            try:
                                sender.create_secret_chat(username)
                            except Exception:
                                pass
                            encrypted = True
                        elif msg.text == '--server':
                            command_line = '--src={} --dst={} --mask={} --mtu={:d}'.format(
                                args.src, args.dst, args.mask, args.mtu)
                            print('Requested encyption for: ' + command_line,
                                  file=sys.stderr)
                            print('Sending configuration:' + command_line,
                                  file=sys.stderr)
                            sender.msg(username, str(command_line))
                    else:
                        print('Receiving configuration:' + data,
                              file=sys.stderr)
                        args = parser.parse_args(sys.argv + data.split())
                        tun.down()
                        setup_tun()
                        tun.up()
                else:
                    # Decode data and write it to the tunnel
                    data = base64.b64decode(msg.text)
                    received += len(data)
                    tun.write(data)
                    #print('Packet written', file=sys.stderr)

    def setup_tun():
        if args.server:
            tun.addr = args.dst
            tun.dstaddr = args.src
        else:
            tun.addr = args.src + ' '
            tun.dstaddr = args.dst

        tun.netmask = args.mask
        tun.mtu = args.mtu

        print('\tSrc:  ' + tun.addr, file=sys.stderr)
        print('\tDst:  ' + tun.dstaddr, file=sys.stderr)
        print('\tMask: ' + tun.netmask, file=sys.stderr)
        print('\tMTU:  ' + str(tun.mtu), file=sys.stderr)

# Create TUN device for network capture and injections

    tun = TunTapDevice(name='teletun')

    print('Device ' + tun.name + ' has been created, information follows:',
          file=sys.stderr)

    if args.server or not args.auto:
        # Set IP address based on --server header
        setup_tun()

# Start TUN device
    tun.up()
    up = True

    print('Device ' + tun.name + ' is up.', file=sys.stderr)

    if not args.server and args.encrypted:
        print('Requesting encyption for: ' + username, file=sys.stderr)
        sender.msg(username, '--encrypted')
        time.sleep(3)

# Create the receive thread via our helper method
    thread = threading.Thread(target=main_loop_starter)

    # Start the thread for receiving
    print('Connecting...', file=sys.stderr)
    thread.start()

    if not args.server and args.auto:
        print('Waiting for configuration...', file=sys.stderr)
        command_line = '--server'
        sender.msg(username, str(command_line))

    while up:
        # Continually read from the tunnel and write data to telegram in base64
        # TODO: Telegram supports str, base64 can probably be replaced for something less overhead-inducing
        buf = tun.read(tun.mtu)
        data = base64.b64encode(buf)
        data = ''.join(map(chr, data))
        sent += len(data)
        if (not args.server and args.encrypted) or encrypted:
            sender.msg('!_' + username, data)
        elif not args.encrypted:
            sender.msg(username, data)


# Cleanup and stop application
    up = False
    tun.down()
    receiver.stop()

    print('Bytes sent via Telegram: ' + str(sent), file=sys.stderr)
    print('Bytes received via Telegram: ' + str(received), file=sys.stderr)
    print('Done.', file=sys.stderr)

    # Literally Overkill
    current_process = psutil.Process()
    os.kill(current_process.pid, signal.SIGKILL)
Beispiel #21
0
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()
            respacket.show()

    time.sleep(0.01)
Beispiel #22
0
    return (~cksum) & 0xFFFF


def shortToBytes(short):
    high = (short & 0xff00) >> 8
    low = (short & 0x00ff)
    return chr(high) + chr(low)

if __name__ == '__main__':
    tap = TunTapDevice(name='ipsec-tap', flags=IFF_TAP)
    tap.up()
    tap.persist(True)

    while True:
        try:
            buf = tap.read(tap.mtu)
            print 'old', hexlify(buf)
            # Valeri @ studentpub
            new_addr = struct.pack('4B', 192, 168, 10, 174)
            new_buf = buf[:34] + new_addr + buf[38:]
            ip_header = new_buf[18:38]
            checksum = ip_checksum([format(ord(c), "x")
                                    for c in ip_header], 20)

            print hex(checksum)
            final_buf = new_buf[:28] + shortToBytes(checksum) + new_buf[30:]
            print 'new', hexlify(final_buf)
            print
            tap.write(final_buf)
            # TODO encrypt buf
            # TODO send to wlan0
Beispiel #23
0
    sys.exit(ERROR)

print('TAP device UP')
try:
    tap.up()
    #    tun.up()
    print('Success')
except:
    print('TAP up failure')
    sys.exit(ERROR)

packetnumber = 0

try:
    while (True):
        raw_packet = tap.read(tap.mtu)  # buf = tun.read(tun.mtu)
        eth_frame = eth.Ethernet_Frame(raw_packet)
        print(str(eth_frame))

        if f.ETHER_TYPE[eth_frame.eth_type.hex()] == 'ARP':
            arp_packet = arp.ARP_packet(eth_frame.data)
            print(str(arp_packet))

            if f.OP[arp_packet.op.hex()] == 'ARP_request':
                if arp_packet.conv_reply_packet():
                    eth_frame.src_mac_addr = arp_packet.sender_mac_addr
                    eth_frame.dst_mac_addr = arp_packet.target_mac_addr
                    eth_frame.data = arp_packet.packet
                    print(str(arp_packet))

                tap.write(eth_frame.frame)
Beispiel #24
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