public static PermittedByAcl permittedByAcl(String aclName) { return new PermittedByAcl(aclName); }
@Override @Nonnull public AclLineMatchExpr toAclLineMatchExpr(Map<String, ObjectGroup> objectGroups) { String aclName = CiscoConfiguration.computeServiceObjectAclName(_name); return new PermittedByAcl(aclName, String.format("Match service object: '%s'", _name)); } }
@Override public AclLineMatchExpr toAclLineMatchExpr() { return new PermittedByAcl(computeIcmpObjectGroupAclName(_name)); } }
@Override public AclLineMatchExpr toAclLineMatchExpr() { return new PermittedByAcl(computeServiceObjectAclName(_name)); } }
@Override public AclLineMatchExpr toAclLineMatchExpr() { return new PermittedByAcl(computeProtocolObjectGroupAclName(_name)); } }
@Override public AclLineMatchExpr toAclLineMatchExpr() { return new PermittedByAcl(computeServiceObjectGroupAclName(_name)); } }
@Override @Nonnull public AclLineMatchExpr toAclLineMatchExpr(Map<String, ObjectGroup> objectGroups) { ObjectGroup objectGroup = objectGroups.get(_name); String aclName; if (objectGroup instanceof ProtocolObjectGroup) { aclName = CiscoConfiguration.computeProtocolObjectGroupAclName(_name); } else if (objectGroup instanceof ServiceObjectGroup) { aclName = CiscoConfiguration.computeServiceObjectGroupAclName(_name); } else { return FalseExpr.INSTANCE; } return new PermittedByAcl(aclName, String.format("Match object-group: '%s'", _name)); } }
@Override public AclLineMatchExpr toAclLineMatchExpr( CiscoConfiguration cc, Configuration c, MatchSemantics matchSemantics, Warnings w) { /* For now assume no match for non-existent ACLs */ if (!c.getIpAccessLists().containsKey(_name)) { return FalseExpr.INSTANCE; } return new PermittedByAcl( _name, String.format("Match if permitted by ip access-group '%s'", _name)); } }
@Override public AclLineMatchExpr visitPermittedByAcl(PermittedByAcl permittedByAcl) { PermittedByAcl newPermittedByAcl = new PermittedByAcl( _aclRenamer.apply(permittedByAcl.getAclName()), permittedByAcl.getDefaultAccept(), permittedByAcl.getDescription()); _literalsMap.put(permittedByAcl, newPermittedByAcl); return newPermittedByAcl; }
/** * Scope the headerspace permitted by an {@link IpAccessList} to those flows that also match * {@code invariantExpr}. */ @VisibleForTesting static IpAccessList scopedAcl(AclLineMatchExpr invariantExpr, IpAccessList acl) { return IpAccessList.builder() .setName(INVARIANT_ACL_NAME) .setLines( ImmutableList.<IpAccessListLine>builder() .add(rejecting(not(invariantExpr))) .add(accepting(new PermittedByAcl(acl.getName()))) .build()) .build(); } }
@Nullable @VisibleForTesting IpAccessList buildScreensPerZone(@Nonnull Zone zone, String aclName) { List<AclLineMatchExpr> matches = zone.getScreens().stream() .map( screenName -> { Screen screen = _masterLogicalSystem.getScreens().get(screenName); String screenAclName = ACL_NAME_SCREEN + screenName; IpAccessList screenAcl = _c.getIpAccessLists() .computeIfAbsent(screenAclName, x -> buildScreen(screen, screenAclName)); return screenAcl != null ? new PermittedByAcl(screenAcl.getName(), false) : null; }) .filter(Objects::nonNull) .collect(Collectors.toList()); return matches.isEmpty() ? null : IpAccessList.builder() .setName(aclName) .setLines(ImmutableList.of(IpAccessListLine.accepting(new AndMatchExpr(matches)))) .build(); }
@Nullable IpAccessList buildIncomingFilter(Interface iface) { String screenAclName = ACL_NAME_SCREEN_INTERFACE + iface.getName(); IpAccessList screenAcl = _c.getIpAccessLists().computeIfAbsent(screenAclName, x -> buildScreensPerInterface(iface)); // merge screen options to incoming filter // but keep both originial filters in the config, so we can run search filter queris on them String inAclName = iface.getIncomingFilter(); IpAccessList inAcl = inAclName != null ? _c.getIpAccessLists().get(inAclName) : null; Set<AclLineMatchExpr> aclConjunctList; if (screenAcl == null) { return inAcl; } else if (inAcl == null) { aclConjunctList = ImmutableSet.of(new PermittedByAcl(screenAcl.getName(), false)); } else { aclConjunctList = ImmutableSet.of( new PermittedByAcl(screenAcl.getName(), false), new PermittedByAcl(inAclName, false)); } String combinedAclName = ACL_NAME_COMBINED_INCOMING + iface.getName(); IpAccessList combinedAcl = IpAccessList.builder() .setName(combinedAclName) .setLines( ImmutableList.of(IpAccessListLine.accepting(new AndMatchExpr(aclConjunctList)))) .build(); _c.getIpAccessLists().put(combinedAclName, combinedAcl); return combinedAcl; }
@Nullable @VisibleForTesting IpAccessList buildScreensPerInterface(Interface iface) { Zone zone = _masterLogicalSystem.getInterfaceZones().get(iface.getName()); if (zone == null) { return null; } // build a acl for each zone String zoneAclName = ACL_NAME_SCREEN_ZONE + zone.getName(); IpAccessList zoneAcl = _c.getIpAccessLists() .computeIfAbsent(zoneAclName, x -> buildScreensPerZone(zone, zoneAclName)); return zoneAcl == null ? null : IpAccessList.builder() .setName(ACL_NAME_SCREEN_INTERFACE + iface.getName()) .setLines(ImmutableList.of(IpAccessListLine.accepting(new PermittedByAcl(zoneAclName)))) .build(); }
@Override public IpAccessList toIpAccessList(LineAction action, PaloAltoConfiguration pc, Vsys vsys) { List<IpAccessListLine> lines = new TreeList<>(); for (ServiceOrServiceGroupReference memberReference : _references) { String vsysName = memberReference.getVsysName(pc, vsys); if (vsysName != null) { lines.add( new IpAccessListLine( action, new PermittedByAcl( computeServiceGroupMemberAclName(vsysName, memberReference.getName())), _name)); } } return IpAccessList.builder() .setName(_name) .setLines(lines) .setSourceName(_name) .setSourceType(PaloAltoStructureType.SERVICE_GROUP.getDescription()) .build(); } }
@Test public void testUndefinedReference() { _aclb .setLines( ImmutableList.of( IpAccessListLine.accepting().setMatchCondition(new PermittedByAcl("???")).build())) .build(); List<AclSpecs> aclSpecs = getAclSpecs(ImmutableSet.of("c1")); // The sanitized version of the acl should have one unmatchable line assertThat(aclSpecs, hasSize(1)); CanonicalAcl acl = aclSpecs.get(0).acl; assertThat(acl.getSanitizedAcl().getLines(), equalTo(ImmutableList.of(UNMATCHABLE))); assertThat(acl.hasUndefinedRef(0), equalTo(true)); }
@Test public void testAclMatch() { // Test ACL line expressions which are permitted by other ACLs Map<String, IpAccessList> acceptAcl = createAclMap("acl1", "1.2.3.4/32", LineAction.PERMIT); Map<String, IpAccessList> rejectAcl = createAclMap("acl1", "1.2.3.4/32", LineAction.DENY); PermittedByAcl exprMatch = new PermittedByAcl("acl1", false); // Confirm a flow matching the ACL is correctly identified as accepted assertThat(exprMatch, matches(createFlow("1.2.3.4"), "", acceptAcl)); // Confirm a flow NOT matching the ACL is correctly identified as NOT accepted assertThat(exprMatch, not(matches(createFlow("10.10.10.10"), "", acceptAcl))); // Confirm a flow matching the ACL is correctly identified as NOT accepted (line action is // reject) assertThat(exprMatch, not(matches(createFlow("1.2.3.4"), "", rejectAcl))); } }
@Test public void testPermittedByAcl() { IpAccessList.Builder aclBuilder = IpAccessList.builder().setName("foo"); IpAccessList acl = aclBuilder .setLines( ImmutableList.of( IpAccessListLine.accepting().setMatchCondition(matchSrcInterface("a")).build())) .build(); Map<String, IpAccessList> namedAcls = ImmutableMap.of(acl.getName(), acl); assertThat( referencedSources(namedAcls, new PermittedByAcl(acl.getName())), equalTo(ImmutableSet.of("a"))); } }
@Test public void testReferencedAclUsesSrcInterface() { // Create ACL that references an ACL that references an interface _aclb .setLines( ImmutableList.of( IpAccessListLine.accepting() .setMatchCondition(new PermittedByAcl("referencedAcl")) .build())) .build(); _aclb .setLines( ImmutableList.of( IpAccessListLine.accepting() .setMatchCondition(new MatchSrcInterface(ImmutableList.of("iface"))) .build())) .setName("referencedAcl") .build(); List<AclSpecs> aclSpecs = getAclSpecs(ImmutableSet.of("c1")); // There should be two AclSpecs. Both should be aware of the interface "iface" assertThat(aclSpecs, hasSize(2)); for (AclSpecs spec : aclSpecs) { assertThat( spec.acl.getInterfaces(), equalTo(ImmutableSet.of("iface", "unreferencedInterface"))); } }
@Test public void testUndefinedReference() { IpAccessListLine aclLine = IpAccessListLine.accepting().setMatchCondition(new PermittedByAcl("???")).build(); _aclb.setLines(ImmutableList.of(aclLine)).setName("acl").build(); TableAnswerElement answer = answer(new FilterLineReachabilityQuestion()); // Construct the expected result. Should find an undefined ACL result. Multiset<Row> expected = ImmutableMultiset.of( Row.builder(COLUMN_METADATA) .put(COL_SOURCES, ImmutableList.of(_c1.getHostname() + ": acl")) .put(COL_UNREACHABLE_LINE, aclLine.toString()) .put(COL_UNREACHABLE_LINE_ACTION, PERMIT) .put(COL_BLOCKING_LINES, ImmutableList.of()) .put(COL_DIFF_ACTION, false) .put(COL_REASON, UNDEFINED_REFERENCE) .build()); assertThat(answer.getRows().getData(), equalTo(expected)); }
ImmutableList.of( IpAccessListLine.accepting() .setMatchCondition(new PermittedByAcl("???")) .build(), IpAccessListLine.rejecting() equalTo( ImmutableList.of( IpAccessListLine.accepting().setMatchCondition(new PermittedByAcl("???")).build(), IpAccessListLine.rejecting() .setMatchCondition(