예제 #1
0
def import_from_file(hosts_path=None, file_path=None):
    """Import entries from a text file

    :param hosts_path: Path to the hosts file to update
    :param file_path: Path to the file containing the hosts entries to import
    :return: A dict containing the result and user message to output
    """
    if hosts_path and not os.path.exists(hosts_path):
        return {
            'result': 'failed',
            'message': 'Cannot read hosts file: {0}'.format(hosts_path)
        }
    if not os.path.exists(file_path):
        return {
            'result': 'failed',
            'message': 'Cannot read import file: {0}'.format(file_path)
        }
    else:
        hosts = Hosts(path=hosts_path)
        pre_count = len(hosts.entries)
        import_file_output = hosts.import_file(import_file_path=file_path)
        post_count = len(hosts.entries)
        write_result = import_file_output.get('write_result')
        message = 'New entries:\t{0}\nTotal entries:\t{1}\n'.format(
            post_count - pre_count, write_result.get('total_written'))
    return {'result': import_file_output.get('result'), 'message': message}
예제 #2
0
def test_file_import_fails_when_not_readable(tmpdir):
    """
    Test import fails if file to import is not readable
    """
    hosts_file = tmpdir.mkdir("etc").join("hosts")
    hosts_file.write("82.132.132.132\texample.com\texample")
    hosts_entries = Hosts(path=hosts_file.strpath)
    result = hosts_entries.import_file('/invalid_file')
    assert result.get('result') == 'failed'
예제 #3
0
def test_import_file_returns_duplicate_correctly(tmpdir):
    """
    Test that adding an entry that exists will return a duplicate count of 1
    and a write count of 2 (where existing 82.132.132.132 is written along with
    new 10.10.10.10 entry)
    """
    hosts_file = tmpdir.mkdir("etc").join("hosts")
    hosts_file.write("82.132.132.132\texample.com\texample\n")
    import_file = tmpdir.mkdir("input").join("infile")
    import_file.write("10.10.10.10\thello.com\n82.132.132.132\texample.com\texample\n")
    hosts_entries = Hosts(path=hosts_file.strpath)
    feedback = hosts_entries.import_file(import_file_path=import_file.strpath)
    add_result = feedback.get('add_result')
    write_result = feedback.get('write_result')
    assert add_result.get('duplicate_count') == 1
    assert write_result.get('ipv4_entries_written') == 2
예제 #4
0
def test_import_file_increments_invalid_counter(tmpdir):
    """
    Test that correct counters values are returned
    when a text file of host entries is imported
    Existing host file has: 1 ipv4 entry
    Import file has: 2 ipv4 entries plus 1 invalid entry

    Add should return 2
    Dedupe will find a single duplicate
    Add will return 1 as invalid
    Write will write 1 new entry plus the existing entry (1 + 1 = 2)
    """
    hosts_file = tmpdir.mkdir("etc").join("hosts")
    hosts_file.write("82.132.132.132\texample.com\texample\n")
    import_file = tmpdir.mkdir("input").join("infile")
    import_file.write("example\n\n10.10.10.10\thello.com\n82.132.132.132\texample.com\texample\n")
    hosts_entries = Hosts(path=hosts_file.strpath)
    import_file_result = hosts_entries.import_file(import_file.strpath)
    assert not import_file_result.get('result') == 'failed'
    import_file_write_result = import_file_result.get('write_result')
    assert import_file_result.get('invalid_count') == 1
    assert import_file_write_result.get('ipv4_entries_written') == 2
    assert import_file_write_result.get('total_written') == 2
