Ejemplo n.º 1
0
    def __str__(self):
        """Render the output of the PF policy into config."""
        target = []
        pretty_platform = '%s%s' % (self._PLATFORM[0].upper(),
                                    self._PLATFORM[1:])
        # Create address table.
        for name in sorted(self.address_book):
            v4 = sorted([x for x in self.address_book[name] if x.version == 4])
            v6 = sorted([x for x in self.address_book[name] if x.version == 6])
            entries = ',\\\n'.join(str(x) for x in v4 + v6)
            target.append('table <%s> {%s}' % (name, entries))
        # pylint: disable=unused-variable
        for (header, filter_name, filter_type, terms) in self.pf_policies:
            # Add comments for this filter
            target.append('# %s %s Policy' %
                          (pretty_platform, header.FilterName(self._PLATFORM)))

            # reformat long text comments, if needed
            comments = aclgenerator.WrapWords(header.comment, 70)
            if comments and comments[0]:
                for line in comments:
                    target.append('# %s' % line)
                target.append('#')
            # add the p4 tags
            target.extend(aclgenerator.AddRepositoryTags('# '))
            target.append('# ' + filter_type)

            # add the terms
            for term in terms:
                term_str = str(term)
                if term_str:
                    target.append(term_str)
            target.append('')

        return '\n'.join(target)
Ejemplo n.º 2
0
    def __str__(self):
        target_header = []
        target = []
        # add the p4 tags
        target.extend(aclgenerator.AddRepositoryTags('! '))

        for (header, filter_name, filter_list, terms,
             obj_target) in self.cisco_policies:
            for filter_type in filter_list:
                target.extend(
                    self._AppendTargetByFilterType(filter_name, filter_type))
                if filter_type == 'object-group':
                    obj_target.AddName(filter_name)

                # Add the Perforce Id/Date tags, these must come after
                # remove/re-create of the filter, otherwise config mode doesn't
                # know where to place these remarks in the configuration.
                if self.verbose:
                    if filter_type == 'standard' and filter_name.isdigit():
                        target.extend(
                            aclgenerator.AddRepositoryTags(
                                'access-list %s remark ' % filter_name,
                                date=False,
                                revision=False))
                    else:
                        target.extend(
                            aclgenerator.AddRepositoryTags(' remark ',
                                                           date=False,
                                                           revision=False))

                    # add a header comment if one exists

                    for comment in aclgenerator.WrapWords(
                            header.comment, _COMMENT_MAX_WIDTH):
                        for line in comment.split('\n'):
                            if (self._PLATFORM == 'cisco'
                                    and filter_type == 'standard'
                                    and filter_name.isdigit()):
                                target.append('access-list %s remark %s' %
                                              (filter_name, line))
                            else:
                                target.append(' remark %s' % line)

                # now add the terms
                for term in terms:
                    term_str = str(term)
                    if term_str:
                        target.append(term_str)

            if obj_target.valid:
                target = [str(obj_target)] + target
            # ensure that the header is always first
            target = target_header + target
            target += ['', 'exit', '']
        return '\n'.join(target)
Ejemplo n.º 3
0
    def __str__(self):
        """Render the output of the JuniperSRX policy into config."""
        target = IndentList(self.INDENT)
        target.append('security {')

        # ADDRESSBOOK
        target.extend(self._GenerateAddressBook())

        # POLICIES
        target.IndentAppend(1, '/*')
        target.extend(aclgenerator.AddRepositoryTags(self.INDENT * 1))
        target.IndentAppend(1, '*/')

        target.IndentAppend(1, 'replace: policies {')

        for (header, terms, filter_options) in self.srx_policies:
            if self._NOVERBOSE not in filter_options[4:]:
                target.IndentAppend(2, '/*')
                target.extend([
                    self.INDENT * 2 + line for line in aclgenerator.WrapWords(
                        header.comment, self._MAX_HEADER_COMMENT_LENGTH)
                ])
                target.IndentAppend(2, '*/')

            # ZONE DIRECTION
            if filter_options[1] == 'all' and filter_options[3] == 'all':
                target.IndentAppend(2, 'global {')
            else:
                target.IndentAppend(
                    2, 'from-zone ' + filter_options[1] + ' to-zone ' +
                    filter_options[3] + ' {')

            # GROUPS
            if header.apply_groups:
                target.IndentAppend(
                    3, JunipersrxList('apply-groups', header.apply_groups))
            # GROUPS EXCEPT
            if header.apply_groups_except:
                target.IndentAppend(
                    3,
                    JunipersrxList('apply-groups-except',
                                   header.apply_groups_except))
            for term in terms:
                str_result = str(term)
                if str_result:
                    target.append(str_result)
            target.IndentAppend(2, '}')
        target.IndentAppend(1, '}')
        target.append('}')

        # APPLICATIONS
        target.extend(self._GenerateApplications())

        return '\n'.join(target)
