Esempio n. 1
0
    def _TranslatePolicy(self, pol, exp_info):
        self.pcap_policies = []
        current_date = datetime.datetime.utcnow().date()
        exp_info_date = current_date + datetime.timedelta(weeks=exp_info)

        good_afs = ['inet', 'inet6', 'mixed']
        good_options = ['in', 'out']
        direction = ''

        for header, terms in pol.filters:
            filter_type = None
            if self._PLATFORM not in header.platforms:
                continue

            filter_options = header.FilterOptions(self._PLATFORM)[1:]
            filter_name = header.FilterName(self._PLATFORM)

            # ensure all options after the filter name are expected
            for opt in filter_options:
                if opt not in good_afs + good_options:
                    raise UnsupportedTargetOptionError(
                        '%s %s %s %s' %
                        ('\nUnsupported option found in', self._PLATFORM,
                         'target definition:', opt))

            if 'in' in filter_options:
                direction = 'in'
            elif 'out' in filter_options:
                direction = 'out'

            # Check for matching af
            for address_family in good_afs:
                if address_family in filter_options:
                    # should not specify more than one AF in options
                    if filter_type is not None:
                        raise aclgenerator.UnsupportedFilterError(
                            '%s %s %s %s' %
                            ('\nMay only specify one of', good_afs,
                             'in filter options:', filter_options))
                    filter_type = address_family
            if filter_type is None:
                filter_type = 'mixed'

            # add the terms
            accept_terms = []
            deny_terms = []
            term_names = set()
            for term in terms:
                if term.name in term_names:
                    raise aclgenerator.DuplicateTermError(
                        'You have a duplicate term: %s' % term.name)

                if term.expiration:
                    if term.expiration <= exp_info_date:
                        logging.info(
                            'INFO: Term %s in policy %s expires '
                            'in less than two weeks.', term.name, filter_name)
                    if term.expiration <= current_date:
                        logging.warning(
                            'WARNING: Term %s in policy %s is expired and '
                            'will not be rendered.', term.name, filter_name)
                        continue

                if not term:
                    continue

                if term.action[0] == 'accept':
                    accept_terms.append(
                        self._TERM(term, filter_name, filter_type, direction))
                elif term.action[0] == 'deny' or term.action[0] == 'reject':
                    deny_terms.append(
                        self._TERM(term, filter_name, filter_type, direction))

            self.pcap_policies.append(
                (header, filter_name, filter_type, accept_terms, deny_terms))
