Ejemplo n.º 1
0
 def unblock(self):
     '''
     '''
     st,output = getstatusoutput("pfctl -a switchyard -Fr") # flush rules
     log_debug("Flushing rules: {}".format(output))
     st,output = getstatusoutput("pfctl -X {}".format(self._token))
     log_info("Releasing pf: {}".format(output.replace('\n', '; ')))
Ejemplo n.º 2
0
    def __init__(self, interfaces, rules):
        super().__init__(interfaces, rules)
        self._intf = interfaces
        st,output = getstatusoutput("iptables-save")
        self._saved_iptables = output
        self._arpignore = {}
        self._rulecmds = [ 'iptables -F', 'iptables -t raw -F' ]

        # --protocol {}  -i {} --port {}
        doall = False
        for r in rules:
            cmds = self._parse_rule(r)
            self._rulecmds.extend(cmds)
            if r == 'all':
                doall = True

        if doall:
            badintf = []
            for intf in interfaces:
                st,output = getstatusoutput('sysctl net.ipv4.conf.{}.arp_ignore'.format(intf))
                if st != 0:
                    badintf.append(intf)
                    continue
                self._arpignore[intf] = int(output.split()[-1])
                st,output = getstatusoutput('sysctl -w net.ipv4.conf.{}.arp_ignore=8'.format(intf))
            for intf in badintf:
                self._intf.remove(intf) # alias of interfaces, so just remove
                                        # from self._intf
        log_debug("Rules to install: {}".format(self._rulecmds))
Ejemplo n.º 3
0
    def send_packet(self, dev, packet):
        '''
        Send a Switchyard Packet object on the given device 
        (string name of device).

        Raises SwitchyException if packet object isn't valid, or device
        name isn't recognized.
        '''
        if isinstance(dev, int):
            dev = self._lookup_devname(dev)

        if isinstance(dev, Interface):
            dev = dev.name

        pdev = self.pcaps.get(dev, None)
        if not pdev:
            raise SwitchyException(
                "Unrecognized device name for packet send: {}".format(dev))
        else:
            if packet is None:
                raise SwitchyException("No packet object given to send_packet")
            if not isinstance(packet, Packet):
                raise SwitchyException(
                    "Object given to send_packet is not a Packet (it is: {})".
                    format(type(packet)))
            # convert packet to bytes and send it
            rawpkt = packet.to_bytes()
            log_debug("Sending packet on device {}: {}".format(
                dev, str(packet)))
            pdev.send_packet(rawpkt)
Ejemplo n.º 4
0
 def block(self):
     '''
     pfctl -a switchyard -f- < rules.txt
     pfctl -a switchyard -F rules
     pfctl -t switchyard -F r
     '''
     st,output = _sendcmd(["/sbin/pfctl","-aswitchyard", "-f-"], self._rules)
     log_debug("Installing rules: {}".format(output))
Ejemplo n.º 5
0
 def _recv(self, nbytes):
     try:
         data, sourceaddr, destaddr = self._socket_queue_from_stack.get(
             block=self._block, timeout=self._timeout)
         log_debug("recv from {}<-{}:{}".format(data, sourceaddr, destaddr))
         return data, sourceaddr, destaddr
     except Empty as e:
         pass
     log_debug("recv timed out")
     raise timeout("timed out")
Ejemplo n.º 6
0
 def bind(self, address):
     # block firewall port
     # set stack to only allow packets through for addr/port
     self._local_addr = address
     # update firewall and pcap filters
     log_debug(
         "Updating firewall/bpf rule on bind(): {} dst port {}".format(
             self._protoname, self._local_addr[1]))
     Firewall.add_rule("{}:{}".format(self._protoname, self._local_addr[1]))
     PcapLiveDevice.set_bpf_filter_on_all_devices("{} dst port {}".format(
         self._protoname, self._local_addr[1]))
Ejemplo n.º 7
0
 def _sig_handler(self, signum, stack):
     '''
     Handle process INT signal.
     '''
     log_debug("Got SIGINT.")
     if signum == signal.SIGINT:
         PyLLNet.running = False
         if self.pktqueue.qsize() == 0:
             # put dummy pkt in queue to unblock a 
             # possibly stuck user thread
             self.pktqueue.put( (None,None,None) )
         self.pktqueue = Queue()
Ejemplo n.º 8
0
 def _sig_handler(self, signum, stack):
     '''
     Handle process INT signal.
     '''
     log_debug("Got SIGINT.")
     if signum == signal.SIGINT:
         PyLLNet.running = False
         if self.pktqueue.qsize() == 0:
             # put dummy pkt in queue to unblock a
             # possibly stuck user thread
             self.pktqueue.put((None, None, None))
         self.pktqueue = Queue()
Ejemplo n.º 9
0
    def __init__(self, interfaces, rules):
        super().__init__(interfaces, rules)
        self._interfaces = interfaces
        for r in rules:
            cmds = self._parse_rule(r)
            self._rules.extend(cmds)

        st,output = getstatusoutput("pfctl -E")
        mobj = re.search("Token\s*:\s*(\d+)", output, re.M)
        if mobj is None:
            raise RuntimeError("Couldn't get pfctl token.  Are you running as root?")
        self._token = mobj.groups()[0]
        log_debug("Rules to install: {}".format(self._rules))
        log_info("Enabling pf: {}".format(output.replace('\n', '; ')))