Ejemplo n.º 4
0
    def __str__(self):
        target = []
        pretty_platform = '%s%s' % (self._PLATFORM[0].upper(),
                                    self._PLATFORM[1:])

        if self._RENDER_PREFIX:
            target.append(self._RENDER_PREFIX)

        for (header, filter_name, filter_type, default_action,
             terms) in self.iptables_policies:
            # Add comments for this filter
            target.append('# %s %s Policy' %
                          (pretty_platform, header.FilterName(self._PLATFORM)))

            # reformat long text comments, if needed
            comments = aclgenerator.WrapWords(header.comment, 70)
            if comments and comments[0]:
                for line in comments:
                    target.append('# %s' % line)
                target.append('#')
            # add the p4 tags
            target.extend(aclgenerator.AddRepositoryTags('# '))
            target.append('# ' + filter_type)

            if filter_name in self._GOOD_FILTERS:
                if default_action:
                    target.append(self._DEFAULTACTION_FORMAT %
                                  (filter_name, default_action))
                elif self._PLATFORM == 'speedway':
                    # always specify the default filter states for speedway,
                    # if default action policy not specified for iptables, do nothing.
                    target.append(self._DEFAULTACTION_FORMAT %
                                  (filter_name, self._DEFAULT_ACTION))
            else:
                # Custom chains have no concept of default policy.
                target.append(self._DEFAULTACTION_FORMAT_CUSTOM_CHAIN %
                              filter_name)
            # add the terms
            for term in terms:
                term_str = str(term)
                if term_str:
                    target.append(term_str)

        if self._RENDER_SUFFIX:
            target.append(self._RENDER_SUFFIX)

        target.append('')
        return '\n'.join(target)
Ejemplo n.º 5
0
    def __str__(self):
        target = []
        pretty_platform = '%s%s' % (self._PLATFORM[0].upper(),
                                    self._PLATFORM[1:])

        if self._RENDER_PREFIX:
            target.append(self._RENDER_PREFIX)

        for header, _, filter_type, default_action, terms in self.windows_policies:
            # Add comments for this filter
            target.append(': %s %s Policy' %
                          (pretty_platform, header.FilterName(self._PLATFORM)))

            self._HandlePolicyHeader(header, target)

            # reformat long text comments, if needed
            comments = aclgenerator.WrapWords(header.comment, 70)
            if comments and comments[0]:
                for line in comments:
                    target.append(': %s' % line)
                target.append(':')
            # add the p4 tags
            target.extend(aclgenerator.AddRepositoryTags(': '))
            target.append(': ' + filter_type)

            if default_action:
                raise aclgenerator.UnsupportedTargetOptionError(
                    'Windows generator does not support default actions')

            # add the terms
            for term in terms:
                term_str = str(term)
                if term_str:
                    target.append(term_str)
                    self._HandleTermFooter(header, term, target)

        target.append('')
        return '\n'.join(target)