Esempio n. 2
0
    def _TranslatePolicy(self, pol, exp_info):
        """Translate a policy from objects into strings."""
        current_date = datetime.datetime.utcnow().date()
        exp_info_date = current_date + datetime.timedelta(weeks=exp_info)

        default_action = None
        good_default_actions = ['ACCEPT', 'DROP']
        good_afs = ['inet', 'inet6']
        all_protocols_stateful = True
        self.verbose = True

        for header, terms in pol.filters:
            filter_type = None
            if self._PLATFORM not in header.platforms:
                continue

            self.filter_options = header.FilterOptions(self._PLATFORM)[1:]
            filter_name = header.FilterName(self._PLATFORM)

            self._WarnIfCustomTarget(filter_name)

            # ensure all options after the filter name are expected
            for opt in self.filter_options:
                if opt not in good_default_actions + good_afs + self._GOOD_OPTIONS:
                    raise UnsupportedTargetOptionError(
                        '%s %s %s %s' %
                        ('\nUnsupported option found in', self._PLATFORM,
                         'target definition:', opt))

            # disable stateful?
            if 'nostate' in self.filter_options:
                all_protocols_stateful = False
            if 'noverbose' in self.filter_options:
                self.verbose = False

            # Check for matching af
            for address_family in good_afs:
                if address_family in self.filter_options:
                    # should not specify more than one AF in options
                    if filter_type is not None:
                        raise UnsupportedFilterError(
                            '%s %s %s %s' %
                            ('\nMay only specify one of', good_afs,
                             'in filter options:', self.filter_options))
                    filter_type = address_family
            if filter_type is None:
                filter_type = 'inet'

            if self._PLATFORM == 'iptables' and filter_name == 'FORWARD':
                default_action = 'DROP'

            # does this policy override the default filter actions?
            for next_target in header.target:
                if next_target.platform == self._PLATFORM:
                    if len(next_target.options) > 1:
                        for arg in next_target.options:
                            if arg in good_default_actions:
                                default_action = arg
            if default_action and default_action not in good_default_actions:
                raise UnsupportedDefaultActionError(
                    '%s %s %s %s %s' %
                    ('\nOnly', ', '.join(good_default_actions),
                     'default filter action allowed;', default_action,
                     'used.'))

            # add the terms
            new_terms = []
            term_names = set()
            for term in terms:
                term.name = self.FixTermLength(
                    term.name, 'abbreviateterms' in self.filter_options,
                    'truncateterms' in self.filter_options)
                if term.name in term_names:
                    raise aclgenerator.DuplicateTermError(
                        'You have a duplicate term: %s' % term.name)
                term_names.add(term.name)
                if not term.logging and term.log_limit:
                    raise LimitButNoLogError(
                        'Term %s: Cannoy use log-limit without logging' %
                        term.name)

                term = self.FixHighPorts(
                    term,
                    af=filter_type,
                    all_protocols_stateful=all_protocols_stateful)
                if not term:
                    continue

                if term.expiration:
                    if term.expiration <= exp_info_date:
                        logging.info(
                            'INFO: Term %s in policy %s expires '
                            'in less than two weeks.', term.name, filter_name)
                    if term.expiration <= current_date:
                        logging.warning(
                            'WARNING: Term %s in policy %s is expired and '
                            'will not be rendered.', term.name, filter_name)
                        continue

                new_terms.append(
                    self._TERM(term, filter_name, all_protocols_stateful,
                               default_action, filter_type, self.verbose))

            self.iptables_policies.append(
                (header, filter_name, filter_type, default_action, new_terms))
