Skip to content

Commit

Permalink
Cisco ASA: Add enable_dsmo header option
Browse files Browse the repository at this point in the history
  • Loading branch information
hkam40k committed Jul 9, 2021
1 parent 72cfb69 commit 9d0c63c
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
26 changes: 23 additions & 3 deletions capirca/lib/ciscoasa.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from capirca.lib import aclgenerator
from capirca.lib import cisco
from capirca.lib import nacaddr
from capirca.lib import summarizer


_ACTION_TABLE = {
Expand Down Expand Up @@ -64,12 +65,13 @@ class NoCiscoPolicyError(Error):
class Term(cisco.Term):
"""A single ACL Term."""

def __init__(self, term, filter_name, af=4):
def __init__(self, term, filter_name, af=4, enable_dsmo=False):
self.term = term
self.filter_name = filter_name
self.options = []
assert af in (4, 6)
self.af = af
self.enable_dsmo = enable_dsmo

def __str__(self):
# Verify platform specific terms. Skip whole term if platform does not
Expand Down Expand Up @@ -123,6 +125,8 @@ def __str__(self):
source_address = nacaddr.ExcludeAddrs(
source_address,
source_address_exclude)
if len(source_address) > 1 and self.enable_dsmo:
source_address = summarizer.Summarize(source_address)
else:
# source address not set
source_address = ['any']
Expand All @@ -137,6 +141,8 @@ def __str__(self):
destination_address = nacaddr.ExcludeAddrs(
destination_address,
destination_address_exclude)
if len(destination_address) > 1 and self.enable_dsmo:
destination_address = summarizer.Summarize(destination_address)
else:
# destination address not set
destination_address = ['any']
Expand Down Expand Up @@ -184,6 +190,8 @@ def __str__(self):
(saddr == 'any')) and
((isinstance(daddr, nacaddr.IPv4)) or (daddr == 'any'))):
do_output = True
elif isinstance(saddr, summarizer.DSMNet) or isinstance(daddr, summarizer.DSMNet):
do_output = True
if self.af == 6:
if (((isinstance(saddr, nacaddr.IPv6)) or
(saddr == 'any')) and
Expand Down Expand Up @@ -252,6 +260,16 @@ def _TermletToStr(self, filter_name, action, proto, saddr, sport, daddr,
else:
daddr = 'host %s' % (daddr.network_address)

if isinstance(saddr, summarizer.DSMNet):
saddr = '%s %s' % summarizer.ToDottedQuad(saddr, negate=False)
if saddr.endswith('255.255.255.255'):
saddr = f'host {saddr.split()[0]}'

if isinstance(daddr, summarizer.DSMNet):
daddr = '%s %s' % summarizer.ToDottedQuad(daddr, negate=False)
if daddr.endswith('255.255.255.255'):
daddr = f'host {daddr.split()[0]}'

# fix ports
if not sport:
sport = ''
Expand Down Expand Up @@ -325,7 +343,8 @@ def _TranslatePolicy(self, pol, exp_info):
exp_info_date = current_date + datetime.timedelta(weeks=exp_info)

for header, terms in self.policy.filters:
filter_name = header.FilterName('ciscoasa')
filter_options = header.FilterOptions(self._PLATFORM)
filter_name = header.FilterName(self._PLATFORM)

new_terms = []
# now add the terms
Expand All @@ -339,7 +358,8 @@ def _TranslatePolicy(self, pol, exp_info):
'will not be rendered.', term.name, filter_name)
continue

new_terms.append(str(Term(term, filter_name)))
enable_dsmo = len(filter_options) > 1 and 'enable_dsmo' in filter_options[1:]
new_terms.append(str(Term(term, filter_name, enable_dsmo=enable_dsmo)))

self.ciscoasa_policies.append((header, filter_name, new_terms))

Expand Down
29 changes: 29 additions & 0 deletions tests/lib/ciscoasa_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import unittest

from capirca.lib import ciscoasa
from capirca.lib import nacaddr
from capirca.lib import naming
from capirca.lib import policy
import mock
Expand All @@ -34,6 +35,13 @@
}
"""

GOOD_DSMO_HEADER = """
header {
comment:: "this is a test acl"
target:: ciscoasa test-filter enable_dsmo
}
"""

GOOD_TERM_1 = """
term good-term-1 {
verbatim:: ciscoasa "mary had a little lamb"
Expand All @@ -49,6 +57,14 @@
}
"""

GOOD_DSMO_TERM = """
term good-dsmo-term {
protocol:: tcp
destination-address:: SOME_HOST
action:: accept
}
"""

SUPPORTED_TOKENS = {
'action',
'comment',
Expand Down Expand Up @@ -144,6 +160,19 @@ def testBuildWarningTokens(self):
self.assertEqual(st, SUPPORTED_TOKENS)
self.assertEqual(sst, SUPPORTED_SUB_TOKENS)

def testDsmo(self):
addr_list = list()
for octet in range(0, 256):
net = nacaddr.IP('192.168.' + str(octet) + '.64/27')
addr_list.append(net)
self.naming.GetNetAddr.return_value = addr_list

acl = ciscoasa.CiscoASA(policy.ParsePolicy(GOOD_DSMO_HEADER + GOOD_DSMO_TERM,
self.naming), EXP_INFO)
self.assertIn('permit tcp any 192.168.0.64 255.255.0.224', str(acl))

self.naming.GetNetAddr.assert_called_once_with('SOME_HOST')


if __name__ == '__main__':
unittest.main()

0 comments on commit 9d0c63c

Please sign in to comment.