예제 #5
0
파일: src.py 프로젝트: niruhsa/muCast
class MulticastAnnouncerListener:
    def __init__(self, **kwargs):
        self.MCAST_GROUP = '224.1.1.1'
        self.MCAST_PORT = 4180
        self.IS_ALL_GROUPS = True
        self.blacklisted_interfaces = ['lo', 'lo0']
        self.blacklisted_ips = []
        self.localSubnets = []
        self.ips = {}
        self.logfile = kwargs['l']
        self.hostsfile = kwargs['o']
        self.input_hostsfile = kwargs['i']
        self.seperator = kwargs['s']
        self.verbose = kwargs['v']
        self.name = kwargs['nickname']
        self.blacklist = str(kwargs['bl']).split(",")
        self.blacklisted_subnets = []

        self.log = logging.getLogger(__name__)
        syslog = logging.StreamHandler()

        formatter = logging.Formatter("%(message)s")
        syslog.setFormatter(formatter)
        self.log.setLevel(logging.DEBUG)
        self.log.addHandler(syslog)
        self.log = logging.LoggerAdapter(self.log, {'app_name': 'muCast'})

        if self.input_hostsfile and not self.hostsfile:
            self.log.error(
                '[ERROR] You can only import a hosts file if you are also writing a hosts file via -o'
            )
            os._exit(1)
        if self.hostsfile: self.hosts = Hosts(path=self.hostsfile)
        else: self.hosts = False
        if os.path.exists(self.input_hostsfile) and os.path.isfile(
                self.input_hostsfile) and self.input_hostsfile:
            imported = self.hosts.import_file(self.input_hostsfile)
            self.log.debug('[ OK ] Imported hosts file: {}'.format(
                self.input_hostsfile))
        elif self.input_hostsfile:
            self.log.error(
                '[ERROR] The hosts file to import {} does not exist or no permission has been given to read it'
                .format(self.input_hostsfile))
            os._exit(1)

        if not self.logfile: self.log.debug("[ OK ] Writing to stdout")
        else:
            self.log.debug('[ OK ] Writing to logfile: {}'.format(
                self.logfile))

        sys.stdout.flush()
        sys.stderr.flush()

        self.blacklistedSubnets()

        localSubnets = threading.Thread(target=self.getLocalSubnets,
                                        args=()).start()
        receive = threading.Thread(target=self.receive, args=()).start()

    def getLocalSubnets(self):
        while True:
            blacklisted_ips = []
            localSubnets = []
            for inter in netifaces.interfaces():
                if inter not in self.blacklisted_interfaces:
                    interface = netifaces.ifaddresses(inter)
                    for address in interface:
                        blacklisted_ips.append(interface[address][0]['addr'])
                        try:
                            bits = None
                            ip_addr = None

                            if 'netmask' in interface[address][0].keys():
                                netmask = interface[address][0]['netmask']
                                bits = IPAddress(netmask).netmask_bits()
                            if 'addr' in interface[address][0].keys():
                                ip_addr = interface[address][0]['addr']

                            cidr = "{}/{}".format(ip_addr, bits)
                            localSubnets.append(
                                ipaddress.ip_network(cidr, False))
                        except Exception as e:
                            #if self.verbose: self.log.error("[LISTENER - getLocalSubnets() - (Try/Catch statement)]: {}".format(e))
                            pass
            self.blacklisted_ips = blacklisted_ips
            self.localSubnets = localSubnets
            time.sleep(1)

    def blacklistedSubnets(self):
        for subnet in self.blacklist:
            try:
                self.blacklisted_subnets.append(IPNetwork(str(subnet)))
            except:
                pass

    def receive(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                             socket.IPPROTO_UDP)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        if self.IS_ALL_GROUPS: sock.bind(('', self.MCAST_PORT))
        else: socket.bind((self.MCAST_GROUP, self.MCAST_PORT))

        mreq = struct.pack("4sl", socket.inet_aton(self.MCAST_GROUP),
                           socket.INADDR_ANY)
        sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

        while True:
            recv = sock.recv(10240).decode("utf-8")
            self.parseResponse(recv)

    def parseResponse(self, recv):
        try:
            nickname = recv.split(":")[0]
            address = ipaddress.ip_address(recv.split(":")[1])
            packet_id = recv.split(":")[2]
            timestamp = recv.split(":")[3]
            if self.verbose:
                self.log.debug(
                    "[VERBOSE] Packet {} from {} with content {} received at {} ({} difference in ms)"
                    .format(packet_id, nickname, address, timestamp,
                            ((time.time() - float(timestamp)) / 1000)))
            for subnet in self.localSubnets:
                subnet = IPNetwork(str(subnet))
                ip = IPAddress(str(address))

                is_blacklisted = False
                for b_subnet in self.blacklisted_subnets:
                    if ip in b_subnet: is_blacklisted = True

                if ip in subnet and nickname != self.name and not is_blacklisted:
                    self.ips[nickname] = address
                    if self.logfile: self.writeLogFile()
                    if self.hosts: self.writeHostsFile(recv)
                    self.log.info(
                        codecs.decode(("{}{}{}".format(address, self.seperator,
                                                       nickname)),
                                      'unicode_escape'))
        except Exception as e:
            if self.verbose and "does not appear to be an IPv4 or IPv6 address" not in str(
                    e):
                self.log.error("[LISTENER - parseResponse()]: {}".format(e))
            else:
                pass

    def writeLogFile(self):
        with open(self.logfile, 'w') as file:
            file_content = ""
            for nickname in self.ips:
                ip = self.ips[nickname]
                file_content += "{}{}{}\n".format(ip, self.seperator, nickname)
            file.write(codecs.decode(file_content, 'unicode_escape'))
            file.close()

    def writeHostsFile(self, recv):
        try:
            nickname = recv.split(":")[0]
            address = ipaddress.ip_address(recv.split(":")[1])
            packet_id = recv.split(":")[2]
            timestamp = recv.split(":")[3]
            ip_type = ipaddress.ip_address(address)
            self.hosts.remove_all_matching(name=nickname)
            if isinstance(ip_type, ipaddress.IPv4Address):
                new_entry = HostsEntry(entry_type='ipv4',
                                       address=str(address),
                                       names=[nickname])
            elif isinstance(ip_type, ipaddress.IPv6Address) and self.ipv6:
                new_entry = HostsEntry(entry_type='ipv6',
                                       address=str(address),
                                       names=[nickname])
            else:
                new_entry = HostsEntry(entry_type='blank',
                                       address=str(address),
                                       names=[nickname])

            self.hosts.add([new_entry])
            self.hosts.write()
        except Exception as e:
            if self.verbose:
                self.log.error("[LISTENER - writeHostsFile()]: {}".format(e))
            else:
                pass