Ejemplo n.º 6
0
    def __str__(self):
        # Verify platform specific terms. Skip whole term if platform does not
        # match.
        if self.term.platform:
            if self._PLATFORM not in self.term.platform:
                return ''
        if self.term.platform_exclude:
            if self._PLATFORM in self.term.platform_exclude:
                return ''

        ret_str = []

        # Don't render icmpv6 protocol terms under inet, or icmp under inet6
        if ((self.af == 'inet6' and 'icmp' in self.term.protocol)
                or (self.af == 'inet' and 'icmpv6' in self.term.protocol)):
            logging.debug(
                self.NO_AF_LOG_PROTO.substitute(term=self.term.name,
                                                proto=', '.join(
                                                    self.term.protocol),
                                                af=self.af))
            return ''

        # Term verbatim output - this will skip over most normal term
        # creation code by returning early. Warnings provided in policy.py
        if self.term.verbatim:
            for next_verbatim in self.term.verbatim:
                if next_verbatim[0] == self._PLATFORM:
                    ret_str.append(str(next_verbatim[1]))
            return '\n'.join(ret_str)

        # Create a new term
        self._SetDefaultAction()
        if self._TERM_FORMAT:
            ret_str.append(self._TERM_FORMAT.substitute(term=self.term_name))

        if self._PREJUMP_FORMAT:
            ret_str.append(
                self._PREJUMP_FORMAT.substitute(filter=self.filter,
                                                term=self.term_name))

        if self.verbose:
            if self.term.owner:
                self.term.comment.append('Owner: %s' % self.term.owner)
            # reformat long comments, if needed
            #
            # iptables allows individual comments up to 256 chars.
            # But our generator will limit a single comment line to < 120, using:
            # max = 119 - 27 (static chars in comment command) - [length of term name]
            comment_max_width = 92 - len(self.term_name)
            if comment_max_width < 40:
                comment_max_width = 40
            comments = aclgenerator.WrapWords(self.term.comment,
                                              comment_max_width)
            # append comments to output
            if comments and comments[0]:
                for line in comments:
                    if not line:
                        continue  # iptables-restore does not like 0-length comments.
                    # term comments
                    # Strip out quotes as iptables cant have nested quotes
                    ret_str.append(
                        self._COMMENT_FORMAT.substitute(
                            filter=self.filter,
                            term=self.term_name,
                            comment=str(line).replace('\"', '')))

        # Unsupported configuration; in the case of 'accept' or 'next', we
        # skip the rule.  In other cases, we blow up (raise an exception)
        # to ensure that this is not considered valid configuration.
        if self.term.source_prefix or self.term.destination_prefix:
            if str(self.term.action[0]) not in set(['accept', 'next']):
                raise UnsupportedFilterError(
                    '%s %s %s %s %s %s %s %s' %
                    ('\nTerm', self.term.name, 'has action',
                     str(self.term.action[0]),
                     'with source_prefix or destination_prefix,',
                     ' which is unsupported in', self._PLATFORM,
                     'iptables output.'))
            return ('# skipped %s due to source or destination prefix rule' %
                    self.term.name)

        # protocol
        if self.term.protocol:
            protocol = self.term.protocol
        else:
            protocol = ['all']
        if 'hopopt' in protocol and self.af == 'inet':
            logging.warning('Term %s is using hopopt in IPv4 context.',
                            self.term_name)
            return ''

        (term_saddr, exclude_saddr, term_daddr,
         exclude_daddr) = self._CalculateAddresses(
             self.term.source_address, self.term.source_address_exclude,
             self.term.destination_address,
             self.term.destination_address_exclude)
        if not term_saddr:
            logging.debug(
                self.NO_AF_LOG_ADDR.substitute(term=self.term.name,
                                               direction='source',
                                               af=self.af))
            return ''
        if not term_daddr:
            logging.debug(
                self.NO_AF_LOG_ADDR.substitute(term=self.term.name,
                                               direction='destination',
                                               af=self.af))
            return ''

        # ports
        source_port = []
        destination_port = []
        if self.term.source_port:
            source_port = self.term.source_port
        if self.term.destination_port:
            destination_port = self.term.destination_port

        # icmp-types
        icmp_types = ['']
        if self.term.icmp_type:
            icmp_types = self.NormalizeIcmpTypes(self.term.icmp_type, protocol,
                                                 self.af)

        source_interface = ''
        if self.term.source_interface:
            source_interface = self.term.source_interface

        destination_interface = ''
        if self.term.destination_interface:
            destination_interface = self.term.destination_interface

        log_hits = False
        if self.term.logging:
            # Iptables sends logs to hosts configured syslog
            log_hits = True

        # options
        tcp_flags = []
        tcp_track_options = []
        for next_opt in [str(x) for x in self.term.option]:
            #
            # Sanity checking and high-ports are added as appropriate in
            # pre-processing that is done in __str__ within class Iptables.
            # Option established will add destination port high-ports if protocol
            # contains only tcp, udp or both.  This is done earlier in class Iptables.
            #
            if ((next_opt.find('established') == 0
                 or next_opt.find('tcp-established') == 0)
                    and 'ESTABLISHED' not in [x.strip()
                                              for x in self.options]):
                if next_opt.find(
                        'tcp-established') == 0 and protocol != ['tcp']:
                    raise TcpEstablishedError('%s %s %s' % (
                        '\noption tcp-established can only be applied for proto tcp.',
                        '\nError in term:', self.term.name))

                if self.trackstate:
                    # Use nf_conntrack to track state -- works with any proto
                    self.options.append('-m state --state ESTABLISHED,RELATED')
                elif protocol == ['tcp']:
                    # Simple established-only rule for TCP: Must have ACK field
                    # (SYN/ACK or subsequent ACK), or RST and no other flags.
                    tcp_track_options = [(['ACK'], ['ACK']),
                                         (['SYN', 'FIN', 'ACK',
                                           'RST'], ['RST'])]

            # Iterate through flags table, and create list of tcp-flags to append
            for next_flag in self._TCP_FLAGS_TABLE:
                if next_opt.find(next_flag) == 0:
                    tcp_flags.append(self._TCP_FLAGS_TABLE.get(next_flag))
            if next_opt in self._KNOWN_OPTIONS_MATCHERS:
                self.options.append(self._KNOWN_OPTIONS_MATCHERS[next_opt])
        if self.term.packet_length:
            # Policy format is "#-#", but iptables format is "#:#"
            self.options.append('-m length --length %s' %
                                self.term.packet_length.replace('-', ':'))
        if self.term.fragment_offset:
            self.options.append('-m u32 --u32 4&0x1FFF=%s' %
                                self.term.fragment_offset.replace('-', ':'))
        icmp_code = ['']
        if self.term.icmp_code:
            icmp_code = self.term.icmp_code

        for saddr in exclude_saddr:
            ret_str.extend(
                self._FormatPart('', saddr, '', '', '', '', '', '', '', '', '',
                                 '', '', self._action_table.get('next')))
        for daddr in exclude_daddr:
            ret_str.extend(
                self._FormatPart('', '', '', daddr, '', '', '', '', '', '', '',
                                 '', '', self._action_table.get('next')))

        for saddr in term_saddr:
            for daddr in term_daddr:
                for icmp in icmp_types:
                    for code in icmp_code:
                        for proto in protocol:
                            for tcp_matcher in tcp_track_options or (([],
                                                                      []), ):
                                ret_str.extend(
                                    self._FormatPart(
                                        str(proto), saddr, source_port, daddr,
                                        destination_port, self.options,
                                        tcp_flags, icmp, code, tcp_matcher,
                                        source_interface,
                                        destination_interface, log_hits,
                                        self._action_table.get(
                                            str(self.term.action[0]))))

        if self._POSTJUMP_FORMAT:
            ret_str.append(
                self._POSTJUMP_FORMAT.substitute(filter=self.filter,
                                                 term=self.term_name))

        return '\n'.join(str(v) for v in ret_str if v)