Esempio n. 3
0
    def _TranslatePolicy(self, pol, exp_info):
        self.arista_traffic_policies = []
        _AF_MAP_TXT = {"inet": "ipv4", "inet6": "ipv6"}

        current_date = datetime.datetime.utcnow().date()
        exp_info_date = current_date + datetime.timedelta(weeks=exp_info)

        for header, terms in pol.filters:
            if self._PLATFORM not in header.platforms:
                continue

            filter_options = header.FilterOptions(self._PLATFORM)
            filter_name = header.FilterName(self._PLATFORM)
            noverbose = "noverbose" in filter_options[1:]

            term_names = set()
            new_terms = []  # list of generated terms
            policy_field_sets = []  # list of generated field-sets
            policy_counters = set()  # set of the counters in the policy

            # default to mixed policies
            filter_type = "mixed"
            if len(filter_options) > 1:
                filter_type = filter_options[1]

            # if the filter_type is mixed, we need to iterate through the
            # supported address families. treat the incoming policy term
            # (pol_term) as a template for the term and override the necessary
            # elements of the term for the inet6 evaluation.
            #
            # only make a copy of the pol_term if filter_type = "mixed"
            ftypes = []

            if filter_type == "mixed":
                ftypes = ["inet", "inet6"]
            else:
                ftypes = [filter_type]

            for pol_term in terms:
                for ft in ftypes:
                    if filter_type == "mixed":
                        term = copy.deepcopy(pol_term)
                    else:
                        term = pol_term

                    # if the term name is default-* we will render this into the
                    # appropriate default term name to be used in this filter.
                    default_term = re.match(r"^default\-.*", term.name,
                                            re.IGNORECASE)

                    # TODO(sulrich): if term names become unique to address
                    # families, this can be removed.
                    if (filter_type == "mixed" and ft == "inet6"):
                        term.name = _AF_MAP_TXT[ft] + '-' + term.name

                    if default_term:
                        term.name = _AF_MAP_TXT[ft] + "-default-all"

                    if term.name in term_names:
                        raise aclgenerator.DuplicateTermError(
                            "multiple terms named: %s" % term.name)
                    term_names.add(term.name)

                    term = self.FixHighPorts(term, af=ft)
                    if not term:
                        continue

                    if term.expiration:
                        if term.expiration <= exp_info_date:
                            logging.info(
                                "INFO: term %s in policy %s expires "
                                "in less than two weeks.",
                                term.name,
                                filter_name,
                            )
                        if term.expiration <= current_date:
                            logging.warning(
                                "WARNING: term %s in policy %s is expired and "
                                "will not be rendered.",
                                term.name,
                                filter_name,
                            )
                            continue

                    # emit warnings for unsupported options / terms
                    if term.option:
                        unsupported_opts = []
                        for opt in [str(x) for x in term.option]:
                            if opt.startswith("sample") or \
                               opt.startswith("first-fragment"):
                                unsupported_opts.append(opt)

                        # unsupported options are in use and should be skipped
                        if len(unsupported_opts) > 0:
                            logging.warning(
                                "WARNING: term %s in policy %s uses an "
                                "unsupported option (%s) and will not be "
                                "rendered.",
                                term.name,
                                filter_name,
                                " ".join(unsupported_opts),
                            )
                            continue

                    has_unsupported_match_criteria = (
                        term.dscp_except or term.dscp_match or term.ether_type
                        or term.flexible_match_range or term.forwarding_class
                        or term.forwarding_class_except or term.next_ip
                        or term.port or term.traffic_type)
                    if has_unsupported_match_criteria:
                        logging.warning(
                            "WARNING: term %s in policy %s uses an "
                            "unsupported match criteria and will not "
                            "be rendered.",
                            term.name,
                            filter_name,
                        )
                        continue

                    if (("is-fragment" in term.option
                         or "fragment" in term.option)
                            and filter_type == "inet6"):
                        raise AristaTpFragmentInV6Error(
                            "the term %s uses is-fragment but "
                            "is a v6 policy." % term.name)

                    # this should error out more gracefully in mixed configs
                    if (("is-fragment" in term.option
                         or "fragment" in term.option) and ft == "inet6"):
                        logging.warning(
                            "WARNING: term %s in mixed policy %s uses "
                            "fragment the ipv6 version of the term will not be "
                            "rendered.",
                            term.name,
                            filter_name,
                        )
                        continue

                    # check for traffic-policy specific feature interactions
                    if (("is-fragment" in term.option
                         or "fragment" in term.option)
                            and (term.source_port or term.destination_port)):
                        logging.warning(
                            "WARNING: term %s uses fragment as well as src/dst "
                            "port matches.  traffic-policies currently do not "
                            "support this match combination. the term will not "
                            "be rendered",
                            term.name,
                        )
                        continue

                    # check for common unsupported actions (e.g.: next)
                    if term.action == ["next"]:
                        logging.warning(
                            "WARNING: term %s uses an unsupported action "
                            "(%s) and will not be rendered",
                            term.name,
                            " ".join(term.action),
                        )
                        continue

                    # generate the prefix sets when there are inline addres
                    # exclusions in a term. these will be referenced within the
                    # term
                    if term.source_address_exclude:
                        src_addr = term.GetAddressOfVersion(
                            "source_address", self._AF_MAP[ft])
                        src_addr_ex = term.GetAddressOfVersion(
                            "source_address_exclude", self._AF_MAP[ft])
                        src_addr, src_addr_ex = self._MinimizePrefixes(
                            src_addr, src_addr_ex)

                        if src_addr_ex:
                            fs = self._GenPrefixFieldset(
                                "src", "%s" % term.name, src_addr, src_addr_ex,
                                _AF_MAP_TXT[ft])
                            policy_field_sets.append(fs)

                    if term.destination_address_exclude:
                        dst_addr = term.GetAddressOfVersion(
                            "destination_address", self._AF_MAP[ft])
                        dst_addr_ex = term.GetAddressOfVersion(
                            "destination_address_exclude", self._AF_MAP[ft])
                        dst_addr, dst_addr_ex = self._MinimizePrefixes(
                            dst_addr, dst_addr_ex)

                        if dst_addr_ex:
                            fs = self._GenPrefixFieldset(
                                "dst", "%s" % term.name,
                                term.destination_address,
                                term.destination_address_exclude,
                                _AF_MAP_TXT[ft])
                            policy_field_sets.append(fs)

                    # generate the unique list of named counters
                    if term.counter:
                        # we can't have '.' in counter names
                        term.counter = re.sub(r"\.", "-", str(term.counter))
                        policy_counters.add(term.counter)

                    new_terms.append(self._TERM(term, ft, noverbose))

            self.arista_traffic_policies.append(
                (header, filter_name, filter_type, new_terms, policy_counters,
                 policy_field_sets))
