diff --git a/CHANGELOG.txt b/CHANGELOG.txt index f0bbd72e..0fc6fcdc 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -3,14 +3,22 @@ CHANGELOG 2.0.34 UTILS: * UTIL API - introduce postman_collection +* UTIL type=device actions=display-shadowrule | improve JSON output +* UTIL develop - introduce create_template_mgmt_permittedips.php +* UTIL type=device | introduce actions==sp_spg-create-BP +* UTIL type=device | extend actions=actions=sp_spg-create-BP:true/false,SP-NAME - with SP-NAME defined only the OUTBOUND profile is created with the defined SP-NAME +* UTIL optimise test_filter script for QA BUGFIX: * UTIL API - bugfix related to JSON output * UTIL type=rule | bugfix 'filter=(rule is.unused.fast)' if searching via API mode on Panorama * class PanAPIConnector | bugfix to avoid using shadow-apikeynohidden for PAN-OS >=9 if Panorama is used as proxy * UTIL type=rule 'filter=(src has OBJECTNAME)' - fix if object does not exist at same DG level or above - filter is now returning false +* UTIL type=tag | bugfix for 'filter=(reflocation is shared )' GENERAL: +* introduce UTIL actions test script +* framework | bugfixes for different CLASSES related to UTIL test_filter / test_action found issues 2.0.33 (20220404) diff --git a/composer.json b/composer.json index 985c00b4..78146d34 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,11 @@ } ], "require": { - "php": ">=7.4.0" + "php": ">=7.4.0", + "ext-json": "*", + "ext-curl": "*", + "ext-dom": "*", + "ext-mbstring": "*", + "ext-bcmath": "*" } } diff --git a/lib/container-classes/AddressRuleContainer.php b/lib/container-classes/AddressRuleContainer.php index 30a36b66..2f859c57 100644 --- a/lib/container-classes/AddressRuleContainer.php +++ b/lib/container-classes/AddressRuleContainer.php @@ -120,7 +120,7 @@ public function API_add($Obj) * * @return bool True if Zone was found and removed. False if not found. */ - public function remove($Obj, $rewriteXml = TRUE, $forceAny = FALSE) + public function remove($Obj, $rewriteXml = TRUE, $forceAny = FALSE, $context = null) { $count = count($this->o); @@ -128,8 +128,12 @@ public function remove($Obj, $rewriteXml = TRUE, $forceAny = FALSE) if( $ret && $count == 1 && !$forceAny ) { - derr("you are trying to remove last Object from a rule which will set it to ANY, please use forceAny=true for object: " - . $this->toString()); + $string = "you are trying to remove last Object from a rule which will set it to ANY, please use forceAny=true for object: " . $this->toString(); + if( $context === null ) + derr( $string ); + + PH::ACTIONstatus( $context, 'skipped', $string); + return false; } if( $ret && $rewriteXml ) @@ -144,9 +148,9 @@ public function remove($Obj, $rewriteXml = TRUE, $forceAny = FALSE) * @param bool $forceAny * @return bool */ - public function API_remove($Obj, $forceAny = FALSE) + public function API_remove($Obj, $forceAny = FALSE, $context = null) { - if( $this->remove($Obj, TRUE, $forceAny) ) + if( $this->remove($Obj, TRUE, $forceAny, $context) ) { $con = findConnectorOrDie($this); diff --git a/lib/container-classes/ServiceRuleContainer.php b/lib/container-classes/ServiceRuleContainer.php index a6056686..ab43b68c 100644 --- a/lib/container-classes/ServiceRuleContainer.php +++ b/lib/container-classes/ServiceRuleContainer.php @@ -256,8 +256,13 @@ public function rewriteXML() { if( $this->appDef ) DH::Hosts_to_xmlDom($this->xmlroot, $this->o, 'member', TRUE, 'application-default'); - else + elseif( $this->xmlroot !== null ) DH::Hosts_to_xmlDom($this->xmlroot, $this->o, 'member', TRUE); + elseif( $this->xmlroot === null ) + { + //DH::Hosts_to_xmlDom($this->xmlroot, $this->o, 'member', TRUE); + } + } diff --git a/lib/misc-classes/PH.php b/lib/misc-classes/PH.php index d1e0fca0..537e8adb 100644 --- a/lib/misc-classes/PH.php +++ b/lib/misc-classes/PH.php @@ -885,6 +885,8 @@ public static function UTILdeprecated( $type, $argv, $argc, $PHP_FILE) mwarning( 'this script '.basename($PHP_FILE).' is deprecated, please use: pan-os-php.php', null, FALSE ); PH::print_stdout( PH::boldText("pan-os-php".$argString) ); + PH::print_stdout( PH::boldText("sleeping now 15 seconds") ); + sleep(15); PH::callPANOSPHP( $type, $argv, $argc, $PHP_FILE ); diff --git a/lib/misc-classes/filters/filters-Address.php b/lib/misc-classes/filters/filters-Address.php index 8a2bb72a..6da0d2b0 100644 --- a/lib/misc-classes/filters/filters-Address.php +++ b/lib/misc-classes/filters/filters-Address.php @@ -1241,7 +1241,7 @@ 'arg' => true, 'help' => 'returns TRUE if object IP value describe multiple IP addresses; e.g. ip-range: 10.0.0.0-10.0.0.255 will match "ip.count > 200"', 'ci' => array( - 'fString' => '(%PROP%)', + 'fString' => '(%PROP% 5)', 'input' => 'input/panorama-8.0.xml' ) ); diff --git a/lib/misc-classes/filters/filters-Rule.php b/lib/misc-classes/filters/filters-Rule.php index 30ca04f4..4e51c376 100644 --- a/lib/misc-classes/filters/filters-Rule.php +++ b/lib/misc-classes/filters/filters-Rule.php @@ -1084,6 +1084,10 @@ ); RQuery::$defaultFilters['rule']['tag']['operators']['has.regex'] = array( 'Function' => function (RuleRQueryContext $context) { + + if( !isset( $context->object->tags ) ) + return FALSE; + foreach( $context->object->tags->tags() as $tag ) { $matching = preg_match($context->value, $tag->name()); @@ -1148,7 +1152,8 @@ RQuery::$defaultFilters['rule']['app']['operators']['has.regex'] = array( 'Function' => function (RuleRQueryContext $context) { $rule = $context->object; - if( $rule->isNatRule() || $rule->isDecryptionRule() || $rule->isCaptivePortalRule() || $rule->isAuthenticationRule() || $rule->isDoSRule() ) + + if( !isset( $context->object->apps ) ) return FALSE; foreach( $context->object->apps->apps() as $app ) @@ -1172,7 +1177,7 @@ RQuery::$defaultFilters['rule']['app']['operators']['has.recursive'] = array( 'Function' => function (RuleRQueryContext $context) { $rule = $context->object; - if( $rule->isNatRule() || $rule->isDecryptionRule() || $rule->isCaptivePortalRule() || $rule->isAuthenticationRule() || $rule->isDoSRule() ) + if( !isset( $rule->apps ) ) return FALSE; foreach( $rule->apps->getAll() as $app) @@ -1208,7 +1213,7 @@ RQuery::$defaultFilters['rule']['app']['operators']['includes.full.or.partial'] = array( 'Function' => function (RuleRQueryContext $context) { $rule = $context->object; - if( $rule->isNatRule() || $rule->isDecryptionRule() || $rule->isCaptivePortalRule() || $rule->isAuthenticationRule() || $rule->isDoSRule() ) + if( !isset( $rule->apps ) ) return FALSE; /** @var Rule|SecurityRule|AppOverrideRule|PbfRule|QoSRule $object */ @@ -1224,7 +1229,7 @@ RQuery::$defaultFilters['rule']['app']['operators']['includes.full.or.partial.nocase'] = array( 'Function' => function (RuleRQueryContext $context) { $rule = $context->object; - if( $rule->isNatRule() || $rule->isDecryptionRule() || $rule->isCaptivePortalRule() || $rule->isAuthenticationRule() || $rule->isDoSRule() ) + if( !isset( $rule->apps ) ) return FALSE; return $rule->apps->includesApp($context->value, FALSE) === TRUE; @@ -1238,7 +1243,7 @@ RQuery::$defaultFilters['rule']['app']['operators']['included-in.full.or.partial'] = array( 'Function' => function (RuleRQueryContext $context) { $rule = $context->object; - if( $rule->isNatRule() || $rule->isDecryptionRule() || $rule->isCaptivePortalRule() || $rule->isAuthenticationRule() || $rule->isDoSRule() ) + if( !isset( $rule->apps ) ) return FALSE; /** @var Rule|SecurityRule|AppOverrideRule|PbfRule|QoSRule $object */ @@ -1254,7 +1259,7 @@ RQuery::$defaultFilters['rule']['app']['operators']['included-in.full.or.partial.nocase'] = array( 'Function' => function (RuleRQueryContext $context) { $rule = $context->object; - if( $rule->isNatRule() || $rule->isDecryptionRule() || $rule->isCaptivePortalRule() || $rule->isAuthenticationRule() || $rule->isDoSRule() ) + if( !isset( $rule->apps ) ) return FALSE; return $rule->apps->includedInApp($context->value, FALSE) === TRUE; @@ -1268,7 +1273,7 @@ RQuery::$defaultFilters['rule']['app']['operators']['custom.has.signature'] = array( 'Function' => function (RuleRQueryContext $context) { $rule = $context->object; - if( $rule->isNatRule() || $rule->isDecryptionRule() || $rule->isCaptivePortalRule() || $rule->isAuthenticationRule() || $rule->isDoSRule() ) + if( !isset( $rule->apps ) ) return FALSE; /** @var Rule|SecurityRule|AppOverrideRule|PbfRule|QoSRule $object */ @@ -1290,6 +1295,9 @@ if( $rule->isNatRule() ) return $rule->service === null; + if( $rule->services === null ) + return false; + return $rule->services->isAny(); }, 'arg' => FALSE, @@ -1311,7 +1319,7 @@ RQuery::$defaultFilters['rule']['service']['operators']['has'] = array( 'eval' => function ($object, &$nestedQueries, $value) { /** @var Rule|SecurityRule|NatRule|DecryptionRule|AppOverrideRule|CaptivePortalRule|AuthenticationRule|PbfRule|QoSRule|DoSRule $object */ - return $object->services->has($value) === TRUE; + return $object->isSecurityRule() && $object->services->has($value) === TRUE; }, 'arg' => TRUE, 'argObjectFinder' => "\$objectFind=null;\n\$objectFind=\$object->services->parentCentralStore->find('!value!');" @@ -1325,6 +1333,9 @@ return FALSE; return $object->service === $value; } + if( $object->services === null ) + return FALSE; + if( $object->services->count() != 1 || !$object->services->has($value) ) return FALSE; @@ -1349,6 +1360,9 @@ return FALSE; } + if( $rule->services === null ) + return FALSE; + foreach( $rule->services->all() as $service ) { $matching = preg_match($context->value, $service->name()); @@ -1387,6 +1401,9 @@ return $rule->service->hasNamedObjectRecursive($value); } + if( $rule->services === null ) + return FALSE; + return $rule->services->hasNamedObjectRecursive($value); }, 'arg' => TRUE, @@ -1406,6 +1423,9 @@ return FALSE; } + if( $rule->services === null ) + return FALSE; + /** @var Service|ServiceGroup $value */ $objects = $rule->services->all(); @@ -1445,6 +1465,9 @@ return FALSE; } + if( $rule->services === null ) + return FALSE; + /** @var Service|ServiceGroup $value */ $objects = $rule->services->all(); foreach( $objects as $object ) @@ -1484,6 +1507,9 @@ return FALSE; } + if( $rule->services === null ) + return FALSE; + /** @var Service|ServiceGroup $value */ $objects = $rule->services->all(); @@ -1524,6 +1550,9 @@ return FALSE; } + if( $rule->services === null ) + return FALSE; + /** @var Service|ServiceGroup $value */ $objects = $rule->services->all(); foreach( $objects as $object ) @@ -1563,6 +1592,9 @@ return FALSE; } + if( $rule->services === null ) + return FALSE; + return $rule->services->hasValue($value, TRUE); }, 'arg' => TRUE, @@ -1583,6 +1615,9 @@ return FALSE; } + if( $rule->services === null ) + return FALSE; + return $rule->services->hasValue($value); }, 'arg' => TRUE, @@ -1603,6 +1638,9 @@ return FALSE; } + if( $rule->services === null ) + return FALSE; + if( $rule->services->count() != 1 ) return FALSE; @@ -1620,9 +1658,9 @@ $counter = $context->value; $rule = $context->object; - if( $rule->isNatRule() ) + if( !$rule->isSecurityRule() ) { - mwarning("this filter does not yet support NAT Rules"); + mwarning("this filter does only yet support Security Rules", null, FALSE); return FALSE; } @@ -1649,9 +1687,9 @@ $counter = $context->value; $rule = $context->object; - if( $rule->isNatRule() ) + if( !$rule->isSecurityRule() ) { - mwarning("this filter does not yet support NAT Rules"); + mwarning("this filter does only yet support Security Rules", null, FALSE); return FALSE; } @@ -1678,9 +1716,9 @@ $counter = $context->value; $rule = $context->object; - if( $rule->isNatRule() ) + if( !$rule->isSecurityRule() ) { - mwarning("this filter does not yet support NAT Rules"); + mwarning("this filter does only yet support Security Rules", null, FALSE); return FALSE; } diff --git a/lib/misc-classes/trait/ReferenceableObject.php b/lib/misc-classes/trait/ReferenceableObject.php index f0bcb4cc..a54fe012 100644 --- a/lib/misc-classes/trait/ReferenceableObject.php +++ b/lib/misc-classes/trait/ReferenceableObject.php @@ -235,7 +235,7 @@ public function getReferencesLocation( &$counter_array = array() ) { #print get_class( $cur)."\n"; //Firewall - if( isset($cur->owner->owner) && $cur->owner->owner !== null && $cur->owner->owner->name() !== "") + if( isset($cur->owner->owner) && $cur->owner->owner !== null && method_exists($cur->owner->owner,'name') && $cur->owner->owner->name() !== "") { #print $cur->owner->owner->name()."\n"; $location_array[$cur->owner->owner->name()] = $cur->owner->owner->name(); @@ -246,14 +246,14 @@ public function getReferencesLocation( &$counter_array = array() ) } //Panorama - if( isset($cur->owner->owner->owner) && $cur->owner->owner->owner !== null && $cur->owner->owner->owner->name() !== "") + if( isset($cur->owner->owner->owner) && $cur->owner->owner->owner !== null && method_exists($cur->owner->owner->owner,'name') && $cur->owner->owner->owner->name() !== "") { #print $cur->owner->owner->owner->name()."\n"; $location_array[$cur->owner->owner->owner->name()] = $cur->owner->owner->owner->name(); - if( isset($counter_array[$cur->owner->owner->name()])) - $counter_array[$cur->owner->owner->name()] += 1; + if( isset($counter_array[$cur->owner->owner->owner->name()])) + $counter_array[$cur->owner->owner->owner->name()] += 1; else - $counter_array[$cur->owner->owner->name()] = 1; + $counter_array[$cur->owner->owner->owner->name()] = 1; } diff --git a/lib/object-classes/AddressGroup.php b/lib/object-classes/AddressGroup.php index 4e9d2ec5..94e7aff0 100644 --- a/lib/object-classes/AddressGroup.php +++ b/lib/object-classes/AddressGroup.php @@ -600,6 +600,12 @@ public function rewriteXML() if( $this->isDynamic() ) derr('unsupported rewriteXML for dynamic group'); + if( !isset($this->owner->owner) ) + return; + + if( $this->xmlroot === false || $this->membersRoot === false ) + return; + if( $this->owner->owner->version >= 60 ) DH::Hosts_to_xmlDom($this->membersRoot, $this->members, 'member', FALSE); else diff --git a/lib/object-classes/AddressStore.php b/lib/object-classes/AddressStore.php index fcdec244..42d3cf6b 100644 --- a/lib/object-classes/AddressStore.php +++ b/lib/object-classes/AddressStore.php @@ -723,7 +723,7 @@ public function rewriteAddressGroupStoreXML() */ public function newAddress($name, $type, $value, $description = '') { - $found = $this->find($name, null, TRUE); + $found = $this->find($name, null, FALSE); if( $found !== null ) derr("cannot create Address named '" . $name . "' as this name is already in use"); diff --git a/lib/object-classes/SecurityProfileStore.php b/lib/object-classes/SecurityProfileStore.php index 1c7d3ec1..0f48a89d 100644 --- a/lib/object-classes/SecurityProfileStore.php +++ b/lib/object-classes/SecurityProfileStore.php @@ -512,11 +512,11 @@ public function load_predefined_url_categories_from_domxml(DOMElement $xml) /** - * @param SecurityProfile $tag + * @param SecurityProfile| URLProfile | AntiSpywareProfile | AntiVirusProfile | VulnerabilityProfile | FileBlockingProfile | WildfireProfile $tag * * @return bool True if Zone was found and removed. False if not found. */ - public function removeSecurityProfile(SecurityProfile $tag) + public function removeSecurityProfile( $tag) { $ret = $this->remove($tag); diff --git a/lib/object-classes/ServiceGroup.php b/lib/object-classes/ServiceGroup.php index d12cc391..5e4705fc 100644 --- a/lib/object-classes/ServiceGroup.php +++ b/lib/object-classes/ServiceGroup.php @@ -394,6 +394,9 @@ public function rewriteXML() if( !isset($this->owner->owner) ) return; + if( $this->xmlroot === false ) + return; + if( $this->owner->owner->version >= 60 ) { $membersRoot = DH::findFirstElement('members', $this->xmlroot); @@ -755,29 +758,37 @@ public function replaceGroupbyService( $context ) } } - $store = $this->owner; - $store->remove($this); if( $mapping->hasUdpMappings() ) - $newService = $store->newService($this->name(), 'udp', $mapping->udpMappingToText()); + { + $tmp_string = str_replace("udp/", "", $mapping->udpMappingToText()); + $newService = $store->newService($this->name(), 'udp', $tmp_string); + } else - $newService = $store->newService($this->name(), 'tcp', $mapping->tcpMappingToText()); + { + $tmp_string = str_replace("tcp/", "", $mapping->tcpMappingToText() ); + $newService = $store->newService($this->name(), 'tcp', $tmp_string); + } $this->replaceMeGlobally($newService); if( $mapping->hasUdpMappings() ) { - $string = " * replaced by service with same name and value: udp/{$newService->dstPortMapping()->udpMappingToText()}"; + $tmp_dstmapping = $newService->dstPortMapping(); + $string = " * replaced by service with same name and value: {$tmp_dstmapping->udpMappingToText()}"; PH::ACTIONlog($context, $string); } else { - $string = " * replaced by service with same name and value: tcp/{$newService->dstPortMapping()->tcpMappingToText()}"; + $tmp_dstmapping = $newService->dstPortMapping(); + $string = " * replaced by service with same name and value: {$tmp_dstmapping->tcpMappingToText()}"; PH::ACTIONlog($context, $string); } + + return TRUE; } diff --git a/lib/rule-classes/RuleStore.php b/lib/rule-classes/RuleStore.php index a03b4850..2bec0b8c 100644 --- a/lib/rule-classes/RuleStore.php +++ b/lib/rule-classes/RuleStore.php @@ -1382,7 +1382,11 @@ public function remove($rule, $deleteForever = FALSE) if( count($this->_postRules ) > 0 ) $this->postRulesRoot->removeChild($rule->xmlroot); else - DH::clearDomNodeChilds($this->xmlroot); + { + if( $this->xmlroot !== null ) + DH::clearDomNodeChilds($this->xmlroot); + } + $rule->owner = null; diff --git a/tests/api_test_filters.php b/tests/api_test_filters.php index 54a07d76..a1a8bcca 100644 --- a/tests/api_test_filters.php +++ b/tests/api_test_filters.php @@ -146,15 +146,15 @@ function runCommand($bin, &$stream, $force = TRUE, $command = '') if( $type == 'rule' ) - $util = '../utils/rules-edit.php'; + $util = '../utils/pan-os-php type=rule'; elseif( $type == 'address' ) - $util = '../utils/address-edit.php'; + $util = '../utils/pan-os-php type=address'; elseif( $type == 'service' ) - $util = '../utils/service-edit.php'; + $util = '../utils/pan-os-php type=service'; elseif( $type == 'tag' ) - $util = '../utils/tag-edit.php'; + $util = '../utils/pan-os-php type=tag'; elseif( $type == 'zone' ) - $util = '../utils/zone-edit.php'; + $util = '../utils/pan-os-php type=zone'; elseif( $type == 'securityprofile' ) { PH::print_stdout( "******* SKIPPED for now *******" ); diff --git a/tests/api_test_mergers.php b/tests/api_test_mergers.php index ac48433d..1ab832cc 100644 --- a/tests/api_test_mergers.php +++ b/tests/api_test_mergers.php @@ -126,12 +126,12 @@ function runCommand($bin, &$stream, $force = TRUE, $command = '') $dupalgorithm_array = array(); if( $merger == 'address' ) { - $util = '../utils/address-merger.php'; + $util = '../utils/pan-os-php type=address-merger'; $dupalgorithm_array[] = ''; } elseif( $merger == 'addressgroup' ) { - $util = '../utils/addressgroup-merger.php'; + $util = '../utils/pan-os-php type=addressgroup-merger'; $dupalgorithm_array[] = 'SameMembers'; $dupalgorithm_array[] = 'SameIP4Mapping'; $dupalgorithm_array[] = 'Whereused'; @@ -139,13 +139,13 @@ function runCommand($bin, &$stream, $force = TRUE, $command = '') } elseif( $merger == 'service' ) { - $util = '../utils/service-merger.php'; + $util = '../utils/pan-os-php type=service-merger'; $dupalgorithm_array[] = 'SamePorts'; $dupalgorithm_array[] = 'Whereused'; } elseif( $merger == 'servicegroup' ) { - $util = '../utils/servicegroup-merger.php'; + $util = '../utils/pan-os-php type=servicegroup-merger'; $dupalgorithm_array[] = 'SameMembers'; $dupalgorithm_array[] = 'SamePortMapping'; $dupalgorithm_array[] = 'Whereused'; diff --git a/tests/test_actions.php b/tests/test_actions.php index 4f1a77cf..efce98ee 100644 --- a/tests/test_actions.php +++ b/tests/test_actions.php @@ -19,8 +19,229 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -require_once '../lib/pan_php_framework.php'; +set_include_path(dirname(__FILE__) . '/../' . PATH_SEPARATOR . get_include_path()); +require_once dirname(__FILE__) . "/../lib/pan_php_framework.php"; + +PH::print_stdout("\n*************************************************"); +PH::print_stdout("**************** ACTION TESTERS *****************\n"); PH::processCliArgs(); +if( ini_get('safe_mode') ) +{ + derr("SAFE MODE IS ACTIVE"); +} + + +function runCommand($bin, &$stream, $force = TRUE, $command = '') +{ + $stream = ''; + + $bin .= $force ? " 2>&1" : ''; + + $descriptorSpec = array + ( + 0 => array('pipe', 'r'), + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w'), + ); + + $pipes = array(); + + $process = proc_open($bin, $descriptorSpec, $pipes); + + if( $process !== FALSE ) + { + fwrite($pipes[0], $command); + fclose($pipes[0]); + + $stream = stream_get_contents($pipes[1]); + fclose($pipes[1]); + + $stream += stream_get_contents($pipes[2]); + fclose($pipes[2]); + + return proc_close($process); + } + else + return -1; + +} + +$totalActionCount = 0; + +$missingActionArgCount = 0; + +$totalActionWithCiCount = 0; +$missing_actions = array(); + + +$pathString = dirname(__FILE__)."/../utils/lib"; +$JSONarray = file_get_contents( $pathString."/util_action_filter.json"); +$json_a = json_decode($JSONarray, true); + +foreach( $json_a as $type => $UTILtype ) +{ + #if( $type !== "rule" ) + # continue; + + $ci = array(); + $ci['input'] = 'input/panorama-8.0.xml'; + + foreach( $UTILtype['action'] as $actionName => &$action ) + { + $totalActionCount++; + + if( $type == "address" && ($actionName == 'value-set-reverse-dns' || + $actionName == 'value-set-ip-for-fqdn' ) + ) + continue; + + if( $type == "rule" && ($actionName == 'position-move-to-bottom' || + $actionName == 'position-move-to-top' ) + ) + continue; + + + if( isset($action['args']) ) + { + $missingActionArgCount++; + $missing_actionsArgument[$type][] = $actionName; + continue; + } + + + + if( !isset($action['ci']) ) + { + $missing_actions[$type][] = $actionName; + #continue; + } + + $totalActionWithCiCount++; + + print "check TYPE: " . $type . " action: " . $actionName . "\n"; + + + if( $type == 'rule' ) + $util = '../utils/pan-os-php.php type=rule'; + elseif( $type == 'address' ) + $util = '../utils/pan-os-php.php type=address'; + elseif( $type == 'service' ) + $util = '../utils/pan-os-php.php type=service'; + elseif( $type == 'tag' ) + $util = '../utils/pan-os-php.php type=tag'; + elseif( $type == 'zone' ) + $util = '../utils/pan-os-php.php type=zone'; + elseif( $type == 'schedule' ) + $util = '../utils/pan-os-php.php type=schedule'; + #elseif( $type == 'application' ) + # $util = '../utils/application-edit.php'; + + elseif( $type == 'securityprofile' ) + { + PH::print_stdout("******* SKIPPED for now *******"); + continue; + } + elseif( $type == 'securityprofilegroup' ) + { + PH::print_stdout("******* SKIPPED for now *******"); + continue; + } + elseif( $type == 'app' ) + { + PH::print_stdout("******* SKIPPED for now *******"); + continue; + } + elseif( $type == 'application' ) + { + PH::print_stdout("******* SKIPPED for now *******"); + continue; + } + elseif( $type == 'interface' ) + { + PH::print_stdout("******* SKIPPED for now *******"); + continue; + } + elseif( $type == 'virtualwire' ) + { + PH::print_stdout("******* SKIPPED for now *******"); + continue; + } + elseif( $type == 'routing' ) + { + PH::print_stdout("******* SKIPPED for now *******"); + continue; + } + elseif( $type == 'device' ) + { + PH::print_stdout("******* SKIPPED for now *******"); + continue; + } + elseif( $type == 'threat' ) + { + PH::print_stdout("******* SKIPPED for now *******"); + continue; + } + else + { + derr('unsupported'); + } + + + $location = 'any'; + $output = '/dev/null'; + $ruletype = 'any'; + + + $cli = "php $util in={$ci['input']} out={$output} location={$location} 'actions={$actionName}'"; + + if( $type == 'rule' ) + $cli .= " ruletype={$ruletype}"; + + $cli .= ' shadow-ignoreinvalidaddressobjects'; + $cli .= ' 2>&1'; + + PH::print_stdout(" * Executing CLI: {$cli}"); + + $output = array(); + $retValue = 0; + + exec($cli, $output, $retValue); + + foreach( $output as $line ) + { + $string = ' ## '; + $string .= $line; + PH::print_stdout($string); + } + + if( $retValue != 0 ) + derr("CLI exit with error code '{$retValue}'"); + + PH::print_stdout(""); + + } +} + +PH::print_stdout("\n***** *****"); +PH::print_stdout(" - Processed {$totalActionCount} actions"); +PH::print_stdout(" - Found {$totalActionWithCiCount} that are CI enabled"); +PH::print_stdout(" - Found {$missingActionArgCount} that are missing because of actions argument available"); + + +PH::print_stdout("\n"); +PH::print_stdout(" - the following actions has no test argument:"); +print_r($missing_actions); + +PH::print_stdout("\n"); +PH::print_stdout(" - the following actions are not tested:"); +print_r($missing_actionsArgument); + +PH::print_stdout(""); +PH::print_stdout("\n*********** FINISHED TESTING FILTERS ************"); +PH::print_stdout("*************************************************\n"); + + + diff --git a/tests/test_filters.php b/tests/test_filters.php index 4908aff3..c4a05ec0 100644 --- a/tests/test_filters.php +++ b/tests/test_filters.php @@ -75,7 +75,7 @@ function runCommand($bin, &$stream, $force = TRUE, $command = '') foreach( RQuery::$defaultFilters as $type => &$filtersByField ) { - #if( $type != 'zone' ) + #if( $type != 'rule' ) # continue; foreach( $filtersByField as $fieldName => &$filtersByOperator ) @@ -104,21 +104,20 @@ function runCommand($bin, &$stream, $force = TRUE, $command = '') if( $type == 'rule' ) - $util = '../utils/rules-edit.php'; + $util = '../utils/pan-os-php.php type=rule'; elseif( $type == 'address' ) - $util = '../utils/address-edit.php'; + $util = '../utils/pan-os-php.php type=address'; elseif( $type == 'service' ) - $util = '../utils/service-edit.php'; + $util = '../utils/pan-os-php.php type=service'; elseif( $type == 'tag' ) - $util = '../utils/tag-edit.php'; + $util = '../utils/pan-os-php.php type=tag'; elseif( $type == 'zone' ) - $util = '../utils/zone-edit.php'; + $util = '../utils/pan-os-php.php type=zone'; elseif( $type == 'schedule' ) - $util = '../utils/schedule-edit.php'; + $util = '../utils/pan-os-php.php type=schedule'; #elseif( $type == 'application' ) # $util = '../utils/application-edit.php'; - elseif( $type == 'securityprofile' ) { PH::print_stdout( "******* SKIPPED for now *******" ); @@ -168,7 +167,6 @@ function runCommand($bin, &$stream, $force = TRUE, $command = '') derr('unsupported'); } - $location = 'any'; $output = '/dev/null'; $ruletype = 'any'; @@ -179,6 +177,7 @@ function runCommand($bin, &$stream, $force = TRUE, $command = '') if( $type == 'rule' ) $cli .= " ruletype={$ruletype}"; + $cli .= ' shadow-ignoreinvalidaddressobjects'; $cli .= ' 2>&1'; PH::print_stdout( " * Executing CLI: {$cli}" ); diff --git a/tests/test_mergers.php b/tests/test_mergers.php index 84c2dd34..d7a3dc2c 100644 --- a/tests/test_mergers.php +++ b/tests/test_mergers.php @@ -85,14 +85,14 @@ function runCommand($bin, &$stream, $force = TRUE, $command = '') $dupalgorithm_array = array(); if( $merger == 'address' ) { - $util = '../utils/address-merger.php'; + $util = '../utils/pan-os-php.php type=address-merger'; $dupalgorithm_array[] = 'SameAddress'; $dupalgorithm_array[] = 'Identical'; $dupalgorithm_array[] = 'Whereused'; } elseif( $merger == 'addressgroup' ) { - $util = '../utils/addressgroup-merger.php'; + $util = '../utils/pan-os-php.php type=addressgroup-merger'; $dupalgorithm_array[] = 'SameMembers'; $dupalgorithm_array[] = 'SameIP4Mapping'; $dupalgorithm_array[] = 'Whereused'; @@ -100,20 +100,20 @@ function runCommand($bin, &$stream, $force = TRUE, $command = '') } elseif( $merger == 'service' ) { - $util = '../utils/service-merger.php'; + $util = '../utils/pan-os-php.php type=service-merger'; $dupalgorithm_array[] = 'SamePorts'; $dupalgorithm_array[] = 'Whereused'; } elseif( $merger == 'servicegroup' ) { - $util = '../utils/servicegroup-merger.php'; + $util = '../utils/pan-os-php.php type=servicegroup-merger'; $dupalgorithm_array[] = 'SameMembers'; $dupalgorithm_array[] = 'SamePortMapping'; $dupalgorithm_array[] = 'Whereused'; } elseif( $merger == 'tag' ) { - $util = '../utils/tag-merger.php'; + $util = '../utils/pan-os-php.php type=tag-merger'; $dupalgorithm_array[] = 'SameColor'; $dupalgorithm_array[] = 'Identical'; $dupalgorithm_array[] = 'WhereUsed'; @@ -136,6 +136,8 @@ function runCommand($bin, &$stream, $force = TRUE, $command = '') #if( $merger != 'address' ) $cli .= " DupAlgorithm={$dupalgorithm}"; + + $cli .= ' shadow-ignoreinvalidaddressobjects'; $cli .= ' 2>&1'; PH::print_stdout( " * Executing CLI: {$cli}" ); diff --git a/tests/test_rule_merger.php b/tests/test_rule_merger.php index 38cde2eb..33100d63 100644 --- a/tests/test_rule_merger.php +++ b/tests/test_rule_merger.php @@ -123,6 +123,7 @@ function runCommand($bin, &$stream, $force = TRUE, $command = '') $cli .= " {$prePost}"; + $cli .= ' shadow-ignoreinvalidaddressobjects'; $cli .= ' 2>&1'; PH::print_stdout(" * Executing CLI: {$cli}"); diff --git a/tests/test_utilscripts.php b/tests/test_utilscripts.php index aa35b1a5..7a915768 100644 --- a/tests/test_utilscripts.php +++ b/tests/test_utilscripts.php @@ -60,6 +60,7 @@ $cli .= $additional; + $cli .= ' shadow-ignoreinvalidaddressobjects'; $cli .= ' 2>&1'; PH::print_stdout( " * Executing CLI: {$cli}" ); diff --git a/utils/common/actions-address.php b/utils/common/actions-address.php index 47f07a59..21df5bbc 100644 --- a/utils/common/actions-address.php +++ b/utils/common/actions-address.php @@ -1950,7 +1950,7 @@ $fqdn = $object->value(); $reverseDns = gethostbynamel($fqdn); - if( count( $reverseDns ) == 0 ) + if( $reverseDns === FALSE || count( $reverseDns ) == 0 ) { $string = "'value-set-ip-for-fqdn' could not be resolved"; return; @@ -2240,9 +2240,9 @@ $objectRef->addObject($objToReplace); if( $context->isAPI ) - $objectRef->API_remove($object); + $objectRef->API_remove($object, FALSE, $context); else - $objectRef->remove($object); + $objectRef->remove($object, TRUE, FALSE, $context); } elseif( $class == 'NatRule' ) { @@ -2332,7 +2332,13 @@ if( $object === $member ) $text .= $context->padding . PH::boldText( $member->value() ); else - $text .= $context->padding . $member->value(); + { + if( $member->isAddress() ) + $text .= $context->padding . $member->value(); + else + $text .= $context->padding . "GROUP: ".$member->name()." missing IPv4"; + } + } foreach( $objRef_owner->snathosts->members() as $key => $member ) { diff --git a/utils/common/actions-device.php b/utils/common/actions-device.php index 7ab2672e..4511e388 100644 --- a/utils/common/actions-device.php +++ b/utils/common/actions-device.php @@ -840,6 +840,7 @@ } + $jsonArray = array(); foreach( $shadowArray as $name => $array ) { foreach( $array as $ruletype => $entries ) @@ -950,9 +951,17 @@ PH::print_stdout(""); if( $rule !== null ) + { PH::print_stdout( " * RULE of type ".$ruletype.": '" . $rule->name(). "' owner: '".$ownerDG."' shadows rule: " ); + $tmpName = $rule->name(); + } + else + { PH::print_stdout( " * RULE of type ".$ruletype.": '" . $key."'" ); + $tmpName = $key; + } + foreach( $item as $shadow ) { @@ -964,10 +973,13 @@ $shadow = str_replace( ".", "", $shadow ); $shadow = str_replace( "'", "", $shadow ); PH::print_stdout( " - '" . $shadow."'" ); + $jsonArray[$ruletype][$tmpName][] = $shadow; } } } } + + PH::$JSON_TMP['sub'] = $jsonArray; } ); @@ -1335,6 +1347,321 @@ ); +DeviceCallContext::$supportedActions['sp_spg-create-BP'] = array( + 'name' => 'sp_spg-create-bp', + 'GlobalInitFunction' => function (DeviceCallContext $context) { + $context->first = true; + + if( $context->subSystem->isPanorama() ) + { + $countDG = count( $context->subSystem->getDeviceGroups() ); + if( $countDG == 0 ) + { + #$dg = $context->subSystem->createDeviceGroup( "alert-only" ); + derr( "NO DG available; please run 'pa_device-edit in=InputConfig.xml out=OutputConfig.xml actions=devicegroup-create:DG-NAME' first", null, false ); + } + } + }, + 'MainFunction' => function (DeviceCallContext $context) + { + $object = $context->object; + $classtype = get_class($object); + + if( $context->first ) + { + $pathString = dirname(__FILE__)."/../../iron-skillet"; + $av_xmlString_v8 = file_get_contents( $pathString."/panos_v8.1/templates/panorama/snippets/profiles_virus.xml"); + $av_xmlString_v9 = file_get_contents( $pathString."/panos_v9.1/templates/panorama/snippets/profiles_virus.xml"); + $av_xmlString_v10 = file_get_contents( $pathString."/panos_v10.0/templates/panorama/snippets/profiles_virus.xml"); + + $as_xmlString_v8 = file_get_contents( $pathString."/panos_v8.1/templates/panorama/snippets/profiles_spyware.xml"); + $as_xmlString_v9 = file_get_contents( $pathString."/panos_v9.1/templates/panorama/snippets/profiles_spyware.xml"); + $as_xmlString_v10 = file_get_contents( $pathString."/panos_v10.0/templates/panorama/snippets/profiles_spyware.xml"); + + $vp_xmlString = file_get_contents( $pathString."/panos_v10.0/templates/panorama/snippets/profiles_vulnerability.xml"); + + $url_xmlString_v8 = file_get_contents( $pathString."/panos_v8.1/templates/panorama/snippets/profiles_url_filtering.xml"); + $url_xmlString_v9 = file_get_contents( $pathString."/panos_v9.1/templates/panorama/snippets/profiles_url_filtering.xml"); + $url_xmlString_v10 = file_get_contents( $pathString."/panos_v10.0/templates/panorama/snippets/profiles_url_filtering.xml"); + + $fb_xmlString = file_get_contents( $pathString."/panos_v10.0/templates/panorama/snippets/profiles_file_blocking.xml"); + + $wf_xmlString = file_get_contents( $pathString."/panos_v10.0/templates/panorama/snippets/profiles_wildfire_analysis.xml"); + + if( $classtype == "VirtualSystem" || $classtype == "DeviceGroup" ) + { + $sub = $object; + + if( $context->arguments['shared'] && !$context->subSystem->isFirewall() ) + $sharedStore = $sub->owner; + else + $sharedStore = $sub; + + + $ownerDocument = $sub->xmlroot->ownerDocument; + + $force = false; // check about actions argument introduction + if( isset($context->arguments['sp-name']) ) + $nameArray = array("Outbound"); + else + $nameArray = array("Alert-Only", "Outbound", "Inbound", "Internal", "Exception"); + + + foreach( $nameArray as $name) + { + if( isset($context->arguments['sp-name']) ) + { + $ironskilletName = $name; + $name = $context->arguments['sp-name']; + } + else + $ironskilletName = $name; + + + if( $context->object->owner->version < 90 ) + $customURLarray = array("Black-List", "White-List", "Custom-No-Decrypt"); + else + $customURLarray = array("Block", "Allow", "Custom-No-Decrypt"); + foreach( $customURLarray as $entry ) + { + $block = $sharedStore->customURLProfileStore->find($entry); + if( $block === null ) + { + $block = $sharedStore->customURLProfileStore->newCustomSecurityProfileURL($entry); + if( $context->isAPI ) + $block->API_sync(); + } + } + + + $av = $sharedStore->AntiVirusProfileStore->find($name . "-AV"); + if( $av === null ) + { + $store = $sharedStore->AntiVirusProfileStore; + $av = new AntiVirusProfile($name . "-AV", $store); + $newdoc = new DOMDocument; + if( $context->object->owner->version < 90 ) + $newdoc->loadXML($av_xmlString_v8); + elseif( $context->object->owner->version < 100 ) + $newdoc->loadXML($av_xmlString_v9); + else + $newdoc->loadXML($av_xmlString_v10); + $node = $newdoc->importNode($newdoc->firstChild, TRUE); + $node = DH::findFirstElementByNameAttr("entry", $ironskilletName . "-AV", $node); + if( $node !== null && $node->hasChildNodes() ) + { + $node = $ownerDocument->importNode($node, TRUE); + $av->load_from_domxml($node); + $av->owner = null; + if( isset($context->arguments['sp-name']) ) + $av->setName( $name."-AV"); + $store->addSecurityProfile($av); + + if( $context->isAPI ) + $av->API_sync(); + } + else + { + $store->removeSecurityProfile( $av ); + $av = null; + } + } + + $as = $sharedStore->AntiSpywareProfileStore->find($name . "-AS"); + if( $as === null ) + { + $store = $sharedStore->AntiSpywareProfileStore; + $as = new AntiSpywareProfile($name . "-AS", $store); + $newdoc = new DOMDocument; + if( $context->object->owner->version < 90 ) + $newdoc->loadXML($as_xmlString_v8); + elseif( $context->object->owner->version < 100 ) + $newdoc->loadXML($as_xmlString_v9); + else + $newdoc->loadXML($as_xmlString_v10); + $node = $newdoc->importNode($newdoc->firstChild, TRUE); + $node = DH::findFirstElementByNameAttr("entry", $ironskilletName . "-AS", $node); + if( $node !== null && $node->hasChildNodes() ) + { + $node = $newdoc->importNode($node, TRUE); + $node = $ownerDocument->importNode($node, TRUE); + $as->load_from_domxml($node); + $as->owner = null; + if( isset($context->arguments['sp-name']) ) + $as->setName( $name."-AS"); + $store->addSecurityProfile($as); + + if( $context->isAPI ) + $as->API_sync(); + } + else + { + $store->removeSecurityProfile( $as ); + $as = null; + } + } + + $vp = $sharedStore->VulnerabilityProfileStore->find($name . "-VP"); + if( $vp === null ) + { + $store = $sharedStore->VulnerabilityProfileStore; + $vp = new VulnerabilityProfile($name . "-VP", $store); + $newdoc = new DOMDocument; + $newdoc->loadXML($vp_xmlString); + $node = $newdoc->importNode($newdoc->firstChild, TRUE); + $node = DH::findFirstElementByNameAttr("entry", $ironskilletName . "-VP", $node); + if( $node !== null && $node->hasChildNodes() ) + { + $node = $newdoc->importNode($node, TRUE); + $node = $ownerDocument->importNode($node, TRUE); + $vp->load_from_domxml($node); + $vp->owner = null; + if( isset($context->arguments['sp-name']) ) + $vp->setName( $name."-VP"); + $store->addSecurityProfile($vp); + + if( $context->isAPI ) + $vp->API_sync(); + } + else + { + $store->removeSecurityProfile( $vp ); + $vp = null; + } + } + + $url = $sharedStore->URLProfileStore->find($name . "-URL"); + if( $url === null ) + { + $store = $sharedStore->URLProfileStore; + $url = new URLProfile($name . "-URL", $store); + $newdoc = new DOMDocument; + if( $context->object->owner->version < 90 ) + $newdoc->loadXML($url_xmlString_v8); + elseif( $context->object->owner->version < 100 ) + $newdoc->loadXML($url_xmlString_v9); + else + $newdoc->loadXML($url_xmlString_v10); + $node = $newdoc->importNode($newdoc->firstChild, TRUE); + $node = DH::findFirstElementByNameAttr("entry", $ironskilletName . "-URL", $node); + if( $node !== null && $node->hasChildNodes() ) + { + $node = $newdoc->importNode($node, TRUE); + $node = $ownerDocument->importNode($node, TRUE); + $url->load_from_domxml($node); + $url->owner = null; + if( isset($context->arguments['sp-name']) ) + $url->setName( $name."-URL"); + $store->addSecurityProfile($url); + + if( $context->isAPI ) + $url->API_sync(); + } + else + { + $store->removeSecurityProfile( $url ); + $url = null; + } + } + + $fb = $sharedStore->FileBlockingProfileStore->find($name . "-FB"); + if( $fb === null ) + { + $store = $sharedStore->FileBlockingProfileStore; + $fb = new FileBlockingProfile($name . "-FB", $store); + $newdoc = new DOMDocument; + $newdoc->loadXML($fb_xmlString); + $node = $newdoc->importNode($newdoc->firstChild, TRUE); + $node = DH::findFirstElementByNameAttr("entry", $ironskilletName . "-FB", $node); + if( $node !== null && $node->hasChildNodes() ) + { + $node = $newdoc->importNode($node, TRUE); + $node = $ownerDocument->importNode($node, TRUE); + $fb->load_from_domxml($node); + $fb->owner = null; + if( isset($context->arguments['sp-name']) ) + $fb->setName( $name."-FB"); + $store->addSecurityProfile($fb); + + if( $context->isAPI ) + $fb->API_sync(); + } + else + { + $store->removeSecurityProfile( $fb ); + $fb = null; + } + } + + $wf = $sharedStore->WildfireProfileStore->find($name . "-WF"); + if( $wf === null ) + { + $store = $sharedStore->WildfireProfileStore; + $wf = new WildfireProfile($name . "-WF", $store); + $newdoc = new DOMDocument; + $newdoc->loadXML($wf_xmlString); + $node = $newdoc->importNode($newdoc->firstChild, TRUE); + $node = DH::findFirstElementByNameAttr("entry", $ironskilletName . "-WF", $node); + if( $node !== null && $node->hasChildNodes() ) + { + $node = $newdoc->importNode($node, TRUE); + $node = $ownerDocument->importNode($node, TRUE); + $wf->load_from_domxml($node); + $wf->owner = null; + if( isset($context->arguments['sp-name']) ) + $wf->setName( $name."-WF"); + $store->addSecurityProfile($wf); + + if( $context->isAPI ) + $wf->API_sync(); + } + else + { + $store->removeSecurityProfile( $wf ); + $wf = null; + } + } + + $secprofgrp = $sharedStore->securityProfileGroupStore->find($name); + if( $secprofgrp === null ) + { + $secprofgrp = new SecurityProfileGroup($name, $sharedStore->securityProfileGroupStore, TRUE); + + if( $av !== null ) + $secprofgrp->setSecProf_AV($av->name()); + if( $as !== null ) + $secprofgrp->setSecProf_Spyware($as->name()); + if( $vp !== null ) + $secprofgrp->setSecProf_Vuln($vp->name()); + if( $url !== null ) + $secprofgrp->setSecProf_URL($url->name()); + if( $fb !== null ) + $secprofgrp->setSecProf_FileBlock($fb->name()); + if( $wf !== null ) + $secprofgrp->setSecProf_Wildfire($wf->name()); + + + $sharedStore->securityProfileGroupStore->addSecurityProfileGroup($secprofgrp); + + if( $context->isAPI ) + $secprofgrp->API_sync(); + } + } + + $context->first = false; + } + } + }, + 'args' => array( + 'shared' => array('type' => 'bool', 'default' => 'false', + 'help' => "if set to true; securityProfiles are create at SHARED level; at least one DG must be available" + ), + 'sp-name' => array('type' => 'string', 'default' => '*nodefault*', + 'help' => "if set, only ironskillet SP called 'Outbound' are created with the name defined" + ) + ) +); + DeviceCallContext::$supportedActions['LogForwardingProfile-create-BP'] = array( 'name' => 'logforwardingprofile-create-bp', 'GlobalInitFunction' => function (DeviceCallContext $context) { @@ -2791,4 +3118,11 @@ " - find-zone-from-ip:8.8.8.8,vr3,api@0011C890C,vsys1\n" . " - find-zone-from-ip:8.8.8.8,vr5,Datacenter_template\n" . " - find-zone-from-ip:8.8.8.8,vr3,file@firewall.xml,vsys1\n" -); \ No newline at end of file +); + + +//new actions: +//1 /api/?type=op&cmd= + +//2 /api/?type=op&cmd= +// /api/?&type=op&cmd=admin diff --git a/utils/common/actions-rule.php b/utils/common/actions-rule.php index ed07cbed..72418034 100644 --- a/utils/common/actions-rule.php +++ b/utils/common/actions-rule.php @@ -1425,6 +1425,13 @@ 'MainFunction' => function (RuleCallContext $context) { $rule = $context->object; + if( !$rule->isSecurityRule() ) + { + $string = "Rule is of type ".get_class($rule)." - not supported"; + PH::ACTIONstatus( $context, "SKIPPED", $string ); + return; + } + if( $context->isAPI ) $rule->services->API_setApplicationDefault(); else @@ -1437,8 +1444,21 @@ 'MainFunction' => function (RuleCallContext $context) { $rule = $context->object; + if( $rule->isNatRule() ) + { + $string = "Rule is of type ".get_class($rule)." - implementation missing"; + PH::ACTIONstatus( $context, "SKIPPED", $string ); + return; + } + elseif( $rule->isAppOverrideRule() ) + { + $string = "Rule is of type ".get_class($rule)." - not supported"; + PH::ACTIONstatus( $context, "SKIPPED", $string ); + return; + } + if( $context->isAPI ) - $rule->services->API_setAny(); + $rule->services->API_setAny(); else $rule->services->setAny(); }, @@ -1501,6 +1521,15 @@ 'section' => 'app', 'MainFunction' => function (RuleCallContext $context) { $rule = $context->object; + + if( !$rule->isSecurityRule() ) + { + $string = "Rule is NOT of type Security"; + PH::ACTIONstatus( $context, "SKIPPED", $string ); + return; + } + + if( $context->isAPI ) $rule->apps->API_setAny(); else @@ -1820,7 +1849,12 @@ } if( !$context->isAPI ) - derr("only supported in API mode!"); + { + $string = "only supported in API mode!"; + PH::ACTIONstatus( $context, "SKIPPED", $string ); + return; + } + if( $rule->setLogStart(TRUE) ) { @@ -1848,7 +1882,12 @@ } if( !$context->isAPI ) - derr("only supported in API mode!"); + { + $string = "only supported in API mode!"; + PH::ACTIONstatus( $context, "SKIPPED", $string ); + return; + } + if( $rule->setLogStart(FALSE) ) { @@ -1918,7 +1957,11 @@ } if( !$context->isAPI ) - derr("only supported in API mode!"); + { + $string = "only supported in API mode!"; + PH::ACTIONstatus( $context, "SKIPPED", $string ); + return; + } if( $rule->setLogEnd(FALSE) ) { @@ -1946,7 +1989,11 @@ } if( !$context->isAPI ) - derr("only supported in API mode!"); + { + $string = "only supported in API mode!"; + PH::ACTIONstatus( $context, "SKIPPED", $string ); + return; + } if( $rule->setLogEnd(TRUE) ) { @@ -1996,7 +2043,11 @@ } if( !$context->isAPI ) - derr("only supported in API mode!"); + { + $string = "only supported in API mode!"; + PH::ACTIONstatus( $context, "SKIPPED", $string ); + return; + } if( $rule->setLogSetting($context->arguments['profName']) ) { @@ -2259,7 +2310,11 @@ } if( !$context->isAPI ) - derr("only supported in API mode!"); + { + $string = "only supported in API mode!"; + PH::ACTIONstatus( $context, "SKIPPED", $string ); + return; + } if( $rule->removeSecurityProfile() ) { @@ -2286,7 +2341,11 @@ } if( !$context->isAPI ) - derr("only supported in API mode!"); + { + $string = "only supported in API mode!"; + PH::ACTIONstatus( $context, "SKIPPED", $string ); + return; + } if( $rule->setSecurityProfileGroup($context->arguments['profName']) ) { diff --git a/utils/develop/create/create_interface.php b/utils/develop/create/create_interface.php index 68d24388..750d6e58 100644 --- a/utils/develop/create/create_interface.php +++ b/utils/develop/create/create_interface.php @@ -54,177 +54,6 @@ $pan = $util->pan; -/* -PH::processCliArgs(); - -foreach ( PH::$args as $index => &$arg ) -{ - if( !isset($supportedArguments[$index]) ) - { - //var_dump($supportedArguments); - display_error_usage_exit("unsupported argument provided: '$index'"); - } -} - -if( isset(PH::$args['help']) ) -{ - display_usage_and_exit(); -} - - -if( ! isset(PH::$args['in']) ) - display_error_usage_exit('"in" is missing from arguments'); -$configInput = PH::$args['in']; -if( !is_string($configInput) || strlen($configInput) < 1 ) - display_error_usage_exit('"in" argument is not a valid string'); - -if(isset(PH::$args['out']) ) -{ - $configOutput = PH::$args['out']; - if (!is_string($configOutput) || strlen($configOutput) < 1) - display_error_usage_exit('"out" argument is not a valid string'); -} - -if( isset(PH::$args['debugapi']) ) -{ - $debugAPI = true; -} - -if( isset(PH::$args['folder']) ) -{ - $offline_folder = PH::$args['folder']; -} - - -################ -// -// What kind of config input do we have. -// File or API ? -// -// -$configInput = PH::processIOMethod($configInput, true); -$xmlDoc1 = null; - -if( $configInput['status'] == 'fail' ) -{ - fwrite(STDERR, "\n\n**ERROR** " . $configInput['msg'] . "\n\n");exit(1); -} - -if( $configInput['type'] == 'file' ) -{ - if( !file_exists($configInput['filename']) ) - derr("file '{$configInput['filename']}' not found"); - - $xmlDoc1 = new DOMDocument(); - if( ! $xmlDoc1->load($configInput['filename']) ) - derr("error while reading xml config file"); - -} -elseif ( $configInput['type'] == 'api' ) -{ - - if($debugAPI) - $configInput['connector']->setShowApiCalls(true); - print " - Downloading config from API... "; - - if( isset(PH::$args['loadpanoramapushedconfig']) ) - { - print " - 'loadPanoramaPushedConfig' was requested, downloading it through API..."; - $xmlDoc1 = $configInput['connector']->getPanoramaPushedConfig(); - } - else - { - $xmlDoc1 = $configInput['connector']->getCandidateConfig(); - - } - $hostname = $configInput['connector']->info_hostname; - - #$xmlDoc1->save( $offline_folder."/orig/".$hostname."_prod_new.xml" ); - - print "OK!\n"; - -} -else - derr('not supported yet'); - -// -// Determine if PANOS or Panorama -// -$xpathResult1 = DH::findXPath('/config/devices/entry/vsys', $xmlDoc1); -if( $xpathResult1 === FALSE ) - derr('XPath error happened'); -if( $xpathResult1->length <1 ) -{ - $xpathResult1 = DH::findXPath('/panorama', $xmlDoc1); - if( $xpathResult1->length <1 ) - $configType = 'panorama'; - else - $configType = 'pushed_panorama'; -} -else - $configType = 'panos'; -unset($xpathResult1); - -print " - Detected platform type is '{$configType}'\n"; - -############## actual not used - -if( $configType == 'panos' ) - $pan = new PANConf(); -elseif( $configType == 'panorama' ) - $pan = new PanoramaConf(); - - - -if( $configInput['type'] == 'api' ) - $pan->connector = $configInput['connector']; - - - - - - -// - -################ - - -// -// Location provided in CLI ? -// -if( isset(PH::$args['location']) ) -{ - $objectslocation = PH::$args['location']; - if( !is_string($objectslocation) || strlen($objectslocation) < 1 ) - display_error_usage_exit('"location" argument is not a valid string'); -} -else -{ - if( $configType == 'panos' ) - { - print " - No 'location' provided so using default ='vsys1'\n"; - $objectslocation = 'vsys1'; - } - elseif( $configType == 'panorama' ) - { - print " - No 'location' provided so using default ='shared'\n"; - $objectslocation = 'shared'; - } - elseif( $configType == 'pushed_panorama' ) - { - print " - No 'location' provided so using default ='vsys1'\n"; - $objectslocation = 'vsys1'; - } -} - - - -########################################## -########################################## - -$pan->load_from_domxml($xmlDoc1); - -*/ ############## $sub = $pan->findVirtualSystem($util->objectsLocation[0]); diff --git a/utils/develop/create/create_template_mgmt_permittedips.php b/utils/develop/create/create_template_mgmt_permittedips.php new file mode 100644 index 00000000..8908e312 --- /dev/null +++ b/utils/develop/create/create_template_mgmt_permittedips.php @@ -0,0 +1,136 @@ + 'in', 'shortHelp' => 'input file or api. ie: in=config.xml or in=api://192.168.1.1 or in=api://0018CAEC3@panorama.company.com', 'argDesc' => '[filename]|[api://IP]|[api://serial@IP]'); +$supportedArguments['out'] = array('niceName' => 'out', 'shortHelp' => 'output file to save config after changes. Only required when input is a file. ie: out=save-config.xml', 'argDesc' => '[filename]'); +$supportedArguments['location'] = array('niceName' => 'location', 'shortHelp' => 'specify if you want to limit your query to a VSYS. By default location=vsys1 for PANOS. ie: location=any or location=vsys2,vsys1', 'argDesc' => '=sub1[,sub2]'); +$supportedArguments['template'] = array('niceName' => 'template', 'shortHelp' => 'specify if you want to limit your query to a TEMPLATE. By default template=any for Panorama', 'argDesc' => 'template'); +$supportedArguments['debugapi'] = array('niceName' => 'DebugAPI', 'shortHelp' => 'prints API calls when they happen'); +$supportedArguments['help'] = array('niceName' => 'help', 'shortHelp' => 'this message'); +$supportedArguments['loadpanoramapushedconfig'] = array('niceName' => 'loadPanoramaPushedConfig', 'shortHelp' => 'load Panorama pushed config from the firewall to take in account panorama objects and rules'); +$supportedArguments['folder'] = array('niceName' => 'folder', 'shortHelp' => 'specify the folder where the offline files should be saved'); + +$usageMsg = PH::boldText("USAGE: ") . "php " . basename(__FILE__) . " in=inputfile.xml location=vsys1 " . + "actions=action1:arg1 ['filter=(type is.group) or (name contains datacenter-)']\n" . + "php " . basename(__FILE__) . " help : more help messages\n"; + +############## + +$util = new UTIL("custom", $argv, $argc, __FILE__, $supportedArguments, $usageMsg); +$util->utilInit(); + +########################################## +########################################## + +$util->load_config(); +#$util->location_filter(); + +$pan = $util->pan; +$connector = $pan->connector; + + +/////////////////////////////////////////////////////// + +if( $pan->isFirewall() ) +{ + $str = ""; + $tmp_name = "Firewall"; +} + +elseif( $pan->isPanorama() ) +{ + if( isset(PH::$args['template']) ) + $template_name = PH::$args['template']; + else + derr( "argument 'template=TEMPLATENAME' missing " ); + + $template = $pan->findTemplate( $template_name ); + if( $template === null ) + { + PH::print_stdout(""); + PH::print_stdout(" * available templates:"); + foreach( $pan->getTemplates() as $temp ) + PH::print_stdout( " - ".$temp->name() ); + + derr( "template name: '".$template_name."' not found in configuration", null, false ); + } + + $str = "/config/devices/entry[@name='localhost.localdomain']/template/entry[@name='" . $template_name . "']"; + $tmp_name = "Template ".$template_name; +} + +$tmp_additional = "/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system/permitted-ip"; + + + +$tmp_ip = "192.168"; +$thirdOctet = 255; +$fourthOctet = 255; + +for( $i = 1; $i < $thirdOctet; $i++ ) +{ + $tmp_value = ""; + for( $ii = 1; $ii < $fourthOctet; $ii++ ) + { + //IP A.B.C.D => A.B. == 192.168 + //C => i + //D => ii + $IP = $tmp_ip . "." . $i . "." . $ii . ""; + PH::print_stdout( " - add IP: " . $IP . " to ".$tmp_name." mgmt permitted IPs" ); + + + $xpath = $str; + $xpath .= $tmp_additional; + + $tmp_value .=""; + } + $connector->sendSetRequest($xpath, $tmp_value); +} + + +############################################## + +print "\n\n\n"; + +// save our work !!! +$util->save_our_work(); + + +print "\n\n************ END OF CREATE-INTERFACE UTILITY ************\n"; +print "**************************************************\n"; +print "\n\n"; diff --git a/utils/lib/MERGER.php b/utils/lib/MERGER.php index 48941d1f..5f590a39 100644 --- a/utils/lib/MERGER.php +++ b/utils/lib/MERGER.php @@ -2331,8 +2331,8 @@ function service_merging() $text = " ancestor name: '{$ancestor->name()}' DG: "; if( $ancestor->owner->owner->name() == "" ) $text .= "'shared'"; else $text .= "'{$ancestor->owner->owner->name()}'"; - $text .= " value: '{$ancestor->value()}' "; - PH::print_stdout($text); + $text .= " value: '{$ancestor->getDestPort()}' "; + PH::print_stdout( $text ); if( $this->upperLevelSearch ) $tmpstring = "|->ERROR ancestor: '" . $object->_PANC_shortName() . "' cannot be merged. "; @@ -2355,9 +2355,16 @@ function service_merging() if( $this->apiMode ) { if( $pickedObject->isTcp() ) - $pickedObject->API_setDestPort($localMapping->tcpMappingToText()); + { + $tmp_string = str_replace("tcp/", "", $localMapping->tcpMappingToText()); + $pickedObject->API_setDestPort( $tmp_string ); + } else - $pickedObject->API_setDestPort($localMapping->udpMappingToText()); + { + $tmp_string = str_replace("udp/", "", $localMapping->udpMappingToText()); + $pickedObject->API_setDestPort( $tmp_string ); + } + PH::print_stdout(" - removing '{$object->name()}' from places where it's used:"); $object->API_removeWhereIamUsed(TRUE, 7); $object->owner->API_remove($object); @@ -2366,9 +2373,16 @@ function service_merging() else { if( $pickedObject->isTcp() ) - $pickedObject->setDestPort($localMapping->tcpMappingToText()); + { + $tmp_string = str_replace("tcp/", "", $localMapping->tcpMappingToText()); + $pickedObject->setDestPort($tmp_string); + } else - $pickedObject->setDestPort($localMapping->udpMappingToText()); + { + $tmp_string = str_replace("udp/", "", $localMapping->udpMappingToText()); + $pickedObject->setDestPort( $tmp_string ); + } + PH::print_stdout(" - removing '{$object->name()}' from places where it's used:"); $object->removeWhereIamUsed(TRUE, 7); diff --git a/utils/lib/PLAYBOOK__.php b/utils/lib/PLAYBOOK__.php index 30b5f987..4264dbf0 100644 --- a/utils/lib/PLAYBOOK__.php +++ b/utils/lib/PLAYBOOK__.php @@ -94,10 +94,20 @@ function __construct( $argv, $argc ) derr( "invalid JSON file provided", null, FALSE ); if( !isset(PH::$args['in']) ) - $input = $details['in']; + { + if( !isset( $details['in'] ) ) + derr( "argument 'in=inputconfig.xml' missing", null, false ); + else + $input = $details['in']; + } if( !isset(PH::$args['out']) && !$this->isAPI ) - $output = $details['out']; + { + if( !isset( $details['out'] ) ) + derr( "argument 'out=outputconfig.xml' missing", null, false ); + else + $output = $details['out']; + } if( !isset(PH::$args['stagename']) && !$this->isAPI ) {