Ejemplo n.º 7
0
    def __str__(self):
        """Render config output from this term object."""

        # Verify platform specific terms. Skip whole term if platform does not
        # match.
        if self.term.platform:
            if self._PLATFORM not in self.term.platform:
                return ''
        if self.term.platform_exclude:
            if self._PLATFORM in self.term.platform_exclude:
                return ''

        ret_str = []
        self._SetDefaultAction()

        # Create a new term
        ret_str.append('\n# term %s' % self.term.name)

        comments = aclgenerator.WrapWords(self.term.comment, 80)
        # append comments to output
        if comments and comments[0]:
            for line in comments:
                ret_str.append('# %s' % str(line))

        if str(self.term.action[0]) not in self._ACTION_TABLE:
            raise aclgenerator.UnsupportedFilterError(
                '%s %s %s %s' % ('\n', self.term.name, self.term.action[0],
                                 'action not currently supported.'))

        if self.direction and str(self.direction) not in self._DIRECTION_TABLE:
            raise aclgenerator.UnsupportedFilterError(
                '%s %s %s %s' % ('\n', self.term.name, self.term.direction,
                                 'direction not currently supported.'))
        # protocol
        if self.term.protocol:
            protocol = self.term.protocol
        else:
            protocol = []

        # source address
        term_saddrs = self._CheckAddressAf(self.term.source_address)
        if not term_saddrs:
            logging.debug(
                self.NO_AF_LOG_ADDR.substitute(term=self.term.name,
                                               direction='source',
                                               af=self.af))
            return ''
        term_saddr = self._GenerateAddrStatement(
            term_saddrs, self.term.source_address_exclude)

        # destination address
        term_daddrs = self._CheckAddressAf(self.term.destination_address)
        if not term_daddrs:
            logging.debug(
                self.NO_AF_LOG_ADDR.substitute(term=self.term.name,
                                               direction='destination',
                                               af=self.af))
            return ''
        term_daddr = self._GenerateAddrStatement(
            term_daddrs, self.term.destination_address_exclude)

        # ports
        source_port = []
        destination_port = []
        if self.term.source_port:
            source_port = self._GeneratePortStatement(self.term.source_port)
        if self.term.destination_port:
            destination_port = self._GeneratePortStatement(
                self.term.destination_port)

        # icmp-type
        icmp_types = ['']
        if self.term.icmp_type:
            if self.af != 'mixed':
                af = self.af
            elif protocol == ['icmp']:
                af = 'inet'
            elif protocol == ['icmpv6']:
                af = 'inet6'
            else:
                raise aclgenerator.UnsupportedFilterError(
                    '%s %s %s' %
                    ('\n', self.term.name,
                     'icmp protocol is not defined or not supported.'))
            icmp_types = self.NormalizeIcmpTypes(self.term.icmp_type, protocol,
                                                 af)

        # options
        tcp_flags_set = []
        tcp_flags_check = []
        for next_opt in [str(x) for x in self.term.option]:
            for next_flag in self._TCP_FLAGS_TABLE:
                if next_opt.find(next_flag) == 0:
                    if protocol != ['tcp']:
                        raise aclgenerator.UnsupportedFilterError(
                            '%s %s %s' %
                            ('\n', self.term.name,
                             'tcp flags may only be specified with tcp protocol.'
                             ))
                    tcp_flags_set.append(self._TCP_FLAGS_TABLE.get(next_flag))
                    tcp_flags_check.append(
                        self._TCP_FLAGS_TABLE.get(next_flag))

        # If tcp-established is set, override any of the flags above with the
        # S/SA flags.  Issue an error if flags are specified with 'established'.
        for opt in [str(x) for x in self.term.option]:
            if opt == 'established' or opt == 'tcp-established':
                if tcp_flags_set or tcp_flags_check:
                    raise aclgenerator.UnsupportedFilterError(
                        '%s %s %s' %
                        ('\n', self.term.name,
                         'tcp flags may not be specified with tcp-established.'
                         ))
                # We need to set 'flags A/A' for established regardless of whether or
                # not we're stateful:
                # - if we stateful, the default is 'flags S/SA' which prevent writing
                # rules for reply packets.
                # - if we're stateless, this is the only way to do it.
                if not protocol or 'tcp' in protocol:
                    tcp_flags_set.append(self._TCP_FLAGS_TABLE.get('ack'))
                    tcp_flags_check.append(self._TCP_FLAGS_TABLE.get('ack'))

        # The default behavior of pf is 'keep state flags S/SA'.  If we're not
        # stateless, and if flags have not been specified explicitly via options,
        # append that here.  Note that pf allows appending flags for udp and icmp;
        # they are just ignored, as long as TCP is in the proto.  This lets you
        # doing things like 'proto { tcp udp icmp } flags S/SA' and have the flags
        # only applied to the tcp bits that match.  However, the policy description
        # language prohibits setting flags on non-TCP, since it doesn't make sense
        # on all platforms.
        if ((not protocol or protocol == ['tcp']) and self.stateful
                and not tcp_flags_set and not tcp_flags_check):
            tcp_flags_set.append(self._TCP_FLAGS_TABLE.get('syn'))
            tcp_flags_check.append(self._TCP_FLAGS_TABLE.get('syn'))
            tcp_flags_check.append(self._TCP_FLAGS_TABLE.get('ack'))

        ret_str.extend(
            self._FormatPart(
                self.term.action[0],
                self.direction,
                self.term.logging,
                self.af,
                protocol,
                term_saddr,
                source_port,
                term_daddr,
                destination_port,
                tcp_flags_set,
                tcp_flags_check,
                icmp_types,
                self.options,
                self.stateful,
            ))

        return '\n'.join(str(v) for v in ret_str if v is not '')
