def testServiceIncorrectSyntax(self): badservicedata = [] badservicedata.append('SVC1 = 80//tcp 80/udp') badservicedata.append('SVC2 = 81/tcp') testdefs = naming.Naming(None) self.assertRaises(naming.NamingSyntaxError, testdefs.ParseServiceList, badservicedata)
def testNamespaceCollisionError(self): badservicedata = [] badservicedata.append('SVC1 = 80/tcp') badservicedata.append('SVC1 = 81/udp') testdefs = naming.Naming(None) self.assertRaises(naming.NamespaceCollisionError, testdefs.ParseServiceList, badservicedata)
def setUp(self): super().setUp() self.defs = naming.Naming(None) servicedata = [] servicedata.append('SVC1 = 80/tcp 81/udp 82/tcp') servicedata.append('SVC2 = 80/tcp 81/udp 82/tcp SVC2') servicedata.append('SVC3 = 80/tcp 81/udp') servicedata.append('SVC4 = 80/tcp # some service') servicedata.append('TCP_90 = 90/tcp') servicedata.append('SVC5 = TCP_90') servicedata.append('SVC6 = SVC1 SVC5') networkdata = [] networkdata.append('NET1 = 10.1.0.0/8 # network1') networkdata.append('NET2 = 10.2.0.0/16 # network2.0') networkdata.append(' NET1') networkdata.append('9OCLOCK = 1.2.3.4/32 # 9 is the time') networkdata.append('FOOBAR = 9OCLOCK') networkdata.append('FOO_V6 = ::FFFF:FFFF:FFFF:FFFF') networkdata.append('BAR_V6 = ::1/128') networkdata.append('BAZ = FOO_V6') networkdata.append(' BAR_V6') networkdata.append('BING = NET1 # foo') networkdata.append(' FOO_V6') self.defs.ParseServiceList(servicedata) self.defs.ParseNetworkList(networkdata)
def testServiceMap(self): definitions = naming.Naming() definitions._ParseLine('SSH = 22/tcp', 'services') definitions._ParseLine('SMTP = 25/tcp', 'services') definitions._ParseLine('FOOBAR = 10.0.0.0/8', 'networks') definitions._ParseLine(' 2001:4860:8000::/33', 'networks') pol1 = paloaltofw.PaloAltoFW( policy.ParsePolicy(GOOD_HEADER_1 + SVC_TERM_1, definitions), EXP_INFO) self.assertEqual( pol1.service_map.entries, { ((), ('22', ), 'tcp'): { 'name': 'service-ssh-term-1-tcp' }, ((), ('25', ), 'tcp'): { 'name': 'service-smtp-term-1-tcp' } }, pol1.service_map.entries) pol2 = paloaltofw.PaloAltoFW( policy.ParsePolicy(GOOD_HEADER_1 + SVC_TERM_2, definitions), EXP_INFO) # The expectation is that there will be a single port mapped. self.assertEqual( pol2.service_map.entries, {((), ('25', ), 'tcp'): { 'name': 'service-smtp-term-1-tcp' }}, pol2.service_map.entries)
def get_definitions(networks_file, services_file): defs = naming.Naming() with open(networks_file, "r") as f: defs._ParseFile(f, "networks") with open(services_file, "r") as f: defs._ParseFile(f, "services") return defs
def main(): # TODO(robankeny): Lets move this to gflags usage = 'usage: %prog [options] arg' _parser = OptionParser(usage) _parser.add_option('--definitions-directory', dest='definitions', help='definitions directory', default='./def') _parser.add_option('-p', '--policy-file', dest='pol', help='policy file', default='./policies/sample.pol') _parser.add_option('-d', '--destination', dest='dst', help='destination IP', default='200.1.1.1') _parser.add_option('-s', '--source', dest='src', help='source IP', default='any') _parser.add_option('--proto', '--protocol', dest='proto', help='Protocol (tcp, udp, icmp, etc.)', default='tcp') _parser.add_option('--dport', '--destination-port', dest='dport', help='destination port', default='80') _parser.add_option('--sport', '--source-port', dest='sport', help='source port', default='1025') (FLAGS, unused_args) = _parser.parse_args() defs = naming.Naming(FLAGS.definitions) policy_obj = policy.ParsePolicy(open(FLAGS.pol).read(), defs) check = aclcheck.AclCheck(policy_obj, src=FLAGS.src, dst=FLAGS.dst, sport=FLAGS.sport, dport=FLAGS.dport, proto=FLAGS.proto) print(str(check))
def Run(base_directory, definitions_directory, policy_file, output_directory, context): definitions = None try: definitions = naming.Naming(definitions_directory) except naming.NoDefinitionsError: err_msg = 'bad definitions directory: %s' % definitions_directory logging.fatal(err_msg) # thead-safe list for storing files to write manager = context.Manager() write_files = manager.list() with_errors = False if policy_file: # render just one file logging.info('rendering one file') RenderFile(base_directory, policy_file, output_directory, definitions, FLAGS.exp_info, write_files) elif FLAGS.max_renderers == 1: # If only one process, run it sequentially policies = DiscoverAllPolicies(base_directory, output_directory, definitions) for pol in policies: RenderFile(base_directory, pol.get('in_file'), pol.get('out_dir'), definitions, FLAGS.exp_info, write_files) else: # render all files in parallel policies = DiscoverAllPolicies(base_directory, output_directory, definitions) pool = context.Pool(processes=FLAGS.max_renderers) results = [] for pol in policies: results.append( pool.apply_async(RenderFile, args=(base_directory, pol.get('in_file'), pol.get('out_dir'), definitions, FLAGS.exp_info, write_files))) pool.close() pool.join() for result in results: try: result.get() except (ACLParserError, ACLGeneratorError) as e: with_errors = True logging.warning( '\n\nerror encountered in rendering ' 'process:\n%s\n\n', e) # actually write files to disk WriteFiles(write_files) if with_errors: logging.warning('done, with errors.') sys.exit(1) else: logging.info('done.')
def _load_test_definitions(netstr, svcstr=None): # type: (Text, Text) -> naming.Naming """Parses a Capirca Naming from the given network and services strings.""" defs = naming.Naming() if netstr: defs._ParseFile(StringIO(netstr), 'networks') if svcstr: defs._ParseFile(StringIO(svcstr), 'services') return defs
def Run(base_directory, definitions_directory, policy_file, output_directory, exp_info, max_renderers, ignore_directories, optimize, shade_check, context): definitions = None try: definitions = naming.Naming(definitions_directory) except naming.NoDefinitionsError: err_msg = 'bad definitions directory: %s' % definitions_directory logging.fatal(err_msg) # thead-safe list for storing files to write manager = context.Manager() write_files = manager.list() with_errors = False if policy_file: # render just one file logging.info('rendering one file') RenderFile(base_directory, policy_file, output_directory, definitions, exp_info, optimize, shade_check, write_files) else: # render all files in parallel logging.info('finding policies...') pols = [] pols.extend( DescendRecursively(base_directory, output_directory, definitions, ignore_directories)) pool = context.Pool(processes=max_renderers) results = [] for pol in pols: results.append( pool.apply_async(RenderFile, args=(base_directory, pol.get('in_file'), pol.get('out_dir'), definitions, exp_info, optimize, shade_check, write_files))) pool.close() pool.join() for result in results: try: result.get() except (ACLParserError, ACLGeneratorError) as e: with_errors = True logging.warning( '\n\nerror encountered in rendering ' 'process:\n%s\n\n', e) # actually write files to disk WriteFiles(write_files) if with_errors: logging.warning('done, with errors.') sys.exit(1) else: logging.info('done.')
def testUndefinedTokenNesting(self): bad_servicedata = ['FOO = 7/tcp BAR'] bad_networkdata = ['NETGROUP = 10.0.0.0/8 FOOBAR'] baddefs = naming.Naming(None) baddefs.ParseServiceList(bad_servicedata) baddefs.ParseNetworkList(bad_networkdata) self.assertRaises(naming.UndefinedServiceError, baddefs._CheckUnseen, 'services') self.assertRaises(naming.UndefinedAddressError, baddefs._CheckUnseen, 'networks')
def setUp(self): self.defs = naming.Naming(None) servicedata = [] servicedata.append('SSH = 22/tcp') networkdata = [] networkdata.append('NET172 = 172.16.0.0/12') networkdata.append('NET10 = 10.0.0.0/8') self.defs.ParseServiceList(servicedata) self.defs.ParseNetworkList(networkdata) self.pol = policy.ParsePolicy(POLICYTEXT, self.defs)
def setUp(self): """Call before every test case.""" super().setUp() parser = optparse.OptionParser() parser.add_option('-d', '--def', dest='definitions', help='definitions directory', default='../def') (FLAGS, args) = parser.parse_args() self.defs = naming.Naming(FLAGS.definitions)
def __init__(self, filename, defs_data=None): """Build policy object and naming definitions from provided filenames. Args: filename: location of a .pol file defs_data: location of naming definitions directory, if any """ self.defs = naming.Naming(defs_data) self.filter = [] try: self.data = open(filename, 'r').readlines() except IOError, error_info: info = str(filename) + ' cannot be opened' raise FileOpenError('%s\n%s' % (info, error_info))
def __init__(self, config: Mapping, device_policies: List[str], netbox: pynetbox.api): """Initialize the instance. Arguments: config (dict): the Homer config. device_policies (list): List of Capirca policies to generate. netbox (pynetbox.api): the Netbox API instance. """ self._config = config self._device_policies = device_policies self._public_policies_dir = Path(self._config['base_paths']['public'], 'policies') self._private_base_path = self._config['base_paths'].get( 'private', None) definitions_path = Path(self._config['base_paths']['public'], 'definitions') self.definitions = naming.Naming(str(definitions_path)) # If we want to use Netbox as network definition source if self._config['capirca'].get('netbox_definitons', False) and netbox: try: script_result = netbox.extras.scripts.get( 'capirca.GetHosts').result if str(script_result.status) != 'Completed': raise HomerError( 'Netbox capirca.GetHosts script status is: {}.'.format( script_result.status)) runtime = datetime.fromisoformat( script_result.completed[:-1]) # To remove the final Z now = datetime.utcnow() # Warn the user if the Netbox data is 3 day old or more if runtime < now - timedelta(days=3): logger.warning( 'Netbox capirca.GetHosts script is > 3 days old.') netbox_definitons = script_result.data.output except pynetbox.RequestError: raise HomerError( 'Make sure homer can reach the capirca.GetHosts script on Netbox.' ) # ParseNetworkList expects an array of lines, while Netbox API returns a string with \n self.definitions.ParseNetworkList(netbox_definitons.splitlines())
def __init__(self, filename, defs_data=None): """Build policy object and naming definitions from provided filenames. Args: filename: location of a .pol file defs_data: location of naming definitions directory, if any """ self.defs = naming.Naming(defs_data) self.filter = [] try: self.data = open(filename, 'r').readlines() except IOError as error_info: info = str(filename) + ' cannot be opened' raise FileOpenError('%s\n%s' % (info, error_info)) indent = 0 in_header = False in_term = False filt = Filter() term = Term() in_string = False for line in self.data: words = line.strip().split() quotes = len(line.split('"')) + 1 if quotes % 2: # are we in or out of double quotes in_string = not in_string # flip status of quote status if not in_string: if '{' in words: indent += 1 if words: if words[0] == 'header': in_header = True if words[0] == 'term': in_term = True term = Term(words[1]) if in_header and words[0] == 'target::': if filt.name != words[ 2]: # avoid empty dupe filters due to filt = Filter( words[2]) # multiple target header lines if in_term: if words[0] == 'source-address::': term.source.extend(words[1:]) if words[0] == 'destination-address::': term.destination.extend(words[1:]) if words[0] == 'source-port::': term.sport.extend(words[1:]) if words[0] == 'destination-port::': term.dport.extend(words[1:]) if words[0] == 'action::': term.action.extend(words[1:]) if words[0] == 'protocol::': term.protocol.extend(words[1:]) if words[0] == 'option::': term.option.extend(words[1:]) if '}' in words: indent -= 1 if in_header: self.filter.append(filt) in_header = False if in_term: filt.term.append(term) in_term = False
def setUp(self): self.db = naming.Naming(None) self.db.ParseServiceList(_SERVICE.split('\n')) self.db.ParseNetworkList(_NETWORK.split('\n'))
def testPanPorts(self): POL = """ header { target:: paloalto from-zone trust to-zone untrust } term rule-1 { %s action:: accept }""" T = """ protocol:: udp destination-port:: NTP """ definitions = naming.Naming() definitions._ParseLine('NTP = 123/tcp 123/udp', 'services') definitions._ParseLine('DNS = 53/tcp 53/udp', 'services') pol = policy.ParsePolicy(POL % T, definitions) paloalto = paloaltofw.PaloAltoFW(pol, EXP_INFO) output = str(paloalto) name = "service-rule-1-udp" path = "/entry[@name='%s']/protocol/udp/port" % name x = paloalto.config.findtext(PATH_SERVICE + path) self.assertEqual(x, "123", output) path = "/entry[@name='%s']/protocol/udp/source-port" % name x = paloalto.config.findtext(PATH_SERVICE + path) self.assertIsNone(x, output) T = """ protocol:: udp source-port:: NTP """ pol = policy.ParsePolicy(POL % T, definitions) paloalto = paloaltofw.PaloAltoFW(pol, EXP_INFO) output = str(paloalto) name = "service-rule-1-udp" path = "/entry[@name='%s']/protocol/udp/port" % name x = paloalto.config.findtext(PATH_SERVICE + path) self.assertEqual(x, "0-65535", output) path = "/entry[@name='%s']/protocol/udp/source-port" % name x = paloalto.config.findtext(PATH_SERVICE + path) self.assertEqual(x, "123", output) T = """ protocol:: tcp source-port:: NTP destination-port:: NTP DNS """ pol = policy.ParsePolicy(POL % T, definitions) paloalto = paloaltofw.PaloAltoFW(pol, EXP_INFO) output = str(paloalto) name = "service-rule-1-tcp" path = "/entry[@name='%s']/protocol/tcp/port" % name x = paloalto.config.findtext(PATH_SERVICE + path) self.assertEqual(x, "53,123", output) path = "/entry[@name='%s']/protocol/tcp/source-port" % name x = paloalto.config.findtext(PATH_SERVICE + path) self.assertEqual(x, "123", output) T = """ protocol:: tcp """ pol = policy.ParsePolicy(POL % T, definitions) paloalto = paloaltofw.PaloAltoFW(pol, EXP_INFO) output = str(paloalto) name = "any-tcp" path = "/entry[@name='%s']/protocol/tcp/port" % name x = paloalto.config.findtext(PATH_SERVICE + path) self.assertEqual(x, "0-65535", output) path = "/entry[@name='%s']/protocol/tcp/source-port" % name x = paloalto.config.find(PATH_SERVICE + path) self.assertIsNone(x, output) T = """ protocol:: tcp udp """ pol = policy.ParsePolicy(POL % T, definitions) paloalto = paloaltofw.PaloAltoFW(pol, EXP_INFO) output = str(paloalto) name = "any-tcp" path = "/entry[@name='%s']/protocol/tcp/port" % name x = paloalto.config.findtext(PATH_SERVICE + path) self.assertEqual(x, "0-65535", output) name = "any-udp" path = "/entry[@name='%s']/protocol/udp/port" % name x = paloalto.config.findtext(PATH_SERVICE + path) self.assertEqual(x, "0-65535", output) x = paloalto.config.findall(PATH_RULES + "/entry[@name='rule-1']/service/member") services = {elem.text for elem in x} self.assertEqual({"any-tcp", "any-udp"}, services, output)
def testNoAddrObj(self): definitions = naming.Naming() definitions._ParseLine('NET1 = 10.1.0.0/24', 'networks') definitions._ParseLine('NET2 = 10.2.0.0/24', 'networks') definitions._ParseLine('NET3 = 10.3.1.0/24', 'networks') definitions._ParseLine(' 10.3.2.0/24', 'networks') definitions._ParseLine('NET4 = 2001:db8:0:aa::/64', 'networks') definitions._ParseLine(' 2001:db8:0:bb::/64', 'networks') definitions._ParseLine('NET5 = NET3 NET4', 'networks') POL = """ header { target:: paloalto from-zone trust to-zone untrust %s no-addr-obj } term rule-1 { %s action:: accept protocol:: tcp }""" T = """ source-address:: NET1 destination-address:: NET2 NET3 """ pol = policy.ParsePolicy(POL % ("inet", T), definitions) paloalto = paloaltofw.PaloAltoFW(pol, EXP_INFO) output = str(paloalto) x = paloalto.config.findall(PATH_RULES + "/entry[@name='rule-1']/source/member") self.assertTrue(len(x) > 0, output) addrs = {elem.text for elem in x} self.assertEqual({"10.1.0.0/24"}, addrs, output) x = paloalto.config.findall( PATH_RULES + "/entry[@name='rule-1']/destination/member") self.assertTrue(len(x) > 0, output) addrs = {elem.text for elem in x} self.assertEqual({"10.2.0.0/24", "10.3.1.0/24", "10.3.2.0/24"}, addrs, output) T = """ source-address:: NET4 """ pol = policy.ParsePolicy(POL % ("inet6", T), definitions) paloalto = paloaltofw.PaloAltoFW(pol, EXP_INFO) output = str(paloalto) x = paloalto.config.findall(PATH_RULES + "/entry[@name='rule-1']/source/member") self.assertTrue(len(x) > 0, output) addrs = {elem.text for elem in x} self.assertEqual({"2001:db8:0:aa::/64", "2001:db8:0:bb::/64"}, addrs, output) x = paloalto.config.findall( PATH_RULES + "/entry[@name='rule-1']/destination/member") self.assertTrue(len(x) > 0, output) addrs = {elem.text for elem in x} self.assertEqual({"any"}, addrs, output) T = """ destination-address:: NET5 """ pol = policy.ParsePolicy(POL % ("mixed", T), definitions) paloalto = paloaltofw.PaloAltoFW(pol, EXP_INFO) output = str(paloalto) x = paloalto.config.findall(PATH_RULES + "/entry[@name='rule-1']/source/member") self.assertTrue(len(x) > 0, output) addrs = {elem.text for elem in x} self.assertEqual({"any"}, addrs, output) x = paloalto.config.findall( PATH_RULES + "/entry[@name='rule-1']/destination/member") self.assertTrue(len(x) > 0, output) addrs = {elem.text for elem in x} self.assertEqual( { "10.3.1.0/24", "10.3.2.0/24", "2001:db8:0:aa::/64", "2001:db8:0:bb::/64" }, addrs, output) POL = """ header { target:: paloalto from-zone trust to-zone untrust inet no-addr-obj } term rule-1 { source-address:: NET1 NET2 action:: accept protocol:: tcp } header { target:: paloalto from-zone trust to-zone untrust inet addr-obj } term rule-1 { destination-address:: NET3 action:: accept protocol:: tcp }""" pol = policy.ParsePolicy(POL, definitions) self.assertRaisesRegex( paloaltofw.UnsupportedHeaderError, '^Cannot mix addr-obj and no-addr-obj header ' 'option in a single policy file$', paloaltofw.PaloAltoFW, pol, EXP_INFO)
def _init_definitions(definitions_or_path): # type: (Union[str, naming.Naming]) -> naming.Naming if isinstance(definitions_or_path, naming.Naming): return definitions_or_path return naming.Naming(naming_dir=definitions_or_path)
def testParseServiceFile(self): filedefs = naming.Naming(None) data = io.BytesIO('HTTP = 80/tcp\n'.encode('utf8')) filedefs._ParseFile(data, 'services') self.assertEqual(filedefs.GetService('HTTP'), ['80/tcp'])
def testPanApplication(self): POL1 = """ header { target:: paloalto from-zone trust to-zone untrust } term rule-1 { action:: accept }""" POL2 = """ header { target:: paloalto from-zone trust to-zone untrust } term rule-1 { pan-application:: %s action:: accept %s }""" APPS = [ {'app1'}, {'app1', 'app2'}, {'app1', 'app2', 'app3'}, ] POL3 = """ header { target:: paloalto from-zone trust to-zone untrust } term rule-1 { pan-application:: web-browsing action:: accept%s }""" T0 = '' T1 = """ protocol:: tcp """ T2 = """ protocol:: tcp destination-port:: PORT1 PORT2 """ POL4 = """ header { target:: paloalto from-zone trust to-zone untrust %s } term rule-1 { pan-application:: web-browsing action:: accept protocol:: %s }""" POL5 = """ header { target:: paloalto from-zone trust to-zone untrust } term rule-1 { pan-application:: web-browsing action:: accept protocol:: icmp icmp-type:: echo-request }""" POL6 = """ header { target:: paloalto from-zone trust to-zone untrust } term rule-1 { pan-application:: web-browsing protocol:: tcp icmp destination-port:: PORT1 action:: accept }""" pol = policy.ParsePolicy(POL1, self.naming) paloalto = paloaltofw.PaloAltoFW(pol, EXP_INFO) output = str(paloalto) x = paloalto.config.findtext( PATH_RULES + "/entry[@name='rule-1']/application/member") self.assertEqual(x, 'any', output) for i, app in enumerate(APPS): pol = policy.ParsePolicy(POL2 % (' '.join(app), ''), self.naming) paloalto = paloaltofw.PaloAltoFW(pol, EXP_INFO) output = str(paloalto) x = paloalto.config.findall( PATH_RULES + "/entry[@name='rule-1']/application/member") apps = {elem.text for elem in x} self.assertEqual(APPS[i], apps, output) for i, app in enumerate(APPS): pol = policy.ParsePolicy(POL2 % (' '.join(app), 'protocol:: tcp'), self.naming) paloalto = paloaltofw.PaloAltoFW(pol, EXP_INFO) output = str(paloalto) x = paloalto.config.findall( PATH_RULES + "/entry[@name='rule-1']/application/member") apps = {elem.text for elem in x} self.assertEqual(APPS[i], apps, output) pol = policy.ParsePolicy(POL3 % T0, self.naming) paloalto = paloaltofw.PaloAltoFW(pol, EXP_INFO) output = str(paloalto) x = paloalto.config.findtext(PATH_RULES + "/entry[@name='rule-1']/service/member") self.assertEqual(x, 'application-default', output) pol = policy.ParsePolicy(POL3 % T1, self.naming) paloalto = paloaltofw.PaloAltoFW(pol, EXP_INFO) output = str(paloalto) x = paloalto.config.findtext(PATH_RULES + "/entry[@name='rule-1']/service/member") self.assertEqual(x, 'any-tcp', output) definitions = naming.Naming() definitions._ParseLine('PORT1 = 8080/tcp', 'services') definitions._ParseLine('PORT2 = 8081/tcp', 'services') pol = policy.ParsePolicy(POL3 % T2, definitions) paloalto = paloaltofw.PaloAltoFW(pol, EXP_INFO) output = str(paloalto) x = paloalto.config.findtext(PATH_RULES + "/entry[@name='rule-1']/service/member") self.assertEqual(x, 'service-rule-1-tcp', output) regex = ('^Term rule-1 contains non tcp, udp protocols ' 'with pan-application:') pol = policy.ParsePolicy(POL4 % ('inet', 'tcp icmp'), self.naming) self.assertRaisesRegex(paloaltofw.UnsupportedFilterError, regex, paloaltofw.PaloAltoFW, pol, EXP_INFO) pol = policy.ParsePolicy(POL4 % ('inet6', 'icmpv6'), self.naming) self.assertRaisesRegex(paloaltofw.UnsupportedFilterError, regex, paloaltofw.PaloAltoFW, pol, EXP_INFO) pol = policy.ParsePolicy(POL5, self.naming) self.assertRaisesRegex(paloaltofw.UnsupportedFilterError, regex, paloaltofw.PaloAltoFW, pol, EXP_INFO) self.assertRaisesRegex( policy.MixedPortandNonPortProtos, '^Term rule-1 contains mixed uses of protocols ' 'with and without port numbers', policy.ParsePolicy, POL6, definitions)
def testParseNetFile(self): filedefs = naming.Naming(None) data = ['FOO = 127.0.0.1 # some network\n'] filedefs._ParseFile(data, 'networks') self.assertEqual(filedefs.GetNetAddr('FOO'), [nacaddr.IPv4('127.0.0.1')])
def Run(base_directory: str, definitions_directory: str, policy_file: str, output_directory: str, exp_info: int, max_renderers: int, ignore_directories: List[str], optimize: bool, shade_check: bool, context: multiprocessing.context.BaseContext): """Generate ACLs. Args: base_directory: directory containing policy files. definitions_directory: directory containing NETWORK and SERVICES definition files. policy_file: path to a single policy file to render. output_directory: directory in which rendered files are placed. exp_info: print a info message when a term is set to expire in that many weeks. max_renderers: the number of renderers to run in parallel. ignore_directories: directories to ignore when searching for policy files. optimize: a boolean indicating if we should turn on optimization or not. shade_check: should we raise an error if a term is completely shaded. context: multiprocessing context """ definitions = None try: definitions = naming.Naming(definitions_directory) except naming.NoDefinitionsError: err_msg = 'bad definitions directory: %s' % definitions_directory logging.fatal(err_msg) return # static type analyzer can't detect that logging.fatal exits program # thead-safe list for storing files to write manager: multiprocessing.managers.SyncManager = context.Manager() write_files: WriteList = manager.list() with_errors = False logging.info('finding policies...') if policy_file: # render just one file logging.info('rendering one file') RenderFile(base_directory, pathlib.Path(policy_file), pathlib.Path(output_directory), definitions, exp_info, optimize, shade_check, write_files) elif max_renderers == 1: # If only one process, run it sequentially policies = DescendDirectory(base_directory, ignore_directories) for pol in policies: RenderFile(base_directory, pol, pathlib.Path(output_directory), definitions, exp_info, optimize, shade_check, write_files) else: # render all files in parallel policies = DescendDirectory(base_directory, ignore_directories) pool = context.Pool(processes=max_renderers) results: List[multiprocessing.pool.AsyncResult] = [] for pol in policies: results.append( pool.apply_async(RenderFile, args=(base_directory, pol, output_directory, definitions, exp_info, optimize, shade_check, write_files))) pool.close() pool.join() for result in results: try: result.get() except (ACLParserError, ACLGeneratorError) as e: with_errors = True logging.warning( '\n\nerror encountered in rendering process:\n%s\n\n', e) # actually write files to disk WriteFiles(write_files) if with_errors: logging.warning('done, with errors.') sys.exit(1) else: logging.info('done.')
def main(argv): """Determines the code path based on the arguments passed.""" del argv # Unused. parser = cli_options() options = parser.parse_args() db = naming.Naming(options.defs) p = pprint.PrettyPrinter(indent=1, depth=4, width=1).pprint # if -i and any other option: if options.ip and any( [options.gmp, options.cmp, options.obj, options.svc, options.port]): logging.info('You can only use -i with -t or by itself') # if -i and -t elif options.token and options.ip: try: get_nets([options.token], db) except naming.UndefinedAddressError: logging.info("Network group '%s' is not defined!", options.token) else: results = compare_ip_token(options, db) logging.info(results) # if -t, but not -i; invalid! elif options.token and not options.ip: logging.info('You must specify an IP Address with -i [addr]') # if -i elif options.ip: for ip in options.ip: groups = get_ip_parents(ip, db) logging.info('Results for IP: %s', ip) # iterate and print the tokens we found. for name, networks in groups: # print the group name [0], and the networks it was in [1] logging.info('%s %s', name, networks) elif options.gmp: common, diff1, diff2 = group_diff(options, db) print_diff(options.gmp[0], common, diff1, diff2) logging.info('') print_diff(options.gmp[1], common, diff2, diff1) # if -c elif options.cmp: meta, results = compare_tokens(options, db) first_name = meta[0] second_name = meta[1] union = meta[2] logging.info('Union of %s and %s:\n %s\n', first_name, second_name, union) logging.info('Diff of %s and %s:', first_name, second_name) for i in results: logging.info(' %s', i) logging.info('') first_obj, sec_obj = options.cmp if check_encapsulated('network', first_obj, sec_obj, db): logging.info('%s fully encapsulates %s', sec_obj, first_obj) else: logging.info('%s does _not_ fully encapsulate %s', sec_obj, first_obj) # check the other way around. if check_encapsulated('network', sec_obj, first_obj, db): logging.info('%s fully encapsulates %s', first_obj, sec_obj) else: logging.info('%s does _not_ fully encapsulate %s', first_obj, sec_obj) # if -o elif options.obj: for obj in options.obj: try: token, ips = get_nets([obj], db)[0] except naming.UndefinedAddressError: logging.info('%s is an invalid object', obj) else: logging.info('%s:', token) # convert list of ip objects to strings and sort them ips.sort(key=lambda x: int(x.ip)) p([str(x) for x in ips]) # if -s elif options.svc: try: results = get_ports(options.svc, db) except naming.UndefinedServiceError: logging.info('%s contains an invalid service object', str(options.svc)) else: for result in get_ports(options.svc, db): svc, port = result logging.info('%s:', svc) p(port) # if -p elif options.port: port, protocol, result = get_services(options, db) logging.info('%s/%s:', port, protocol) p(result) # if nothing is passed elif not any((options.cmp, options.ip, options.token, options.obj, options.svc, options.port)): parser.print_help() logging.info('')
def get_acl(inputs): """Generates an ACL using Capirca. Args: inputs: Module parameters. Returns: ACL string. """ header_base = ''' header { comment:: "$comment" target:: $platform $options } ''' result = "" # Create copy of input options removing any spaces inputs['options_copy'] = [ str(elem).replace(" ", "") for elem in inputs['filter_options'] ] # Add from/to-zone to 'paloalto' and 'srx'. if inputs['platform'] in ('paloalto' 'srx'): if len(inputs['options_copy']) < 2: raise AnsibleError( "The number of options for {0} is less than 2".format( inputs['platform'])) inputs['options_copy'][0] = "from-zone " + inputs['options_copy'][0] inputs['options_copy'][1] = "to-zone " + inputs['options_copy'][1] # Create option string for header inputs['options'] = ' '.join( [str(elem) for elem in inputs['options_copy']]) header_template = Template(header_base) header = header_template.safe_substitute(inputs) defs = naming.Naming(inputs['def_folder']) terms = open(inputs['pol_file']).read() pol = policy.ParsePolicy(header + '\n' + terms, defs, optimize=True) # Exp info in weeks EXP_INFO = 2 # List from https://github.com/google/capirca/blob/master/capirca/aclgen.py#L202 # Does Python have a Switch statement? if inputs['platform'] == 'juniper': result = juniper.Juniper(pol, EXP_INFO) elif inputs['platform'] == 'cisco': result = cisco.Cisco(pol, EXP_INFO) elif inputs['platform'] == 'ciscoasa': result = ciscoasa.CiscoASA(pol, EXP_INFO) elif inputs['platform'] == 'brocade': result = brocade.Brocade(pol, EXP_INFO) elif inputs['platform'] == 'arista': result = arista.Arista(pol, EXP_INFO) elif inputs['platform'] == 'aruba': result = aruba.Aruba(pol, EXP_INFO) elif inputs['platform'] == 'ipset': result = ipset.Ipset(pol, EXP_INFO) elif inputs['platform'] == 'iptables': result = iptables.Iptables(pol, EXP_INFO) elif inputs['platform'] == 'nsxv': result = nsxv.Nsxv(pol, EXP_INFO) elif inputs['platform'] == 'packetfilter': result = packetfilter.PacketFilter(pol, EXP_INFO) elif inputs['platform'] == 'pcap': result = pcap.PcapFilter(pol, EXP_INFO) elif inputs['platform'] == 'speedway': result = speedway.Speedway(pol, EXP_INFO) elif inputs['platform'] == 'srx': result = junipersrx.JuniperSRX(pol, EXP_INFO) elif inputs['platform'] == 'srxlo': result = srxlo.SRXlo(pol, EXP_INFO) elif inputs['platform'] == 'windows_advfirewall': result = windows_advfirewall.WindowsAdvFirewall(pol, EXP_INFO) elif inputs['platform'] == 'ciscoxr': result = ciscoxr.CiscoXR(pol, EXP_INFO) elif inputs['platform'] == 'nftables': result = nftables.Nftables(pol, EXP_INFO) elif inputs['platform'] == 'gce': result = gce.GCE(pol, EXP_INFO) elif inputs['platform'] == 'paloalto': result = paloaltofw.PaloAltoFW(pol, EXP_INFO) elif inputs['platform'] == 'cloudarmor': result = cloudarmor.CloudArmor(pol, EXP_INFO) return str(result)
def testParseServiceFile(self): filedefs = naming.Naming(None) data = ['HTTP = 80/tcp\n'] filedefs._ParseFile(data, 'services') self.assertEqual(filedefs.GetService('HTTP'), ['80/tcp'])
def main(unused_argv): if FLAGS.verbose: logging.basicConfig(level=logging.INFO) if FLAGS.debug: logging.basicConfig(level=logging.DEBUG) logging.debug( 'binary: %s\noptimize: %d\nbase_directory: %s\n' 'policy_file: %s\nrendered_acl_directory: %s', str(sys.argv[0]), int(FLAGS.optimize), str(FLAGS.base_directory), str(FLAGS.policy_file), str(FLAGS.output_directory)) definitions = None try: definitions = naming.Naming(FLAGS.definitions_directory) except naming.NoDefinitionsError: err_msg = 'bad definitions directory: %s' % FLAGS.definitions_directory logging.fatal(err_msg) # thead-safe list for storing files to write manager = multiprocessing.Manager() write_files = manager.list() with_errors = False if FLAGS.policy_file: # render just one file logging.info('rendering one file') RenderFile(FLAGS.policy_file, FLAGS.output_directory, definitions, FLAGS.exp_info, write_files) else: # render all files in parallel logging.info('finding policies...') pols = [] pols.extend( DescendRecursively(FLAGS.base_directory, FLAGS.output_directory, definitions)) pool = multiprocessing.Pool(processes=FLAGS.max_renderers) results = [] for x in pols: results.append( pool.apply_async(RenderFile, args=(x.get('in_file'), x.get('out_dir'), definitions, FLAGS.exp_info, write_files))) pool.close() pool.join() for result in results: try: result.get() except (ACLParserError, ACLGeneratorError) as e: with_errors = True logging.warn( '\n\nerror encountered in rendering process:\n%s\n\n', e) # actually write files to disk WriteFiles(write_files) if with_errors: logging.warn('done, with errors.') sys.exit(1) else: logging.info('done.')