Ejemplo n.º 10
0
    def __low_level_dispatch(pcapdev, devname, pktqueue):
        '''
        Thread entrypoint for doing low-level receive and dispatch
        for a single pcap device.
        '''
        count = 0
        while PyLLNet.running:
            # a non-zero timeout value is ok here; this is an
            # independent thread that handles input for this
            # one pcap device.  it throws any packets received
            # into the shared queue (which is read by the actual
            # user code)
            pktinfo = pcapdev.recv_packet(timeout=0.2)
            if pktinfo is None:
                continue
            log_debug("Got packet on device {}, dlt {}".format(devname, pcapdev.dlt))
            pktqueue.put( (devname,pcapdev.dlt,pktinfo) )
            count += 1
            if count % 100 == 0:
                stats = pcapdev.stats()
                log_debug("Periodic device statistics {}: {} received, {} dropped, {} dropped/if".format(devname, stats.ps_recv, stats.ps_drop, stats.ps_ifdrop))

        log_debug("Receiver thread for {} exiting".format(devname))
        stats = pcapdev.stats()
        log_debug("Final device statistics {}: {} received, {} dropped, {} dropped/if".format(devname, stats.ps_recv, stats.ps_drop, stats.ps_ifdrop))
Ejemplo n.º 11
0
    def __low_level_dispatch(pcapdev, devname, pktqueue):
        '''
        Thread entrypoint for doing low-level receive and dispatch
        for a single pcap device.
        '''
        count = 0
        while PyLLNet.running:
            # a non-zero timeout value is ok here; this is an
            # independent thread that handles input for this
            # one pcap device.  it throws any packets received
            # into the shared queue (which is read by the actual
            # user code)
            pktinfo = pcapdev.recv_packet(timeout=0.2)
            if pktinfo is None:
                continue
            log_debug("Got packet on device {}, dlt {}".format(
                devname, pcapdev.dlt))
            pktqueue.put((devname, pcapdev.dlt, pktinfo))
            count += 1
            if count % 100 == 0:
                stats = pcapdev.stats()
                log_debug(
                    "Periodic device statistics {}: {} received, {} dropped, {} dropped/if"
                    .format(devname, stats.ps_recv, stats.ps_drop,
                            stats.ps_ifdrop))

        log_debug("Receiver thread for {} exiting".format(devname))
        stats = pcapdev.stats()
        log_debug(
            "Final device statistics {}: {} received, {} dropped, {} dropped/if"
            .format(devname, stats.ps_recv, stats.ps_drop, stats.ps_ifdrop))
Ejemplo n.º 12
0
    def __init__(self, family, xtype, proto=0, fileno=0):
        family = AddressFamily(family)
        if family != AddressFamily.AF_INET:
            raise NotImplementedError(
                "socket for family {} not implemented".format(family))
        if xtype not in [SOCK_DGRAM, SOCK_STREAM]:
            raise NotImplementedError(
                "socket type {} not implemented".format(xtype))
        self._family = family
        self._socktype = xtype
        self._protoname = 'udp'
        self._proto = IPProtocol.UDP
        if self._socktype == SOCK_STREAM:
            self._protoname = 'tcp'
            self._proto = IPProtocol.TCP
        self._timeout = None
        self._block = True
        self._remote_addr = (None, None)
        self._local_addr = ('0.0.0.0', _get_ephemeral_port())

        log_debug("Adding firewall/bpf rule {} dst port {}".format(
            self._protoname, self._local_addr[1]))
        try:
            Firewall.add_rule("{}:{}".format(self._protoname,
                                             self._local_addr[1]))
            # only get packets with destination port of local port, or any
            # icmp packets
            PcapLiveDevice.set_bpf_filter_on_all_devices(
                "{} dst port {} or icmp".format(self._protoname,
                                                self._local_addr[1]))
        except:
            with yellow():
                print(
                    "Unable to complete socket emulation setup (failed on firewall/bpf filter installation).  Did you start the program via srpy?"
                )
                import traceback
            print("Here is the raw exception information:")
            with red():
                print(indent(traceback.format_exc(), '    '))
            sys.exit()

        ApplicationLayer.init()
        self._socket_queue_to_stack, self._socket_queue_from_stack = ApplicationLayer.queues(
        )
Ejemplo n.º 13
0
    def send_packet(self, dev, packet):
        '''
        Send a Switchyard Packet object on the given device 
        (string name of device).

        Raises SwitchyException if packet object isn't valid, or device
        name isn't recognized.
        '''
        pdev = self.pcaps.get(dev, None)
        if not pdev:
            raise SwitchyException("Unrecognized device name for packet send: {}".format(dev))
        else:
            if packet is None:
                raise SwitchyException("No packet object given to send_packet")
            if not isinstance(packet, Packet):
                raise SwitchyException("Object given to send_packet is not a Packet (it is: {})".format(type(packet)))
            # convert packet to bytes and send it
            rawpkt = packet.to_bytes()
            log_debug("Sending packet on device {}: {}".format(dev, str(packet)))
            pdev.send_packet(rawpkt)