Ejemplo n.º 8
0
    def __str__(self):
        """Render config output from this term object."""
        # Verify platform specific terms. Skip whole term if platform does not
        # match.
        if self.term.platform:
            if 'srx' not in self.term.platform:
                return ''
        if self.term.platform_exclude:
            if 'srx' in self.term.platform_exclude:
                return ''
        ret_str = IndentList(JuniperSRX.INDENT)

        # COMMENTS
        comment_max_width = 68
        if self.term.owner and self.verbose:
            self.term.comment.append('Owner: %s' % self.term.owner)
        comments = aclgenerator.WrapWords(self.term.comment, comment_max_width)
        if comments and comments[0] and self.verbose:
            ret_str.IndentAppend(3, '/*')
            for line in comments:
                ret_str.IndentAppend(3, line)
            ret_str.IndentAppend(3, '*/')

        ret_str.IndentAppend(3, 'policy ' + self.term.name + ' {')
        ret_str.IndentAppend(4, 'match {')
        # SOURCE-ADDRESS
        if self.term.source_address:
            saddr_check = set()
            for saddr in self.term.source_address:
                saddr_check.add(saddr.parent_token)
            saddr_check = sorted(saddr_check)
            ret_str.IndentAppend(5,
                                 JunipersrxList('source-address', saddr_check))
        else:
            ret_str.IndentAppend(5, 'source-address any;')

        # DESTINATION-ADDRESS
        if self.term.destination_address:
            daddr_check = []
            for daddr in self.term.destination_address:
                daddr_check.append(daddr.parent_token)
            daddr_check = set(daddr_check)
            daddr_check = list(daddr_check)
            daddr_check.sort()
            ret_str.IndentAppend(
                5, JunipersrxList('destination-address', daddr_check))
        else:
            ret_str.IndentAppend(5, 'destination-address any;')

        # APPLICATION
        if (not self.term.source_port and not self.term.destination_port
                and not self.term.icmp_type and not self.term.protocol):
            ret_str.IndentAppend(5, 'application any;')
        else:
            if hasattr(self.term, 'replacement_application_name'):
                ret_str.IndentAppend(
                    5, 'application ' +
                    self.term.replacement_application_name + '-app;')
            else:
                ret_str.IndentAppend(5,
                                     'application ' + self.term.name + '-app;')

        # DSCP MATCH
        if self.term.dscp_match:
            ret_str.IndentAppend(5, JunipersrxList('dscp',
                                                   self.term.dscp_match))

        # DSCP EXCEPT
        if self.term.dscp_except:
            ret_str.IndentAppend(
                5, JunipersrxList('dscp-except', self.term.dscp_except))

        ret_str.IndentAppend(4, '}')

        # ACTIONS
        for action in self.term.action:
            ret_str.IndentAppend(4, 'then {')

            # VPN target can be only specified when ACTION is accept
            if str(action) == 'accept' and self.term.vpn:
                ret_str.IndentAppend(5, self.ACTIONS.get(str(action)) + ' {')
                ret_str.IndentAppend(6, 'tunnel {')
                ret_str.IndentAppend(7, 'ipsec-vpn %s;' % self.term.vpn[0])
                if self.term.vpn[1]:
                    ret_str.IndentAppend(7,
                                         'pair-policy %s;' % self.term.vpn[1])

                ret_str.IndentAppend(6, '}')
                ret_str.IndentAppend(5, '}')
            else:
                ret_str.IndentAppend(5, self.ACTIONS.get(str(action)) + ';')

            # DSCP SET
            if self.term.dscp_set:
                ret_str.IndentAppend(5, 'dscp ' + self.term.dscp_set + ';')

            # LOGGING
            if self.term.logging:
                ret_str.IndentAppend(5, 'log {')
                ret_str.IndentAppend(6, 'session-init;')
                for log_target in self.term.logging:
                    if str(log_target) == 'log-both':
                        ret_str.IndentAppend(6, 'session-close;')
                ret_str.IndentAppend(5, '}')

            ret_str.IndentAppend(4, '}')

            ret_str.IndentAppend(3, '}')

        return '\n'.join(ret_str)
