Beispiel #1
0
    def get_contiguous(self):
        """
        Return the number of possible networks matching a non contiguous wildcard for source and destination
        Return 0 is Source and Destination has a contiguous wildcard

        :return: Integer (check description)
        """
        def __number_nets(wild):
            # The number of matches in a wildcard is defined by the number of 1
            x = 0
            wildS = wild.split('.')
            for octect in wildS:
                wildB = format(int(octect), 'b').zfill(8)
                x += wildB.count('1')

            return x

        net_number = 0
        if self.wildcard:
            if self.source_address != 'any' and self.source_address != '0.0.0.0/255.255.255.255':
                if not wild_is_contiguous(self.source_address.split('/')[1]):
                    net_number = __number_nets(
                        self.source_address.split('/')[1])

            if self.destination_address != 'any' and self.destination_address != '0.0.0.0/255.255.255.255':
                if not wild_is_contiguous(
                        self.destination_address.split('/')[1]):
                    if net_number == 0:
                        net_number = __number_nets(
                            self.destination_address.split('/')[1])
                    else:
                        net_number = net_number * __number_nets(
                            self.destination_address.split('/')[1])

        return net_number
Beispiel #2
0
    def _checkNetWild(self, net, wild, net_check):
        """
        Check if net_check is included in a network/wildcard

        :param net: network address
        :param mask: mask address
        :param net_check: network to find if it's included.
        :return:
        """
        if '/' not in net_check:
            return False
        if net == '0.0.0.0':
            return True
        if not wild_is_contiguous(wild):
            net_list = split_non_contiguous(net, wild)
        else:
            net_list = [net + '/' + wild]

        if not wild_is_contiguous(net_check.split('/')[1]):
            net_check_list = split_non_contiguous(
                net_check.split('/')[0],
                net_check.split('/')[1])
        else:
            net_check_list = [net_check]
        '''
        Now we should have two lists without any non-contiguous IP included. Time to go through both of them
        checking that all networks to be "checked" are included
        '''
        net_checked = []
        for net1 in net_list:
            try:
                if net1.split('/')[1] == '0.0.0.0':
                    # When using wildcard 0.0.0.0 is 255.255.255.255, but Netaddr use the 0.0.0.0 ask mask for ALL, so this needs to be changed
                    net1 = net1.split('/')[0] + '/' + '255.255.255.255'
                net_object_ori = netaddr.IPNetwork(net1)
            except:
                return None
            if len(net_check_list) == 0:
                break
            net_check_temp = net_check_list[:]
            for net2 in net_check_temp:
                try:
                    net_object_des = netaddr.IPNetwork(net2)
                except:
                    return None
                if net2 in net_checked:
                    continue
                if net_object_des in net_object_ori:
                    net_checked.append(net2)
                    net_check_list.remove(net2)

        return len(net_check_list) == 0
Beispiel #3
0
    def has_non_contiguous(self):
        """
        Check if there is any wildcard non contiguous in the rule
        :return: TRUE/FALSE
        """
        if self.wildcard:
            if self.source_address == 'any':
                if self.destination_address == 'any':
                    return False
                else:
                    return not wild_is_contiguous(self.destination_address.split('/')[1])
            elif self.destination_address == 'any':
                    return not wild_is_contiguous(self.source_address.split('/')[1])

            return not (wild_is_contiguous(self.source_address.split('/')[1]) or
                        wild_is_contiguous(self.destination_address.split('/')[1]))
        return False
Beispiel #4
0
    def split_non_contiguous_wild(self):
        """
        It will try to split a rule with a non contiguous wildcard into several networks
         It's not going to split any rule in more than <NONCONT_LIMIT> networks

        :return: None
        """
        end = False
        pos_list = -1
        non_c = False
        if type(self.rules[0]) != str:  # To avoid errors with "empty" policies
            while not end:
                pos_list += 1
                if pos_list >= len(self.rules):
                    break
                contig_num = self.rules[pos_list].get_contiguous()
                if 0 < contig_num <= NONCONT_LIMIT:
                    # This is a limit in the number of "new rules" that can be created

                    original_rule = self.rules[pos_list].get_rule()
                    original_rule_number = pos_list + 1

                    if original_rule[1] != 'any' and original_rule[
                            1] != '0.0.0.0/255.255.255.255':
                        if not wild_is_contiguous(
                                original_rule[1].split('/')[1]):
                            netlistS = split_non_contiguous(
                                original_rule[1].split('/')[0],
                                original_rule[1].split('/')[1])
                            if len(netlistS) > 0:
                                non_c = True
                            else:
                                # It's possible that we can't split the source (because it will create more than 128)
                                # but still it's possible to split the destination
                                netlistS = [original_rule[1]]
                        else:
                            netlistS = [original_rule[1]]
                    else:
                        netlistS = ['0.0.0.0/255.255.255.255']

                    if original_rule[2] != 'any' and original_rule[
                            2] != '0.0.0.0/255.255.255.255':
                        if not wild_is_contiguous(
                                original_rule[2].split('/')[1]):
                            netlistD = split_non_contiguous(
                                original_rule[2].split('/')[0],
                                original_rule[2].split('/')[1])
                            if len(netlistD) > 0:
                                non_c = True
                            else:
                                netlistD = [original_rule[2]]
                        else:
                            netlistD = [original_rule[2]]
                    else:
                        netlistD = ['0.0.0.0/255.255.255.255']

                    # At this point we could have two different list with Source IPs and Dest IP, that together they
                    # can't reach NONCONT_LIMIT networks. We just combine then.
                    if non_c:
                        source_dest_list = []
                        for a in netlistS:
                            for b in netlistD:
                                source_dest_list.append([a, b])

                        inew_number = original_rule_number
                        for new_net in source_dest_list:
                            if source_dest_list.index(new_net) == 0:
                                self.rules[original_rule_number -
                                           1].set_source(new_net[0])
                                self.rules[original_rule_number -
                                           1].set_destination(new_net[1])
                            else:
                                inew_number += 1
                                # The first entry we already have it
                                newrule = FWRule()
                                newrule.set_rule_data(
                                    sAddress=new_net[0],
                                    dAddress=new_net[1],
                                    dPort=original_rule[3],
                                    sPort=original_rule[4],
                                    protocol=original_rule[5],
                                    ACCEPT=original_rule[6],
                                    wildcard=True,
                                    name=original_rule[0],
                                    rulenumber=inew_number)
                                if self.DEBUG:
                                    newrule.set_debug()
                                self.rules.insert(inew_number - 1, newrule)
                        pos_list = inew_number - 1  # Lists starts in 0!

                if self.get_rules_number() == pos_list or pos_list >= 50000:
                    # 50000 seems to be a good safe value to break the while in case of any issue. I would not expect to split in more than 50k rules
                    break
            self.renum_policy()