Ejemplo n.º 14
0
    def __init__(self, devlist, name=None):
        LLNetBase.__init__(self)
        signal.signal(signal.SIGINT, self._sig_handler)
        signal.signal(signal.SIGTERM, self._sig_handler)
        signal.signal(signal.SIGHUP, self._sig_handler)
        signal.signal(signal.SIGUSR1, self._sig_handler)
        signal.signal(signal.SIGUSR2, self._sig_handler)

        self.devs = devlist # self.__initialize_devices(includelist, excludelist)
        self.devinfo = self.__assemble_devinfo()
        self.pcaps = {}
        self.__make_pcaps()
        log_info("Using network devices: {}".format(' '.join(self.devs)))
        for devname, intf in self.devinfo.items():
            log_debug("{}: {}".format(devname, str(intf)))

        PyLLNet.running = True
        self.__spawn_threads()

        if name:
            self.__name = name
        else:
            self.__name = gethostname()
Ejemplo n.º 15
0
    def __init__(self, devlist, name=None):
        LLNetBase.__init__(self)
        signal.signal(signal.SIGINT, self._sig_handler)
        signal.signal(signal.SIGTERM, self._sig_handler)
        signal.signal(signal.SIGHUP, self._sig_handler)
        signal.signal(signal.SIGUSR1, self._sig_handler)
        signal.signal(signal.SIGUSR2, self._sig_handler)

        self.devs = devlist  # self.__initialize_devices(includelist, excludelist)
        self.devinfo = self.__assemble_devinfo()
        self.pcaps = {}
        self.__make_pcaps()
        log_info("Using network devices: {}".format(' '.join(self.devs)))
        for devname, intf in self.devinfo.items():
            log_debug("{}: {}".format(devname, str(intf)))

        PyLLNet.running = True
        self.__spawn_threads()

        if name:
            self.__name = name
        else:
            self.__name = gethostname()
Ejemplo n.º 16
0
    def shutdown(self):
        '''
        Should be called by Switchyard user code when a network object is
        being shut down.  (This method cleans up internal threads and network
        interaction objects.)
        '''
        if not PyLLNet.running:
            return

        PyLLNet.running = False
        log_debug("Joining threads for shutdown")
        for t in self.threads:
            t.join()
        log_debug("Closing pcap devices")
        for devname,pdev in self.pcaps.items():
            pdev.close()
        log_debug("Done cleaning up")
Ejemplo n.º 17
0
    def shutdown(self):
        '''
        Should be called by Switchyard user code when a network object is
        being shut down.  (This method cleans up internal threads and network
        interaction objects.)
        '''
        if not PyLLNet.running:
            return

        PyLLNet.running = False
        log_debug("Joining threads for shutdown")
        for t in self.threads:
            t.join()
        log_debug("Closing pcap devices")
        for devname, pdev in self.pcaps.items():
            pdev.close()
        log_debug("Done cleaning up")
Ejemplo n.º 18
0
 def shutdown(self):
     self.__linkem.shutdown()
     self.__done = True
     log_debug("Joining node codeexec thread {} node {}".format(self.__t.name, self.__name))
     self.__t.join()
Ejemplo n.º 19
0
def setup_switchyard_stack(proto, localaddr):
    log_debug("Starting up stack thread")
    ApplicationLayer.init()
    return ApplicationLayer.queues()
Ejemplo n.º 20
0
 def _send(self, data, remote_addr):
     log_debug("socketemu send: {}->{}:{}".format(data, self._local_addr,
                                                  remote_addr))
     self._socket_queue_to_stack.put((data, self._local_addr, remote_addr))
Ejemplo n.º 21
0
 def add_rule(self, rule):
     for cmd in self._parse_rule(rule):
         st,output = getstatusoutput(cmd)
         self._rulecmds.append(cmd)
         log_debug("Adding firewall rule: {}".format(cmd))
Ejemplo n.º 22
0
 def add_rule(self, rule):
     cmds = self._parse_rule(rule)
     self._rules.extend(cmds)
     st,output = _sendcmd(["/sbin/pfctl","-aswitchyard", "-f-"], cmds)
     log_debug("Adding firewall rules: {}".format(cmds))
Ejemplo n.º 23
0
 def shutdown(self):
     self.__linkem.shutdown()
     self.__done = True
     log_debug("Joining node codeexec thread {} node {}".format(
         self.__t.name, self.__name))
     self.__t.join()
Ejemplo n.º 24
0
 def add_rule(self, rule):
     for cmd in self._parse_rule(rule):
         st, output = getstatusoutput(cmd)
         self._rulecmds.append(cmd)
         log_debug("Adding firewall rule: {}".format(cmd))
Ejemplo n.º 25
0
 def __del__(self):
     log_debug("Exiting socket code")