Ejemplo n.º 9
0
    def __str__(self):
        # Verify platform specific terms. Skip whole term if platform does not
        # match.
        if self.term.platform:
            if self.platform not in self.term.platform:
                return ''
        if self.term.platform_exclude:
            if self.platform in self.term.platform_exclude:
                return ''

        source_address_set = set()
        destination_address_set = set()
        ret_str = ['\n']
        if self.verbose:
            ret_str.append(' remark %s' % self.term.name)
            comments = aclgenerator.WrapWords(self.term.comment,
                                              _COMMENT_MAX_WIDTH)
            if comments and comments[0]:
                for comment in comments:
                    ret_str.append(' remark %s' % str(comment))

        # Term verbatim output - this will skip over normal term creation
        # code by returning early.  Warnings provided in policy.py.
        if self.term.verbatim:
            for next_verbatim in self.term.verbatim:
                if next_verbatim[0] == self.platform:
                    ret_str.append(str(next_verbatim[1]))
                return '\n'.join(ret_str)

        # protocol
        if not self.term.protocol:
            protocol = ['ip']

        else:
            protocol = [
                proto if proto in self.ALLOWED_PROTO_STRINGS else
                self.PROTO_MAP.get(proto) for proto in self.term.protocol
            ]

        # addresses
        source_address = self.term.source_address
        if not self.term.source_address:
            source_address = [nacaddr.IPv4('0.0.0.0/0', token='any')]
        source_address_set.add(source_address[0].parent_token)

        destination_address = self.term.destination_address
        if not self.term.destination_address:
            destination_address = [nacaddr.IPv4('0.0.0.0/0', token='any')]
        destination_address_set.add(destination_address[0].parent_token)
        # ports
        source_port = [()]
        destination_port = [()]
        if self.term.source_port:
            source_port = self.term.source_port
        if self.term.destination_port:
            destination_port = self.term.destination_port
        for saddr in source_address_set:
            for daddr in destination_address_set:
                for sport in source_port:
                    for dport in destination_port:
                        for proto in protocol:
                            ret_str.append(
                                self._TermletToStr(
                                    _ACTION_TABLE.get(str(
                                        self.term.action[0])), proto, saddr,
                                    sport, daddr, dport))

        return '\n'.join(ret_str)
