def initialize_vic(): # Read config file and get parameters. log.info ("Reading vic config from "+ DEFAULT_CONFIG_FILE) f = open(DEFAULT_CONFIG_FILE, "r") vic_config = yaml.load(f) f.close() # Configure each vic vic_id = 0 taps = {} for vic in vic_config: log.info ("Configuring vic id: "+ str(vic_id)) ip = vic['ip'] log.info("vic_ip: "+ ip) mac = vic['mac'] log.info("vic_mac: "+ mac) # Create virtual interface tap = TunTapDevice(name="vic-"+str(vic_id), flags=IFF_TAP) tap.hwaddr = '\x00\x11\x22\x33\x44\x55' tap.addr = ip tap.mtu = 1500 tap.up() log.info("Tap device {0} is up with mac: {1}".format("vic-"+str(vic_id), binascii.hexlify(tap.hwaddr))) taps[ip] = tap tap_list = [] for ip in taps.keys(): tap_list.append(taps[ip]) log.info("Waiting for packets on vics...") while True: handle_packets(tap_list)
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"
class MainHandler(websocket.WebSocketHandler): def __init__(self, *args, **kwargs): super(MainHandler, self).__init__(*args,**kwargs) self.thread = None def open(self): self.set_nodelay(True) self.tun = TunTapDevice(flags= (IFF_TAP | IFF_NO_PI)) self.tun.addr = '192.168.1.1' self.tun.dstaddr = '192.168.1.2' self.tun.netmask = '255.255.255.0' self.tun.mtu = 1500 self.tun.up() self.thread = TunThread(tun=self.tun, socket = self) self.thread.start() def on_message(self, message): print('wrote %s byte message to %s' % (len(message), self.tun.name)) print(':'.join('{0:x}'.format(ord(c)) for c in message)) self.tun.write(message) def on_close(self): print('Closing %s' % self.tun.name) self.tun.close() if self.thread is not None: self.thread.running = False
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)
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()
def main(): global tap, my_mac, my_ip, server if len(sys.argv) != 3: print("Usage: %s url password" % sys.argv[0]) sys.exit(1) server = sys.argv[1] password = sys.argv[2] while server.endswith('/'): server = server[:-1] session = requests.Session() if os.path.exists("/tmp/tap0cache"): with open("/tmp/tap0cache", "rb") as f: data = f.read(10) my_mac = data[:6] my_ip = data[6:10] else: ans = session.post(server + '/connect', password) res = ans.content if ans.status_code != 200: raise ValueError("Failed to connect: " + str(res)) my_mac = res[:6] my_ip = res[6:10] with open("/tmp/tap0cache", "wb") as f: f.write(res) tap = TunTapDevice(flags=IFF_TAP) tap.addr = ".".join(map(str, my_ip)) print("My ip is:", tap.addr) tap.netmask = '255.255.0.0' tap.mtu = 1300 tap.hwaddr = my_mac tap.up() tap_reader = threading.Thread(target=read_data, daemon=True) tap_reader.start() sender = threading.Thread(target=send_data, daemon=True) sender.start() while True: ans = session.post(server + '/recv', my_mac) if ans.status_code == 204: continue if ans.status_code == 403: os.remove("/tmp/tap0cache") if ans.status_code != 200: print("recv: received status code " + str(ans.status_code) + ": " + ans.text) sys.exit(1) def process_packet(data): packet_mac = get_mac(data) if packet_mac == my_mac or packet_mac == BROADCAST: tap.write(data) parse_packets(BytesIO(ans.content), process_packet)
def setup_devs(name, if_idx): tap = TunTapDevice(name="{}-tap{}".format(name, if_idx), flags=IFF_TAP | IFF_NO_PI) tap.up() sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW) sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 33554432) sock.bind(("{}-eth{}".format(name, if_idx), socket.SOCK_RAW)) return tap, sock
class VPNClient(): def __init__(self, tkns): self.clients = [] self.iface = TunTapDevice(flags=IFF_TAP | IFF_NO_PI, name=iface) if addr is not None and netmask is not None: self.iface.addr = addr if addr is not None and netmask is not None: self.iface.netmask = netmask self.iface.hwaddr = macaddr self.iface.mtu = mtu self.iface.persist(True) self.iface.up() self.loop = asyncio.get_event_loop() os.system(ifup) self.ifacethread = IFaceThread(self.iface) self.ifacethread.start() if not sys.platform == 'win32': self.loop.add_signal_handler(signal.SIGINT, lambda: self.loop.stop()) self.loop.add_signal_handler(signal.SIGTERM, lambda: self.loop.stop()) i = 0 for tkn in tkns: c = VPNBot(self, self.ifacethread, i) i += 1 future = asyncio.ensure_future(c.start(tkn), loop=self.loop) future.add_done_callback(lambda f: self.loop.stop()) self.clients.append(c) self.loop.call_later(.1, self.poll_thread) print("Tap interface started") print( f"VARS: MTU{mtu}, ADDR{addr}, HWADDR{macaddr}, DSCVPN{TUNVER} - {len(tkns)} clients" ) try: self.loop.run_forever() except KeyboardInterrupt: print('Received signal to terminate bot and event loop.') finally: self.loop = asyncio.get_event_loop() for x in self.clients: asyncio.ensure_future(x.close(), loop=self.loop) self.loop.run_forever() self.ifacethread.stop() def is_mine(self, user): for x in self.clients: if x.user == user: return True return False def poll_thread(self): for c in self.clients: asyncio.ensure_future(c.send_pkts(), loop=self.loop) self.loop.call_later(.1, self.poll_thread)
def setup_tap(addr,netmask): tap = TunTapDevice(flags=IFF_TAP) #tap = TapTunnel() print tap.name tap.addr = addr #tun.dstaddr = '10.8.0.2' tap.netmask = netmask tap.mtu = 1500 print tap #tap.persist(True) tap.up() return tap
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()
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
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()
def main(): global tap, password if len(sys.argv) != 2: print("Usage: %s password" % sys.argv[0]) sys.exit(1) password = sys.argv[1] tap = TunTapDevice(flags=IFF_TAP) tap.addr = ".".join(map(str, IP_PREFIX + (0, 1))) tap.netmask = '255.255.0.0' tap.mtu = 1300 tap.hwaddr = MYMAC tap.up() tap_reader = threading.Thread(target=read_data, daemon=True) tap_reader.start() print('Serving on 8088...') WSGIServer(application, port=8088, numthreads=1000).start()
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()
class TunTap(object): def __init__(self): self.tun = TunTapDevice(name="fhdi") self.cs = Lock() def open(self): self.tun.addr = '172.16.0.1' self.tun.netmask = '255.255.255.0' self.tun.mtu = 1500 self.tun.up() def close(self): self.tun.close() def write(self, buf): self.cs.acquire() self.tun.write(buf) self.cs.release()
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)
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"
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: ")
def opened(self): cherrypy.log("YMK in TunWebSocketHandler opened") if TunWebSocketHandler.tun is None: cherrypy.log("YMK in TunWebSocketHandler new tun") tun = TunTapDevice(flags=IFF_TUN | IFF_NO_PI) tun.addr = g.config.get('server', 'ip') # tun.dstaddr = '10.10.0.2' tun.netmask = g.config.get('server', 'netmask') tun.mtu = int(g.config.get('server', 'mtu')) tun.up() TunWebSocketHandler.tun = tun if TunWebSocketHandler.thread is None: cherrypy.log("YMK in TunWebSocketHandler new thread") TunWebSocketHandler.thread = Thread(target=self.background_send) TunWebSocketHandler.thread.daemon = True TunWebSocketHandler.thread.start() TunWebSocketHandler.thread_counter += 1
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()
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
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)
def __create_tun(self, ip_sec): tun = TunTapDevice(name='SYNC' + ip_sec) tun.addr = self.__ip_prefix + ip_sec tun.netmask = '255.255.255.0' tun.persist(True) tun.up()
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
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
import pytun from pytun import TunTapDevice try: import uvloop except ImportError: uvloop = None COUNT = 0 tun = TunTapDevice(name="mytun_serv", flags=pytun.IFF_TUN | pytun.IFF_NO_PI) tun.addr = "10.10.10.2" tun.dstaddr = "10.10.10.1" tun.netmask = "255.255.255.0" tun.mtu = 1048 tun.persist(True) tun.up() STREAM_ID = 100 class VPNServerProtocol(QuicConnectionProtocol): # -00 specifies 'dq', 'doq', and 'doq-h00' (the latter obviously tying to # the version of the draft it matches). This is confusing, so we'll just # support them all, until future drafts define conflicting behaviour. SUPPORTED_ALPNS = ["dq", "doq", "doq-h00"] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._vpn = None def tun_read(self):
# 'port' : 2000, # '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,
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
class VPN: def run(self, tokens): self.loop = asyncio.get_event_loop() self.tokens = tokens self.clients = [] self.channels = [] self.session = None self.ready = False async def runner(): try: await self.start() except: pass loop = asyncio.get_event_loop() future = asyncio.ensure_future(runner(), loop=loop) try: loop.run_forever() except: return async def receive(self, message): try: if (len(message.attachments) == 1): async with aiohttp.ClientSession() as session: async with session.get( message.attachments[0].url) as response: d = await response.read() self.ifacethread.recv_batch(d) elif len(message.content) > 0: self.ifacethread.recv_batch(b64decode(message.content)) except Exception as e: print(e) traceback.print_exc() def send_pkts(self): asyncio.ensure_future(self._send_pkts(), loop=self.loop) async def _send_pkts(self): while not self.ready: # Wait for initialization to finish await asyncio.sleep(1) continue if len(self.ifacethread.batches) > 0: b = await self.ifacethread.get_batch() pkts, cln = b if debug: print(f" batch {cln} | {len(pkts)} (LB:{time()-self.lastsend}") self.lastsend = time() channel = choice(self.channels) if cln < 1480: pktxt = b64encode(b''.join(pkts)).decode("utf-8") asyncio.ensure_future(channel.send(pktxt), loop=self.loop) else: fd = BytesIO() fc = 0 for q in pkts: if debug: print(f" send {len(q)} | {fc}") fd.write(q) asyncio.ensure_future(channel.send( file=discord.File(BytesIO(fd.getvalue()), "d")), loop=self.loop) self.loop.call_later(1.5, self.send_pkts) else: self.loop.call_later(0.3, self.send_pkts) async def start(self): print('Starting...') print(f'Creating {len(self.tokens)} clients') for client in range(len(self.tokens)): print(f'Creating client #{client}') self.clients.append(VPNBot(self, client)) # Set the first client as the receiver self.clients[0].receiver = True for client, token in enumerate(self.tokens): print(f'Starting client #{client} with token {token}') self.loop.create_task(self.clients[client].start(token)) self.session = aiohttp.ClientSession() self.iface = TunTapDevice(flags=IFF_TAP | IFF_NO_PI, name=iface) if addr is not None and netmask is not None: self.iface.addr = addr if addr is not None and netmask is not None: self.iface.netmask = netmask self.iface.hwaddr = macaddr self.iface.mtu = mtu self.iface.persist(True) self.iface.up() os.system(ifup) self.ifacethread = IFaceThread(self.iface) self.ifacethread.start() self.lastsend = time() print("Tap interface started") print(f"VARS: MTU{mtu}, ADDR{addr}, HWADDR{macaddr}") self.loop.call_later(.1, self.send_pkts) while any(client.ready == False for client in self.clients): # Wait for all clients to come up await asyncio.sleep(1) continue self.channels = [ client.get_channel(ispchan) for client in self.clients ] self.ready = True
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)
from chips.api.api import Component, Chip, Input, Output, Stimulus, Response from chips.compiler.exceptions import C2CHIPError from demo.rundemo import build_xst, compile_user_design, download_digilent from pytun import TunTapDevice, IFF_TAP, IFF_NO_PI import sys import os import select tap = TunTapDevice(flags=IFF_TAP|IFF_NO_PI, name="tap0") tap.addr = '192.168.1.0' tap.netmask = '255.255.255.0' tap.mtu = 1500 tap.up() class ConsoleOut(Output): def __init__(self, chip, name): Output.__init__(self, chip, name) def data_sink(self, data): sys.stdout.write(chr(data)) sys.stdout.flush() class Leds(Output): def __init__(self, chip, name): Output.__init__(self, chip, name) def data_sink(self, data): print "leds:", bin(data) class NetworkOut(Output): def __init__(self, chip, name): Output.__init__(self, chip, name) self.packet_len=0
class TUN(object): """TUN device""" def __init__(self, tun_dev, tun_addr, tun_remote_addr, tun_nm, tun_mtu, wsfactory): self.tun_dev = tun_dev self.tun_addr = tun_addr self.addr = tun_addr # used by mtcrypt self.tun_nm = tun_nm self.tun_mtu = int(tun_mtu) self.wsfactory = wsfactory if BSD == True: try: self.tunfd = os.open("/dev/"+tun_dev, os.O_RDWR) call(["/sbin/ifconfig", tun_dev, tun_addr, tun_remote_addr, "up"]) except: log.msg("Error opening TUN device. In use? Permissions?", logLevel=logging.WARN) sys.exit(ERR) reactor.addReader(self) logstr = ("Opened TUN device on %s") % (self.tun_dev) log.msg(logstr, logLevel=logging.INFO) elif LINUX == True: try: self.tun = TunTapDevice(name=tun_dev, flags=(IFF_TUN|IFF_NO_PI)) except: log.msg("Error opening TUN device. In use? Permissions?", logLevel=logging.WARN) sys.exit(ERR) 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) elif WINDOWS == True: self.overlappedTx = pywintypes.OVERLAPPED() self.overlappedTx.hEvent = win32event.CreateEvent(None, 0, 0, None) addr_tmp = self.tun_addr.split('.') self.tun_ipv4_address = list() for i in range(0, 4): self.tun_ipv4_address.append(int(addr_tmp[i])) nm_tmp = self.tun_nm.split('.') self.tun_ipv4_netmask = list() self.tun_ipv4_network = list() for i in range(0, 4): self.tun_ipv4_netmask.append(int(nm_tmp[i])) self.tun_ipv4_network.append(int(addr_tmp[i]) & int(nm_tmp[i])) self.TAP_IOCTL_CONFIG_POINT_TO_POINT = self.TAP_CONTROL_CODE(5, 0) self.TAP_IOCTL_SET_MEDIA_STATUS = self.TAP_CONTROL_CODE(6, 0) self.TAP_IOCTL_CONFIG_TUN = self.TAP_CONTROL_CODE(10, 0) try: self.tun_handle = self.openTunTap() except: log.msg("Could not open TUN device. Permissions?", logLevel=logging.WARN) sys.exit(ERR) log.msg("Opened TUN device", logLevel=logging.INFO) self.tunRead = TunRead(self.tun_handle, self.wsfactory) self.tunRead.start() if WINDOWS == True: def doWrite(self, data): win32file.WriteFile(self.tun_handle, data, self.overlappedTx) win32event.WaitForSingleObject(self.overlappedTx.hEvent, win32event.INFINITE) self.overlappedTx.Offset = self.overlappedTx.Offset + len(data) def openTunTap(self): guid = self.get_device_guid() tun_handle = win32file.CreateFile( r'\\.\Global\%s.tap' % guid, win32file.GENERIC_READ | win32file.GENERIC_WRITE, win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE, None, win32file.OPEN_EXISTING, win32file.FILE_ATTRIBUTE_SYSTEM|win32file.FILE_FLAG_OVERLAPPED, None) win32file.DeviceIoControl(tun_handle, self.TAP_IOCTL_SET_MEDIA_STATUS, '\x01\x00\x00\x00', None) configTunParam = [] configTunParam += self.tun_ipv4_address configTunParam += self.tun_ipv4_network configTunParam += self.tun_ipv4_netmask configTunParam = ''.join([chr(b) for b in configTunParam]) win32file.DeviceIoControl( tun_handle, self.TAP_IOCTL_CONFIG_TUN, configTunParam, None) return tun_handle def get_device_guid(self): ADAPTER_KEY = r'SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}' TUNTAP_COMPONENT_ID = 'tap0901' with reg.OpenKey(reg.HKEY_LOCAL_MACHINE, ADAPTER_KEY) as adapters: try: for i in range(10000): key_name = reg.EnumKey(adapters, i) with reg.OpenKey(adapters, key_name) as adapter: try: component_id = reg.QueryValueEx(adapter, 'ComponentId')[0] if component_id == TUNTAP_COMPONENT_ID: return reg.QueryValueEx(adapter, 'NetCfgInstanceId')[0] except WindowsError, err: pass except WindowsError, err: pass def CTL_CODE(self, device_type, function, method, access): return (device_type << 16) | (access << 14) | (function << 2) | method; def TAP_CONTROL_CODE(self, request, method): return self.CTL_CODE(34, request, method, 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
def setUp(self): tap = TunTapDevice(name=TAP_NAME, flags=IFF_TAP) tap.up() self.tap = tap
#!/usr/bin/python from pytun import TunTapDevice from select import select import time tun1 = TunTapDevice() tun2 = TunTapDevice() print "Name %s" % tun1.name tun1.addr = '10.8.0.1' tun1.dstaddr = '10.8.0.2' tun1.netmask = '255.255.255.0' tun1.mtu = 1500 tun1.up() print "Name %s" % tun2.name tun2.addr = '10.8.0.2' tun2.dstaddr = '10.8.0.1' tun2.netmask = '255.255.255.0' tun2.mtu = 1500 tun2.up() while True: r = select([tun1, tun2], [], [])[0][0] try: buf = r.read(r.mtu) if r == tun1: read = tun1.name tun2.write("Hi tun1!") else: read = tun2.name
tun = TunTapDevice() if "client" == args.role: log("Running as client.") tun.addr = args.client_ip #"10.1.0.2" tun.dstaddr = args.server_ip #"10.1.0.1" else: log("Running as server.") tun.addr = args.server_ip #"10.1.0.1" tun.dstaddr = args.client_ip #"10.1.0.2" tun.netmask = "255.255.255.0" tun.mtu = MTU log(\ """%s: mtu %d addr %s netmask %s dstaddr %s""" % \ (tun.name, tun.mtu, tun.addr, tun.netmask, tun.dstaddr) ) tun.up() log("%s: up now." % tun.name) # ---------- open UDP sockets reads = [tun] # for `select` function peers = [] for portNum in UDP_PORTS: newSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) newSocket.bind(("127.0.0.1", portNum)) reads.append(newSocket) peers.append(False) log("UDP: open ports %s" % ", ".join([str(i) for i in UDP_PORTS])) # TODO drop root
tun0 = TunTapDevice(name='tun0', flags=IFF_TUN + IFF_NO_PI) #'127.0.0.1' tun0.addr = '10.1.8.82' tun0.dstaddr = '10.1.8.83' tun0.netmask = '255.255.255.0' tun0.mtu = 1500 ip = IP(src="192.168.1.2", dst="192.168.1.1") udp = UDP(sport=4444, dport=4444) payload = Raw(load="Hi! I'm UDP-packet") packet = ip / udp / payload packet.show() new_packet = change_dst_ip(packet, "192.168.1.3") new_packet.show() try: tun0.up() while True: tun0.write(str(packet)) #tun0.write("Hi! I'm UDP-packet") time.sleep(5) tun0.write(str(new_packet)) time.sleep(5) finally: tun0.close()
class TUN(object): """TUN device""" def __init__(self, tun_dev, tun_addr, tun_remote_addr, tun_nm, tun_mtu, wsfactory): self.tun_dev = tun_dev self.tun_addr = tun_addr self.addr = tun_addr # used by mtcrypt self.tun_nm = tun_nm self.tun_mtu = int(tun_mtu) self.wsfactory = wsfactory if BSD == True: try: self.tunfd = os.open("/dev/" + tun_dev, os.O_RDWR) call([ "/sbin/ifconfig", tun_dev, tun_addr, tun_remote_addr, "up" ]) except: log.msg("Error opening TUN device. In use? Permissions?", logLevel=logging.WARN) sys.exit(ERR) reactor.addReader(self) logstr = ("Opened TUN device on %s") % (self.tun_dev) log.msg(logstr, logLevel=logging.INFO) elif LINUX == True: try: self.tun = TunTapDevice(name=tun_dev, flags=(IFF_TUN | IFF_NO_PI)) except: log.msg("Error opening TUN device. In use? Permissions?", logLevel=logging.WARN) sys.exit(ERR) 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) elif WINDOWS == True: self.overlappedTx = pywintypes.OVERLAPPED() self.overlappedTx.hEvent = win32event.CreateEvent(None, 0, 0, None) addr_tmp = self.tun_addr.split('.') self.tun_ipv4_address = list() for i in range(0, 4): self.tun_ipv4_address.append(int(addr_tmp[i])) nm_tmp = self.tun_nm.split('.') self.tun_ipv4_netmask = list() self.tun_ipv4_network = list() for i in range(0, 4): self.tun_ipv4_netmask.append(int(nm_tmp[i])) self.tun_ipv4_network.append(int(addr_tmp[i]) & int(nm_tmp[i])) self.TAP_IOCTL_CONFIG_POINT_TO_POINT = self.TAP_CONTROL_CODE(5, 0) self.TAP_IOCTL_SET_MEDIA_STATUS = self.TAP_CONTROL_CODE(6, 0) self.TAP_IOCTL_CONFIG_TUN = self.TAP_CONTROL_CODE(10, 0) try: self.tun_handle = self.openTunTap() except: log.msg("Could not open TUN device. Permissions?", logLevel=logging.WARN) sys.exit(ERR) log.msg("Opened TUN device", logLevel=logging.INFO) self.tunRead = TunRead(self.tun_handle, self.wsfactory) self.tunRead.start() if WINDOWS == True: def doWrite(self, data): win32file.WriteFile(self.tun_handle, data, self.overlappedTx) win32event.WaitForSingleObject(self.overlappedTx.hEvent, win32event.INFINITE) self.overlappedTx.Offset = self.overlappedTx.Offset + len(data) def openTunTap(self): guid = self.get_device_guid() tun_handle = win32file.CreateFile( r'\\.\Global\%s.tap' % guid, win32file.GENERIC_READ | win32file.GENERIC_WRITE, win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE, None, win32file.OPEN_EXISTING, win32file.FILE_ATTRIBUTE_SYSTEM | win32file.FILE_FLAG_OVERLAPPED, None) win32file.DeviceIoControl(tun_handle, self.TAP_IOCTL_SET_MEDIA_STATUS, '\x01\x00\x00\x00', None) configTunParam = [] configTunParam += self.tun_ipv4_address configTunParam += self.tun_ipv4_network configTunParam += self.tun_ipv4_netmask configTunParam = ''.join([chr(b) for b in configTunParam]) win32file.DeviceIoControl(tun_handle, self.TAP_IOCTL_CONFIG_TUN, configTunParam, None) return tun_handle def get_device_guid(self): ADAPTER_KEY = r'SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}' TUNTAP_COMPONENT_ID = 'tap0901' with reg.OpenKey(reg.HKEY_LOCAL_MACHINE, ADAPTER_KEY) as adapters: try: for i in range(10000): key_name = reg.EnumKey(adapters, i) with reg.OpenKey(adapters, key_name) as adapter: try: component_id = reg.QueryValueEx( adapter, 'ComponentId')[0] if component_id == TUNTAP_COMPONENT_ID: return reg.QueryValueEx( adapter, 'NetCfgInstanceId')[0] except WindowsError, err: pass except WindowsError, err: pass def CTL_CODE(self, device_type, function, method, access): return (device_type << 16) | (access << 14) | ( function << 2) | method def TAP_CONTROL_CODE(self, request, method): return self.CTL_CODE(34, request, method, 0)