Esempio n. 4
0
    def _TranslatePolicy(self, pol, exp_info):
        """Translate a policy from objects into strings."""
        self.windows_policies = []
        current_date = datetime.datetime.utcnow().date()
        exp_info_date = current_date + datetime.timedelta(weeks=exp_info)

        default_action = None
        good_default_actions = ['permit', 'block']
        good_options = []

        for header, terms in pol.filters:
            filter_type = None
            if self._PLATFORM not in header.platforms:
                continue

            filter_options = header.FilterOptions(self._PLATFORM)[1:]
            filter_name = header.FilterName(self._PLATFORM)

            # ensure all options after the filter name are expected
            for opt in filter_options:
                if opt not in good_default_actions + self._GOOD_AFS + good_options:
                    raise aclgenerator.UnsupportedTargetOptionError(
                        '%s %s %s %s' %
                        ('\nUnsupported option found in', self._PLATFORM,
                         'target definition:', opt))

            # Check for matching af
            for address_family in self._GOOD_AFS:
                if address_family in filter_options:
                    # should not specify more than one AF in options
                    if filter_type is not None:
                        raise aclgenerator.UnsupportedFilterError(
                            '%s %s %s %s' %
                            ('\nMay only specify one of', self._GOOD_AFS,
                             'in filter options:', filter_options))
                    filter_type = address_family
            if filter_type is None:
                filter_type = 'inet'

            # does this policy override the default filter actions?
            for next_target in header.target:
                if next_target.platform == self._PLATFORM:
                    if len(next_target.options) > 1:
                        for arg in next_target.options:
                            if arg in good_default_actions:
                                default_action = arg
            if default_action and default_action not in good_default_actions:
                raise aclgenerator.UnsupportedTargetOptionError(
                    '%s %s %s %s %s' %
                    ('\nOnly', ', '.join(good_default_actions),
                     'default filter action allowed;', default_action,
                     'used.'))

            # add the terms
            new_terms = []
            term_names = set()
            for term in terms:
                if term.name in term_names:
                    raise aclgenerator.DuplicateTermError(
                        'You have a duplicate term: %s' % term.name)
                term_names.add(term.name)

                if term.expiration:
                    if term.expiration <= exp_info_date:
                        logging.info(
                            'INFO: Term %s in policy %s expires '
                            'in less than two weeks.', term.name, filter_name)
                    if term.expiration <= current_date:
                        logging.warning(
                            'WARNING: Term %s in policy %s is expired and '
                            'will not be rendered.', term.name, filter_name)
                        continue
                if 'established' in term.option or 'tcp-established' in term.option:
                    continue
                new_terms.append(
                    self._TERM(term, filter_name, default_action, filter_type))

            self.windows_policies.append(
                (header, filter_name, filter_type, default_action, new_terms))