Ejemplo n.º 10
0
    def __str__(self):
        # Verify platform specific terms. Skip whole term if platform does not
        # match.
        if self.term.platform:
            if self.platform not in self.term.platform:
                return ''
        if self.term.platform_exclude:
            if self.platform in self.term.platform_exclude:
                return ''

        ret_str = []

        # Term verbatim output - this will skip over normal term creation
        # code by returning early.  Warnings provided in policy.py.
        if self.term.verbatim:
            for next_verbatim in self.term.verbatim:
                if next_verbatim[0] == self.platform:
                    ret_str.append(str(next_verbatim[1]))
                return '\n'.join(ret_str)

        v4_addresses = [
            x for x in self.term.address if not isinstance(x, nacaddr.IPv6)
        ]
        if self.filter_name.isdigit():
            if self.verbose:
                ret_str.append('access-list %s remark %s' %
                               (self.filter_name, self.term.name))
                comments = aclgenerator.WrapWords(self.term.comment,
                                                  _COMMENT_MAX_WIDTH)
                for comment in comments:
                    ret_str.append('access-list %s remark %s' %
                                   (self.filter_name, comment))

            action = _ACTION_TABLE.get(str(self.term.action[0]))
            if v4_addresses:
                for addr in v4_addresses:
                    if addr.prefixlen == 32:
                        ret_str.append(
                            'access-list %s %s %s%s%s' %
                            (self.filter_name, action, addr.network_address,
                             self.logstring, self.dscpstring))
                    else:
                        ret_str.append(
                            'access-list %s %s %s %s%s%s' %
                            (self.filter_name, action, addr.network_address,
                             addr.hostmask, self.logstring, self.dscpstring))
            else:
                ret_str.append('access-list %s %s %s%s%s' %
                               (self.filter_name, action, 'any',
                                self.logstring, self.dscpstring))
        else:
            if self.verbose:
                ret_str.append(' remark ' + self.term.name)
                comments = aclgenerator.WrapWords(self.term.comment,
                                                  _COMMENT_MAX_WIDTH)
                if comments and comments[0]:
                    for comment in comments:
                        ret_str.append(' remark ' + str(comment))

            action = _ACTION_TABLE.get(str(self.term.action[0]))
            if v4_addresses:
                for addr in v4_addresses:
                    if addr.prefixlen == 32:
                        ret_str.append(' %s host %s%s%s' %
                                       (action, addr.network_address,
                                        self.logstring, self.dscpstring))
                    elif self.platform == 'arista':
                        ret_str.append(
                            ' %s %s/%s%s%s' %
                            (action, addr.network_address, addr.prefixlen,
                             self.logstring, self.dscpstring))
                    else:
                        ret_str.append(
                            ' %s %s %s%s%s' %
                            (action, addr.network_address, addr.hostmask,
                             self.logstring, self.dscpstring))
            else:
                ret_str.append(
                    ' %s %s%s%s' %
                    (action, 'any', self.logstring, self.dscpstring))

        return '\n'.join(ret_str)
Ejemplo n.º 11
0
    def __str__(self):
        netdestinations = []
        ret_str = []
        term_af = self.AF_MAP.get(self.filter_type)

        if self.term.verbatim:
            for next_verbatim in self.term.verbatim:
                if next_verbatim[0] == _PLATFORM and next_verbatim[1]:
                    ret_str.append('%s%s' % (self._IDENT, next_verbatim[1]))

            return '\n'.join(t for t in ret_str if t)

        comments = self.term.comment[:]

        if self.term.owner:
            comments.append('Owner: %s' % self.term.owner)

        if comments:
            for line in aclgenerator.WrapWords(comments,
                                               self._COMMENT_LINE_LENGTH):
                ret_str.append('%s%s %s' %
                               (self._IDENT, _COMMENT_MARKER, line))

        src_addr_token = ''
        dst_addr_token = ''

        if self._SOURCE_IS_USER_OPT_STR in self.term.option:
            src_addr_token = self._USER_STR
        else:
            if self.term.source_address:
                src_addr = self.term.GetAddressOfVersion(
                    'source_address', term_af)
                if not src_addr:
                    return ''

                src_netdest_id = '%s%s' % (self.term.name.lower(),
                                           self._SRC_NETDEST_SUF)
                src_addr_token = '%s %s' % (self._ALIAS_STR, src_netdest_id)
                netdestinations.append(
                    self._GenerateNetdest(src_netdest_id, src_addr, term_af))

            else:
                src_addr_token = self._ANY_STR

        if self._DESTINATION_IS_USER_OPT_STR in self.term.option:
            dst_addr_token = self._USER_STR
        else:
            if self.term.destination_address:
                dst_addr = self.term.GetAddressOfVersion(
                    'destination_address', term_af)
                if not dst_addr:
                    return ''

                dst_netdest_id = '%s%s' % (self.term.name.lower(),
                                           self._DST_NETDEST_SUF)
                dst_addr_token = '%s %s' % (self._ALIAS_STR, dst_netdest_id)
                netdestinations.append(
                    self._GenerateNetdest(dst_netdest_id, dst_addr, term_af))
            else:
                dst_addr_token = self._ANY_STR

        dst_protocol_list = []
        if self.term.protocol:
            dst_protocol_list = self._GeneratePortTokens(
                self.term.protocol, self.term.destination_port)
        else:
            dst_protocol_list = [self._ANY_STR]

        for dst_port in dst_protocol_list:
            str_tok = [' ']

            if self._NEGATE_OPT_STR in self.term.option:
                str_tok.append(self._NEGATOR)

            if term_af == 6:
                str_tok.append(self._IPV6_START_STR)

            str_tok.append(src_addr_token)
            str_tok.append(dst_addr_token)

            str_tok.append(dst_port)
            str_tok.append(self._ACTIONS.get(self.term.action[0]))
            ret_str.append(' '.join(t for t in str_tok if t))

        self.netdestinations = netdestinations

        return '\n'.join(t for t in ret_str if t)