From 431ad31141021f37098390cc11a6fcb85a494281 Mon Sep 17 00:00:00 2001 From: AnastasiaIBA Date: Sun, 13 Sep 2020 15:07:09 +0300 Subject: [PATCH 01/55] Panorama support is added --- CheckPointObjects/CheckPointObjects.cs | 18 +- MigrationBase/SupportedVendors.cs | 7 +- MigrationBase/VendorConverter.cs | 46 +- PaloAltoMigration/PanoramaConverter.cs | 3946 ++++++++++++++++++++++++ PaloAltoMigration/PanoramaParser.cs | 164 + PaloAltoMigration/Panorama_Config.cs | 626 ++++ SmartMove/App.xaml.cs | 5 + SmartMove/CommandLine.cs | 529 ++++ SmartMove/MainWindow.xaml.cs | 70 +- SmartMove/Program.cs | 62 + 10 files changed, 5459 insertions(+), 14 deletions(-) create mode 100644 PaloAltoMigration/PanoramaConverter.cs create mode 100644 PaloAltoMigration/PanoramaParser.cs create mode 100644 PaloAltoMigration/Panorama_Config.cs create mode 100644 SmartMove/CommandLine.cs create mode 100644 SmartMove/Program.cs diff --git a/CheckPointObjects/CheckPointObjects.cs b/CheckPointObjects/CheckPointObjects.cs index fc7f99ac..c7d3ba1a 100644 --- a/CheckPointObjects/CheckPointObjects.cs +++ b/CheckPointObjects/CheckPointObjects.cs @@ -42,6 +42,7 @@ public abstract class CheckPointObject protected const string CommentsValidityRegex = @"[^A-Za-z0-9 @#*$(){}\[\]_.\-=:,/]"; public const string Any = "any"; + public const string All = "All"; public const string All_Internet = "All_Internet"; public const string icmpProtocol = "icmp-proto"; @@ -283,6 +284,8 @@ public override string ToCLIScriptInstruction() public class CheckPoint_NetworkGroup : CheckPointObject { public List Members = new List(); + + public bool IsPanoramaDeviceGroup = false; /// /// This property is used to overcome the problematic order of objects creation for @@ -639,6 +642,9 @@ public enum TrackTypes { None, Log }; public bool SourceNegated { get; set; } public bool DestinationNegated { get; set; } + public List Target = new List();//"install-on" parameter of CP rule + public bool TargetNegated { get; set; } + private string _conversionComments; public string ConversionComments { @@ -697,6 +703,7 @@ public override string ToCLIScript() + WriteParam("position", "top", "") + WriteParam("inline-layer", SubPolicyName, "") + WriteParam("name", Name, "") + + WriteListParam("install-on", (from o in Target select o).ToList(), true) + WriteParam("custom-fields.field-1", ConversionComments.Substring(0, Math.Min(ConversionComments.Length, 150)), ""); } @@ -736,6 +743,10 @@ public CheckPoint_Rule Clone() { newRule.Time.Add(obj); } + foreach (string obj in Target) + { + newRule.Target.Add(obj); + } CloneApplicationsToRule(newRule); return newRule; @@ -906,6 +917,8 @@ public enum NatMethod { Static, Hide }; public CheckPointObject TranslatedDestination; public CheckPointObject TranslatedService; + public List Target = new List(); + public CheckPoint_NAT_Rule() { Enabled = true; @@ -923,7 +936,9 @@ public override string ToCLIScript() + WriteParam("comments", Comments, "") + WriteParam("method", Method.ToString().ToLower(), "") + WriteParam("enabled", Enabled, true) - + WriteParam("position", "top", ""); + + WriteParam("position", "top", "") + + WriteListParam("install-on", (from o in Target select o).ToList(), true); + } public override string ToCLIScriptInstruction() @@ -946,6 +961,7 @@ public CheckPoint_NAT_Rule Clone() newRule.TranslatedService = TranslatedService; newRule.ConvertedCommandId = ConvertedCommandId; newRule.ConversionIncidentType = ConversionIncidentType; + newRule.Target = Target; return newRule; } diff --git a/MigrationBase/SupportedVendors.cs b/MigrationBase/SupportedVendors.cs index 173b457a..c4af4a64 100644 --- a/MigrationBase/SupportedVendors.cs +++ b/MigrationBase/SupportedVendors.cs @@ -39,6 +39,9 @@ public class SupportedVendors public const string PaloAltoConfigurationFileLabel = "PaloAlto configuration file:"; public const string PaloAltoProduct = "PaloAlto PAN-OS to Check Point Migration Tool"; public const string PaloAltoProductDescription = "This tool supports migration of PaloAlto PAN-OS 7.x \nand above configuration files."; + public const string PaloAltoPanoramaConfigurationFileLabel = "PaloAlto Panorama configuration files archive:"; + public const string PaloAltoPanoramaProduct = "PaloAlto Panorama to Check Point Migration Tool"; + public const string PaloAltoPanoramaProductDescription = "This tool supports migration of PaloAlto Panorama 7.x \nand above configuration files."; #endregion @@ -72,6 +75,8 @@ public enum Vendor [Description("Fortinet FortiGate")] FortiGate, [Description("PaloAlto PAN-OS")] - PaloAlto + PaloAlto, + [Description("PaloAlto Panorama")] + PaloAltoPanorama } } diff --git a/MigrationBase/VendorConverter.cs b/MigrationBase/VendorConverter.cs index 4dd29563..a41036ba 100644 --- a/MigrationBase/VendorConverter.cs +++ b/MigrationBase/VendorConverter.cs @@ -305,7 +305,7 @@ public void ExportNatLayerAsHtml() // Generate the report body file.WriteLine(""); file.WriteLine(" "); - file.WriteLine(" "); + file.WriteLine(" "); file.WriteLine(" "); int ruleNumber = 1; @@ -457,6 +457,11 @@ public void ExportNatLayerAsHtml() } file.WriteLine(curRuleHtmlPart); curRuleHtmlFull.Add(curRuleHtmlPart); + + var dummy = ConversionIncidentType.None; + curRuleHtmlPart = " "; + file.WriteLine(curRuleHtmlPart); + curRuleHtmlFull.Add(curRuleHtmlPart); curRuleHtmlPart = " "; file.WriteLine(curRuleHtmlPart); @@ -499,7 +504,7 @@ public void ExportNatLayerAsHtml() file.WriteLine("

Conversion Errors

"); file.WriteLine("
No. Source Destination Service Translated-Source Translated-Destination Translated-Service CommentsNo. Source Destination Service Translated-Source Translated-Destination Translated-Service Install On Comments
" + RuleStringList2Html(rule.Target, false, CheckPointObject.All, ref dummy) + "" + rule.Comments + "
"); file.WriteLine(" "); - file.WriteLine(" "); + file.WriteLine(" "); file.WriteLine(" "); foreach (var ruleHtml in rulesWithConversionErrors) @@ -520,7 +525,7 @@ public void ExportNatLayerAsHtml() file.WriteLine("

Conversion Notifications

"); file.WriteLine("
No. Source Destination Service Translated-Source Translated-Destination Translated-Service CommentsNo. Source Destination Service Translated-Source Translated-Destination Translated-Service Install On Comments
"); file.WriteLine(" "); - file.WriteLine(" "); + file.WriteLine(" "); file.WriteLine(" "); foreach (var ruleHtml in rulesWithConversionInfos) @@ -689,7 +694,7 @@ protected virtual bool AddCheckPointObject(CheckPointObject cpObject) { _cpObjects.AddObject(cpObject); - if (cpObject.Name.Contains(AutoGeneratedNameWithError)) + if (cpObject.Name != null && cpObject.Name.Contains(AutoGeneratedNameWithError)) { cpObject.ConversionIncidentType = ConversionIncidentType.ManualActionRequired; } @@ -1715,6 +1720,39 @@ protected string RuleItemsList2Html(List ruleItems, bool isCel return res; } + protected string RuleStringList2Html(List ruleString, bool isCellNegated, string defaultValue, ref ConversionIncidentType ruleConversionIncidentType) + { + if (ruleString.Count == 0) + { + return defaultValue; + } + + string res = ""; + + if (isCellNegated) + { + res += "
"; + res += "
Negated
"; + res += "
"; + } + + foreach (string item in ruleString) + { + if (_cpObjects.IsKnownService(item)) + { + res += "
" + item + "
"; + } + else + { + + res += ""; + + } + } + + return res; + } + protected string NatRuleItem2Html(string itemName) { return string.Format("", Path.GetFileName(ObjectsHtmlFile), itemName); diff --git a/PaloAltoMigration/PanoramaConverter.cs b/PaloAltoMigration/PanoramaConverter.cs new file mode 100644 index 00000000..94c0bd6f --- /dev/null +++ b/PaloAltoMigration/PanoramaConverter.cs @@ -0,0 +1,3946 @@ +using CheckPointObjects; +using CommonUtils; +using MigrationBase; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; +using PaloAltoMigration; +using System.Security.Cryptography.X509Certificates; + +namespace PanoramaPaloAltoMigration +{ + public class PanoramaConverter : VendorConverter + { + #region GUI params + + public bool OptimizeConf { get; set; } //check if Optimized configuration is requested + public bool ConvertUserConf { get; set; } //check if User converion is requested + public string LDAPAccoutUnit { get; set; } //read LDAP Account Unit Name for gethering users + + #endregion + + #region Private Members + + private PanoramaParser _paParser; + private bool _isNatConverted; + + private HashSet _vsysNames = new HashSet(); + private HashSet _deviceGroupNames = new HashSet();//Panorama + //private Dictionary _devicesUIDDict = new Dictionary(); + + private List _errorsList = new List(); //storing conversion errors for config or each device group + private List _warningsList = new List(); //storing conversion warnings for config or each device group + + private int _rulesInConvertedPackage = 0; //counter + private int _rulesInNatLayer = 0; //counter + + private int _warningsConvertedPackage = 0; //counter + private int _errorsConvertedPackage = 0; //counter + + private HashSet _timesNamesSet = new HashSet(); + private int _timeCutterCounter = 0; //postfix for Time objects + + private HashSet _objectsNamesSet = new HashSet(); + private int _numPostfix = 0; + + private Dictionary cpPredefServicesTypes = new Dictionary(); + + #endregion + + #region Constants + + private const string LOCAL_DEVICE_ENTRY_NAME = "localhost.localdomain"; + + private const string PA_ANY_VALUE = "any"; + + private const string CP_OBJECT_TYPE_NAME_ZONE = "zone"; + private const string CP_OBJECT_TYPE_NAME_ADDRESS_HOST = "address host"; + private const string CP_OBJECT_TYPE_NAME_ADDRESS_NETWORK = "address network"; + private const string CP_OBJECT_TYPE_NAME_ADDRESS_RANGE = "address range"; + private const string CP_OBJECT_TYPE_NAME_ADDRESS_GROUP = "addresses group"; + private const string CP_OBJECT_TYPE_NAME_SERVICE_TCP = "tcp service"; + private const string CP_OBJECt_TYPE_NAME_SERVICE_UDP = "udp service"; + private const string CP_OBJECT_TYPE_NAME_SERVICE_GROUP = "services group"; + private const string CP_OBJECT_TYPE_NAME_APPLICATION_GROUP = "application group"; + private const string CP_OBJECT_TYPE_NAME_ACCESS_ROLE = "access-role"; + + private const string NETWORK_NETMASK = "32"; + private const string NETWORK_NETMASK_WS = "/32"; + + private const string SERVICE_TYPE_TCP = "TCP"; + private const string SERVICE_TYPE_UDP = "UDP"; + + private const string PA_APPLICATIONS_FILE_NAME = "PA_Apps_CP.csv"; + private const string PA_APP_FILTERS_FILE_NAME = "PA_AppFilters_CP.csv"; + + private const string PA_APPLICATION_DEFAULT = "application-default"; + + private const string PA_INTRAZONE_NAME = "interzone"; + + private const string RE_NET_ADDRESS = "^(\\d+\\.){3}\\d+(/\\d{0,2})?"; // 192.168.1.12/24 or 192.168.1.0/32 or 192.168.1.55 + private const string RE_NAME_UNSAFE = @"[^A-Za-z0-9_.-]"; + + #endregion + + #region Methods are used for reports + + //count of converted rules. + // -1 is VSYSs + public override int RulesInConvertedPackage() + { + return _rulesInConvertedPackage; + } + + //count of warnings of conversion + // -1 if VSYSs + public int WarningsInConvertedPackage() + { + return _warningsConvertedPackage; + } + + //count of errors of conversion + // -1 if VSYSs + public int ErrorsInConvertedPackage() + { + return _errorsConvertedPackage; + } + + public override int RulesInConvertedOptimizedPackage() + { + return 0; + } + + //count of NAT rules + // -1 if VSYSs + public override int RulesInNatLayer() + { + return _rulesInNatLayer; + } + + public override void ExportConfigurationAsHtml() + { + //not used as we have VSYSs + } + + public override void ExportPolicyPackagesAsHtml() + { + //not used as we have VSYSs + } + + protected string RuleItemsList2Html_pa(List ruleItems, List appsItems, bool isCellNegated, string defaultValue, ref ConversionIncidentType ruleConversionIncidentType) + { + if (ruleItems.Count == 0 && (appsItems == null || appsItems.Count == 0)) + { + return defaultValue; + } + + string res = ""; + + if (isCellNegated) + { + res += "
"; + res += "
Negated
"; + res += "
"; + } + + foreach (CheckPointObject item in ruleItems) + { + if (_cpObjects.IsKnownService(item.Name)) + { + res += "
" + item.Name + "
"; + } + else if (item.GetType() == typeof(CheckPoint_PredifinedObject)) + { + res += "
" + item.Name + "
"; + } + else + { + if (item.ConversionIncidentType != ConversionIncidentType.None) + { + if (item.ConversionIncidentType > ruleConversionIncidentType) // Error type overrides information type!!! + { + ruleConversionIncidentType = item.ConversionIncidentType; + } + res += "
" + BuildConversionIncidentLinkTag(item.ConvertedCommandId) + "" + item.Name + "
"; + } + else + { + res += ""; + } + } + } + + if (appsItems != null) + { + foreach (CheckPointObject item in appsItems) + { + res += "
" + item.Name + "
"; + } + } + + return res; + } + + public void ExportPolicyPackagesAsHtmlConfig() + { + const string ruleIdPrefix = "rule_"; + + foreach (CheckPoint_Package package in _cpPackages) + { + string filename = _targetFolder + "\\" + package.Name + ".html"; + + using (var file = new StreamWriter(filename, false)) + { + var rulesWithConversionErrors = new Dictionary(); + var rulesWithConversionInfos = new Dictionary(); + var rulesWithInspection = new Dictionary>(); + + GeneratePackageHtmlReportHeaders(file, package.Name, package.ConversionIncidentType != ConversionIncidentType.None); + + // Generate the report body + file.WriteLine("
No. Source Destination Service Translated-Source Translated-Destination Translated-Service CommentsNo. Source Destination Service Translated-Source Translated-Destination Translated-Service Install On Comments
"); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + + int ruleNumber = 1; + + foreach (CheckPoint_Rule rule in package.ParentLayer.Rules) + { + List ruleAppsList = new List(); + if (rule.GetType() == typeof(CheckPoint_RuleWithApplication)) + { + CheckPoint_RuleWithApplication ruleApp = (CheckPoint_RuleWithApplication)rule; + ruleAppsList.AddRange(ruleApp.Application); + } + + bool isSubPolicy = false; + string action = ""; + string actionStyle = ""; + var dummy = ConversionIncidentType.None; + + switch (rule.Action) + { + case CheckPoint_Rule.ActionType.Accept: + case CheckPoint_Rule.ActionType.Drop: + action = rule.Action.ToString(); + actionStyle = rule.Action.ToString().ToLower(); + break; + + case CheckPoint_Rule.ActionType.SubPolicy: + isSubPolicy = true; + action = "Sub-policy: " + rule.SubPolicyName; + actionStyle = ""; + break; + } + + string curParentRuleId = string.Format("{0}{1}", ruleIdPrefix, ruleNumber); + + if (rule.Enabled) + { + file.WriteLine(" "); + if (isSubPolicy) + { + file.WriteLine(" "); + } + else + { + file.WriteLine(" "); + } + } + else + { + file.WriteLine(" "); + if (isSubPolicy) + { + file.WriteLine(" "); + } + else + { + file.WriteLine(" "); + } + } + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + //file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + + if (isSubPolicy) + { + foreach (CheckPoint_Layer subPolicy in package.SubPolicies) + { + int subRuleNumber = 1; + + foreach (CheckPoint_Rule subRule in subPolicy.Rules) + { + List subRuleAppsList = new List(); + if (subRule.GetType() == typeof(CheckPoint_RuleWithApplication)) + { + CheckPoint_RuleWithApplication subRuleApp = (CheckPoint_RuleWithApplication)subRule; + subRuleAppsList.AddRange(subRuleApp.Application); + } + + if (subRule.Layer == rule.SubPolicyName) + { + var ruleConversionIncidentType = ConversionIncidentType.None; + bool isInspectedRule = !string.IsNullOrEmpty(subRule.Tag); + string curRuleNumber = ruleNumber + "." + subRuleNumber; + string curRuleId = ruleIdPrefix + curRuleNumber; + + if (subRule.Enabled) + { + file.WriteLine(" "); + } + else + { + file.WriteLine(" "); + } + + var sbCurRuleNumberColumnTag = new StringBuilder(); + sbCurRuleNumberColumnTag.Append(" "); + file.WriteLine(sbCurRuleNumberColumnTag.ToString()); + + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + /* */ + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + + subRuleNumber++; + + if (package.ConversionIncidentType != ConversionIncidentType.None && ruleConversionIncidentType != ConversionIncidentType.None) + { + if (ruleConversionIncidentType == ConversionIncidentType.ManualActionRequired) + { + rulesWithConversionErrors.Add(curRuleId, subRule); + } + else + { + rulesWithConversionInfos.Add(curRuleId, subRule); + } + } + + if (isInspectedRule) + { + string[] fortiClassMapNames = subRule.Tag.Split(','); // there may be several class-maps matching the same fw rule... + subRule.Tag = curRuleId; // replace class-map name (it is now the key of this dic) by curRuleId... + + foreach (var classMapName in fortiClassMapNames) + { + if (!rulesWithInspection.ContainsKey(classMapName)) + { + var inspectedRules = new List(); + rulesWithInspection.Add(classMapName, inspectedRules); + } + rulesWithInspection[classMapName].Add(subRule); + } + } + } + } + } + } + + ruleNumber++; + } + + file.WriteLine("
No. Name Source Destination Service Action Time Track Install On Comments Conversion Comments
" + + string.Format(HtmlSubPolicyArrowImageTagFormat, curParentRuleId + "_img", HtmlDownArrowImageSourceData) + ruleNumber + "" + ruleNumber + "
" + + string.Format(HtmlSubPolicyArrowImageTagFormat, curParentRuleId + "_img", HtmlDownArrowImageSourceData) + ruleNumber + HtmlDisabledImageTag + "" + ruleNumber + HtmlDisabledImageTag + "" + rule.Name + "" + RuleItemsList2Html(rule.Source, rule.SourceNegated, CheckPointObject.Any, ref dummy) + "" + RuleItemsList2Html(rule.Destination, rule.DestinationNegated, CheckPointObject.Any, ref dummy) + "" + RuleItemsList2Html_pa(rule.Service, ruleAppsList, false, CheckPointObject.Any, ref dummy) + "" + action + "" + RuleItemsList2Html(rule.Time, false, CheckPointObject.Any, ref dummy) + "" + rule.Track.ToString() + "" + RuleStringList2Html(rule.Target, rule.TargetNegated, CheckPointObject.All, ref dummy) + "" + rule.Target.ToString() + "" + rule.Comments + "" + rule.ConversionComments + "
"); + sbCurRuleNumberColumnTag.Append(" "); + sbCurRuleNumberColumnTag.Append(curRuleNumber); + if (isInspectedRule) + { + sbCurRuleNumberColumnTag.Append(BuildInspectedRuleInfo(subRule.Tag)); + } + if (subRule.ConversionIncidentType != ConversionIncidentType.None) + { + sbCurRuleNumberColumnTag.Append(BuildConversionIncidentLinkTag(subRule.ConvertedCommandId)); + ruleConversionIncidentType = subRule.ConversionIncidentType; + } + if (!subRule.Enabled) + { + sbCurRuleNumberColumnTag.Append(HtmlDisabledImageTag); + } + sbCurRuleNumberColumnTag.Append("" + subRule.Name + "" + RuleItemsList2Html(subRule.Source, subRule.SourceNegated, CheckPointObject.Any, ref ruleConversionIncidentType) + "" + RuleItemsList2Html(subRule.Destination, subRule.DestinationNegated, CheckPointObject.Any, ref ruleConversionIncidentType) + "" + RuleItemsList2Html_pa(subRule.Service, subRuleAppsList, false, CheckPointObject.Any, ref ruleConversionIncidentType) + "" + subRule.Action.ToString() + "" + RuleItemsList2Html(subRule.Time, false, CheckPointObject.Any, ref ruleConversionIncidentType) + "" + subRule.Track.ToString() + "" + subRule.Target.ToString() + "" + subRule.Comments + "" + subRule.ConversionComments + "
"); + + if (rulesWithConversionErrors.Count > 0 || rulesWithConversionInfos.Count > 0 || rulesWithInspection.Count > 0) + { + file.WriteLine("

Policy Conversion Issues

"); + } + + // Generate the errors report + if (rulesWithConversionErrors.Count > 0) + { + file.WriteLine(""); + + file.WriteLine("

Conversion Errors

"); + file.WriteLine(""); + file.WriteLine(" "); + file.WriteLine(" " + + " " + + ""); + file.WriteLine(" "); + + foreach (var ruleEntry in rulesWithConversionErrors) + { + var dummy = ConversionIncidentType.None; + + if (ruleEntry.Value.Enabled) + { + file.WriteLine(" "); + } + else + { + file.WriteLine(" "); + } + + var sbCurRuleNumberColumnTag = new StringBuilder(); + sbCurRuleNumberColumnTag.Append(" "); + file.WriteLine(sbCurRuleNumberColumnTag.ToString()); + + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + } + + file.WriteLine("
No. Name Source DestinationService Action Time TrackInstall On Comments Conversion Comments
"); + sbCurRuleNumberColumnTag.Append(""); + sbCurRuleNumberColumnTag.Append(ruleEntry.Key.Replace(ruleIdPrefix, "")); + sbCurRuleNumberColumnTag.Append(""); + if (ruleEntry.Value.ConversionIncidentType != ConversionIncidentType.None) + { + sbCurRuleNumberColumnTag.Append(BuildConversionIncidentLinkTag(ruleEntry.Value.ConvertedCommandId)); + } + if (!ruleEntry.Value.Enabled) + { + sbCurRuleNumberColumnTag.Append(HtmlDisabledImageTag); + } + sbCurRuleNumberColumnTag.Append("" + ruleEntry.Value.Name + "" + RuleItemsList2Html(ruleEntry.Value.Source, ruleEntry.Value.SourceNegated, CheckPointObject.Any, ref dummy) + "" + RuleItemsList2Html(ruleEntry.Value.Destination, ruleEntry.Value.DestinationNegated, CheckPointObject.Any, ref dummy) + "" + RuleItemsList2Html(ruleEntry.Value.Service, false, CheckPointObject.Any, ref dummy) + "" + ruleEntry.Value.Action.ToString() + "" + RuleItemsList2Html(ruleEntry.Value.Time, false, CheckPointObject.Any, ref dummy) + "" + ruleEntry.Value.Track.ToString() + "" + ruleEntry.Value.Target.ToString() + "" + ruleEntry.Value.Comments + "" + ruleEntry.Value.ConversionComments + "
"); + } + + if (rulesWithConversionInfos.Count > 0 || rulesWithInspection.Count > 0) + { + int counter = (rulesWithInspection.Count > 0) ? 1 : 0; + counter += rulesWithConversionInfos.Count; + + file.WriteLine(""); + file.WriteLine("

Conversion Notifications

"); + } + + // Generate the information report + if (rulesWithConversionInfos.Count > 0) + { + file.WriteLine(""); + file.WriteLine(" "); + file.WriteLine(" " + + " " + + ""); + file.WriteLine(" "); + + foreach (var ruleEntry in rulesWithConversionInfos) + { + var dummy = ConversionIncidentType.None; + + if (ruleEntry.Value.Enabled) + { + file.WriteLine(" "); + } + else + { + file.WriteLine(" "); + } + + var sbCurRuleNumberColumnTag = new StringBuilder(); + sbCurRuleNumberColumnTag.Append(" "); + file.WriteLine(sbCurRuleNumberColumnTag.ToString()); + + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + file.WriteLine(" "); + } + + file.WriteLine("
No. Name Source DestinationService Action Time TrackInstall On Comments Conversion Comments
"); + sbCurRuleNumberColumnTag.Append(""); + sbCurRuleNumberColumnTag.Append(ruleEntry.Key.Replace(ruleIdPrefix, "")); + sbCurRuleNumberColumnTag.Append(""); + if (ruleEntry.Value.ConversionIncidentType != ConversionIncidentType.None) + { + sbCurRuleNumberColumnTag.Append(BuildConversionIncidentLinkTag(ruleEntry.Value.ConvertedCommandId)); + } + if (!ruleEntry.Value.Enabled) + { + sbCurRuleNumberColumnTag.Append(HtmlDisabledImageTag); + } + sbCurRuleNumberColumnTag.Append("" + ruleEntry.Value.Name + "" + RuleItemsList2Html(ruleEntry.Value.Source, ruleEntry.Value.SourceNegated, CheckPointObject.Any, ref dummy) + "" + RuleItemsList2Html(ruleEntry.Value.Destination, ruleEntry.Value.DestinationNegated, CheckPointObject.Any, ref dummy) + "" + RuleItemsList2Html(ruleEntry.Value.Service, false, CheckPointObject.Any, ref dummy) + "" + ruleEntry.Value.Action.ToString() + "" + RuleItemsList2Html(ruleEntry.Value.Time, false, CheckPointObject.Any, ref dummy) + "" + ruleEntry.Value.Track.ToString() + "" + ruleEntry.Value.Target.ToString() + "" + ruleEntry.Value.Comments + "" + ruleEntry.Value.ConversionComments + "
"); + } + + file.WriteLine(""); + file.WriteLine(""); + } + } + } + + public string BuildInspectedRuleInfo(string fortiClassMapName) + { + string inspectTooltip = "Rule traffic is affected by FortiGate inspect policy. [class-map objects: " + fortiClassMapName + "]"; + string htmlInspectedImageTag = string.Format(HtmlAlertImageTagFormat, inspectTooltip); + return htmlInspectedImageTag; + } + + //Catalog is Root file if several device groups exist + public void CreateCatalogObjects() + { + string filename = this.ObjectsHtmlFile; + + using (var file = new StreamWriter(filename, false)) + { + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine("

List of Device Group Objects for " + this._vendorFileName + "

"); + file.WriteLine("
    "); + foreach (string deviceGroupName in _deviceGroupNames) + { + if (File.Exists(this._targetFolder + deviceGroupName + "\\" + deviceGroupName + "_objects.html")) + { + file.WriteLine("
  • " + "" + "

    " + deviceGroupName + "

    " + "
    " + "
  • "); + } + else + { + file.WriteLine("
  • " + "

    " + deviceGroupName + "

    " + "
  • "); + } + } + file.WriteLine("
"); + file.WriteLine(""); + file.WriteLine(""); + } + } + + //Catalog is Root file if several device groups exist + public void CreateCatalogPolicies() + { + string filename = this.PolicyHtmlFile; + + using (var file = new StreamWriter(filename, false)) + { + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine("

List of Device Group Policies for " + this._vendorFileName + "

"); + file.WriteLine("
    "); + foreach (string deviceGroupName in _deviceGroupNames) + { + if (File.Exists(this._targetFolder + deviceGroupName + "\\" + deviceGroupName + "_policy.html")) + { + file.WriteLine("
  • " + "" + "

    " + deviceGroupName + "

    " + "
    " + "
  • "); + } + else + { + file.WriteLine("
  • " + "

    " + deviceGroupName + "

    " + "
  • "); + } + } + file.WriteLine("
"); + file.WriteLine(""); + file.WriteLine(""); + } + } + + //Catalog is Root file if several device groups exist + public void CreateCatalogNATs() + { + string filename = this.NatHtmlFile; + + using (var file = new StreamWriter(filename, false)) + { + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine("

List of Device Group NATs for " + this._vendorFileName + "

"); + file.WriteLine("
    "); + foreach (string deviceGroupName in _deviceGroupNames) + { + if (File.Exists(this._targetFolder + deviceGroupName + "\\" + deviceGroupName + "_NAT.html")) + { + file.WriteLine("
  • " + "" + "

    " + deviceGroupName + "

    " + "
    " + "
  • "); + } + else + { + file.WriteLine("
  • " + "

    " + deviceGroupName + "

    " + "
  • "); + } + } + file.WriteLine("
"); + file.WriteLine(""); + file.WriteLine(""); + } + } + + //Catalog is Root file if several device groups exist + public void CreateCatalogErrors() + { + string filename = this._targetFolder + "\\" + _vendorFileName + "_errors.html"; + + using (var file = new StreamWriter(filename, false)) + { + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine("

List of Device Group Errors for " + this._vendorFileName + "

"); + file.WriteLine("
    "); + foreach (string deviceGroupName in _deviceGroupNames) + { + if (File.Exists(this._targetFolder + deviceGroupName + "\\" + deviceGroupName + "_errors.html")) + { + file.WriteLine("
  • " + "" + "

    " + deviceGroupName + "

    " + "
    " + "
  • "); + } + else + { + file.WriteLine("
  • " + "

    " + deviceGroupName + "

    " + "
  • "); + } + } + file.WriteLine("
"); + file.WriteLine(""); + file.WriteLine(""); + } + } + + //Catalog is Root file if several device groups exist + public void CreateCatalogWarnings() + { + string filename = this._targetFolder + "\\" + _vendorFileName + "_warnings.html"; + + using (var file = new StreamWriter(filename, false)) + { + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine("

List of Device Group Warnings for " + this._vendorFileName + "

"); + file.WriteLine("
    "); + foreach (string deviceGroupName in _deviceGroupNames) + { + if (File.Exists(this._targetFolder + deviceGroupName + "\\" + deviceGroupName + "_warnings.html")) + { + file.WriteLine("
  • " + "" + "

    " + deviceGroupName + "

    " + "
    " + "
  • "); + } + else + { + file.WriteLine("
  • " + "

    " + deviceGroupName + "

    " + "
  • "); + } + } + file.WriteLine("
"); + file.WriteLine(""); + file.WriteLine(""); + } + } + + //report about Errors + public void CreateErrorsHtml(string deviceGroupName) + { + string filename = _targetFolder + "//" + deviceGroupName + "_errors.html"; + + using (var file = new StreamWriter(filename, false)) + { + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine("

List of " + deviceGroupName + " Errors

"); + file.WriteLine(""); + for (int i = 0; i < _errorsList.Count; i++) + { + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + } + file.WriteLine("
"); + file.WriteLine(i); + file.WriteLine(""); + file.WriteLine(_errorsList[i]); + file.WriteLine("
"); + file.WriteLine(""); + file.WriteLine(""); + } + } + + //report about Warnings + public void CreateWarningsHtml(string deviceGroupName) + { + string filename = _targetFolder + "//" + deviceGroupName + "_warnings.html"; + + using (var file = new StreamWriter(filename, false)) + { + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine("

List of " + deviceGroupName + " Warnings

"); + file.WriteLine(""); + for (int i = 0; i < _warningsList.Count; i++) + { + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + file.WriteLine(""); + } + file.WriteLine("
"); + file.WriteLine(i); + file.WriteLine(""); + file.WriteLine(_warningsList[i]); + file.WriteLine("
"); + file.WriteLine(""); + file.WriteLine(""); + } + } + + #endregion + + #region Converter + + public override void Initialize(VendorParser vendorParser, string vendorFilePath, string toolVersion, string targetFolder, string domainName) + { + _paParser = (PanoramaParser)vendorParser; + if (_paParser == null) + { + throw new InvalidDataException("Unexpected!!!"); + } + base.Initialize(vendorParser, vendorFilePath, toolVersion, targetFolder, domainName); + } + + protected override bool AddCheckPointObject(CheckPointObject cpObject) + { + if (cpObject != null) + { + cpObject.Comments = string.IsNullOrWhiteSpace(cpObject.Comments) ? "" : (" " + cpObject.Comments); + if (base.AddCheckPointObject(cpObject)) + { + string vendor = Vendor.PaloAlto.ToString(); + if (!cpObject.Tags.Contains(vendor)) + { + cpObject.Tags.Add(vendor); + } + } + } + + return false; + } + + // + // + //method to get correlation between divice groups and zones + // + public Dictionary> getZones(Panorama_Config paConfig) + { + Dictionary> deviceTemplateDictionary = new Dictionary>(); + Dictionary> deviceDevgroupDictionary = new Dictionary>(); + Dictionary> templateZoneDictionary = new Dictionary>(); + Dictionary> devgroupZoneDictionary = new Dictionary>(); + Dictionary> deviceZoneDictionary = new Dictionary>(); + + + foreach (PA_TemplateStackEntry paTemplateStackEntry in paConfig.Devices.DevicesEntry.TemplateStackEntries) + { + List templatesList = new List(); + foreach (string template in paTemplateStackEntry.StackTemplatesMembers) + { + templatesList.Add(template); + } + foreach (PA_DevicesTemplateStackEntry device in paTemplateStackEntry.DevicesEntries) + { + deviceTemplateDictionary.Add(device.Name, templatesList); + } + } + + foreach (PA_TemplateEntry paTemplateEntry in paConfig.Devices.DevicesEntry.TemplateEntries) + { + foreach (PA_VsysEntry vsys in paTemplateEntry.Config.TemplateDevices.TemplateDevicesEntry.VsysEntries) + { + if (!templateZoneDictionary.ContainsKey(paTemplateEntry.Name)) + templateZoneDictionary.Add(paTemplateEntry.Name, vsys.ZoneEntries); + } + + } + + foreach (PA_DeviceGroupEntry deviceGroup in paConfig.Devices.DevicesEntry.DeviceGroupEntries) + { + List deviceNamesList = new List(); + foreach (PA_DevicesGroupDevicesEntry deviceEntry in deviceGroup.DevicesGroupDevicesEntries) + { + deviceNamesList.Add(deviceEntry.Name); + } + deviceDevgroupDictionary.Add(deviceGroup.Name, deviceNamesList); + } + + foreach (string device in deviceTemplateDictionary.Keys) + { + foreach (string template in deviceTemplateDictionary[device]) + { + if (templateZoneDictionary.ContainsKey(template)) + { + if (!deviceZoneDictionary.ContainsKey(device)) + deviceZoneDictionary.Add(device, templateZoneDictionary[template]); + } + } + + } + + foreach (string devGroup in deviceDevgroupDictionary.Keys) + { + foreach (string device in deviceDevgroupDictionary[devGroup]) + { + if (deviceZoneDictionary.ContainsKey(device)) + { + if (!devgroupZoneDictionary.ContainsKey(devGroup)) + devgroupZoneDictionary.Add(devGroup, deviceZoneDictionary[device]); + } + } + + } + + return devgroupZoneDictionary; + } + + public override void Convert(bool convertNat) + { + string targetFileNameMain = _vendorFileName; + string targetFolderMain = _targetFolder; + + Panorama_Config paConfig = _paParser.Config; + + //call method to get divice-group and zones correlation + Dictionary> devgroupZoneDictionary = getZones(paConfig); + + _isNatConverted = convertNat; + if (LDAPAccoutUnit != null) + LDAP_Account_Unit = LDAPAccoutUnit.Trim(); + + Dictionary _devicesUIDDict = GetDevicesUIDdict(_paParser._ArchiveName); + + if (paConfig != null) + { + List s_TagEntries = new List(); + Dictionary s_cpAddressesDict = null; + Dictionary s_cpNetGroupsDict = null; + Dictionary s_cpServicesDict = null; + Dictionary s_paServicesTypesDict = null; + Dictionary s_cpServicesGroupsDict = null; + List s_paAppFiltersList = null; + Dictionary s_cpAppGroupsDict = null; + Dictionary> s_cpSchedulesDict = null; + PA_PreRulebase s_preRulebase = null; + PA_PostRulebase s_postRulebase = null; + + if (paConfig.Shared != null) + { + s_cpAddressesDict = ConvertAddresses(paConfig.Shared, null); + + s_cpNetGroupsDict = ConvertAddressesGroupsWithInspection(paConfig.Shared, s_cpAddressesDict, null, null); + + s_cpServicesDict = ConvertServices(paConfig.Shared, null); + + s_paServicesTypesDict = GetServicesTypes(paConfig.Shared, null); + + s_cpServicesGroupsDict = ConvertServicesGroupsWithInspection(paConfig.Shared, s_cpServicesDict, null); + + List s_appsMatchList = GetApplicationsMatchList(); + + s_paAppFiltersList = GetPAApplicationsFilters(paConfig.Shared, null); + + s_cpAppGroupsDict = ConvertApplicationsGroups(new List(paConfig.Shared.ApplicationGroupsEntries), s_appsMatchList, null, s_paAppFiltersList, s_cpServicesGroupsDict); + + s_cpSchedulesDict = new Dictionary>(); + s_cpSchedulesDict = new Dictionary>(); + ConvertSchedules(paConfig.Shared).ForEach(x => + { + string key = x.Name; + x = InspectCpScheduleName(x); + List cpTimesList = null; + if (s_cpSchedulesDict.ContainsKey(key)) + cpTimesList = s_cpSchedulesDict[key]; + else + cpTimesList = new List(); + cpTimesList.Add(x); + s_cpSchedulesDict[key] = cpTimesList; + }); + + s_preRulebase = paConfig.Shared.PreRulebase; + s_postRulebase = paConfig.Shared.PostRulebase; + } + if (paConfig.Devices != null) + { + if (paConfig.Devices.DevicesEntry != null && paConfig.Devices.DevicesEntry.Name.Equals(LOCAL_DEVICE_ENTRY_NAME)) //we parse PA config from PA + { + if (paConfig.Devices.DevicesEntry.DeviceGroupEntries != null && + paConfig.Devices.DevicesEntry.DeviceGroupEntries != null && + paConfig.Devices.DevicesEntry.DeviceGroupEntries.Count > 0) + { + if (paConfig.Devices.DevicesEntry.DeviceGroupEntries.Count == 1) + { + List FWGroup_List = getPanoramaDeviceGroup(paConfig.Devices.DevicesEntry.DeviceGroupEntries[0], _devicesUIDDict); + + List devicesGroupList = new List(); + devicesGroupList.AddRange(FWGroup_List); + + foreach (CheckPoint_NetworkGroup FWGroup in FWGroup_List) + { + if (s_cpNetGroupsDict != null) + s_cpNetGroupsDict.Add(FWGroup.Name, FWGroup); + else + s_cpNetGroupsDict = new Dictionary + { + { FWGroup.Name, FWGroup} + }; + } + + ConvertPaDeviceGroupEntry(targetFolderMain, targetFileNameMain, paConfig.Devices.DevicesEntry.DeviceGroupEntries[0], devgroupZoneDictionary, + s_TagEntries, + s_cpAddressesDict, + s_cpNetGroupsDict, + s_cpServicesDict, + s_paServicesTypesDict, + s_cpServicesGroupsDict, + s_paAppFiltersList, + s_cpAppGroupsDict, + s_cpSchedulesDict, + s_preRulebase, + s_postRulebase, + devicesGroupList, + _devicesUIDDict + ); + } + else + { + foreach (PA_DeviceGroupEntry paDeviceGroupEntry in paConfig.Devices.DevicesEntry.DeviceGroupEntries) + { + string paDeviceGroupName = paDeviceGroupEntry.Name; + _deviceGroupNames.Add(paDeviceGroupName); + string targetFolderdeviceGroup = targetFolderMain + "\\" + paDeviceGroupName; + System.IO.Directory.CreateDirectory(targetFolderdeviceGroup); + + + List FWGroup_List = getPanoramaDeviceGroup(paDeviceGroupEntry, _devicesUIDDict); + + List devicesGroupList = new List(); + devicesGroupList.AddRange(FWGroup_List); + + Dictionary s_cpNetGroupsDict_Global = new Dictionary();//to avoid duplication of device groups + s_cpNetGroupsDict_Global = s_cpNetGroupsDict_Global.Concat(s_cpNetGroupsDict.Where(x => !s_cpNetGroupsDict_Global.ContainsKey(x.Key))).ToDictionary(x => x.Key, x => x.Value); + + foreach (CheckPoint_NetworkGroup FWGroup in FWGroup_List) + { + if (s_cpNetGroupsDict != null) + { + if (!s_cpNetGroupsDict.ContainsKey(FWGroup.Name)) + s_cpNetGroupsDict.Add(FWGroup.Name, FWGroup); + } + + else + s_cpNetGroupsDict = new Dictionary + { + { FWGroup.Name, FWGroup} + }; + } + + ConvertPaDeviceGroupEntry(targetFolderdeviceGroup, paDeviceGroupName, paDeviceGroupEntry, devgroupZoneDictionary, + s_TagEntries, + s_cpAddressesDict, + s_cpNetGroupsDict, + s_cpServicesDict, + s_paServicesTypesDict, + s_cpServicesGroupsDict, + s_paAppFiltersList, + s_cpAppGroupsDict, + s_cpSchedulesDict, + s_preRulebase, + s_postRulebase, + devicesGroupList, + _devicesUIDDict + ); + s_cpNetGroupsDict.Clear();//to avoid duplication of device groups + s_cpNetGroupsDict = s_cpNetGroupsDict.Concat(s_cpNetGroupsDict_Global.Where(x => !s_cpNetGroupsDict.ContainsKey(x.Key))).ToDictionary(x => x.Key, x => x.Value); + } + + _warningsConvertedPackage = -1; + _errorsConvertedPackage = -1; + _rulesInConvertedPackage = -1; + _rulesInNatLayer = -1; + CleanCheckPointObjectsLists(); + + // changing target folder path to folder contains config file + ChangeTargetFolder(targetFolderMain, targetFileNameMain); + + // create HTML files which contain links to each report + CreateCatalogObjects(); + CreateCatalogNATs(); + CreateCatalogPolicies(); + CreateCatalogErrors(); + CreateCatalogWarnings(); + } + } + } + } + } + + RaiseConversionProgress(70, "Optimizing Firewall rulebase ..."); + RaiseConversionProgress(80, "Generating CLI scripts ..."); + + VendorHtmlFile = _vendorFilePath; + + ObjectsScriptFile = _targetFolder; + PolicyScriptFile = _targetFolder; + } + + /// + /// Creates network group object for panorama device group + /// + public List getPanoramaDeviceGroup(PA_DeviceGroupEntry deviceGroupEntry, Dictionary _devicesUIDDict) + { + List devices = deviceGroupEntry.DevicesGroupDevicesEntries; + List tags = deviceGroupEntry.TagsEntries; + List tagsList = new List(); + CheckPoint_NetworkGroup FWGroup; + List FWGroup_List = new List(); + + foreach (PA_DevicesGroupDevicesEntry deviceEntry in devices) + { + string deviceName = null; + if (_devicesUIDDict.ContainsKey(deviceEntry.Name)) + { + deviceName = _devicesUIDDict[deviceEntry.Name]; + } + + FWGroup = new CheckPoint_NetworkGroup(); + FWGroup.Name = "FW_" + deviceName; + FWGroup.IsPanoramaDeviceGroup = true; + foreach (PA_TagEntry tagEntry in tags) + { + tagsList.Add(tagEntry.Name); + } + FWGroup.Tags.AddRange(tagsList); + FWGroup_List.Add(FWGroup); + } + + return FWGroup_List; + } + + public void ConvertPaDeviceGroupEntry(string targetFolderNew, string targetFileNameNew, PA_DeviceGroupEntry paDeviceGroupEntry, Dictionary> devgroupZoneDictionary, + List s_TagEntries, + Dictionary s_cpAddressesDict, + Dictionary s_cpNetGroupsDict, + Dictionary s_cpServicesDict, + Dictionary s_paServicesTypesDict, + Dictionary s_cpServicesGroupsDict, + List s_paAppFiltersList, + Dictionary s_cpAppGroupsDict, + Dictionary> s_cpSchedulesDict, + PA_PreRulebase s_preRulebase, + PA_PostRulebase s_postRulebase, + List devicesGroupList, + Dictionary _devicesUIDDict + ) + { + RaiseConversionProgress(35, "Convert configuration..."); + RaiseConversionProgress(40, "Convert objects..."); + + _cpObjects.Initialize(); // must be first!!! + CleanCheckPointObjectsLists(); // must be first!!! + + //change folder path for writing reports + //if there are several device groups then each report will be placed to separate folder + //if only one device group exists then report will be in the same folder as config file + ChangeTargetFolder(targetFolderNew, targetFileNameNew); + + //convert PaloAlto Ojbects to CheckPoint Objects and save them to correspondings List + + Dictionary cpZonesDict = null; + + if (devgroupZoneDictionary.ContainsKey(paDeviceGroupEntry.Name)) + { + cpZonesDict = ConvertZones(devgroupZoneDictionary[paDeviceGroupEntry.Name]); + } + + Dictionary cpAddressesDict = ConvertAddresses(paDeviceGroupEntry, s_cpAddressesDict); + + Dictionary cpNetGroupsDict = ConvertAddressesGroupsWithInspection(paDeviceGroupEntry, cpAddressesDict, s_cpNetGroupsDict, s_TagEntries); + + Dictionary cpServicesDict = ConvertServices(paDeviceGroupEntry, s_cpServicesDict); + + Dictionary paServicesTypesDict = GetServicesTypes(paDeviceGroupEntry, s_paServicesTypesDict); + + Dictionary cpServicesGroupsDict = ConvertServicesGroupsWithInspection(paDeviceGroupEntry, cpServicesDict, s_cpServicesGroupsDict); + + List appsMatchList = GetApplicationsMatchList(); + + List paAppFiltersList = GetPAApplicationsFilters(paDeviceGroupEntry, s_paAppFiltersList); + + Dictionary cpAppGroupsDict = + ConvertApplicationsGroups(new List(paDeviceGroupEntry.ApplicationGroupsEntries), appsMatchList, s_cpAppGroupsDict, paAppFiltersList, cpServicesGroupsDict); + + Dictionary> cpSchedulesDict = null; + if (s_cpSchedulesDict != null) + cpSchedulesDict = new Dictionary>(s_cpSchedulesDict); + else + cpSchedulesDict = new Dictionary>(); + ConvertSchedules(paDeviceGroupEntry).ForEach(x => + { + string key = x.Name; + x = InspectCpScheduleName(x); + List cpTimesList = null; + if (cpSchedulesDict.ContainsKey(key)) + cpTimesList = cpSchedulesDict[key]; + else + cpTimesList = new List(); + cpTimesList.Add(x); + cpSchedulesDict[key] = cpTimesList; + }); + + Dictionary cpAccessRolesDict = new Dictionary(); + + RaiseConversionProgress(60, "Convert policy..."); + + ConvertSecurityPolicy(paDeviceGroupEntry, cpZonesDict, + cpAddressesDict, cpNetGroupsDict, + cpServicesDict, cpServicesGroupsDict, + appsMatchList, cpAppGroupsDict, paAppFiltersList, + cpSchedulesDict, cpAccessRolesDict, s_preRulebase, s_postRulebase, devicesGroupList, _devicesUIDDict); + + (new List(cpAccessRolesDict.Values)).ForEach(x => AddCheckPointObject(x)); + + if (_isNatConverted) + { + ConvertNatPolicy(paDeviceGroupEntry, cpAddressesDict, cpNetGroupsDict, cpServicesDict, paServicesTypesDict, cpServicesGroupsDict, devicesGroupList, _devicesUIDDict); + } + + //if non-optimized convert method is used then all objects are added + + if (!OptimizeConf) + { + if (cpZonesDict != null) + (new List(cpZonesDict.Values)).ForEach(x => AddCheckPointObject(x)); + + (new List(cpAddressesDict.Values)).ForEach(x => AddCheckPointObject(x)); + (new List(cpNetGroupsDict.Values)).ForEach(x => AddCheckPointObject(x)); + (new List(cpServicesDict.Values)).ForEach(x => + { + if (x.GetType() != typeof(CheckPoint_PredifinedObject)) + { + AddCheckPointObject(x); + } + }); + + (new List(cpServicesGroupsDict.Values)).ForEach(x => AddCheckPointObject(x)); + (new List(cpAppGroupsDict.Values)).ForEach(x => AddCheckPointObject(x)); + (new List>(cpSchedulesDict.Values)).ForEach(x => x.ForEach(y => AddCheckPointObject(y))); + } + + //Creating Result Files in Scripting Format and their reports in HTML format + //Console.WriteLine("Create object scripts..."); + CreateObjectsScript(); + CreateObjectsHtml(); + + CreatePackagesScript(); + ExportPolicyPackagesAsHtmlConfig(); + + CreateErrorsHtml(targetFileNameNew); + CreateWarningsHtml(targetFileNameNew); + + ExportNatLayerAsHtml(); + + _warningsConvertedPackage = _warningsList.Count; + _errorsConvertedPackage = _errorsList.Count; + + // to clean; must be the last!!! + _cpObjects.ClearRepository(); + CleanSavedData(); + } + + public void CleanSavedData() + { + _errorsList.Clear(); + _warningsList.Clear(); + _timeCutterCounter = 0; + _numPostfix = 0; + _objectsNamesSet.Clear(); + } + + public string InspectObjectName(string objName, string objType) + { + string objNameNew = ""; + + string[] reservedWords = new string[] + { + "all", "All", "and", "any", "Any", + "apr", "Apr", "april", "April", "aug", "Aug", "august", "August", + "black", "blackboxs", "blue", "broadcasts", "call", "comment", + "conn", "date", "day", "debug", "dec", "Dec", "december", "December", + "deffunc", "define", "delete", "delstate", "direction", "do", "domains", + "drop", "dst", "dynamic", "else", "expcall", "expires", "export", "fcall", + "feb", "Feb", "february", "February", "firebrick", "foreground", "forest", + "format", "fri", "Fri", "friday", "Friday", "from", "fw1", "FW1", "fwline", + "fwrule", "gateways", "get", "getstate", "gold", "gray", "green", "hashsize", + "hold", "host", "hosts", "if", "ifaddr", "ifid", "implies", "in", "inbound", + "instate", "interface", "interfaces", "ipsecdata", "ipsecmethods", "is", + "jan", "Jan", "january", "January", "jul", "Jul", "july", "July", "jun", + "Jun", "june", "June", "kbuf", "keep", "limit", "local", "localhost", "log", + "LOG", "logics", "magenta", "mar", "Mar", "march", "March", "may", "May", + "mday", "medium", "modify", "mon", "Mon", "monday", "Monday", "month", + "mortrap", "navy", "netof", "nets", "nexpires", "not", "nov", "Nov", + "november", "November", "oct", "Oct", "october", "October", "or", + "orange", "origdport", "origdst", "origsport", "origsrc", "other", + "outbound", "packet", "packetid", "packetlen", "pass", "r_arg", + "r_call_counter", "r_cdir", "r_cflags", "r_chandler", "r_client_community", + "r_client_ifs_grp", "r_community_left", "r_connarg", "r_crule", "r_ctimeout", + "r_ctype", "r_curr_feature_id", "r_data_offset", "r_dtmatch", "r_dtmflags", + "r_entry", "r_g_offset", "r_ipv6", "r_mapped_ip", "r_mflags", "r_mhandler", + "r_mtimeout", "r_oldcdir", "r_pflags", "r_profile_id", "r_ro_client_community", + "r_ro_dst_sr", "r_ro_server_community", "r_ro_src_sr", "r_scvres", + "r_server_community", "r_server_ifs_grp", "r_service_id", "r_simple_hdrlen", + "r_spii_ret", "r_spii_tcpseq", "r_spii_uuid1", "r_spii_uuid2", "r_spii_uuid3", + "r_spii_uuid4", "r_str_dport", "r_str_dst", "r_str_ipp", "r_str_sport", + "r_str_src", "r_user", "record", "red", "refresh", "reject", "routers", + "sat", "Sat", "saturday", "Saturday", "second", "sep", "Sep", "september", + "September", "set", "setstate", "skipme", "skippeer", "sr", "src", "static", + "sun", "Sun", "sunday", "Sunday", "switchs", "sync", "targets", "thu", "Thu", + "thursday", "Thursday", "to", "tod", "tue", "Tue", "tuesday", "Tuesday", "ufp", + "vanish", "vars", "wasskipped", "wed", "Wed", "wednesday", "Wednesday", + "while", "xlatedport", "xlatedst", "xlatemethod", "xlatesport", "xlatesrc", + "xor", "year", "zero", "zero_ip", "mon", "Mon", "monday", "Monday", "tue", + "Tue", "tuesday", "Tuesday", "wed", "Wed", "wednesday", "Wednesday", "thu", + "Thu", "thursday", "Thursday", "fri", "Fri", "friday", "Friday", "sat", "Sat", + "saturday", "Saturday", "sun", "Sun", "sunday", "Sunday", "jan", "Jan", + "january", "January", "feb", "Feb", "february", "February", "mar", "Mar", + "march", "March", "apr", "Apr", "april", "April", "may", "May", "jun", "Jun", + "june", "June", "jul", "Jul", "july", "July", "aug", "Aug", "august", "August", + "sep", "Sep", "september", "September", "oct", "Oct", "october", "October", + "nov", "Nov", "november", "November", "dec", "Dec", "december", "December", + "date", "day", "month", "year", "black", "blue", "cyan", "dark", "firebrick", + "foreground", "forest", "gold", "gray", "green", "magenta", "medium", "navy", + "orange", "red", "sienna", "yellow", "dark", "light", "medium" + }; + + if (reservedWords.Contains(objName)) + { + objNameNew += "_" + objName; + _warningsList.Add(objName + " " + objType.Trim() + " was renamed to " + objNameNew); + objName = objNameNew; + } + + objNameNew = GetSafeName(objName); + if (!objNameNew.Equals(objName)) + { + _warningsList.Add(objName + " " + objType.Trim() + " was renamed to " + objNameNew); + objName = objNameNew; + } + + if (!_objectsNamesSet.Add(objName.ToLower())) + { + objNameNew = objName + "_" + _numPostfix++; + _warningsList.Add(objName + " " + objType.Trim() + " was renamed to " + objNameNew); + objName = objNameNew; + _objectsNamesSet.Add(objName.ToLower()); + } + return objName; + } + + #endregion + + #region Convert Zones + + public Dictionary ConvertZones(List zoneEntries) + { + Dictionary cpZonesDict = new Dictionary(); + + if (zoneEntries != null) + { + foreach (PA_ZoneEntry paZoneEntry in zoneEntries) + { + CheckPoint_Zone cpZone = new CheckPoint_Zone(); + cpZone.Name = InspectObjectName(paZoneEntry.Name, CP_OBJECT_TYPE_NAME_ZONE); + cpZone.Name = cpZone.SafeName(); + cpZone.Comments = paZoneEntry.Description; + cpZone.Tags = paZoneEntry.TagMembers; + cpZonesDict[paZoneEntry.Name] = cpZone; + } + } + + return cpZonesDict; + } + + #endregion + + #region Convert Addresses and Addresses Groups + + public Dictionary ConvertAddresses(PA_Objects paObjects, Dictionary s_cpAddressesDict) + { + Dictionary cpAddressesDict = null; + if (s_cpAddressesDict != null) + cpAddressesDict = new Dictionary(s_cpAddressesDict); + else + cpAddressesDict = new Dictionary(); + + if (paObjects.AddressEntries != null) + { + foreach (PA_AddressEntry paAddressEntry in paObjects.AddressEntries) + { + if (!string.IsNullOrWhiteSpace(paAddressEntry.IpNetmask)) + { + int indexSlash = paAddressEntry.IpNetmask.IndexOf("/"); + + if (indexSlash != -1 && paAddressEntry.IpNetmask.Substring(indexSlash + 1).Trim().Equals(NETWORK_NETMASK)) + { + CheckPoint_Host cpHost = new CheckPoint_Host(); + cpHost.Name = InspectObjectName(paAddressEntry.Name, CP_OBJECT_TYPE_NAME_ADDRESS_HOST); + cpHost.Comments = paAddressEntry.Description; + cpHost.Tags = paAddressEntry.TagMembers; + cpHost.IpAddress = paAddressEntry.IpNetmask.Substring(0, indexSlash); + cpAddressesDict[paAddressEntry.Name] = cpHost; + } + else if (indexSlash != -1 && !paAddressEntry.IpNetmask.Substring(indexSlash + 1).Trim().Equals(NETWORK_NETMASK)) + { + CheckPoint_Network cpNetwork = new CheckPoint_Network(); + cpNetwork.Name = InspectObjectName(paAddressEntry.Name, CP_OBJECT_TYPE_NAME_ADDRESS_NETWORK); + cpNetwork.Comments = paAddressEntry.Description; + cpNetwork.Tags = paAddressEntry.TagMembers; + cpNetwork.Subnet = paAddressEntry.IpNetmask.Substring(0, indexSlash); + cpNetwork.Netmask = IPNetwork.Parse(paAddressEntry.IpNetmask).Netmask.ToString(); + cpAddressesDict[paAddressEntry.Name] = cpNetwork; + } + else if (indexSlash == -1) + { + CheckPoint_Host cpHost = new CheckPoint_Host(); + cpHost.Name = InspectObjectName(paAddressEntry.Name, CP_OBJECT_TYPE_NAME_ADDRESS_HOST); + cpHost.Comments = paAddressEntry.Description; + cpHost.Tags = paAddressEntry.TagMembers; + cpHost.IpAddress = paAddressEntry.IpNetmask; + cpAddressesDict[paAddressEntry.Name] = cpHost; + } + } + + if (!string.IsNullOrWhiteSpace(paAddressEntry.IpRange)) + { + int indexDash = paAddressEntry.IpRange.IndexOf("-"); + + CheckPoint_Range cpRange = new CheckPoint_Range(); + cpRange.Name = InspectObjectName(paAddressEntry.Name, CP_OBJECT_TYPE_NAME_ADDRESS_RANGE); + cpRange.Comments = paAddressEntry.Description; + cpRange.Tags = paAddressEntry.TagMembers; + cpRange.RangeFrom = paAddressEntry.IpRange.Substring(0, indexDash); + cpRange.RangeTo = paAddressEntry.IpRange.Substring(indexDash + 1); + cpAddressesDict[paAddressEntry.Name] = cpRange; + + } + + if (!string.IsNullOrWhiteSpace(paAddressEntry.Fqdn)) + { + int index = (new List(cpAddressesDict.Values)).FindIndex(x => x.GetType() == typeof(CheckPoint_Domain) && x.Name.Equals("." + paAddressEntry.Fqdn)); + CheckPoint_Domain cpDomain = null; + if (index == -1) + { + cpDomain = new CheckPoint_Domain(); + cpDomain.Name = "." + paAddressEntry.Fqdn; + cpDomain.Comments = paAddressEntry.Description; + cpDomain.Tags = paAddressEntry.TagMembers; + } + else + { + cpDomain = (CheckPoint_Domain)(new List(cpAddressesDict.Values))[index]; + } + cpAddressesDict[paAddressEntry.Name] = cpDomain; + } + } + } + + return cpAddressesDict; + } + + public Dictionary ConvertAddressesGroups(PA_Objects paObjects, List s_TagEntries, + List cpAddressesList, + Dictionary s_cpNetGroupsDict + ) + { + Dictionary cpAddressesGroupsDict = null; + if (s_cpNetGroupsDict != null) + cpAddressesGroupsDict = new Dictionary(s_cpNetGroupsDict); + else + cpAddressesGroupsDict = new Dictionary(); + + + List cpNetGrpList = new List(); + if (s_cpNetGroupsDict != null) + cpNetGrpList.AddRange((new List(s_cpNetGroupsDict.Values))); + + if (paObjects.AddressGroupEntries != null) + { + foreach (PA_AddressGroupEntry paAddressGroupEntry in paObjects.AddressGroupEntries) + { + CheckPoint_NetworkGroup cpNetGroup = new CheckPoint_NetworkGroup(); + cpNetGroup.Name = paAddressGroupEntry.Name; + cpNetGroup.Comments = paAddressGroupEntry.Description; + cpNetGroup.Tags = paAddressGroupEntry.TagMembers; + cpNetGrpList.Add(cpNetGroup); + } + } + + Dictionary> tagsToMembersDict = GetDictTagsToNames(paObjects, s_TagEntries, cpAddressesList, cpNetGrpList); + + if (paObjects.AddressGroupEntries != null) + { + foreach (PA_AddressGroupEntry paAddressGroupEntry in paObjects.AddressGroupEntries) + { + CheckPoint_NetworkGroup cpNetGroup = new CheckPoint_NetworkGroup(); + + cpNetGroup.Name = InspectObjectName(GetSafeName(paAddressGroupEntry.Name), CP_OBJECT_TYPE_NAME_ADDRESS_GROUP); + + cpNetGroup.Comments = paAddressGroupEntry.Description; + cpNetGroup.Tags = paAddressGroupEntry.TagMembers; + + if (paAddressGroupEntry.StaticMembers != null && paAddressGroupEntry.StaticMembers.Count > 0) + { + cpNetGroup.Members = paAddressGroupEntry.StaticMembers; + } + + else if (paAddressGroupEntry.Dynamic != null && !string.IsNullOrWhiteSpace(paAddressGroupEntry.Dynamic.Filter)) + { + string adjustedFilter = paAddressGroupEntry.Dynamic.Filter.Trim('\'').Trim('"').Trim(); + + if (tagsToMembersDict.ContainsKey(adjustedFilter)) + { + if (!cpNetGroup.IsPanoramaDeviceGroup) + cpNetGroup.Members = tagsToMembersDict[adjustedFilter]; + } + else + { + _errorsList.Add(cpNetGroup.Name + " dynamic network group is not converted because the filter is too complex"); + cpNetGroup = null; + } + } + + if (cpNetGroup != null) + { + cpAddressesGroupsDict[paAddressGroupEntry.Name] = cpNetGroup; + } + } + } + + return cpAddressesGroupsDict; + } + + public Dictionary> GetDictTagsToNames(PA_Objects paObjects, List s_TagEntries, + List cpAddressesList, List cpNetGrpList) + { + Dictionary> tagsToNamesDict = new Dictionary>(); + + List tagEntriesList = new List(); + if (s_TagEntries != null) + tagEntriesList.AddRange(s_TagEntries); + + tagEntriesList.AddRange(paObjects.TagsEntries); + + foreach (PA_TagEntry paTagEntry in tagEntriesList) + { + if (tagsToNamesDict.ContainsKey(paTagEntry.Name)) + continue; + + List namesList = new List(); + + if (cpAddressesList != null) + { + foreach (CheckPointObject cpAddressEntry in cpAddressesList) + { + if (cpAddressEntry.Tags.Contains(paTagEntry.Name)) + { + namesList.Add(cpAddressEntry.Name); + } + } + } + + if (cpNetGrpList != null) + { + foreach (CheckPoint_NetworkGroup cpAddressGroupEntry in cpNetGrpList) + { + if (cpAddressGroupEntry.Tags.Contains(paTagEntry.Name)) + { + namesList.Add(cpAddressGroupEntry.Name); + } + } + } + + tagsToNamesDict.Add(paTagEntry.Name, namesList); + } + + return tagsToNamesDict; + } + public Dictionary ConvertAddressesGroupsWithInspection(PA_Objects paDeviceGroupEntry, + Dictionary cpAddressesDict, + Dictionary s_cpNetGroupsDict, + List s_TagEntries + ) + { + Dictionary cpNetGroupsList = + ConvertAddressesGroups(paVsysEntry, s_TagEntries, (new List(cpAddressesDict.Values)), s_cpNetGroupsDict); + + Dictionary cpNetGroupsResult = InspectAddressGroups(cpAddressesDict, cpNetGroupsList, null); + + return cpNetGroupsResult; + + } + + public Dictionary InspectAddressGroups(Dictionary cpAddressesNamesDict, + Dictionary cpNetGroupsCheck, + Dictionary cpNetGroupsTemp) + { + Dictionary cpNetGroupsResult = null; + if (cpNetGroupsTemp != null) + { + cpNetGroupsResult = new Dictionary(cpNetGroupsTemp); + } + else + { + cpNetGroupsResult = new Dictionary(); + } + + while (cpNetGroupsCheck.Count > 0) + { + string paNetGroupName = new List(cpNetGroupsCheck.Keys)[0]; + CheckPoint_NetworkGroup cpNetGroupCheck = cpNetGroupsCheck[paNetGroupName]; + cpNetGroupsCheck.Remove(paNetGroupName); + + CheckPoint_NetworkGroup cpNetGroupResult = new CheckPoint_NetworkGroup(); + cpNetGroupResult.Name = cpNetGroupCheck.Name; + cpNetGroupResult.Comments = cpNetGroupCheck.Comments; + cpNetGroupResult.Tags = cpNetGroupCheck.Tags; + cpNetGroupResult.IsPanoramaDeviceGroup = cpNetGroupCheck.IsPanoramaDeviceGroup; + + foreach (string member in cpNetGroupCheck.Members) + { + + if (cpAddressesNamesDict.ContainsKey(member)) //group member is in Addresses + { + cpNetGroupResult.Members.Add(cpAddressesNamesDict[member].Name); + } + else if (cpNetGroupsResult.ContainsKey(member)) //group member is converted and added to Addresses Groups + { + cpNetGroupResult.Members.Add(cpNetGroupsResult[member].Name); + } + else if (cpNetGroupsCheck.ContainsKey(member)) //group member is not converted yet + { + cpNetGroupsResult = InspectAddressGroups(cpAddressesNamesDict, cpNetGroupsCheck, cpNetGroupsResult); + + if (cpNetGroupsResult.ContainsKey(member)) + { + cpNetGroupResult.Members.Add(cpNetGroupsResult[member].Name); + } + else + { + _warningsList.Add(cpNetGroupCheck.Name + " address group contains non-existing member: " + member); + } + } + else + { + _warningsList.Add(cpNetGroupCheck.Name + " address group contains non-existing member: " + member); + } + } + + cpNetGroupsResult.Add(paNetGroupName, cpNetGroupResult); + } + + return cpNetGroupsResult; + } + + #endregion + + #region Convert Schedules + + public List ConvertSchedules(PA_Objects paObjects) + { + List cpTimesList = new List(); + + if (paObjects.ScheduleEntries != null) + { + foreach (PA_ScheduleEntry paScheduleEntry in paObjects.ScheduleEntries) + { + if (paScheduleEntry.Type.Recurring != null) + { + if (paScheduleEntry.Type.Recurring.MembersDaily != null) + { + for (int i = 0; i < paScheduleEntry.Type.Recurring.MembersDaily.Count; i += 3) + { + List timesList = + paScheduleEntry.Type.Recurring.MembersDaily.GetRange(i, Math.Min(3, paScheduleEntry.Type.Recurring.MembersDaily.Count - i)); + + CheckPoint_Time cpTime = new CheckPoint_Time(); + cpTime.Name = paScheduleEntry.Name; + cpTime.Comments = paScheduleEntry.Description; + cpTime.Tags = paScheduleEntry.TagMembers; + cpTime.RecurrencePattern = CheckPoint_Time.RecurrencePatternEnum.Daily; + cpTime.StartNow = true; + cpTime.EndNever = true; + + cpTime = SetHourseRanges(cpTime, timesList); + + cpTimesList.Add(cpTime); + } + } + if (paScheduleEntry.Type.Recurring.Weekly != null) + { + if (paScheduleEntry.Type.Recurring.Weekly.MembersMonday != null) + { + for (int i = 0; i < paScheduleEntry.Type.Recurring.Weekly.MembersMonday.Count; i += 3) + { + List timesList = + paScheduleEntry.Type.Recurring.Weekly.MembersMonday.GetRange(i, Math.Min(3, paScheduleEntry.Type.Recurring.Weekly.MembersMonday.Count - i)); + + CheckPoint_Time cpTime = new CheckPoint_Time(); + cpTime.Name = paScheduleEntry.Name; + cpTime.Comments = paScheduleEntry.Description; + cpTime.Tags = paScheduleEntry.TagMembers; + cpTime.RecurrencePattern = CheckPoint_Time.RecurrencePatternEnum.Weekly; + cpTime.RecurrenceWeekdays.Add(CheckPoint_Time.Weekdays.Mon); + cpTime.StartNow = true; + cpTime.EndNever = true; + + cpTime = SetHourseRanges(cpTime, timesList); + + cpTimesList.Add(cpTime); + } + } + if (paScheduleEntry.Type.Recurring.Weekly.MembersTuesday != null) + { + for (int i = 0; i < paScheduleEntry.Type.Recurring.Weekly.MembersTuesday.Count; i += 3) + { + List timesList = + paScheduleEntry.Type.Recurring.Weekly.MembersTuesday.GetRange(i, Math.Min(3, paScheduleEntry.Type.Recurring.Weekly.MembersTuesday.Count - i)); + + CheckPoint_Time cpTime = new CheckPoint_Time(); + cpTime.Name = paScheduleEntry.Name; + cpTime.Comments = paScheduleEntry.Description; + cpTime.Tags = paScheduleEntry.TagMembers; + cpTime.RecurrencePattern = CheckPoint_Time.RecurrencePatternEnum.Weekly; + cpTime.RecurrenceWeekdays.Add(CheckPoint_Time.Weekdays.Tue); + cpTime.StartNow = true; + cpTime.EndNever = true; + + cpTime = SetHourseRanges(cpTime, timesList); + + cpTimesList.Add(cpTime); + } + } + if (paScheduleEntry.Type.Recurring.Weekly.MembersWednesday != null) + { + for (int i = 0; i < paScheduleEntry.Type.Recurring.Weekly.MembersWednesday.Count; i += 3) + { + List timesList = + paScheduleEntry.Type.Recurring.Weekly.MembersWednesday.GetRange(i, Math.Min(3, paScheduleEntry.Type.Recurring.Weekly.MembersWednesday.Count - i)); + + CheckPoint_Time cpTime = new CheckPoint_Time(); + cpTime.Name = paScheduleEntry.Name; + cpTime.Comments = paScheduleEntry.Description; + cpTime.Tags = paScheduleEntry.TagMembers; + cpTime.RecurrencePattern = CheckPoint_Time.RecurrencePatternEnum.Weekly; + cpTime.RecurrenceWeekdays.Add(CheckPoint_Time.Weekdays.Wed); + cpTime.StartNow = true; + cpTime.EndNever = true; + + cpTime = SetHourseRanges(cpTime, timesList); + + cpTimesList.Add(cpTime); + } + } + if (paScheduleEntry.Type.Recurring.Weekly.MembersThursday != null) + { + for (int i = 0; i < paScheduleEntry.Type.Recurring.Weekly.MembersThursday.Count; i += 3) + { + List timesList = + paScheduleEntry.Type.Recurring.Weekly.MembersThursday.GetRange(i, Math.Min(3, paScheduleEntry.Type.Recurring.Weekly.MembersThursday.Count - i)); + + CheckPoint_Time cpTime = new CheckPoint_Time(); + cpTime.Name = paScheduleEntry.Name; + cpTime.Comments = paScheduleEntry.Description; + cpTime.Tags = paScheduleEntry.TagMembers; + cpTime.RecurrencePattern = CheckPoint_Time.RecurrencePatternEnum.Weekly; + cpTime.RecurrenceWeekdays.Add(CheckPoint_Time.Weekdays.Thu); + cpTime.StartNow = true; + cpTime.EndNever = true; + + cpTime = SetHourseRanges(cpTime, timesList); + + cpTimesList.Add(cpTime); + } + } + if (paScheduleEntry.Type.Recurring.Weekly.MembersFriday != null) + { + for (int i = 0; i < paScheduleEntry.Type.Recurring.Weekly.MembersFriday.Count; i += 3) + { + List timesList = + paScheduleEntry.Type.Recurring.Weekly.MembersFriday.GetRange(i, Math.Min(3, paScheduleEntry.Type.Recurring.Weekly.MembersFriday.Count - i)); + + CheckPoint_Time cpTime = new CheckPoint_Time(); + cpTime.Name = paScheduleEntry.Name; + cpTime.Comments = paScheduleEntry.Description; + cpTime.Tags = paScheduleEntry.TagMembers; + cpTime.RecurrencePattern = CheckPoint_Time.RecurrencePatternEnum.Weekly; + cpTime.RecurrenceWeekdays.Add(CheckPoint_Time.Weekdays.Fri); + cpTime.StartNow = true; + cpTime.EndNever = true; + + cpTime = SetHourseRanges(cpTime, timesList); + + cpTimesList.Add(cpTime); + } + } + if (paScheduleEntry.Type.Recurring.Weekly.MembersSaturday != null) + { + for (int i = 0; i < paScheduleEntry.Type.Recurring.Weekly.MembersSaturday.Count; i += 3) + { + List timesList = + paScheduleEntry.Type.Recurring.Weekly.MembersSaturday.GetRange(i, Math.Min(3, paScheduleEntry.Type.Recurring.Weekly.MembersSaturday.Count - i)); + + CheckPoint_Time cpTime = new CheckPoint_Time(); + cpTime.Name = paScheduleEntry.Name; + cpTime.Comments = paScheduleEntry.Description; + cpTime.Tags = paScheduleEntry.TagMembers; + cpTime.RecurrencePattern = CheckPoint_Time.RecurrencePatternEnum.Weekly; + cpTime.RecurrenceWeekdays.Add(CheckPoint_Time.Weekdays.Sat); + cpTime.StartNow = true; + cpTime.EndNever = true; + + cpTime = SetHourseRanges(cpTime, timesList); + + cpTimesList.Add(cpTime); + } + } + if (paScheduleEntry.Type.Recurring.Weekly.MembersSunday != null) + { + for (int i = 0; i < paScheduleEntry.Type.Recurring.Weekly.MembersSunday.Count; i += 3) + { + List timesList = + paScheduleEntry.Type.Recurring.Weekly.MembersSunday.GetRange(i, Math.Min(3, paScheduleEntry.Type.Recurring.Weekly.MembersSunday.Count - i)); + + CheckPoint_Time cpTime = new CheckPoint_Time(); + cpTime.Name = paScheduleEntry.Name; + cpTime.Comments = paScheduleEntry.Description; + cpTime.Tags = paScheduleEntry.TagMembers; + cpTime.RecurrencePattern = CheckPoint_Time.RecurrencePatternEnum.Weekly; + cpTime.RecurrenceWeekdays.Add(CheckPoint_Time.Weekdays.Sun); + cpTime.StartNow = true; + cpTime.EndNever = true; + + cpTime = SetHourseRanges(cpTime, timesList); + + cpTimesList.Add(cpTime); + } + } + } + } + else if (paScheduleEntry.Type.NonRecurring != null) + { + foreach (string member in paScheduleEntry.Type.NonRecurring.Memebers) + { + int indexDash = member.IndexOf("-"); + + if (indexDash == -1) + { + continue; + } + + CheckPoint_Time cpTime = new CheckPoint_Time(); + cpTime.Name = paScheduleEntry.Name; + cpTime.Comments = paScheduleEntry.Description; + cpTime.Tags = paScheduleEntry.TagMembers; + + cpTime.StartNow = false; + cpTime.EndNever = false; + + DateTime dateStart = DateTime.ParseExact(member.Substring(0, indexDash), "yyyy/MM/dd@HH:mm", System.Globalization.CultureInfo.InvariantCulture); + cpTime.StartDate = dateStart.ToString("dd-MMM-yyyy", CultureInfo.InvariantCulture); + cpTime.StartTime = dateStart.ToString("HH:mm"); + + DateTime dateEnd = DateTime.ParseExact(member.Substring(indexDash + 1), "yyyy/MM/dd@HH:mm", System.Globalization.CultureInfo.InvariantCulture); + cpTime.EndDate = dateEnd.ToString("dd-MMM-yyyy", CultureInfo.InvariantCulture); + cpTime.EndTime = dateEnd.ToString("HH:mm"); + + cpTimesList.Add(cpTime); + } + } + } + } + return cpTimesList; + } + + private CheckPoint_Time SetHourseRanges(CheckPoint_Time cpTime, List timesList) + { + for (int j = 0; j < timesList.Count; j++) + { + int indexDash = timesList[j].IndexOf("-"); + if (indexDash == -1) + { + continue; + } + switch (j) + { + case 0: + cpTime.HoursRangesEnabled_1 = true; + cpTime.HoursRangesFrom_1 = timesList[j].Substring(0, indexDash); + cpTime.HoursRangesTo_1 = timesList[j].Substring(indexDash + 1); + break; + case 1: + cpTime.HoursRangesEnabled_2 = true; + cpTime.HoursRangesFrom_2 = timesList[j].Substring(0, indexDash); + cpTime.HoursRangesTo_2 = timesList[j].Substring(indexDash + 1); + break; + case 2: + cpTime.HoursRangesEnabled_3 = true; + cpTime.HoursRangesFrom_3 = timesList[j].Substring(0, indexDash); + cpTime.HoursRangesTo_3 = timesList[j].Substring(indexDash + 1); + break; + } + } + + return cpTime; + } + + public CheckPoint_Time InspectCpScheduleName(CheckPoint_Time cpTime) + { + string cpTimeName = cpTime.Name; + if (cpTimeName.Length > 11) + { + cpTimeName = cpTimeName.Substring(0, 5) + "_t" + _timeCutterCounter++; + } + + if (!_timesNamesSet.Add(cpTimeName)) + { + cpTimeName = cpTimeName.Substring(0, 5) + "_t" + _timeCutterCounter++; + } + + if (!cpTimeName.Equals(cpTime.Name)) + { + _warningsList.Add(cpTime.Name + " time object was renamed to " + cpTimeName); + cpTime.Name = cpTimeName; + } + return cpTime; + } + + #endregion + + #region Convert Services and Services Groups + + public Dictionary GetServicesTypes(PA_Objects paObjects, Dictionary s_paServicesTypesDict) + { + Dictionary paServicesTypesDict = null; + if (s_paServicesTypesDict != null) + paServicesTypesDict = new Dictionary(s_paServicesTypesDict); + else + paServicesTypesDict = new Dictionary(); + + if (paObjects.ServiceEntries != null) + { + foreach (PA_ServiceEntry paServiceEntry in paObjects.ServiceEntries) + { + if (paServiceEntry.Protocol != null) + { + if (paServiceEntry.Protocol.ServiceTcp != null && paServiceEntry.Protocol.ServiceTcp.Port != null) + { + paServicesTypesDict[paServiceEntry.Name] = SERVICE_TYPE_TCP; + } + + if (paServiceEntry.Protocol.ServiceUdp != null && paServiceEntry.Protocol.ServiceUdp.Port != null) + { + paServicesTypesDict[paServiceEntry.Name] = SERVICE_TYPE_UDP; + } + } + } + } + + return paServicesTypesDict; + } + + public Dictionary ConvertServices(PA_Objects paObjects, Dictionary s_cpServicesDict) + { + Dictionary cpServicesDict = null; + if (s_cpServicesDict != null) + cpServicesDict = new Dictionary(s_cpServicesDict); + else + cpServicesDict = new Dictionary(); + + GetPredefinedServices().ForEach(x => cpServicesDict[x.Name] = InspectService(x)); + + if (paObjects.ServiceEntries != null) + { + foreach (PA_ServiceEntry paServiceEntry in paObjects.ServiceEntries) + { + if (paServiceEntry.Protocol != null) + { + if (paServiceEntry.Protocol.ServiceTcp != null && paServiceEntry.Protocol.ServiceTcp.Port != null) + { + string srvName = paServiceEntry.Name; + + if (!char.IsLetter(paServiceEntry.Name[0])) + { + srvName = SERVICE_TYPE_TCP + "_" + paServiceEntry.Name; + _warningsList.Add(paServiceEntry.Name + " service (TCP) was renamed to " + srvName); + } + + string[] ports = paServiceEntry.Protocol.ServiceTcp.Port.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); + string[] sourcePorts = new string[] { "" }; + if (paServiceEntry.Protocol.ServiceTcp.SourcePort != null) + { + sourcePorts = paServiceEntry.Protocol.ServiceTcp.SourcePort.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); + } + + if (ports.Length > 1 || sourcePorts.Length > 1) + { + //create group + CheckPoint_ServiceGroup cpServicesGrp = new CheckPoint_ServiceGroup(); + cpServicesGrp.Name = InspectObjectName(srvName, CP_OBJECT_TYPE_NAME_SERVICE_GROUP); + cpServicesGrp.Comments = paServiceEntry.Description; + cpServicesGrp.Tags = paServiceEntry.TagMembers; + _warningsList.Add(srvName + " tcp service is replaced by service group: " + cpServicesGrp.Name); + foreach (string port in ports) + { + foreach (string sourcePort in sourcePorts) + { + string srvNameNew = srvName; + srvNameNew += port.Trim().Equals("") ? "" : "_" + port; + srvNameNew += sourcePort.Trim().Equals("") ? "" : "_" + sourcePort; + CheckPoint_TcpService cpTcpService = new CheckPoint_TcpService(); + cpTcpService.Name = InspectObjectName(srvNameNew, CP_OBJECT_TYPE_NAME_SERVICE_TCP); + cpTcpService.Comments = paServiceEntry.Description; + cpTcpService.Tags = paServiceEntry.TagMembers; + cpTcpService.Port = AdjustPorts(port); + cpTcpService.SourcePort = AdjustPorts(sourcePort); + + CheckPointObject cpServiceChecked = InspectService(cpTcpService); + + cpServicesGrp.Members.Add(cpServiceChecked.Name); + cpServicesDict[cpServiceChecked.Name] = cpServiceChecked; + } + } + cpServicesDict[paServiceEntry.Name] = cpServicesGrp; + } + else + { + CheckPoint_TcpService cpTcpService = new CheckPoint_TcpService(); + + cpTcpService.Name = InspectObjectName(srvName, CP_OBJECT_TYPE_NAME_SERVICE_TCP); + + cpTcpService.Comments = paServiceEntry.Description; + cpTcpService.Tags = paServiceEntry.TagMembers; + cpTcpService.Port = AdjustPorts(paServiceEntry.Protocol.ServiceTcp.Port); + cpTcpService.SourcePort = AdjustPorts(paServiceEntry.Protocol.ServiceTcp.SourcePort); + + CheckPointObject cpServiceChecked = InspectService(cpTcpService); + + cpServicesDict[paServiceEntry.Name] = cpServiceChecked; + } + } + + if (paServiceEntry.Protocol.ServiceUdp != null && paServiceEntry.Protocol.ServiceUdp.Port != null) + { + string srvName = paServiceEntry.Name; + if (!char.IsLetter(paServiceEntry.Name[0])) + { + srvName = SERVICE_TYPE_UDP + "_" + paServiceEntry.Name; + _warningsList.Add(paServiceEntry.Name + " service (UDP) was renamed to " + srvName); + } + string[] ports = paServiceEntry.Protocol.ServiceUdp.Port.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); + string[] sourcePorts = new string[] { "" }; + if (paServiceEntry.Protocol.ServiceUdp.SourcePort != null) + { + sourcePorts = paServiceEntry.Protocol.ServiceUdp.SourcePort.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); + } + + if (ports.Length > 1 || sourcePorts.Length > 1) + { + //create group + CheckPoint_ServiceGroup cpServicesGrp = new CheckPoint_ServiceGroup(); + cpServicesGrp.Name = InspectObjectName(srvName, CP_OBJECT_TYPE_NAME_SERVICE_GROUP); + cpServicesGrp.Comments = paServiceEntry.Description; + cpServicesGrp.Tags = paServiceEntry.TagMembers; + _warningsList.Add(srvName + " udp service is replaced by service group: " + cpServicesGrp.Name); + foreach (string port in ports) + { + foreach (string sourcePort in sourcePorts) + { + string srvNameNew = srvName; + srvNameNew += port.Trim().Equals("") ? "" : "_" + port; + srvNameNew += sourcePort.Trim().Equals("") ? "" : "_" + sourcePort; + CheckPoint_UdpService cpUdpService = new CheckPoint_UdpService(); + cpUdpService.Name = InspectObjectName(srvNameNew, CP_OBJECt_TYPE_NAME_SERVICE_UDP); + cpUdpService.Comments = paServiceEntry.Description; + cpUdpService.Tags = paServiceEntry.TagMembers; + cpUdpService.Port = AdjustPorts(port); + cpUdpService.SourcePort = AdjustPorts(sourcePort); + + CheckPointObject cpServiceChecked = InspectService(cpUdpService); + cpServicesGrp.Members.Add(cpServiceChecked.Name); + cpServicesDict[cpServiceChecked.Name] = cpServiceChecked; + } + } + cpServicesDict[paServiceEntry.Name] = cpServicesGrp; + } + else + { + CheckPoint_UdpService cpUdpService = new CheckPoint_UdpService(); + cpUdpService.Name = InspectObjectName(srvName, CP_OBJECt_TYPE_NAME_SERVICE_UDP); + cpUdpService.Comments = paServiceEntry.Description; + cpUdpService.Tags = paServiceEntry.TagMembers; + cpUdpService.Port = AdjustPorts(paServiceEntry.Protocol.ServiceUdp.Port); + cpUdpService.SourcePort = AdjustPorts(paServiceEntry.Protocol.ServiceUdp.SourcePort); + + CheckPointObject cpServiceChecked = InspectService(cpUdpService); + cpServicesDict[paServiceEntry.Name] = cpServiceChecked; + } + } + } + } + } + return cpServicesDict; + } + + public List GetPredefinedServices() + { + List predefinedServices = new List(); + + CheckPoint_ServiceGroup cpServiceGroupHttp = new CheckPoint_ServiceGroup(); + cpServiceGroupHttp.Name = "service-http"; + cpServiceGroupHttp.Members.Add("http"); + cpServiceGroupHttp.Members.Add("HTTP_proxy"); + + predefinedServices.Add(cpServiceGroupHttp); + + CheckPoint_TcpService cpServiceHttps = new CheckPoint_TcpService(); + cpServiceHttps.Name = "service-https"; + cpServiceHttps.Port = "443"; + + predefinedServices.Add(cpServiceHttps); + + return predefinedServices; + } + + private string AdjustPorts(string input) + { + if (!string.IsNullOrWhiteSpace(input) && input.StartsWith("0")) + { + input = "1" + input.Substring(1); + } + return input; + } + + public CheckPointObject InspectService(CheckPointObject cpService) + { + CheckPointObject cpServiceRet = null; + + if (cpService.GetType() == typeof(CheckPoint_TcpService)) + { + CheckPoint_TcpService cpTcpService = (CheckPoint_TcpService)cpService; + bool isFound; + string cpServiceName = _cpObjects.GetKnownServiceName(SERVICE_TYPE_TCP + "_" + cpTcpService.Port, out isFound); + + if (isFound) + { + cpServiceRet = _cpObjects.GetObject(cpServiceName); + cpPredefServicesTypes[cpServiceRet.Name] = SERVICE_TYPE_TCP; + } + else + { + cpServiceRet = cpTcpService; + } + } + else if (cpService.GetType() == typeof(CheckPoint_UdpService)) + { + CheckPoint_UdpService cpUdpService = (CheckPoint_UdpService)cpService; + bool isFound; + string cpServiceName = _cpObjects.GetKnownServiceName(SERVICE_TYPE_UDP + "_" + cpUdpService.Port, out isFound); + + if (isFound) + { + cpServiceRet = _cpObjects.GetObject(cpServiceName); + cpPredefServicesTypes[cpServiceRet.Name] = SERVICE_TYPE_UDP; + } + else + { + cpServiceRet = cpUdpService; + } + } + else if (cpService.GetType() == typeof(CheckPoint_ServiceGroup)) + { + cpServiceRet = cpService; + } + else + { + _errorsList.Add(cpService.Name + " service is not TCP or UDP or service group."); + } + + return cpServiceRet; + } + + public Dictionary ConvertServicesGroups(PA_Objects paObjects, Dictionary s_cpServicesGroupsDict) + { + Dictionary cpServicesGroupsDict = null; + if (s_cpServicesGroupsDict != null) + cpServicesGroupsDict = new Dictionary(s_cpServicesGroupsDict); + else + cpServicesGroupsDict = new Dictionary(); + + if (paObjects.ServiceGroupEntries != null) + { + foreach (PA_ServiceGroupEntry paServiceGroupEntry in paObjects.ServiceGroupEntries) + { + CheckPoint_ServiceGroup cpServiceGroup = new CheckPoint_ServiceGroup(); + cpServiceGroup.Name = InspectObjectName(paServiceGroupEntry.Name, CP_OBJECT_TYPE_NAME_SERVICE_GROUP); + cpServiceGroup.Comments = paServiceGroupEntry.Description; + cpServiceGroup.Tags = paServiceGroupEntry.TagMembers; + cpServiceGroup.Members = paServiceGroupEntry.Members; + cpServicesGroupsDict[paServiceGroupEntry.Name] = cpServiceGroup; + } + } + + return cpServicesGroupsDict; + } + + public Dictionary ConvertServicesGroupsWithInspection(PA_Objects paObjects, Dictionary cpServicesDict, + Dictionary s_cpServicesGroupsDict) + { + Dictionary cpServicesGroupsCheck = ConvertServicesGroups(paObjects, s_cpServicesGroupsDict); + + Dictionary cpServicesGroupsResult = new Dictionary(); + + InspectServicesGroups(cpServicesDict, cpServicesGroupsCheck, cpServicesGroupsResult); + + return cpServicesGroupsResult; + } + + public void InspectServicesGroups(Dictionary cpServicesDict, + Dictionary cpServicesGroupsCheck, + Dictionary cpServicesGroupsResult) + { + while (cpServicesGroupsCheck.Count > 0) + { + string paSrvGroupName = new List(cpServicesGroupsCheck.Keys)[0]; + CheckPoint_ServiceGroup cpSrvGroupCheck = cpServicesGroupsCheck[paSrvGroupName]; + + cpServicesGroupsCheck.Remove(paSrvGroupName); + + InspectServicesGroup(paSrvGroupName, cpSrvGroupCheck, cpServicesDict, cpServicesGroupsCheck, cpServicesGroupsResult); + } + } + + public bool InspectServicesGroup(string paSrvGroupName, + CheckPoint_ServiceGroup cpServicesGroup, + Dictionary cpServicesDict, + Dictionary cpServicesGroupsCheck, + Dictionary cpServicesGroupsResult) + { + bool isOk = true; + + CheckPoint_ServiceGroup cpServicesGroupNew = new CheckPoint_ServiceGroup(); + cpServicesGroupNew.Name = cpServicesGroup.Name; + cpServicesGroupNew.Comments = cpServicesGroup.Comments; + cpServicesGroupNew.Tags = cpServicesGroup.Tags; + + foreach (string member in cpServicesGroup.Members) + { + //group member is in Services List + if (cpServicesDict.ContainsKey(member)) + { + cpServicesGroupNew.Members.Add(cpServicesDict[member].Name); + continue; + } + + //group member is Services Group and converted already + if (cpServicesGroupsResult.ContainsKey(member)) + { + cpServicesGroupNew.Members.Add(cpServicesGroupsResult[member].Name); + continue; + } + + //group member is Services Group and not converted yet + if (cpServicesGroupsCheck.ContainsKey(member)) + { + CheckPoint_ServiceGroup cpSrvGroupNew = cpServicesGroupsCheck[member]; + cpServicesGroupsCheck.Remove(member); + if (InspectServicesGroup(member, cpSrvGroupNew, cpServicesDict, cpServicesGroupsCheck, cpServicesGroupsResult)) + { + cpServicesGroupNew.Members.Add(cpSrvGroupNew.Name); + continue; + } + } + + isOk = false; + _errorsList.Add(cpServicesGroup.Name + " services group can not been converted becuase it contains non-existing member: " + member); + } + + if (isOk) + { + cpServicesGroupsResult[paSrvGroupName] = cpServicesGroupNew; + } + + return isOk; + } + + #endregion + + #region Convert Applications, Applications Groups and Applications Filters + + public List GetApplicationsMatchList() + { + return new List(File.ReadAllLines(PA_APPLICATIONS_FILE_NAME)); + } + + public Dictionary ConvertApplicationsGroups(List paAppsGroupsListCheck, + List appsMatchList, + Dictionary s_cpAppGroupDict, + List paAppFiltersList, + Dictionary cpServicesGroupsDict) + { + Dictionary cpAppGroupDict = null; + if (s_cpAppGroupDict != null) + cpAppGroupDict = new Dictionary(s_cpAppGroupDict); + else + cpAppGroupDict = new Dictionary(); + + if (paAppsGroupsListCheck != null) + { + while (paAppsGroupsListCheck.Count > 0) + { + PA_ApplicationGroupEntry paAppsGroupCheck = paAppsGroupsListCheck[0]; + paAppsGroupsListCheck.RemoveAt(0); + + CheckPoint_ApplicationGroup cpAppGroup = new CheckPoint_ApplicationGroup(); + cpAppGroup.Name = InspectObjectName(GetSafeName(paAppsGroupCheck.Name), CP_OBJECT_TYPE_NAME_APPLICATION_GROUP); + + CheckPoint_ServiceGroup cpServiceGroup = new CheckPoint_ServiceGroup(); + cpServiceGroup.Name = InspectObjectName(GetSafeName(paAppsGroupCheck.Name + "-svc"), CP_OBJECT_TYPE_NAME_APPLICATION_GROUP); + + + foreach (string appMember in paAppsGroupCheck.ApplicationGroupMembers) + { + string matchedLine = appsMatchList.Find(x => x.StartsWith(appMember + ";")); + if (!string.IsNullOrEmpty(matchedLine)) + { + string[] matchedArray = matchedLine.Split(';'); + if (!string.IsNullOrWhiteSpace(matchedArray[1])) + { + string[] matchedValues = matchedArray[1].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + foreach (string matchedValue in matchedValues) + { + if (!matchedValue.Trim().Equals("")) + { + cpAppGroup.Members.Add(matchedValue.Trim()); + } + } + } + else if (!string.IsNullOrWhiteSpace(matchedArray[2])) + { + string[] matchedValues = matchedArray[2].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + foreach (string matchedValue in matchedValues) + { + if (!matchedValue.Trim().Equals("")) + { + cpServiceGroup.Members.Add(matchedValue.Trim()); + + } + } + cpServicesGroupsDict[paAppsGroupCheck.Name + "-svc"] = cpServiceGroup; + } + else + { + _warningsList.Add(paAppsGroupCheck.Name + " application group contains non-mapped application: " + appMember); + } + } + else if (cpAppGroupDict.ContainsKey(appMember)) + { + cpAppGroup.Members.Add(cpAppGroupDict[appMember].Name); + } + else if (paAppFiltersList.Contains(appMember)) + { + _warningsList.Add(paAppsGroupCheck.Name + " application group contains application filter: " + appMember); + } + else if (paAppsGroupsListCheck.FindIndex(x => x.Name.Equals(appMember)) != -1) + { + cpAppGroupDict = ConvertApplicationsGroups(paAppsGroupsListCheck, appsMatchList, cpAppGroupDict, paAppFiltersList, cpServicesGroupsDict); + if (cpAppGroupDict.ContainsKey(appMember)) + { + cpAppGroup.Members.Add(cpAppGroupDict[appMember].Name); + } + else + { + _warningsList.Add(paAppsGroupCheck.Name + " application group contains unknown application: " + appMember); + } + } + else + { + _warningsList.Add(paAppsGroupCheck.Name + " application group contains unknown application: " + appMember); + } + } + + cpAppGroupDict[paAppsGroupCheck.Name] = cpAppGroup; + } + } + + return cpAppGroupDict; + } + + public List GetPAApplicationsFilters(PA_Objects paObjects, List s_cpAppFiltersDict) + { + List paAppFiltersList = null; + if (s_cpAppFiltersDict != null) + paAppFiltersList = new List(s_cpAppFiltersDict); + else + paAppFiltersList = new List(); + + if (paObjects.ApplicationFiltersEntries != null) + { + foreach (PA_ApplicationFilterEntry paAppFilterEntry in paObjects.ApplicationFiltersEntries) + { + paAppFiltersList.Add(paAppFilterEntry.Name); + } + } + + return paAppFiltersList; + } + + #endregion + + #region Convert Security Policy + + public void ConvertSecurityPolicy(PA_DeviceGroupEntry paDeviceGroupEntry, + Dictionary cpZonesDict, + Dictionary cpAddressesDict, + Dictionary cpNetGroupsDict, + Dictionary cpServicesDict, + Dictionary cpServicesGroupsDict, + List appsMatchList, + Dictionary cpAppGroupsDict, + List paAppFiltersList, + Dictionary> cpSchedulesDict, + Dictionary cpAccessRolesDict, PA_PreRulebase s_preRulebase, + PA_PostRulebase s_postRulebase, + List devicesGroupList, + Dictionary _devicesUIDDict + ) + { + Dictionary cpLayersDict = new Dictionary(); + Dictionary cpGroupRuleAppFiltering = new Dictionary(); + + List paRules = new List(); + bool isPolicyPlain = false; + + //add pre-rules from shared section to the device group rules + if (s_preRulebase != null && s_preRulebase.Security != null && s_preRulebase.Security.RulesList != null) + { + foreach (PA_SecurityRuleEntry paSecurityRuleEntry in s_preRulebase.Security.RulesList) + { + isPolicyPlain = + !isPolicyPlain && (paSecurityRuleEntry.FromList.Contains(PA_ANY_VALUE) || paSecurityRuleEntry.ToList.Contains(PA_ANY_VALUE)) ? true : isPolicyPlain; + paRules.Add(paSecurityRuleEntry); + } + } + + if (paDeviceGroupEntry.PreRulebase != null && paDeviceGroupEntry.PreRulebase.Security != null && paDeviceGroupEntry.PreRulebase.Security.RulesList != null) + { + foreach (PA_SecurityRuleEntry paSecurityRuleEntry in paDeviceGroupEntry.PreRulebase.Security.RulesList) + { + isPolicyPlain = + !isPolicyPlain && (paSecurityRuleEntry.FromList.Contains(PA_ANY_VALUE) || paSecurityRuleEntry.ToList.Contains(PA_ANY_VALUE)) ? true : isPolicyPlain; + paRules.Add(paSecurityRuleEntry); + } + } + + if (paDeviceGroupEntry.PostRulebase != null && paDeviceGroupEntry.PostRulebase.Security != null && paDeviceGroupEntry.PostRulebase.Security.RulesList != null) + { + foreach (PA_SecurityRuleEntry paSecurityRuleEntry in paDeviceGroupEntry.PostRulebase.Security.RulesList) + { + isPolicyPlain = + !isPolicyPlain && (paSecurityRuleEntry.FromList.Contains(PA_ANY_VALUE) || paSecurityRuleEntry.ToList.Contains(PA_ANY_VALUE)) ? true : isPolicyPlain; + paRules.Add(paSecurityRuleEntry); + } + } + + //add post-rules from shared section to the device group rules + if (s_postRulebase != null && s_postRulebase.Security != null && s_postRulebase.Security.RulesList != null) + { + foreach (PA_SecurityRuleEntry paSecurityRuleEntry in s_postRulebase.Security.RulesList) + { + isPolicyPlain = + !isPolicyPlain && (paSecurityRuleEntry.FromList.Contains(PA_ANY_VALUE) || paSecurityRuleEntry.ToList.Contains(PA_ANY_VALUE)) ? true : isPolicyPlain; + paRules.Add(paSecurityRuleEntry); + } + } + + var cpPackage = new CheckPoint_Package(); + cpPackage.Name = _policyPackageName; + cpPackage.ParentLayer.Name = cpPackage.NameOfAccessLayer; + + foreach (PA_SecurityRuleEntry paSecurityRuleEntry in paRules) + { + List messagesE = new List(); + + List cpRuleSourceList = new List(); + #region Processing Source of Rule + if (!paSecurityRuleEntry.SourceList.Contains(PA_ANY_VALUE)) + { + foreach (string srcMember in paSecurityRuleEntry.SourceList) + { + if (cpAddressesDict.ContainsKey(srcMember)) + { + cpRuleSourceList.Add(cpAddressesDict[srcMember]); + } + else if (cpNetGroupsDict.ContainsKey(srcMember)) + { + cpRuleSourceList.Add(cpNetGroupsDict[srcMember]); + } + else if (Regex.IsMatch(srcMember, RE_NET_ADDRESS)) + { + if (!srcMember.Contains("/") || srcMember.Contains(NETWORK_NETMASK_WS)) + { + string ipAddress; + + if (srcMember.Contains("/")) + ipAddress = srcMember.Substring(0, srcMember.IndexOf("/")); + else + ipAddress = srcMember.Substring(0); + + CheckPoint_Host cpHostNew = new CheckPoint_Host(); + cpHostNew.Name = "Host_" + ipAddress; + cpHostNew.IpAddress = ipAddress; + + cpAddressesDict[srcMember] = cpHostNew; + + cpRuleSourceList.Add(cpHostNew); + } + else + { + IPNetwork ipNetwork; + if (IPNetwork.TryParse(srcMember, out ipNetwork)) + { + string ipAddress = srcMember.Substring(0, srcMember.IndexOf("/")); + + CheckPoint_Network cpNetworkNew = new CheckPoint_Network(); + cpNetworkNew.Name = "Net_" + ipAddress; + cpNetworkNew.Subnet = ipAddress; + cpNetworkNew.Netmask = ipNetwork.Netmask.ToString(); + + cpAddressesDict[srcMember] = cpNetworkNew; + + cpRuleSourceList.Add(cpNetworkNew); + } + } + } + else + { + messagesE.Add(paSecurityRuleEntry.Name + + " security rule is not converted because source object is not defined or converted: " + + srcMember); + } + } + } + else + { + if (isPolicyPlain && !paSecurityRuleEntry.FromList.Contains(PA_ANY_VALUE) + && !(ConvertUserConf && paSecurityRuleEntry.SourceUserList != null && !paSecurityRuleEntry.SourceUserList.Contains(PA_ANY_VALUE))) + { + paSecurityRuleEntry.FromList.ForEach(fromObj => + { + if ((cpZonesDict != null) && cpZonesDict.ContainsKey(fromObj)) + { + CheckPoint_Zone cpZone = cpZonesDict[fromObj]; + cpRuleSourceList.Add(cpZone); + AddCheckPointObject(cpZone); + } + }); + } + } + #endregion + + List cpRuleDestinationList = new List(); + #region Processing Destination of Rule + if (!paSecurityRuleEntry.DestinationList.Contains(PA_ANY_VALUE)) + { + foreach (string dstMember in paSecurityRuleEntry.DestinationList) + { + if (cpAddressesDict.ContainsKey(dstMember)) + { + cpRuleDestinationList.Add(cpAddressesDict[dstMember]); + } + else if (cpNetGroupsDict.ContainsKey(dstMember)) + { + cpRuleDestinationList.Add(cpNetGroupsDict[dstMember]); + } + else if (Regex.IsMatch(dstMember, RE_NET_ADDRESS)) + { + if (!dstMember.Contains("/") || dstMember.Contains(NETWORK_NETMASK_WS)) + { + string ipAddress; + + if (dstMember.Contains("/")) + ipAddress = dstMember.Substring(0, dstMember.IndexOf("/")); + else + ipAddress = dstMember.Substring(0); + + CheckPoint_Host cpHostNew = new CheckPoint_Host(); + cpHostNew.Name = "Host_" + ipAddress; + cpHostNew.IpAddress = ipAddress; + + cpAddressesDict[dstMember] = cpHostNew; + + cpRuleDestinationList.Add(cpHostNew); + } + else + { + IPNetwork ipNetwork; + if (IPNetwork.TryParse(dstMember, out ipNetwork)) + { + string ipAddress = dstMember.Substring(0, dstMember.IndexOf("/")); + + CheckPoint_Network cpNetworkNew = new CheckPoint_Network(); + cpNetworkNew.Name = "Net_" + ipAddress; + cpNetworkNew.Subnet = ipAddress; + cpNetworkNew.Netmask = ipNetwork.Netmask.ToString(); + + cpAddressesDict[dstMember] = cpNetworkNew; + + cpRuleDestinationList.Add(cpNetworkNew); + } + } + } + else + { + messagesE.Add(paSecurityRuleEntry.Name + + " security rule is not converted because destination object is not defined or converted: " + + dstMember); + } + } + } + else + { + if (isPolicyPlain && !paSecurityRuleEntry.ToList.Contains(PA_ANY_VALUE)) + { + paSecurityRuleEntry.ToList.ForEach(toObj => + { + if ((cpZonesDict != null) && cpZonesDict.ContainsKey(toObj)) + { + CheckPoint_Zone cpZone = cpZonesDict[toObj]; + cpRuleDestinationList.Add(cpZone); + AddCheckPointObject(cpZone); + } + }); + } + } + #endregion + + List cpRuleServiceList = new List(); + List cpRuleApplilcationList = new List(); + bool applicationsFiltering = false; + #region Processing Services, Groups of Services and Applications of Rule + if ((paSecurityRuleEntry.ApplicationList.Contains(PA_ANY_VALUE))) // services only -> processing services + { + if (!(paSecurityRuleEntry.ServiceList.Contains(PA_APPLICATION_DEFAULT) || paSecurityRuleEntry.ServiceList.Contains(PA_ANY_VALUE))) + { + foreach (string paServiceName in paSecurityRuleEntry.ServiceList) + { + CheckPointObject cpServiceObj = null; + if (cpServicesDict.ContainsKey(paServiceName)) + { + + cpServiceObj = cpServicesDict[paServiceName]; + } + else if (cpServicesGroupsDict.ContainsKey(paServiceName)) + { + cpServiceObj = cpServicesGroupsDict[paServiceName]; + } + + if (cpServiceObj != null) + { + cpRuleServiceList.Add(cpServiceObj); + } + else + { + messagesE.Add(paSecurityRuleEntry.Name + + " security rule is not converted because service object is not defined or converted: " + + paServiceName); + } + } + } + } + else //application and services or applications only -> processing applications + { + applicationsFiltering = true; + foreach (string paAppName in paSecurityRuleEntry.ApplicationList) + { + if (cpServicesGroupsDict.ContainsKey(paAppName + "-svc"))//to add mapped PA services from CP application group entry + { + cpRuleServiceList.Add(cpServicesGroupsDict[paAppName + "-svc"]); + } + + if (cpAppGroupsDict.ContainsKey(paAppName)) + { + cpRuleApplilcationList.Add(cpAppGroupsDict[paAppName]); + } + else if (paAppFiltersList.Contains(paAppName)) + { + _warningsList.Add(paSecurityRuleEntry.Name + " security rule contains application filter: " + paAppName); + } + else + { + string matchedLine = appsMatchList.Find(x => x.StartsWith(paAppName + ";")); + if (!string.IsNullOrEmpty(matchedLine)) + { + string[] matchedArray = matchedLine.Split(';'); + if (!string.IsNullOrWhiteSpace(matchedArray[1])) + { + string[] matchedValues = matchedArray[1].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + foreach (string matchedValue in matchedValues) + { + if (!matchedValue.Trim().Equals("")) + { + cpRuleApplilcationList.Add(new CheckPoint_PredifinedObject { Name = matchedValue.Trim() }); + } + } + } + else if (!string.IsNullOrWhiteSpace(matchedArray[2])) + { + string[] matchedValues = matchedArray[2].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + foreach (string matchedValue in matchedValues) + { + if (!matchedValue.Trim().Equals("")) + { + cpRuleApplilcationList.Add(new CheckPoint_PredifinedObject { Name = matchedValue.Trim() }); + } + } + } + else + _warningsList.Add(paSecurityRuleEntry.Name + " security rule contains non-mapped application: " + paAppName); + } + else + { + _warningsList.Add(paSecurityRuleEntry.Name + " security rule contains unknown application: " + paAppName); + } + } + } + + if (!(paSecurityRuleEntry.ServiceList.Contains(PA_APPLICATION_DEFAULT) || paSecurityRuleEntry.ServiceList.Contains(PA_ANY_VALUE))) + { + foreach (string paServiceName in paSecurityRuleEntry.ServiceList) + { + _warningsList.Add(paSecurityRuleEntry.Name + " access rule contains service which was not converted: " + paServiceName); + } + } + } + if (!paSecurityRuleEntry.CategoryList.Contains(PA_ANY_VALUE)) + { + foreach (string paCategoryName in paSecurityRuleEntry.CategoryList) + { + _warningsList.Add(paSecurityRuleEntry.Name + " access rule contains URL-category which was not converted: " + paCategoryName); + } + } + #endregion + + List cpAccessRolesList = new List(); + #region Processing Users Roles + if (ConvertUserConf && paSecurityRuleEntry.SourceUserList != null && !paSecurityRuleEntry.SourceUserList.Contains(PA_ANY_VALUE)) + { + CheckPoint_AccessRole cpAccessRole = new CheckPoint_AccessRole(); + cpAccessRole.Name = InspectObjectName("AR_" + paSecurityRuleEntry.Name, CP_OBJECT_TYPE_NAME_ACCESS_ROLE); + + foreach (string sourceUser in paSecurityRuleEntry.SourceUserList) + { + if (sourceUser.Contains(",")) + { + List values = new List(); + sourceUser.Split(new string[] { "," }, StringSplitOptions.None).ToList().ForEach(x => values.Add(x.Trim().Substring(x.IndexOf("=") + 1))); + AccessRoleUser arUser = new AccessRoleUser(); + arUser.Name = values[0]; + arUser.BaseDn = sourceUser; + + cpAccessRole.Users.Add(arUser); + } + else if (sourceUser.Contains("\\")) + { + AccessRoleUser arUser = new AccessRoleUser(); + arUser.Name = sourceUser.Substring(sourceUser.IndexOf("\\") + 1); + + cpAccessRole.Users.Add(arUser); + } + else + { + AccessRoleUser arUser = new AccessRoleUser(); + arUser.Name = sourceUser; + + cpAccessRole.Users.Add(arUser); + } + } + + if (paSecurityRuleEntry.SourceList != null && !paSecurityRuleEntry.SourceList.Contains(PA_ANY_VALUE)) + { + cpRuleSourceList.ForEach(x => cpAccessRole.Networks.Add(x.Name)); + cpRuleSourceList.Clear(); + } + + cpAccessRolesDict.Add(cpAccessRole.Name, cpAccessRole); + cpAccessRolesList.Add(cpAccessRole); + } + #endregion + + CheckPoint_Rule.ActionType cpRuleActionType = (paSecurityRuleEntry.Action.Equals("allow")) ? + CheckPoint_Rule.ActionType.Accept : CheckPoint_Rule.ActionType.Drop; + + List cpRuleTimeList = new List(); + #region Processing Schedule of Rule + if (paSecurityRuleEntry.Schedule != null && cpSchedulesDict.ContainsKey(paSecurityRuleEntry.Schedule)) + { + cpRuleTimeList.AddRange(cpSchedulesDict[paSecurityRuleEntry.Schedule]); + } + #endregion + + CheckPoint_Rule.TrackTypes cpRuleTrack = ("no".Equals(paSecurityRuleEntry.LogStart) && "no".Equals(paSecurityRuleEntry.LogEnd)) ? + CheckPoint_Rule.TrackTypes.None : CheckPoint_Rule.TrackTypes.Log; + + bool cpRuleEnabled = !("yes".Equals(paSecurityRuleEntry.Disabled)); + + bool cpRuleNegateSource = "yes".Equals(paSecurityRuleEntry.NegateSource); + bool cpRuleNegateDestination = "yes".Equals(paSecurityRuleEntry.NegateDestination); + + List cpTargetDeviceUIDList = AddSecurityRuleTarget(devicesGroupList, paSecurityRuleEntry, _devicesUIDDict); + + if (messagesE.Count == 0) + { + if (isPolicyPlain) + { + //Console.WriteLine("Plain policy rule: " + paSecurityRuleEntry.Name); + + CheckPoint_RuleWithApplication cpRule = CreateCpRule(paSecurityRuleEntry, + cpRuleSourceList, + cpRuleDestinationList, + cpRuleServiceList, + cpRuleApplilcationList, + cpRuleActionType, + cpRuleTimeList, + cpRuleTrack, + cpRuleEnabled, + cpRuleNegateSource, + cpRuleNegateDestination, + cpAddressesDict, + cpNetGroupsDict, + cpServicesDict, + cpServicesGroupsDict, + cpAccessRolesList, + cpAppGroupsDict, + //devicesGroupList, + cpTargetDeviceUIDList + ); + + cpRule.Layer = cpPackage.ParentLayer.Name; + + cpPackage.ParentLayer.Rules.Add(cpRule); + _rulesInConvertedPackage += 1; + + if (applicationsFiltering) + { + cpPackage.ParentLayer.ApplicationsAndUrlFiltering = true; + } + + string ruleCmd = cpRule.ToCLIScript(); + } + else + { + List zonesNamesFromList = paSecurityRuleEntry.FromList; + + List zonesNamesToList = paSecurityRuleEntry.ToList; + + foreach (string zoneNameFrom in zonesNamesFromList) + { + foreach (string zoneNameTo in zonesNamesToList) + { + if (PA_INTRAZONE_NAME.Equals(paSecurityRuleEntry.RuleType) && zoneNameFrom.Equals(zoneNameTo)) + { + continue; + } + if (PA_INTRAZONE_NAME.Equals(paSecurityRuleEntry.RuleType) && !zoneNameFrom.Equals(zoneNameTo)) + { + continue; + } + CheckPoint_RuleWithApplication cpRule = CreateCpRule(paSecurityRuleEntry, + cpRuleSourceList, + cpRuleDestinationList, + cpRuleServiceList, + cpRuleApplilcationList, + cpRuleActionType, + cpRuleTimeList, + cpRuleTrack, + cpRuleEnabled, + cpRuleNegateSource, + cpRuleNegateDestination, + cpAddressesDict, + cpNetGroupsDict, + cpServicesDict, + cpServicesGroupsDict, + cpAccessRolesList, + cpAppGroupsDict, + //devicesGroupList, + cpTargetDeviceUIDList + ); + + string keyLayerName = zoneNameFrom + "_TK_" + zoneNameTo; + string cpGroupRuleName = zoneNameFrom + "__" + zoneNameTo; + + CheckPoint_Layer cpLayer = null; + if (!cpLayersDict.TryGetValue(keyLayerName, out cpLayer)) + { + CheckPoint_Zone cpZoneSrc = cpZonesDict[zoneNameFrom]; + CheckPoint_Zone cpZoneDst = cpZonesDict[zoneNameTo]; + + AddCheckPointObject(cpZoneSrc); + AddCheckPointObject(cpZoneDst); + + cpLayer = new CheckPoint_Layer(); + cpLayer.Name = keyLayerName; + cpLayer.ApplicationsAndUrlFiltering = false; + + cpPackage.SubPolicies.Add(cpLayer); + + CheckPoint_Rule cpGroupRule = new CheckPoint_Rule(); + cpGroupRule.Name = cpGroupRuleName; + cpGroupRule.Source.Add(cpZoneSrc); + cpGroupRule.Destination.Add(cpZoneDst); + cpGroupRule.Layer = cpPackage.NameOfAccessLayer; + cpGroupRule.Action = CheckPoint_Rule.ActionType.SubPolicy; + cpGroupRule.SubPolicyName = cpLayer.Name; + + cpPackage.ParentLayer.Rules.Add(cpGroupRule); + _rulesInConvertedPackage += 1; + + cpGroupRuleAppFiltering[cpGroupRuleName] = false; + } + + cpRule.Layer = cpLayer.Name; + + cpLayer.Rules.Add(cpRule); + _rulesInConvertedPackage += 1; + cpLayersDict[keyLayerName] = cpLayer; + + //--- + if (applicationsFiltering) + { + cpLayer.ApplicationsAndUrlFiltering = true; + cpGroupRuleAppFiltering[cpGroupRuleName] = true; + } + } + } + } + } + else + { + _errorsList.AddRange(messagesE); + } + } + + cpPackage.ParentLayer.Rules.ForEach(x => + { + if (cpGroupRuleAppFiltering.ContainsKey(x.Name) && cpGroupRuleAppFiltering[x.Name]) + x.ConversionComments = "Applications and URL filtering is enabled for layer."; + }); + + foreach (CheckPoint_Layer cpLayer in cpLayersDict.Values) + { + CheckPoint_Rule cpRuleCU = new CheckPoint_Rule(); + cpRuleCU.Name = "Sub-Policy Cleanup"; + cpRuleCU.Layer = cpLayer.Name; + cpLayer.Rules.Add(cpRuleCU); + }; + + var cpRuleFake = new CheckPoint_Rule(); + cpRuleFake.Name = "Cleanup rule"; //the last rule which is created by default by CheckPoint script importer. It is for report only. + cpPackage.ParentLayer.Rules.Add(cpRuleFake); + + AddCheckPointObject(cpPackage); + } + + public List AddSecurityRuleTarget(List devicesGroupList, PA_SecurityRuleEntry paSecurityRuleEntry, Dictionary _devicesUIDDict) + { + List cpTargetDeviceEntries = new List(); + List cpTargetDeviceUIDList = new List(); + + ///get List of devices in current device group + List devices = new List(); + foreach (CheckPoint_NetworkGroup group in devicesGroupList) + { + devices.Add(group.Name); + } + + bool cpRuleNegateTarget = false; + if (paSecurityRuleEntry.Target != null) + { + cpRuleNegateTarget = "yes".Equals(paSecurityRuleEntry.Target.Negate); + + cpTargetDeviceEntries = paSecurityRuleEntry.Target.DevicesEntry; + string deviceName = null; + foreach (PA_TargetDeviceEntry entry in cpTargetDeviceEntries) + { + if (!cpRuleNegateTarget) + { + if (_devicesUIDDict.ContainsKey(entry.Name)) + { + deviceName = _devicesUIDDict[entry.Name]; + } + + cpTargetDeviceUIDList.Add("FW_" + deviceName); + } + else + { //negate option set to "yes" + foreach (string device in devices) + { + if (!("FW_" + entry.Name).Equals(device)) + { + if (_devicesUIDDict.ContainsKey(device)) + { + deviceName = _devicesUIDDict[device]; + } + cpTargetDeviceUIDList.Add(deviceName); + } + } + + } + } + } + return cpTargetDeviceUIDList; + } + + public List AddNatRuleTarget(List devicesGroupList, PA_NatRuleEntry paNatRuleEntry, Dictionary _devicesUIDDict) + { + List cpTargetDeviceEntries = new List(); + List cpTargetDeviceUIDList = new List(); + + ///get List of devices in current device group + List devices = new List(); + foreach (CheckPoint_NetworkGroup group in devicesGroupList) + { + devices.Add(group.Name); + } + + bool cpRuleNegateTarget = false; + if (paNatRuleEntry.Target != null) + { + cpRuleNegateTarget = "yes".Equals(paNatRuleEntry.Target.Negate); + + cpTargetDeviceEntries = paNatRuleEntry.Target.DevicesEntry; + string deviceName = null; + foreach (PA_TargetDeviceEntry entry in cpTargetDeviceEntries) + { + if (!cpRuleNegateTarget) + { + if (_devicesUIDDict.ContainsKey(entry.Name)) + { + deviceName = _devicesUIDDict[entry.Name]; + } + cpTargetDeviceUIDList.Add("FW_" + deviceName); + } + else + { //negate option set to "yes" + foreach (string device in devices) + { + if (!("FW_" + entry.Name).Equals(device)) + { + if (_devicesUIDDict.ContainsKey(device)) + { + deviceName = _devicesUIDDict[device]; + } + + cpTargetDeviceUIDList.Add(deviceName); + } + } + + } + } + } + return cpTargetDeviceUIDList; + } + + private CheckPoint_RuleWithApplication CreateCpRule(PA_SecurityRuleEntry paSecurityRuleEntry, + List cpRuleSourceList, + List cpRuleDestinationList, + List cpRuleServiceList, + List cpRuleApplilcationList, + CheckPoint_Rule.ActionType cpRuleActionType, + List cpRuleTimeList, + CheckPoint_Rule.TrackTypes cpRuleTrack, + bool cpRuleEnabled, + bool cpRuleNegateSource, + bool cpRuleNegateDestination, + Dictionary cpAddressesDict, + Dictionary cpNetGroupsDict, + Dictionary cpServicesDict, + Dictionary cpSrvGroupsDict, + List cpAccessRolesList, + Dictionary cpAppGroupsDict, + List cpTargetDeviceUIDList + ) + { + CheckPoint_RuleWithApplication cpRule = new CheckPoint_RuleWithApplication(); + cpRule.Name = paSecurityRuleEntry.Name; + cpRule.Comments = string.IsNullOrWhiteSpace(paSecurityRuleEntry.Description) ? "" : (" " + paSecurityRuleEntry.Description); + cpRule.Tags = paSecurityRuleEntry.TagMembers; + cpRule.Source.AddRange(cpRuleSourceList); + cpRule.Destination.AddRange(cpRuleDestinationList); + cpRule.Service.AddRange(cpRuleServiceList); + cpRule.Application.AddRange(cpRuleApplilcationList); + cpRule.Action = cpRuleActionType; + cpRule.Time.AddRange(cpRuleTimeList); + cpRule.Track = cpRuleTrack; + cpRule.Enabled = cpRuleEnabled; + if (cpTargetDeviceUIDList != null && cpTargetDeviceUIDList.Count() > 0) + { + cpRule.Target.AddRange(cpTargetDeviceUIDList); + } + cpRule.SourceNegated = cpRuleNegateSource; + cpRule.DestinationNegated = cpRuleNegateDestination; + cpRule.ConversionComments = "Matched rule: " + paSecurityRuleEntry.Name; + + + cpRule.Source.ForEach(x => + { + if (x.GetType() == typeof(CheckPoint_NetworkGroup)) + { + AddCpNetworkGroup((CheckPoint_NetworkGroup)x, cpAddressesDict, cpNetGroupsDict); + } + else if (x.GetType() != typeof(CheckPoint_PredifinedObject)) + { + AddCheckPointObject(x); + } + }); + cpRule.Destination.ForEach(x => + { + if (x.GetType() == typeof(CheckPoint_NetworkGroup)) + { + AddCpNetworkGroup((CheckPoint_NetworkGroup)x, cpAddressesDict, cpNetGroupsDict); + } + else if (x.GetType() != typeof(CheckPoint_PredifinedObject)) + { + AddCheckPointObject(x); + } + }); + cpRule.Service.ForEach(x => + { + if (x.GetType() == typeof(CheckPoint_ServiceGroup)) + { + AddCpServiceGroup((CheckPoint_ServiceGroup)x, cpServicesDict, cpSrvGroupsDict); + } + else if (x.GetType() != typeof(CheckPoint_PredifinedObject)) + { + AddCheckPointObject(x); + } + }); + cpRule.Time.ForEach(x => AddCheckPointObject(x)); + + if (ConvertUserConf && cpAccessRolesList.Count > 0) + { + if (cpRule.Source.Contains(_cpObjects.GetObject(CheckPointObject.Any))) + cpRule.Source.Clear(); + cpRule.Source.AddRange(cpAccessRolesList); + } + cpRule.Application.ForEach(x => + { + if (x.GetType() == typeof(CheckPoint_ApplicationGroup)) + { + AddCpApplicationGroup((CheckPoint_ApplicationGroup)x, cpAppGroupsDict); + } + else if (x.GetType() != typeof(CheckPoint_PredifinedObject)) + { + AddCheckPointObject(x); + } + }); + + return cpRule; + } + + #endregion + + #region Convert Nat Policy + + public void ConvertNatPolicy(PA_DeviceGroupEntry paDeviceGroupEntry, + Dictionary cpAddressesDict, + Dictionary cpNetGroupsDict, + Dictionary cpServicesDict, + Dictionary paServicesTypesDict, + Dictionary cpServicesGroupsDict, + List devicesGroupList, + Dictionary _devicesUIDDict) + { + int counterNatRules = -1; + + if (paDeviceGroupEntry.PreRulebase != null && paDeviceGroupEntry.PreRulebase.Nat != null && paDeviceGroupEntry.PreRulebase.Nat.RulesList != null) + { + foreach (PA_NatRuleEntry paNatRuleEntry in paDeviceGroupEntry.PreRulebase.Nat.RulesList) + { + List cpSourceTranslationList = new List(); + bool isSourceTranslationExists = true; + bool isNatRuleStatic = false; + bool isNatRuleBiDirectional = false; + bool isDestinationTranslationNone = false; + + #region converting source translation to list; checking if NAT Rule Method should be Static + if (paNatRuleEntry.SourceTranslation != null) + { + if (paNatRuleEntry.SourceTranslation.StaticIp != null) + { + if (!string.IsNullOrWhiteSpace(paNatRuleEntry.SourceTranslation.StaticIp.TranslatedAddress)) + { + if (cpAddressesDict.ContainsKey(paNatRuleEntry.SourceTranslation.StaticIp.TranslatedAddress)) + { + cpSourceTranslationList.Add(cpAddressesDict[paNatRuleEntry.SourceTranslation.StaticIp.TranslatedAddress]); + isNatRuleStatic = true; + if (!string.IsNullOrWhiteSpace(paNatRuleEntry.SourceTranslation.StaticIp.IsBiDirectional) + && paNatRuleEntry.SourceTranslation.StaticIp.IsBiDirectional.ToLower().Equals("yes")) + { + isNatRuleBiDirectional = true; + } + } + } + } + else if (paNatRuleEntry.SourceTranslation.DynamicIp != null) + { + if (paNatRuleEntry.SourceTranslation.DynamicIp.TranslatedAddresses != null) + { + foreach (string translatedAddress in paNatRuleEntry.SourceTranslation.DynamicIp.TranslatedAddresses) + { + if (cpAddressesDict.ContainsKey(translatedAddress)) + { + cpSourceTranslationList.Add(cpAddressesDict[translatedAddress]); + } + else if (cpNetGroupsDict.ContainsKey(translatedAddress)) + { + cpSourceTranslationList.Add(cpNetGroupsDict[translatedAddress]); + } + } + } + } + else if (paNatRuleEntry.SourceTranslation.DynamicIpAndPort != null) + { + if (paNatRuleEntry.SourceTranslation.DynamicIpAndPort.TranslatedAddresses != null && + paNatRuleEntry.SourceTranslation.DynamicIpAndPort.TranslatedAddresses.Count > 0) + { + foreach (string translatedAddress in paNatRuleEntry.SourceTranslation.DynamicIpAndPort.TranslatedAddresses) + { + if (cpAddressesDict.ContainsKey(translatedAddress)) + { + cpSourceTranslationList.Add(cpAddressesDict[translatedAddress]); + } + else if (cpNetGroupsDict.ContainsKey(translatedAddress)) + { + cpSourceTranslationList.Add(cpNetGroupsDict[translatedAddress]); + } + } + } + else if (paNatRuleEntry.SourceTranslation.DynamicIpAndPort.InterfaceAddress != null) + { + string intfAddrIP = paNatRuleEntry.SourceTranslation.DynamicIpAndPort.InterfaceAddress.Ip; + if (!string.IsNullOrWhiteSpace(intfAddrIP)) + { + if (cpAddressesDict.ContainsKey(intfAddrIP)) + { + cpSourceTranslationList.Add(cpAddressesDict[intfAddrIP]); + } + else + { + if (intfAddrIP.Contains("/")) + { + intfAddrIP = intfAddrIP.Substring(0, intfAddrIP.IndexOf("/")); + } + + IPAddress ipAddress; + if (IPAddress.TryParse(intfAddrIP, out ipAddress)) + { + CheckPoint_Host cpHost = new CheckPoint_Host(); + cpHost.Name = "NatIntf_" + intfAddrIP; + cpHost.IpAddress = intfAddrIP; + cpSourceTranslationList.Add(cpHost); + + _warningsList.Add(cpHost.Name + " host object is created for NAT rule."); + } + } + } + } + } + } + + if (cpSourceTranslationList.Count == 0) + { + isSourceTranslationExists = false; + // createing Dummy Object because we need to have at least 1 element in cpSourceTranslationList for creating NAT rule + cpSourceTranslationList.Add(new CheckPoint_PredifinedObject { Name = "DUMMY_OBJECT" }); + } + #endregion + + if (paNatRuleEntry.DestinationTranslation == null) + { + isDestinationTranslationNone = true; + } + + foreach (string source in paNatRuleEntry.SourceList) + { + foreach (string destination in paNatRuleEntry.DestinationList) + { + foreach (CheckPointObject cpSourceTranslation in cpSourceTranslationList) + { + CheckPoint_NAT_Rule cpNatRule = new CheckPoint_NAT_Rule(); + + List messagesW = new List(); + List messagesE = new List(); + + CheckPointObject extraNatServiceSourced = null; + CheckPointObject extraNatServiceTranslated = null; + + cpNatRule.Name = GetSafeName(paNatRuleEntry.Name + ((++counterNatRules > 0) ? "_" + counterNatRules : "")); + cpNatRule.Comments = "Matched rule name: " + paNatRuleEntry.Name + ". "; + + cpNatRule.Comments += paNatRuleEntry.Description; + cpNatRule.Tags = paNatRuleEntry.TagMembers; + cpNatRule.Enabled = !("yes".Equals(paNatRuleEntry.Disabled)); + cpNatRule.Method = CheckPoint_NAT_Rule.NatMethod.Hide; + + #region adding original source + if (!PA_ANY_VALUE.Equals(source)) + { + if (cpAddressesDict.ContainsKey(source)) + { + cpNatRule.Source = cpAddressesDict[source]; + } + else if (cpNetGroupsDict.ContainsKey(source)) + { + cpNatRule.Source = cpNetGroupsDict[source]; + } + else if (Regex.IsMatch(source, RE_NET_ADDRESS)) + { + if (!source.Contains("/") || source.Contains(NETWORK_NETMASK_WS)) + { + string ipAddress; + + if (source.Contains("/")) + ipAddress = source.Substring(0, source.IndexOf("/")); + else + ipAddress = source.Substring(0); + + CheckPoint_Host cpHostNew = new CheckPoint_Host(); + cpHostNew.Name = "Host_" + ipAddress; + cpHostNew.IpAddress = ipAddress; + + cpAddressesDict[source] = cpHostNew; + + cpNatRule.Source = cpHostNew; + } + else + { + IPNetwork ipNetwork; + if (IPNetwork.TryParse(source, out ipNetwork)) + { + string ipAddress = source.Substring(0, source.IndexOf("/")); + + CheckPoint_Network cpNetworkNew = new CheckPoint_Network(); + cpNetworkNew.Name = "Net_" + ipAddress; + cpNetworkNew.Subnet = ipAddress; + cpNetworkNew.Netmask = ipNetwork.Netmask.ToString(); + + cpAddressesDict[source] = cpNetworkNew; + + cpNatRule.Source = cpNetworkNew; + } + } + } + else + { + messagesE.Add(paNatRuleEntry.Name + + " NAT rule is not converted because source object is not defined or converted: " + + source); + } + } + #endregion + + #region adding original destination + if (!PA_ANY_VALUE.Equals(destination)) + { + if (cpAddressesDict.ContainsKey(destination)) + { + cpNatRule.Destination = cpAddressesDict[destination]; + } + else if (cpNetGroupsDict.ContainsKey(destination)) + { + cpNatRule.Destination = cpNetGroupsDict[destination]; + } + else if (Regex.IsMatch(destination, RE_NET_ADDRESS)) + { + if (!destination.Contains("/") || destination.Contains(NETWORK_NETMASK_WS)) + { + string ipAddress; + + if (destination.Contains("/")) + ipAddress = destination.Substring(0, destination.IndexOf("/")); + else + ipAddress = destination.Substring(0); + + CheckPoint_Host cpHostNew = new CheckPoint_Host(); + cpHostNew.Name = "Host_" + ipAddress; + cpHostNew.IpAddress = ipAddress; + + cpAddressesDict[destination] = cpHostNew; + + cpNatRule.Destination = cpHostNew; + } + else + { + IPNetwork ipNetwork; + if (IPNetwork.TryParse(destination, out ipNetwork)) + { + string ipAddress = destination.Substring(0, destination.IndexOf("/")); + + CheckPoint_Network cpNetworkNew = new CheckPoint_Network(); + cpNetworkNew.Name = "Net_" + ipAddress; + cpNetworkNew.Subnet = ipAddress; + cpNetworkNew.Netmask = ipNetwork.Netmask.ToString(); + + cpAddressesDict[destination] = cpNetworkNew; + + cpNatRule.Destination = cpNetworkNew; + } + } + } + else + { + messagesE.Add(paNatRuleEntry.Name + + " NAT rule is not converted because destination object is not defined or converted: " + + destination); + } + } + #endregion + + #region adding original service + if (!PA_ANY_VALUE.Equals(paNatRuleEntry.Service)) + { + if (cpServicesDict.ContainsKey(paNatRuleEntry.Service)) + { + cpNatRule.Service = cpServicesDict[paNatRuleEntry.Service]; + } + else if (cpServicesGroupsDict.ContainsKey(paNatRuleEntry.Service)) + { + cpNatRule.Service = cpServicesGroupsDict[paNatRuleEntry.Service]; + } + else + { + messagesE.Add(paNatRuleEntry.Name + + " NAT rule is not converted because service or group of services object is not defined or converted: " + + paNatRuleEntry.Service); + } + } + #endregion + + #region adding source translation and changing NAT rule Method to static if it is required by Source Translation + if (isSourceTranslationExists) + { + cpNatRule.TranslatedSource = cpSourceTranslation; + if (isNatRuleStatic) + { + cpNatRule.Method = CheckPoint_NAT_Rule.NatMethod.Static; + } + } + #endregion + + #region adding destination translation + + if (paNatRuleEntry.DestinationTranslation != null) + { + if (!string.IsNullOrWhiteSpace(paNatRuleEntry.DestinationTranslation.TranslatedAddress)) + { + if (cpAddressesDict.ContainsKey(paNatRuleEntry.DestinationTranslation.TranslatedAddress)) + { + cpNatRule.TranslatedDestination = cpAddressesDict[paNatRuleEntry.DestinationTranslation.TranslatedAddress]; + } + else if (Regex.IsMatch(paNatRuleEntry.DestinationTranslation.TranslatedAddress, RE_NET_ADDRESS)) + { + if (!paNatRuleEntry.DestinationTranslation.TranslatedAddress.Contains("/") || paNatRuleEntry.DestinationTranslation.TranslatedAddress.Contains(NETWORK_NETMASK_WS)) + { + string ipAddress; + + if (paNatRuleEntry.DestinationTranslation.TranslatedAddress.Contains("/")) + ipAddress = paNatRuleEntry.DestinationTranslation.TranslatedAddress.Substring(0, paNatRuleEntry.DestinationTranslation.TranslatedAddress.IndexOf("/")); + else + ipAddress = paNatRuleEntry.DestinationTranslation.TranslatedAddress.Substring(0); + + CheckPoint_Host cpHostNew = new CheckPoint_Host(); + cpHostNew.Name = "Host_" + ipAddress; + cpHostNew.IpAddress = ipAddress; + + cpAddressesDict[paNatRuleEntry.DestinationTranslation.TranslatedAddress] = cpHostNew; + + cpNatRule.TranslatedDestination = cpHostNew; + } + else + { + IPNetwork ipNetwork; + if (IPNetwork.TryParse(paNatRuleEntry.DestinationTranslation.TranslatedAddress, out ipNetwork)) + { + string ipAddress = paNatRuleEntry.DestinationTranslation.TranslatedAddress.Substring(0, paNatRuleEntry.DestinationTranslation.TranslatedAddress.IndexOf("/")); + + CheckPoint_Network cpNetworkNew = new CheckPoint_Network(); + cpNetworkNew.Name = "Net_" + ipAddress; + cpNetworkNew.Subnet = ipAddress; + cpNetworkNew.Netmask = ipNetwork.Netmask.ToString(); + + cpAddressesDict[paNatRuleEntry.DestinationTranslation.TranslatedAddress] = cpNetworkNew; + + cpNatRule.TranslatedDestination = cpNetworkNew; + } + } + } + else + { + messagesE.Add(paNatRuleEntry.Name + + " NAT rule is not converted because destination translation object is not defined or converted: " + + paNatRuleEntry.DestinationTranslation.TranslatedAddress); + } + + if (!string.IsNullOrWhiteSpace(paNatRuleEntry.DestinationTranslation.TranslatedPort)) + { + if (!string.IsNullOrWhiteSpace(paNatRuleEntry.Service)) + { + if (cpServicesDict.ContainsKey(paNatRuleEntry.Service)) + { + CheckPointObject cpService = cpServicesDict[paNatRuleEntry.Service]; + if (cpService.GetType() == typeof(CheckPoint_TcpService)) + { + cpNatRule.TranslatedService = CreateNatServiceTcpFromStatDest(paNatRuleEntry); + } + else if (cpService.GetType() == typeof(CheckPoint_UdpService)) + { + cpNatRule.TranslatedService = CreateNatServiceUdpFromStatDest(paNatRuleEntry); + } + else if (cpService.GetType() == typeof(CheckPoint_PredifinedObject) && paServicesTypesDict.ContainsKey(paNatRuleEntry.Service)) + { + string servicesType = paServicesTypesDict[paNatRuleEntry.Service]; + if (servicesType.Trim().ToUpper().Equals(SERVICE_TYPE_TCP)) + { + cpNatRule.TranslatedService = CreateNatServiceTcpFromStatDest(paNatRuleEntry); + } + else if (servicesType.Trim().ToUpper().Equals(SERVICE_TYPE_UDP)) + { + cpNatRule.TranslatedService = CreateNatServiceUdpFromStatDest(paNatRuleEntry); + } + } + } + else if (cpServicesGroupsDict.ContainsKey(paNatRuleEntry.Service)) + { + bool isTcpSrv = false; + bool isUdpSrv = false; + + GetServicesTypesFromServicesGroup((CheckPoint_ServiceGroup)cpServicesGroupsDict[paNatRuleEntry.Service], + (new List(cpServicesGroupsDict.Values)), + (new List(cpServicesDict.Values)), + out isTcpSrv, out isUdpSrv); + + if (isTcpSrv && !isUdpSrv) + { + cpNatRule.TranslatedService = CreateNatServiceTcpFromStatDest(paNatRuleEntry); + } + else if (!isTcpSrv && isUdpSrv) + { + cpNatRule.TranslatedService = CreateNatServiceUdpFromStatDest(paNatRuleEntry); + } + else + { + cpNatRule.TranslatedService = CreateNatServiceTcpFromStatDest(paNatRuleEntry); + extraNatServiceTranslated = CreateNatServiceUdpFromStatDest(paNatRuleEntry); + + List cpSrvGrpMembersTcp = new List(); + List cpSrvGrpMembersUdp = new List(); + GetServicesGroupsFromServiceGroup( + (CheckPoint_ServiceGroup)cpServicesGroupsDict[paNatRuleEntry.Service], + (new List(cpServicesGroupsDict.Values)), + (new List(cpServicesDict.Values)), + cpSrvGrpMembersTcp, + cpSrvGrpMembersUdp); + + CheckPoint_ServiceGroup cpSrvGrpTcpNat = new CheckPoint_ServiceGroup(); + cpSrvGrpTcpNat.Name = InspectObjectName("Nat_SrcTcpGrp_" + paNatRuleEntry.Name, "services group"); + cpSrvGrpMembersTcp.ForEach(x => cpSrvGrpTcpNat.Members.Add(x.Name)); + + CheckPoint_ServiceGroup cpSrvGrpUdpNat = new CheckPoint_ServiceGroup(); + cpSrvGrpUdpNat.Name = InspectObjectName("Nat_SrcUdpGrp_" + paNatRuleEntry.Name, "services group"); + cpSrvGrpMembersUdp.ForEach(x => cpSrvGrpUdpNat.Members.Add(x.Name)); + + cpNatRule.Service = cpSrvGrpTcpNat; + extraNatServiceSourced = cpSrvGrpUdpNat; + } + } + else // paNatRuleEntry.Service = "any" + { + cpNatRule.TranslatedService = CreateNatServiceTcpFromStatDest(paNatRuleEntry); + extraNatServiceTranslated = CreateNatServiceUdpFromStatDest(paNatRuleEntry); + + CheckPoint_TcpService extraSrcSrvTcp = new CheckPoint_TcpService(); + extraSrcSrvTcp.Name = InspectObjectName("Nat_SrcTcp_" + paNatRuleEntry.Name, "tcp service"); + extraSrcSrvTcp.Port = "1-65535"; + + CheckPoint_UdpService extraSrcSrvUdp = new CheckPoint_UdpService(); + extraSrcSrvUdp.Name = InspectObjectName("Nat_SrcUdp_" + paNatRuleEntry.Name, "udp service"); + extraSrcSrvUdp.Port = "1-65535"; + + cpNatRule.Service = extraSrcSrvTcp; + extraNatServiceSourced = extraSrcSrvUdp; + } + } + } + } + } + + #endregion + + #region adding dynamic destination translation + + if (paNatRuleEntry.DynamicDestinationTranslation != null && !string.IsNullOrWhiteSpace(paNatRuleEntry.DynamicDestinationTranslation.TranslatedAddress) + && !(isNatRuleBiDirectional && isDestinationTranslationNone)) + { + if (cpAddressesDict.ContainsKey(paNatRuleEntry.DynamicDestinationTranslation.TranslatedAddress)) + { + cpNatRule.TranslatedDestination = cpAddressesDict[paNatRuleEntry.DynamicDestinationTranslation.TranslatedAddress]; + } + else if (cpNetGroupsDict.ContainsKey(paNatRuleEntry.DynamicDestinationTranslation.TranslatedAddress)) + { + cpNatRule.TranslatedDestination = cpNetGroupsDict[paNatRuleEntry.DynamicDestinationTranslation.TranslatedAddress]; + } + + if (!string.IsNullOrWhiteSpace(paNatRuleEntry.DynamicDestinationTranslation.TranslatedPort)) + { + if (!string.IsNullOrWhiteSpace(paNatRuleEntry.Service)) + { + if (cpServicesDict.ContainsKey(paNatRuleEntry.Service)) + { + CheckPointObject cpService = cpServicesDict[paNatRuleEntry.Service]; + if (cpService.GetType() == typeof(CheckPoint_TcpService)) + { + cpNatRule.TranslatedService = CreateNatServiceTcpFromDynDest(paNatRuleEntry); + } + else if (cpService.GetType() == typeof(CheckPoint_UdpService)) + { + cpNatRule.TranslatedService = CreateNatServiceUdpFromDynDest(paNatRuleEntry); + } + else if (cpService.GetType() == typeof(CheckPoint_PredifinedObject) && paServicesTypesDict.ContainsKey(paNatRuleEntry.Service)) + { + string servicesType = paServicesTypesDict[paNatRuleEntry.Service]; + if (servicesType.Trim().ToUpper().Equals("TCP")) + { + cpNatRule.TranslatedService = CreateNatServiceTcpFromDynDest(paNatRuleEntry); + } + else if (servicesType.Trim().ToUpper().Equals("UDP")) + { + cpNatRule.TranslatedService = CreateNatServiceUdpFromDynDest(paNatRuleEntry); + } + } + } + else if (cpServicesGroupsDict.ContainsKey(paNatRuleEntry.Service)) + { + bool isTcpSrv = false; + bool isUdpSrv = false; + + GetServicesTypesFromServicesGroup((CheckPoint_ServiceGroup)cpServicesGroupsDict[paNatRuleEntry.Service], + (new List(cpServicesGroupsDict.Values)), + (new List(cpServicesDict.Values)), + out isTcpSrv, out isUdpSrv); + + if (isTcpSrv && !isUdpSrv) + { + cpNatRule.TranslatedService = CreateNatServiceTcpFromDynDest(paNatRuleEntry); + } + else if (!isTcpSrv && isUdpSrv) + { + cpNatRule.TranslatedService = CreateNatServiceUdpFromDynDest(paNatRuleEntry); + } + else + { + cpNatRule.TranslatedService = CreateNatServiceTcpFromDynDest(paNatRuleEntry); + extraNatServiceTranslated = CreateNatServiceUdpFromDynDest(paNatRuleEntry); + + List cpSrvGrpMembersTcp = new List(); + List cpSrvGrpMembersUdp = new List(); + GetServicesGroupsFromServiceGroup( + (CheckPoint_ServiceGroup)cpServicesGroupsDict[paNatRuleEntry.Service], + (new List(cpServicesGroupsDict.Values)), + (new List(cpServicesDict.Values)), + cpSrvGrpMembersTcp, + cpSrvGrpMembersUdp); + + CheckPoint_ServiceGroup cpSrvGrpTcpNat = new CheckPoint_ServiceGroup(); + cpSrvGrpTcpNat.Name = InspectObjectName("Nat_SrcTcpGrp_" + paNatRuleEntry.Name, "services group"); + cpSrvGrpMembersTcp.ForEach(x => cpSrvGrpTcpNat.Members.Add(x.Name)); + + CheckPoint_ServiceGroup cpSrvGrpUdpNat = new CheckPoint_ServiceGroup(); + cpSrvGrpUdpNat.Name = InspectObjectName("Nat_SrcUdpGrp_" + paNatRuleEntry.Name, "services group"); + cpSrvGrpMembersUdp.ForEach(x => cpSrvGrpUdpNat.Members.Add(x.Name)); + + cpNatRule.Service = cpSrvGrpTcpNat; + extraNatServiceSourced = cpSrvGrpUdpNat; + } + } + else // paNatRuleEntry.Service = "any" + { + cpNatRule.TranslatedService = CreateNatServiceTcpFromDynDest(paNatRuleEntry); + extraNatServiceTranslated = CreateNatServiceUdpFromDynDest(paNatRuleEntry); + + CheckPoint_TcpService extraSrcSrvTcp = new CheckPoint_TcpService(); + extraSrcSrvTcp.Name = InspectObjectName("Nat_SrcTcp_" + paNatRuleEntry.Name, "tcp service"); + extraSrcSrvTcp.Port = "1-65535"; + + CheckPoint_UdpService extraSrcSrvUdp = new CheckPoint_UdpService(); + extraSrcSrvUdp.Name = InspectObjectName("Nat_SrcUdp_" + paNatRuleEntry.Name, "udp service"); + extraSrcSrvUdp.Port = "1-65535"; + + cpNatRule.Service = extraSrcSrvTcp; + extraNatServiceSourced = extraSrcSrvUdp; + } + } + } + } + + #endregion + + + List cpTargetDeviceUIDList = AddNatRuleTarget(devicesGroupList, paNatRuleEntry, _devicesUIDDict); + cpNatRule.Target.AddRange(cpTargetDeviceUIDList); + + + if (messagesE.Count == 0) + { + if (!(cpNatRule.Source is CheckPoint_Domain) && + !(cpNatRule.Destination is CheckPoint_Domain) && + !(cpNatRule.TranslatedSource is CheckPoint_Domain) && + !(cpNatRule.TranslatedDestination is CheckPoint_Domain)) + { + if (isNatRuleBiDirectional && isDestinationTranslationNone) + { + //TRANS DEST == NONE + // orig source <- orig destin + // orig destin <- trans source + // trans source <- trans destin + // trans destin <- orig source + + CheckPoint_NAT_Rule cpNatRuleBi = new CheckPoint_NAT_Rule(); + cpNatRuleBi.Comments = cpNatRule.Comments; + cpNatRuleBi.ConversionIncidentType = cpNatRule.ConversionIncidentType; + cpNatRuleBi.ConvertedCommandId = cpNatRule.ConvertedCommandId; + cpNatRuleBi.Enabled = cpNatRule.Enabled; + cpNatRuleBi.Method = cpNatRule.Method; + cpNatRuleBi.Name = cpNatRule.Name + "_BD"; + cpNatRuleBi.Package = cpNatRule.Package; + cpNatRuleBi.Service = cpNatRule.Service; + cpNatRuleBi.Tag = cpNatRule.Tag; + cpNatRuleBi.Tags = cpNatRule.Tags; + cpNatRuleBi.TranslatedService = cpNatRule.TranslatedService; + cpNatRuleBi.VendorCustomData = cpNatRule.VendorCustomData; + cpNatRuleBi.Target = cpNatRule.Target; + cpNatRuleBi.Source = cpNatRule.Destination; + cpNatRuleBi.Destination = cpNatRule.TranslatedSource; + cpNatRuleBi.TranslatedSource = cpNatRule.TranslatedDestination; + cpNatRuleBi.TranslatedDestination = cpNatRule.Source; + + _cpNatRules.Add(cpNatRuleBi); + } + + _cpNatRules.Add(cpNatRule); + AddCheckPointObject(cpNatRule.Source); + AddCheckPointObject(cpNatRule.Destination); + AddCheckPointObject(cpNatRule.Service); + AddCheckPointObject(cpNatRule.TranslatedSource); + AddCheckPointObject(cpNatRule.TranslatedDestination); + AddCheckPointObject(cpNatRule.TranslatedService); + _rulesInNatLayer += 1; + + if (extraNatServiceSourced != null && extraNatServiceTranslated != null) + { + AddCheckPointObject(extraNatServiceSourced); + AddCheckPointObject(extraNatServiceTranslated); + + CheckPoint_NAT_Rule cpNatRuleExtra = cpNatRule.Clone(); + cpNatRuleExtra.Service = extraNatServiceSourced; + cpNatRuleExtra.TranslatedService = extraNatServiceTranslated; + _cpNatRules.Add(cpNatRuleExtra); + _rulesInNatLayer += 1; + } + } + else + { + _errorsList.Add(cpNatRule.Name + " NAT rule contains FQDN object so it can not been converted."); + } + } + else + { + counterNatRules -= 1; + _errorsList.AddRange(messagesE); + } + _warningsList.AddRange(messagesW); + } + } + } + } + } + } + + public CheckPointObject CreateNatServiceTcpFromStatDest(PA_NatRuleEntry paNatRuleEntry) + { + CheckPoint_TcpService natServiceTcp = new CheckPoint_TcpService(); + natServiceTcp.Name = InspectObjectName("Nat_TrTcp_" + paNatRuleEntry.Name, CP_OBJECT_TYPE_NAME_SERVICE_TCP); + natServiceTcp.Port = paNatRuleEntry.DestinationTranslation.TranslatedPort; + + return InspectService(natServiceTcp); + } + + public CheckPointObject CreateNatServiceUdpFromStatDest(PA_NatRuleEntry paNatRuleEntry) + { + CheckPoint_UdpService natServiceUdp = new CheckPoint_UdpService(); + natServiceUdp.Name = InspectObjectName("Nat_TrUdp_" + paNatRuleEntry.Name, CP_OBJECt_TYPE_NAME_SERVICE_UDP); + natServiceUdp.Port = paNatRuleEntry.DestinationTranslation.TranslatedPort; + + return InspectService(natServiceUdp); + } + + public CheckPointObject CreateNatServiceTcpFromDynDest(PA_NatRuleEntry paNatRuleEntry) + { + CheckPoint_TcpService natServiceTcp = new CheckPoint_TcpService(); + natServiceTcp.Name = InspectObjectName("Nat_TrTcp_" + paNatRuleEntry.Name, CP_OBJECT_TYPE_NAME_SERVICE_TCP); + natServiceTcp.Port = paNatRuleEntry.DynamicDestinationTranslation.TranslatedPort; + + return InspectService(natServiceTcp); + } + + public CheckPointObject CreateNatServiceUdpFromDynDest(PA_NatRuleEntry paNatRuleEntry) + { + CheckPoint_UdpService natServiceUdp = new CheckPoint_UdpService(); + natServiceUdp.Name = InspectObjectName("Nat_TrUdp_" + paNatRuleEntry.Name, CP_OBJECt_TYPE_NAME_SERVICE_UDP); + natServiceUdp.Port = paNatRuleEntry.DynamicDestinationTranslation.TranslatedPort; + + return InspectService(natServiceUdp); + } + + public void GetServicesTypesFromServicesGroup( + CheckPoint_ServiceGroup cpSrvGroup, + List cpServicesGroups, + List cpServices, + out bool isTcpSrv, out bool isUdpSrv) + { + isTcpSrv = false; + isUdpSrv = false; + + foreach (string cpSrvMember in cpSrvGroup.Members) + { + CheckPointObject cpSrv = cpServices.Find(x => x.Name.Equals(cpSrvMember)); + if (cpSrv != null) + { + if (cpSrv.GetType() == typeof(CheckPoint_TcpService)) + isTcpSrv = true; + else if (cpSrv.GetType() == typeof(CheckPoint_UdpService)) + isUdpSrv = true; + + continue; + } + + CheckPoint_ServiceGroup cpSrvGrp = cpServicesGroups.Find(x => x.Name.Equals(cpSrvMember)); + if (cpSrvGrp != null) + { + GetServicesTypesFromServicesGroup(cpSrvGrp, cpServicesGroups, cpServices, out isTcpSrv, out isUdpSrv); + } + } + } + + public void GetServicesGroupsFromServiceGroup( + CheckPoint_ServiceGroup cpSrvGroup, + List cpServicesGroups, + List cpServices, + List cpSrvGrpMembersTcp, + List cpSrvGrpMembersUdp) + { + foreach (string cpSrvMember in cpSrvGroup.Members) + { + CheckPointObject cpSrv = cpServices.Find(x => x.Name.Equals(cpSrvMember)); + if (cpSrv != null) + { + if (cpSrv.GetType() == typeof(CheckPoint_TcpService)) + { + cpSrvGrpMembersTcp.Add(cpSrv); + } + else if (cpSrv.GetType() == typeof(CheckPoint_UdpService)) + { + cpSrvGrpMembersUdp.Add(cpSrv); + } + else if (cpSrv.GetType() == typeof(CheckPoint_PredifinedObject) && cpPredefServicesTypes.ContainsKey(cpSrv.Name)) + { + string srvType = cpPredefServicesTypes[cpSrv.Name].ToLower(); + if (srvType.Equals(SERVICE_TYPE_TCP.ToLower())) + { + cpSrvGrpMembersTcp.Add(cpSrv); + } + else if (srvType.Equals(SERVICE_TYPE_UDP.ToLower())) + { + cpSrvGrpMembersUdp.Add(cpSrv); + } + } + continue; + } + + CheckPoint_ServiceGroup cpSrvGrp = cpServicesGroups.Find(x => x.Name.Equals(cpSrvMember)); + if (cpSrvGrp != null) + { + GetServicesGroupsFromServiceGroup(cpSrvGrp, cpServicesGroups, cpServices, cpSrvGrpMembersTcp, cpSrvGrpMembersUdp); + } + } + } + + #endregion + + #region Utility methods + + public void AddCpApplicationGroup(CheckPoint_ApplicationGroup cpAppGrp, + Dictionary cpAppGroupsDict) + { + foreach (string member in cpAppGrp.Members) + { + if (cpAppGroupsDict.ContainsKey(member)) + { + AddCpApplicationGroup(cpAppGroupsDict[member], cpAppGroupsDict); + } + } + AddCheckPointObject(cpAppGrp); + } + + public void AddCpNetworkGroup(CheckPoint_NetworkGroup cpNetGroup, + Dictionary cpAddressesDict, + Dictionary cpNetGroupsDict) + { + foreach (string member in cpNetGroup.Members) + { + if (cpAddressesDict.ContainsKey(member)) + { + AddCheckPointObject(cpAddressesDict[member]); + } + else if (cpNetGroupsDict.ContainsKey(member)) + { + AddCpNetworkGroup(cpNetGroupsDict[member], cpAddressesDict, cpNetGroupsDict); + AddCheckPointObject(cpNetGroupsDict[member]); + } + } + AddCheckPointObject(cpNetGroup); + } + + public void AddCpServiceGroup(CheckPoint_ServiceGroup cpSrvGroup, + Dictionary cpServicesDict, + Dictionary cpSrvGroupsDict) + { + foreach (string member in cpSrvGroup.Members) + { + if (cpServicesDict.ContainsKey(member)) + { + AddCheckPointObject(cpServicesDict[member]); + } + else if (cpSrvGroupsDict.ContainsKey(member)) + { + AddCpServiceGroup(cpSrvGroupsDict[member], cpServicesDict, cpSrvGroupsDict); + AddCheckPointObject(cpSrvGroupsDict[member]); + } + } + AddCheckPointObject(cpSrvGroup); + } + + public static string GetSafeName(string name) + { + if (name != null && !name.Trim().Equals("")) + { + return Regex.Replace(name, RE_NAME_UNSAFE, "_"); + } + else + { + return name; + } + } + + protected override string GetVendorName() + { + return Vendor.PaloAlto.ToString(); + } + #endregion + + public Dictionary GetDevicesUIDdict(string filename) + { + Dictionary devicesUIDDict = new Dictionary(); + + string outConfigsFolder = filename; + string[] configsFolder = Directory.GetDirectories(outConfigsFolder);//get uncompressed folder name + string[] configFilesArray = Directory.GetFiles(configsFolder[0]); + + string configName; + string deviceName; + string deviceUID; + + foreach (string confFile in configFilesArray) + { + + if (confFile.IndexOf("\\") != -1 && confFile.IndexOf(".xml") != -1) + { + configName = confFile.Substring(confFile.LastIndexOf("\\") + 1); + configName = configName.Substring(0, configName.IndexOf(".xml")); + + if (configName.IndexOf("_") != -1) + { + deviceName = configName.Substring(0, configName.LastIndexOf("_")); + deviceUID = configName.Substring(configName.LastIndexOf("_") + 1); + devicesUIDDict.Add(deviceUID, deviceName); + } + } + } + Directory.Delete(outConfigsFolder, true); + return devicesUIDDict; + } + } +} diff --git a/PaloAltoMigration/PanoramaParser.cs b/PaloAltoMigration/PanoramaParser.cs new file mode 100644 index 00000000..bebd6581 --- /dev/null +++ b/PaloAltoMigration/PanoramaParser.cs @@ -0,0 +1,164 @@ +using MigrationBase; +using System; +using System.IO; +using System.Diagnostics; +using System.Collections.Generic; +using System.Xml; +using System.Xml.Serialization; + +namespace PanoramaPaloAltoMigration + +{ + public class PanoramaParser : VendorParser + { + private static string _archiveName; + public string _ArchiveName + { + get => _archiveName; + set => _archiveName = value; + } + + public Panorama_Config Config { get; set; } + + public override void Export(string filename) + { + } + + public override void Parse(string filename) + { + + } + + public void ParseWithTargetFolder(string filename, string targetFolder) + { + if (!targetFolder.EndsWith("\\")) + targetFolder += "\\"; + UncompressArchive(filename,targetFolder); + + string outConfigsFolder = targetFolder + "configs"; + _ArchiveName = outConfigsFolder; + string panoramaConfig = GetPanoramaConfFile(outConfigsFolder); + + XmlSerializer serializer = new XmlSerializer(typeof(Panorama_Config)); + + using (FileStream fileStream = new FileStream(panoramaConfig, FileMode.Open)) + { + Config = (Panorama_Config)serializer.Deserialize(fileStream); + + ParseVersion(null); + } + } + + protected override void ParseVersion(object versionProvider) + { + VendorVersion = Config.Version; + } + + public string GetPanoramaConfFile(string outConfigsFolder) + { + string panoramaConfig = null; + + string[] configsFolder = Directory.GetDirectories(outConfigsFolder);//get uncompressed folder name + string[] configFilesArray = Directory.GetFiles(configsFolder[0]);//get list of panorama and firewalls config files + + foreach (string confFile in configFilesArray) + { + if (DetectPanoramaConfFile(confFile)) + { + panoramaConfig = confFile; + break; + } + } + return panoramaConfig; + } + + public bool DetectPanoramaConfFile(string fileName) + { + bool is_panorama = false; + XmlDocument xDoc = new XmlDocument(); + try + { + xDoc.Load(fileName); + XmlElement xRoot = xDoc.DocumentElement; + XmlNode panoramaNode = xRoot.SelectSingleNode("panorama"); + if (panoramaNode != null) + is_panorama = true; + } + catch { } + return is_panorama; + } + + /// + /// //checks if Panorama or standalone PA firewall configuration is converted + /// + public bool CheckPaloAltoConfiguartion(String filename) + { + bool is_panorama = false; + List archiveExt = new List { ".tgz" }; + + string extension = Path.GetExtension(filename); + + if (archiveExt.Contains(extension)) + { + is_panorama = true; + } + else + { + Console.WriteLine("Configs archive must be in .tgz format!"); + } + return is_panorama; + } + + public void UncompressArchive(string archiveName, string targetFolder) + { + string compressorsDirPath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "compressors"; + string archiveCopyName = targetFolder + archiveName.Substring(archiveName.LastIndexOf("\\") + 1); + archiveCopyName = archiveCopyName.Substring(0, archiveCopyName.IndexOf(".tgz")) + "_copy" + ".tgz"; + File.Copy(archiveName, archiveCopyName, true); + + #region uncompress .TGZ archive + ProcessStartInfo startInfo = new ProcessStartInfo(); + startInfo.UseShellExecute = false; + startInfo.CreateNoWindow = true; + Process uncompressProc = null; + startInfo.FileName = Path.Combine(compressorsDirPath, "gzip.exe"); + startInfo.WorkingDirectory = archiveCopyName.Substring(0, archiveCopyName.LastIndexOf("\\")); + startInfo.Arguments = "-d" + " \"" + archiveCopyName + "\""; + startInfo.RedirectStandardOutput = true; + uncompressProc = Process.Start(startInfo); + startInfo.RedirectStandardError = true; + + string output = uncompressProc.StandardOutput.ReadToEnd(); + uncompressProc.WaitForExit(); + #endregion + + #region uncompress .TAR archive + startInfo = new ProcessStartInfo(); + startInfo.UseShellExecute = false; + startInfo.CreateNoWindow = true; + Process uncompressTarProc = null; + startInfo = new ProcessStartInfo(); + startInfo.UseShellExecute = false; + startInfo.CreateNoWindow = true; + + string tarArchiveName = archiveCopyName.Substring(0, archiveCopyName.LastIndexOf(".tgz")) + ".tar"; + + startInfo.FileName = Path.Combine(compressorsDirPath, "gtar.exe"); + + string outConfigsFolder = tarArchiveName.Substring(0, tarArchiveName.LastIndexOf("\\")) + "\\configs"; + Directory.CreateDirectory(outConfigsFolder); + startInfo.WorkingDirectory = outConfigsFolder; + startInfo.Arguments = "-xvf \"" + tarArchiveName + "\" --force-local"; + startInfo.RedirectStandardOutput = true; + uncompressTarProc = Process.Start(startInfo); + startInfo.RedirectStandardError = true; + + output = uncompressTarProc.StandardOutput.ReadToEnd(); + uncompressTarProc.WaitForExit(); + + if (File.Exists(tarArchiveName)) + File.Delete(tarArchiveName); + #endregion + } + } +} diff --git a/PaloAltoMigration/Panorama_Config.cs b/PaloAltoMigration/Panorama_Config.cs new file mode 100644 index 00000000..91d211f5 --- /dev/null +++ b/PaloAltoMigration/Panorama_Config.cs @@ -0,0 +1,626 @@ +using System.Collections.Generic; +using System.Xml.Serialization; + +namespace PanoramaPaloAltoMigration +{ + #region Abstract Interfaces + + public abstract class PA_Entry + { + [XmlAttribute("name")] + public string Name { get; set; } + } + + public abstract class PA_EntryExt : PA_Entry + { + private string _description; + + [XmlElement("description")] + public string Description + { + get + { + if (_description == null) + return ""; + else + return _description; + } + set + { + _description = value; + } + } + + [XmlArray("tag")] + [XmlArrayItem("member")] + public List TagMembers { get; set; } + } + + #endregion + + #region Main XML tags binding + + [XmlRoot("config")] + public class Panorama_Config + { + [XmlAttribute("version")] + public string Version { get; set; } + + [XmlElement("shared")] + public PA_Shared Shared { get; set; } + + [XmlElement("devices")] + public PA_Devices Devices { get; set; } + + } + + public class PA_Shared : PA_Objects + { + [XmlElement("pre-rulebase")] + public PA_PreRulebase PreRulebase { get; set; } + [XmlElement("post-rulebase")] + public PA_PostRulebase PostRulebase { get; set; } + } + + #region devices XML tags binding + public class PA_Devices + { + [XmlElement("entry")] + public PA_DevicesEntry DevicesEntry { get; set; } + } + #endregion + + + public class PA_DevicesEntry : PA_Entry + { + [XmlArray("device-group")] + [XmlArrayItem("entry")] + public List DeviceGroupEntries { get; set; } + + [XmlArray("template")] + [XmlArrayItem("entry")] + public List TemplateEntries { get; set; } + + [XmlArray("template-stack")] + [XmlArrayItem("entry")] + public List TemplateStackEntries { get; set; } + } + + public class PA_TemplateStackEntry : PA_Entry + { + [XmlArray("templates")] + [XmlArrayItem("member")] + public List StackTemplatesMembers{ get; set; } + + + [XmlArray("devices")] + [XmlArrayItem("entry")] + public List DevicesEntries { get; set; } + } +/* + public class PA_StackTemplates: PA_Entry + { + [XmlElement("member")] + public List StackTemplateMembers { get; set; } + } +*/ + public class PA_DevicesTemplateStackMemberEntry: PA_Entry + { + + } + public class PA_DevicesTemplateStackEntry : PA_Entry + { + + } + + + public class PA_TemplateEntry : PA_Entry + { + [XmlElement("config")] + public PA_TemplateConfig Config { get; set; } + + } + + public class PA_TemplateConfig : PA_Entry + { + [XmlElement("devices")] + public PA_DevicesTemplateEntry TemplateDevices { get; set; } + + } + + public class PA_DevicesTemplateEntry : PA_Entry + { + [XmlElement("entry")] + public PA_DevicesTemplateDevicesEntry TemplateDevicesEntry { get; set; } + } + + public class PA_DevicesTemplateDevicesEntry : PA_Entry + { + [XmlElement("network")] + public PA_Network Network { get; set; } + + [XmlArray("vsys")] + [XmlArrayItem("entry")] + public List VsysEntries { get; set; } + } + + public class PA_DeviceGroupEntry : PA_Objects + { + [XmlElement("pre-rulebase")] + public PA_PreRulebase PreRulebase { get; set; } + [XmlElement("post-rulebase")] + public PA_PostRulebase PostRulebase { get; set; } + + [XmlArray("devices")] + [XmlArrayItem("entry")] + public List DevicesGroupDevicesEntries { get; set; } + } + + public class PA_PostRulebase + { + [XmlElement("default-security-rules")] + public PA_Security Security { get; set; } + } + + public class PA_DevicesGroupDevicesEntry : PA_Entry // devices serial numbers + { + + } + + public class PA_PreRulebase + { + [XmlElement("security")] + public PA_Security Security { get; set; } + + [XmlElement("nat")] + public PA_Nat Nat { get; set; } + } + #endregion + + #region Network XML tags binding + + public class PA_Network + { + [XmlElement("interface")] + public PA_Interface Interface { get; set; } + } + + public class PA_Interface + { + [XmlArray("ethernet")] + [XmlArrayItem("entry")] + public List EthernetEntries { get; set; } + } + + public class PA_EthernetEntry : PA_Entry + { + [XmlElement("layer3")] + public PA_EthernetLayer3 Layer3 { get; set; } + } + + public class PA_EthernetLayer3 + { + + } + + #endregion + + #region XML tags binding of Content + + public class PA_Objects : PA_Entry + { + [XmlArray("tag")] + [XmlArrayItem("entry")] + public List TagsEntries { get; set; } + + [XmlArray("address")] + [XmlArrayItem("entry")] + public List AddressEntries { get; set; } + + [XmlArray("address-group")] + [XmlArrayItem("entry")] + public List AddressGroupEntries { get; set; } + + [XmlArray("service")] + [XmlArrayItem("entry")] + public List ServiceEntries { get; set; } + + [XmlArray("service-group")] + [XmlArrayItem("entry")] + public List ServiceGroupEntries { get; set; } + + [XmlArray("application-group")] + [XmlArrayItem("entry")] + public List ApplicationGroupsEntries { get; set; } + + [XmlArray("application-filter")] + [XmlArrayItem("entry")] + public List ApplicationFiltersEntries { get; set; } + + [XmlArray("schedule")] + [XmlArrayItem("entry")] + public List ScheduleEntries { get; set; } + } + + public class PA_Vsys + { + [XmlElement("entry")] + public List VsysEntries { get; set; } + } + + public class PA_VsysEntry : PA_Objects + { + [XmlArray("zone")] + [XmlArrayItem("entry")] + public List ZoneEntries { get; set; } +/* + [XmlElement("rulebase")] + public PA_Rulebase Rulebase { get; set; }*/ + } + + public class PA_TagEntry : PA_Entry { /* the class is empty as we need to know only 'name' attribute of Tag entry */ } + + public class PA_Rulebase + { + [XmlElement("security")] + public PA_Security Security { get; set; } + + [XmlElement("nat")] + public PA_Nat Nat { get; set; } + } + + #endregion + + #region Zone XML tags binding + + public class PA_ZoneEntry : PA_EntryExt { /* the class is empty as we need to know Zone's name only */ } + + #endregion + + #region Addresses & Address Groups XML tags binding + + public class PA_AddressEntry : PA_EntryExt + { + //control elements which tells which object we have + + [XmlElement("ip-netmask")] + public string IpNetmask { get; set; } + + [XmlElement("ip-range")] + public string IpRange { get; set; } + + [XmlElement("fqdn")] + public string Fqdn { get; set; } + } + + public class PA_AddressGroupEntry : PA_EntryExt + { + [XmlArray("static")] + [XmlArrayItem("member")] + public List StaticMembers { get; set; } + + [XmlElement("dynamic")] + public PA_AddressGroupEntryDynamic Dynamic { get; set; } + } + + public class PA_AddressGroupEntryDynamic + { + [XmlElement("filter")] + public string Filter { get; set; } + } + + #endregion + + #region Services & Service Groups XML tags binding + + public class PA_ServiceEntry : PA_EntryExt + { + [XmlElement("protocol")] + public PA_ServiceProtocol Protocol { get; set; } + } + + public class PA_ServiceProtocol + { + [XmlElement("tcp")] + public PA_ServiceTcpUdp ServiceTcp { get; set; } + + [XmlElement("udp")] + public PA_ServiceTcpUdp ServiceUdp { get; set; } + } + + public class PA_ServiceTcpUdp + { + [XmlElement("port")] + public string Port { get; set; } + + [XmlElement("source-port")] + public string SourcePort { get; set; } + } + + // Definition for the groups of services + + public class PA_ServiceGroupEntry : PA_EntryExt + { + [XmlArray("members")] + [XmlArrayItem("member")] + public List Members { get; set; } + } + + #endregion + + #region Application Group and Application Filter XML tags binding + + public class PA_ApplicationGroupEntry : PA_Entry + { + [XmlArray("members")] + [XmlArrayItem("member")] + public List ApplicationGroupMembers { get; set; } + } + + public class PA_ApplicationFilterEntry : PA_Entry + { + [XmlArray("category")] + [XmlArrayItem("member")] + public List CategoryMembers { get; set; } + + [XmlArray("subcategory")] + [XmlArrayItem("member")] + public List SubcategoryMembers { get; set; } + } + + #endregion + + #region Schedules XML tags binding + + public class PA_ScheduleEntry : PA_EntryExt + { + [XmlElement("schedule-type")] + public PA_ScheduleType Type { get; set; } + } + + public class PA_ScheduleType + { + [XmlElement("recurring")] + public PA_ScheduleRecurring Recurring { get; set; } + + [XmlElement("non-recurring")] + public PA_ScheduleNonRecurring NonRecurring { get; set; } + } + + public class PA_ScheduleRecurring + { + [XmlArray("daily")] + [XmlArrayItem("member")] + public List MembersDaily { get; set; } + + [XmlElement("weekly")] + public PA_ScheduleRecurringWeekly Weekly { get; set; } + } + + public class PA_ScheduleRecurringWeekly + { + [XmlArray("monday")] + [XmlArrayItem("member")] + public List MembersMonday { get; set; } + + [XmlArray("tuesday")] + [XmlArrayItem("member")] + public List MembersTuesday { get; set; } + + [XmlArray("wednesday")] + [XmlArrayItem("member")] + public List MembersWednesday { get; set; } + + [XmlArray("thursday")] + [XmlArrayItem("member")] + public List MembersThursday { get; set; } + + [XmlArray("friday")] + [XmlArrayItem("member")] + public List MembersFriday { get; set; } + + [XmlArray("saturday")] + [XmlArrayItem("member")] + public List MembersSaturday { get; set; } + + [XmlArray("sunday")] + [XmlArrayItem("member")] + public List MembersSunday { get; set; } + } + + public class PA_ScheduleNonRecurring + { + [XmlElement("member")] + public List Memebers { get; set; } + } + + #endregion + + #region Security XML tags binding (policy rules) + + public class PA_Security + { + [XmlArray("rules")] + [XmlArrayItem("entry")] + public List RulesList { get; set; } + } + + public class PA_SecurityRuleEntry : PA_EntryExt + { + [XmlArray("from")] //Source Zone List + [XmlArrayItem("member")] + public List FromList { get; set; } + + [XmlArray("to")] //Destination Zone List + [XmlArrayItem("member")] + public List ToList { get; set; } + + [XmlArray("source")] + [XmlArrayItem("member")] + public List SourceList { get; set; } + + [XmlArray("destination")] + [XmlArrayItem("member")] + public List DestinationList { get; set; } + + [XmlArray("source-user")] + [XmlArrayItem("member")] + public List SourceUserList { get; set; } + + [XmlArray("application")] + [XmlArrayItem("member")] + public List ApplicationList { get; set; } + + [XmlArray("service")] + [XmlArrayItem("member")] + public List ServiceList { get; set; } + + [XmlElement("action")] + public string Action { get; set; } + + [XmlElement("schedule")] + public string Schedule { get; set; } + + [XmlElement("rule-type")] + public string RuleType { get; set; } + + [XmlElement("log-start")] + public string LogStart { get; set; } + + [XmlElement("log-end")] + public string LogEnd { get; set; } + + [XmlElement("disabled")] + public string Disabled { get; set; } + + [XmlArray("category")] + [XmlArrayItem("member")] + public List CategoryList { get; set; } + + [XmlElement("negate-source")] + public string NegateSource { get; set; } + + [XmlElement("negate-destination")] + public string NegateDestination { get; set; } + + [XmlElement("target")] + public PA_Target Target { get; set; } + } + + + public class PA_Target : PA_Entry + { + [XmlElement("negate")] + public string Negate { get; set; } + + [XmlArray("devices")] + [XmlArrayItem("entry")] + public List DevicesEntry { get; set; } + } + + public class PA_TargetDeviceEntry : PA_Entry{} + +#endregion + + #region NAT XML tags binding (NAT rules) + + public class PA_Nat + { + [XmlArray("rules")] + [XmlArrayItem("entry")] + public List RulesList { get; set; } + } + + public class PA_NatRuleEntry : PA_EntryExt + { + [XmlArray("source")] + [XmlArrayItem("member")] + public List SourceList { get; set; } + + [XmlArray("destination")] + [XmlArrayItem("member")] + public List DestinationList { get; set; } + + [XmlElement("service")] + public string Service { get; set; } + + [XmlElement("source-translation")] + public PA_SourceTranslation SourceTranslation { get; set; } + + [XmlElement("destination-translation")] + public PA_DestinationTranslation DestinationTranslation { get; set; } + + [XmlElement("dynamic-destination-translation")] + public PA_DynamicDestinationTranslation DynamicDestinationTranslation { get;set;} + + [XmlElement("disabled")] + public string Disabled { get; set; } + + [XmlElement("target")] + public PA_Target Target { get; set; } + } + + public class PA_SourceTranslation + { + [XmlElement("static-ip")] + public PA_StaticIp StaticIp { get; set; } + + [XmlElement("dynamic-ip")] + public PA_DynamicIp DynamicIp { get; set; } + + [XmlElement("dynamic-ip-and-port")] + public PA_DynamicIpAndPort DynamicIpAndPort { get; set; } + } + + public class PA_StaticIp + { + [XmlElement("translated-address")] + public string TranslatedAddress { get; set; } + + [XmlElement("bi-directional")] + public string IsBiDirectional { get; set; } + } + + public class PA_DynamicIp + { + [XmlArray("translated-address")] + [XmlArrayItem("member")] + public List TranslatedAddresses { get; set; } + } + + public class PA_DynamicIpAndPort + { + [XmlArray("translated-address")] + [XmlArrayItem("member")] + public List TranslatedAddresses { get; set; } + + [XmlElement("interface-address")] + public PA_InterfaceAddress InterfaceAddress { get; set; } + } + + public class PA_InterfaceAddress + { + [XmlElement("ip")] + public string Ip { get; set; } + } + + public class PA_DestinationTranslation + { + [XmlElement("translated-address")] + public string TranslatedAddress { get; set; } + + [XmlElement("translated-port")] + public string TranslatedPort { get; set; } + } + + public class PA_DynamicDestinationTranslation + { + [XmlElement("translated-address")] + public string TranslatedAddress { get; set; } + + [XmlElement("translated-port")] + public string TranslatedPort { get; set; } + } + + #endregion +} diff --git a/SmartMove/App.xaml.cs b/SmartMove/App.xaml.cs index ceb84e5d..f25c263e 100644 --- a/SmartMove/App.xaml.cs +++ b/SmartMove/App.xaml.cs @@ -24,5 +24,10 @@ namespace SmartMove ///
public partial class App : Application { + public App() + { + InitializeComponent(); + } + } } diff --git a/SmartMove/CommandLine.cs b/SmartMove/CommandLine.cs new file mode 100644 index 00000000..5217614e --- /dev/null +++ b/SmartMove/CommandLine.cs @@ -0,0 +1,529 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Linq; +using System.IO; +using CiscoMigration; +using JuniperMigration; +using MigrationBase; +using NetScreenMigration; +using FortiGateMigration; +using PaloAltoMigration; +using PanoramaPaloAltoMigration; +using System.Text.RegularExpressions; + +namespace SmartMove +{ + /// + /// Represents command line logic + /// + class CommandLine + { + private string[] arguments { get; set; } + + public CommandLine(string[] args) + { + this.arguments = args; + } + + #region command line options + //–f “D:\SmartMove\Content\config.txt” + private string configFileName { get; set; } + public string ConfigFileName + { + get { return configFileName; } + set { configFileName = value; } + } + + //–v CiscoASA + private string vendor { get; set; } + public string Vendor + { + get { return vendor; } + set { vendor = value; } + } + + //-t “D:\SmartMove\Content + private string targetFolder { get; set; } + public string TargetFolder + { + get { return targetFolder; } + set { targetFolder = value; } + } + + //-d domain + private string domain { get; set; } + public string Domain + { + get { return domain; } + set { domain = value; } + } + + //-n + private bool convertNat { get; set; } + public bool ConvertNat + { + get { return convertNat; } + set { convertNat = value; } + } + + //-u unit1 + private string ldapAccountUnit { get; set; } + public string LdapAccountUnit + { + get { return ldapAccountUnit; } + set { ldapAccountUnit = value; } + } + + private bool convertUserConfiguration { get; set; } + public bool ConvertUserConfiguration + { + get { return convertUserConfiguration; } + set { convertUserConfiguration = value; } + } + //-i + private bool dontImportUnusedObjects { get; set; } + public bool DontImportUnusedObjects + { + get { return dontImportUnusedObjects; } + set { dontImportUnusedObjects = value; } + } + #endregion + + public int DisplayHelp() + { + Console.WriteLine("SmartMove command usage:"); + Console.WriteLine(); + Console.WriteLine("SmartMove.exe [–f config_file_name] [-v vendor] [-t target_folder] [-d domain] [-n] [-u LDAP_Account_unit] [-i]"); + Console.WriteLine(); + Console.WriteLine("Options:"); + Console.WriteLine("\t" + "-f" + "\t" + "full path to vendor configuration file"); + Console.WriteLine("\t" + "-v" + "\t" + "vendor for conversion (available options: CiscoASA, JuniperSRX, JuniperSSG, FortiNet, PaloAlto, Panorama)"); + Console.WriteLine("\t" + "-t" + "\t" + "migration output folder"); + Console.WriteLine("\t" + "-d" + "\t" + "domain name (for CiscoASA, JuniperSRX, JuniperSSG only)"); + Console.WriteLine("\t" + "-n" + "\t" + "convert NAT configuration"); + Console.WriteLine("\t" + "-u" + "\t" + "LDAP Account unit for convert user configuration option (for FortiNet, PaloAlto and Panorama only)"); + Console.WriteLine("\t" + "-i" + "\t" + "do not import unused objects (for FortiNet, PaloAlto and Panorama only)"); + Console.WriteLine(); + Console.WriteLine("Example:"); + Console.WriteLine("\t" + "SmartMove.exe –f \"D:\\SmartMove\\Content\\config.txt\" –v CiscoASA - t \"D:\\SmartMove\\Content\" –n"); + return 0; + } + + /* + * Verifies that mandatory options are specified in command line. + * Also checks options validity for the specific vendor. + */ + public int CheckOptionsValidity(CommandLine commandLine) + { + var fullVendorsList = new List { "CiscoASA", "JuniperSRX", "JuniperSSG", "FortiNet", "PaloAlto", "Panorama" }; + var vendorsList1 = new List { "CiscoASA", "JuniperSRX", "JuniperSSG" }; + var vendorsList2 = new List { "FortiNet", "PaloAlto", "Panorama" }; + if (String.IsNullOrEmpty(commandLine.Vendor)) + { + Console.WriteLine("Option -v is mandatory but not specified.", MessageTypes.Error); + Console.WriteLine("For command help run \"SmartMove.exe -help\"", MessageTypes.Error); + return 0; + } + if (String.IsNullOrEmpty(commandLine.ConfigFileName)) + { + Console.WriteLine("Option -f is mandatory but not specified.", MessageTypes.Error); + Console.WriteLine("For command help run \"SmartMove.exe -help\"", MessageTypes.Error); + return 0; + } + if (!fullVendorsList.Contains(commandLine.Vendor)) + { + Console.WriteLine("Specified vendor \"" + commandLine.Vendor + "\" is not available.", MessageTypes.Error); + Console.WriteLine("Available options are: CiscoASA, JuniperSRX, JuniperSSG, FortiNet, PaloAlto, Panorama", MessageTypes.Error); + Console.WriteLine("For command help run \"SmartMove.exe -help\"", MessageTypes.Error); + return 0; + } + if (vendorsList1.Contains(commandLine.Vendor)) + { + if (commandLine.ConvertUserConfiguration is true) + { + Console.WriteLine("Option -u is not valid for vendor " + commandLine.Vendor + "!"); + Console.WriteLine("For command help run \"SmartMove.exe -help\"", MessageTypes.Error); + return 0; + } + + if (commandLine.DontImportUnusedObjects is true) + { + Console.WriteLine("Option -i is not valid for vendor " + commandLine.Vendor + "!"); + Console.WriteLine("For command help run \"SmartMove.exe -help\"", MessageTypes.Error); + return 0; + } + + } + if (vendorsList2.Contains(commandLine.Vendor)) + { + if (commandLine.ConvertUserConfiguration is true && commandLine.LdapAccountUnit is null) + { + Console.WriteLine("Value for option -u is not specified!"); + Console.WriteLine("For command help run \"SmartMove.exe -help\"", MessageTypes.Error); + return 0; + } + + } + if ((commandLine.vendor == "JuniperSRX" || commandLine.vendor == "PaloAlto") && !commandLine.configFileName.EndsWith(".xml")) + { + Console.WriteLine("Config file for " + commandLine.vendor + " must be in .xml format!"); + return 0; + } + if (commandLine.vendor == "Panorama" && !commandLine.configFileName.EndsWith(".tgz")) + { + Console.WriteLine("Config files archive for " + commandLine.vendor + " must be in .tgz format!"); + return 0; + } + return 1; + } + + /* + * Workaround method to prevent incorrect interpretation of \" sequense in target directory option while reading command line arguments. + * The reason is that a double quotation mark preceded by a backslash, \", is interpreted as a literal double quotation mark ("). + * This method creates an array of command line arguments from the command line string. + * e.g. + * -t "D:\SmartMove\Content\" + */ + + public string[] regenerateArgs(string commandLineString) + { + String[] args = null; + + var parts = Regex.Matches(commandLineString, @"[\""].+?[\""]|[^ ]+") + .Cast() + .Select(m => m.Value) + .ToList(); + parts.RemoveAt(0); + + string buf; + List finalArgs = new List (); + foreach (var item in parts) + { + if (item.StartsWith("\"") && item.EndsWith("\"")) + { + buf = item.Substring(1, item.Length - 2); + finalArgs.Add(buf); + } + else + { + finalArgs.Add(item); + } + + } + args = finalArgs.ToArray(); + + return args; + } + + /* + * Parses input options and writes its values to ComamndLine class fields + */ + public CommandLine Parse(string[] args) + { + for (int i = 0; i < args.Length; i++) + { + switch (args[i]) + { + case "-f": + { + if (args[i] != args.Last() && !args[i + 1].StartsWith("-")) + { + if (args[i + 1].IndexOf("\\") != -1) + { + this.ConfigFileName = args[i + 1]; + } + else + { + this.configFileName = Directory.GetCurrentDirectory() + "\\" + args[i + 1]; + + } + //set default velue of target folder to cofig file directory + this.TargetFolder = this.ConfigFileName.Substring(0, this.ConfigFileName.LastIndexOf("\\")); + + } else + { + Console.WriteLine("Value for mandatory option -f is not specified! ", MessageTypes.Error); + } + + break; + } + case "-v": + { + if (args[i] != args.Last() && !args[i + 1].StartsWith("-")) + this.vendor = args[i + 1]; + else + Console.WriteLine("Value for mandatory option -v is not specified! ", MessageTypes.Error); + break; + } + case "-t": + { + if (args[i] != args.Last() && !args[i + 1].StartsWith("-")) + this.targetFolder = args[i + 1]; + else + Console.WriteLine("Value for target folder option -t is not specified. Default value will be set!", MessageTypes.Error); + break; + } + case "-d": + { + if (args[i] != args.Last() && !args[i + 1].StartsWith("-")) + this.domain = args[i + 1]; + else + Console.WriteLine("Value for option -d is not specified! ", MessageTypes.Error); + break; + } + case "-n": + { + this.convertNat = true; + break; + } + case "-u": + { + if (args[i] != args.Last() && !args[i + 1].StartsWith("-")) + { + this.ldapAccountUnit = args[i + 1]; + this.ConvertUserConfiguration = true; + } else + { + this.ConvertUserConfiguration = true; + //Console.WriteLine("Value for option -u is not specified! ", MessageTypes.Error); + } + + break; + } + case "-i": + { + this.dontImportUnusedObjects = true; + break; + } + } + } + return this; + } + + /* + * This is the analog to MainWindow.Go_OnClick() function if application is run as WPF. + * It performs the migration. + */ + public void DoMigration(CommandLine commandLine) + { + + string fileName = Path.GetFileNameWithoutExtension(commandLine.ConfigFileName); + //Console.WriteLine("File name: " + fileName); + + if (string.IsNullOrEmpty(commandLine.ConfigFileName) || string.IsNullOrEmpty(fileName)) + { + Console.WriteLine("Configuration file is not selected.", MessageTypes.Error); + return; + } + + if (!File.Exists(commandLine.ConfigFileName)) + { + Console.WriteLine("Cannot find configuration file.", MessageTypes.Error); + return; + } + + if (fileName.Length > 20) + { + Console.WriteLine("Configuration file name is restricted to 20 characters at most.", MessageTypes.Error); + return; + } + + if (!Directory.Exists(commandLine.TargetFolder)) + { + Console.WriteLine("Cannot find target folder for conversion output.", MessageTypes.Error); + return; + } + + VendorParser vendorParser; + + switch (commandLine.Vendor) + { + case "CiscoASA": + vendorParser = new CiscoParser(); + break; + case "JuniperSRX": + vendorParser = new JuniperParser(); + break; + case "JuniperSSG": + vendorParser = new ScreenOSParser(); + break; + case "FortiNet": + vendorParser = new FortiGateParser(); + break; + case "PaloAlto": + vendorParser = new PaloAltoParser(); + break; + case "Panorama": + vendorParser = new PanoramaParser(); + break; + default: + throw new InvalidDataException("Unexpected!!!"); + } + + try + { + string ciscoFile = commandLine.ConfigFileName; + Console.WriteLine("Parsing configuration file..."); + + if (commandLine.Vendor.Equals("Panorama")) + { + PanoramaParser panParser = (PanoramaParser)vendorParser; + panParser.ParseWithTargetFolder(ciscoFile, TargetFolder); + } + else + { + vendorParser.Parse(ciscoFile); + } + } + catch (Exception ex) + { + Console.WriteLine(string.Format("Could not parse configuration file.\n\nMessage: {0}\nModule:\t{1}\nClass:\t{2}\nMethod:\t{3}", ex.Message, ex.Source, ex.TargetSite.ReflectedType.Name, ex.TargetSite.Name), MessageTypes.Error); + return; + } + + #region check middleware version + switch (commandLine.Vendor) + { + case "CiscoASA": + if (string.IsNullOrEmpty(vendorParser.Version)) + { + Console.WriteLine("Unspecified ASA version.\nCannot find ASA version for the selected configuration.\nThe configuration may not parse correctly.", MessageTypes.Warning); + return; + } + else if (vendorParser.MajorVersion < 8 || (vendorParser.MajorVersion == 8 && vendorParser.MinorVersion < 3)) + { + Console.WriteLine("Unsupported ASA version (" + vendorParser.Version + ").\nThis tool supports ASA 8.3 and above configuration files.\nThe configuration may not parse correctly.", MessageTypes.Warning); + return; + } + break; + + case "JuniperSRX": + if (string.IsNullOrEmpty(vendorParser.Version)) + { + Console.WriteLine("Unspecified SRX version.\nCannot find SRX version for the selected configuration.\nThe configuration may not parse correctly.", MessageTypes.Warning); + return; + } + else if (vendorParser.MajorVersion < 12 || (vendorParser.MajorVersion == 12 && vendorParser.MinorVersion < 1)) + { + Console.WriteLine("Unsupported SRX version (" + vendorParser.Version + ").\nThis tool supports SRX 12.1 and above configuration files.\nThe configuration may not parse correctly.", MessageTypes.Warning); + return; + } + break; + + case "JuniperSSG": + break; + + case "FortiNet": + if (string.IsNullOrEmpty(vendorParser.Version)) + { + Console.WriteLine("Unspecified FortiGate version.\nCannot find FortiGate version for the selected configuration.\nThe configuration may not parse correctly.", MessageTypes.Warning); + return; + } + else if (vendorParser.MajorVersion < 5) + { + Console.WriteLine("Unsupported FortiGate version (" + vendorParser.Version + ").\nThis tool supports FortiGate 5.x and above configuration files.\nThe configuration may not parse correctly.", MessageTypes.Warning); + return; + } + break; + case "PaloAlto": + if (string.IsNullOrEmpty(vendorParser.Version)) + { + Console.WriteLine("Unspecified PaloAlto version.\nCannot find PaloAlto PAN-OS version for the selected configuration.\nThe configuration may not parse correctly.", MessageTypes.Warning); + return; + } + else if (vendorParser.MajorVersion < 7) + { + Console.WriteLine("Unsupported PaloAlto version (" + vendorParser.Version + ").\nThis tool supports PaloAlto PAN-OS 7.x and above configuration files.\nThe configuration may not parse correctly.", MessageTypes.Warning); + return; + } + break; + case "Panorama": + if (string.IsNullOrEmpty(vendorParser.Version)) + { + Console.WriteLine("Unspecified PaloAlto Panorama version.\nCannot find PaloAlto Panorama version for the selected configuration.\nThe configuration may not parse correctly.", MessageTypes.Warning); + return; + } + else if (vendorParser.MajorVersion < 7) + { + Console.WriteLine("Unsupported PaloAlto version (" + vendorParser.Version + ").\nThis tool supports PaloAlto Panorama 7.x and above configuration files.\nThe configuration may not parse correctly.", MessageTypes.Warning); + return; + } + break; + } + #endregion + + string vendorFileName = Path.GetFileNameWithoutExtension(commandLine.ConfigFileName); + + string toolVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + + string targetFolder = commandLine.TargetFolder + "\\"; + + bool convertNat = commandLine.ConvertNat; + + string ldapAccountUnit = commandLine.LdapAccountUnit; + + vendorParser.Export(targetFolder + vendorFileName + ".json"); + + VendorConverter vendorConverter; + + switch (commandLine.Vendor) + { + case "CiscoASA": + vendorConverter = new CiscoConverter(); + break; + case "JuniperSRX": + vendorConverter = new JuniperConverter(); + break; + case "JuniperSSG": + vendorConverter = new ScreenOSConverter(); + break; + case "FortiNet": + FortiGateConverter fgConverter = new FortiGateConverter(); + fgConverter.OptimizeConf = commandLine.DontImportUnusedObjects; + fgConverter.ConvertUserConf = commandLine.ConvertUserConfiguration; + fgConverter.LDAPAccoutUnit = ldapAccountUnit; + vendorConverter = fgConverter; + break; + case "PaloAlto": + PaloAltoConverter paConverter = new PaloAltoConverter(); + paConverter.OptimizeConf = commandLine.DontImportUnusedObjects; + paConverter.ConvertUserConf = commandLine.ConvertUserConfiguration; + paConverter.LDAPAccoutUnit = ldapAccountUnit; + vendorConverter = paConverter; + break; + case "Panorama": + PanoramaConverter panoramaConverter = new PanoramaConverter(); + panoramaConverter.OptimizeConf = commandLine.DontImportUnusedObjects; + panoramaConverter.ConvertUserConf = commandLine.ConvertUserConfiguration; + panoramaConverter.LDAPAccoutUnit = ldapAccountUnit; + vendorConverter = panoramaConverter; + break; + default: + throw new InvalidDataException("Unexpected!!!"); + } + + vendorConverter.Initialize(vendorParser, commandLine.ConfigFileName, toolVersion, targetFolder, commandLine.Domain); + + try + { + Console.WriteLine("Conversion is in progress..."); + vendorConverter.Convert(convertNat); + Console.WriteLine("Conversion is finished."); + } + catch (Exception ex) + { + + Console.WriteLine(string.Format("Could not convert configuration file.\n\nMessage: {0}\nModule:\t{1}\nClass:\t{2}\nMethod:\t{3}", ex.Message, ex.Source, ex.TargetSite.ReflectedType.Name, ex.TargetSite.Name), MessageTypes.Error); + return; + } + + vendorConverter.ExportConfigurationAsHtml(); + vendorConverter.ExportPolicyPackagesAsHtml(); + if (commandLine.ConvertNat) + { + vendorConverter.ExportNatLayerAsHtml(); + } + } + } +} diff --git a/SmartMove/MainWindow.xaml.cs b/SmartMove/MainWindow.xaml.cs index 8623301f..80c9688d 100644 --- a/SmartMove/MainWindow.xaml.cs +++ b/SmartMove/MainWindow.xaml.cs @@ -31,6 +31,7 @@ limitations under the License. using NetScreenMigration; using FortiGateMigration; using PaloAltoMigration; +using PanoramaPaloAltoMigration; namespace SmartMove { @@ -299,6 +300,13 @@ private void VendorSelector_OnSelectionChanged(object sender, SelectionChangedEv SkipUnusedObjects.Visibility = Visibility.Visible; ConvertUserConf.Visibility = Visibility.Visible; break; + case Vendor.PaloAltoPanorama: + ConfigurationFileLabel = SupportedVendors.PaloAltoPanoramaConfigurationFileLabel; + DomainNameTB.Visibility = Visibility.Collapsed; + DomainName.Visibility = Visibility.Collapsed; + SkipUnusedObjects.Visibility = Visibility.Visible; + ConvertUserConf.Visibility = Visibility.Visible; + break; } ConfigFilePath.Text = SourceFolder; @@ -336,7 +344,10 @@ private void BrowseConfigFile_OnClick(object sender, RoutedEventArgs e) filter = "conf files (*.conf)|*.conf"; break; case Vendor.PaloAlto: - filter = "xml files (*.xml)|*.xml"; + filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*"; + break; + case Vendor.PaloAltoPanorama: + filter = "Gzipped tar files (*.tgz)|*.tgz"; break; } @@ -450,14 +461,33 @@ private async void Go_OnClick(object sender, RoutedEventArgs e) case Vendor.PaloAlto: vendorParser = new PaloAltoParser(); break; + case Vendor.PaloAltoPanorama: + vendorParser = new PanoramaParser(); + break; default: throw new InvalidDataException("Unexpected!!!"); } + + string vendorFileName = Path.GetFileNameWithoutExtension(ConfigFilePath.Text); + string toolVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + string targetFolder = TargetFolderPath.Text + "\\"; + bool convertNat = ConvertNATConfiguration; + string ldapAccountUnit = LDAPAccountUnit.Text.Trim(); try { string ciscoFile = ConfigFilePath.Text; - await Task.Run(() => vendorParser.Parse(ciscoFile)); + switch (_supportedVendors.SelectedVendor) + { + case Vendor.PaloAltoPanorama: + PanoramaParser panParser = (PanoramaParser)vendorParser; + await Task.Run(() => panParser.ParseWithTargetFolder(ciscoFile,targetFolder)); + break; + default: + await Task.Run(() => vendorParser.Parse(ciscoFile)); + break; + } + } catch (Exception ex) { @@ -515,14 +545,20 @@ private async void Go_OnClick(object sender, RoutedEventArgs e) ShowMessage("Unsupported PaloAlto version (" + vendorParser.Version + ").\nThis tool supports PaloAlto PAN-OS 7.x and above configuration files.\nThe configuration may not parse correctly.", MessageTypes.Warning); } break; + case Vendor.PaloAltoPanorama: + if (string.IsNullOrEmpty(vendorParser.Version)) + { + ShowMessage("Unspecified PaloAlto version.\nCannot find PaloAlto Panorama version for the selected configuration.\nThe configuration may not parse correctly.", MessageTypes.Warning); + return; + } + else if (vendorParser.MajorVersion < 7) + { + ShowMessage("Unsupported PaloAlto version (" + vendorParser.Version + ").\nThis tool supports PaloAlto Panorama 7.x and above configuration files.\nThe configuration may not parse correctly.", MessageTypes.Warning); + return; + } + break; } - string vendorFileName = Path.GetFileNameWithoutExtension(ConfigFilePath.Text); - string toolVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); - string targetFolder = TargetFolderPath.Text + "\\"; - bool convertNat = ConvertNATConfiguration; - string ldapAccountUnit = LDAPAccountUnit.Text.Trim(); - vendorParser.Export(targetFolder + vendorFileName + ".json"); VendorConverter vendorConverter; @@ -552,6 +588,13 @@ private async void Go_OnClick(object sender, RoutedEventArgs e) paConverter.LDAPAccoutUnit = ldapAccountUnit.Trim(); vendorConverter = paConverter; break; + case Vendor.PaloAltoPanorama: + PanoramaConverter panoramaConverter = new PanoramaConverter(); + panoramaConverter.OptimizeConf = SkipUnusedObjectsConversion; + panoramaConverter.ConvertUserConf = ConvertUserConfiguration; + panoramaConverter.LDAPAccoutUnit = ldapAccountUnit.Trim(); + vendorConverter = panoramaConverter; + break; default: throw new InvalidDataException("Unexpected!!!"); } @@ -699,6 +742,17 @@ private void ShowResults(VendorConverter vendorConverter, int convertedLinesCoun ConvertingWarningsCount = (paConverter.WarningsInConvertedPackage() != -1) ? string.Format(" ({0} warnings)", paConverter.WarningsInConvertedPackage()) : " Check report."; ConvertingErrorsCount = (paConverter.ErrorsInConvertedPackage() != -1) ? string.Format(" ({0} errors)", paConverter.ErrorsInConvertedPackage()) : " Check report."; break; + case Vendor.PaloAltoPanorama: + CoversionIssuesPreviewPanel.Visibility = Visibility.Visible; + ConvertedOptimizedPolicyPanel.Visibility = Visibility.Collapsed; + RulebaseOptimizedScriptLink.Visibility = Visibility.Collapsed; + + PanoramaConverter panoramaConverter = (PanoramaConverter)vendorConverter; + ConvertedPolicyRulesCount = (panoramaConverter.RulesInConvertedPackage() != -1) ? string.Format(" ({0} rules)", panoramaConverter.RulesInConvertedPackage()) : " Check report."; + ConvertedNATPolicyRulesCount = (panoramaConverter.RulesInNatLayer() != -1) ? string.Format(" ({0} rules)", panoramaConverter.RulesInNatLayer()) : " Check report."; + ConvertingWarningsCount = (panoramaConverter.WarningsInConvertedPackage() != -1) ? string.Format(" ({0} warnings)", panoramaConverter.WarningsInConvertedPackage()) : " Check report."; + ConvertingErrorsCount = (panoramaConverter.ErrorsInConvertedPackage() != -1) ? string.Format(" ({0} errors)", panoramaConverter.ErrorsInConvertedPackage()) : " Check report."; + break; default: CoversionIssuesPreviewPanel.Visibility = Visibility.Collapsed; ConvertedOptimizedPolicyPanel.Visibility = Visibility.Collapsed; diff --git a/SmartMove/Program.cs b/SmartMove/Program.cs new file mode 100644 index 00000000..700823b1 --- /dev/null +++ b/SmartMove/Program.cs @@ -0,0 +1,62 @@ +using System; +using System.Runtime.InteropServices; + +namespace SmartMove +{ + public static class Program + { + [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] + static extern bool FreeConsole(); + + [STAThread] + /* + * Entry point + */ + public static int Main(string[] args) + { + if (args != null && args.Length > 0) + { + CommandLine commandLine = new CommandLine(args); + + //display command help + if (args[0].Equals("-help") || args[0].Equals("/?")) + { + return commandLine.DisplayHelp(); + } + + args = commandLine.regenerateArgs(Environment.CommandLine); + + commandLine = commandLine.Parse(args); +/* + Console.WriteLine(); + Console.WriteLine(" -> Config file name: " + commandLine.ConfigFileName); + Console.WriteLine(" -> Target folder: " + commandLine.TargetFolder); + Console.WriteLine(" -> Vendor: " + commandLine.Vendor); + Console.WriteLine(" -> Domain: " + commandLine.Domain); + Console.WriteLine(" -> Convert NAT option: " + commandLine.ConvertNat); + Console.WriteLine(" -> LDAP account unit: " + commandLine.LdapAccountUnit); + Console.WriteLine(" -> Convert user configuration option: " + commandLine.ConvertUserConfiguration); + Console.WriteLine(" -> Don't import unused objects option: " + commandLine.DontImportUnusedObjects); + Console.WriteLine();*/ + + int exitCode = commandLine.CheckOptionsValidity(commandLine); + + if (exitCode == 0) + { + return 0; + } else + { + commandLine.DoMigration(commandLine); + return 0; + } + } + else + { + FreeConsole(); + var app = new App(); + return app.Run(); + } + } + + } +} From f95197fa4b318c432a316410bfddc05fe50749b6 Mon Sep 17 00:00:00 2001 From: AnastasiaIBA Date: Sun, 13 Sep 2020 15:14:11 +0300 Subject: [PATCH 02/55] Problem with DNS_UDP/DNS_TCP is resolved. --- PaloAltoMigration/PanoramaConverter.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/PaloAltoMigration/PanoramaConverter.cs b/PaloAltoMigration/PanoramaConverter.cs index 94c0bd6f..32284055 100644 --- a/PaloAltoMigration/PanoramaConverter.cs +++ b/PaloAltoMigration/PanoramaConverter.cs @@ -1909,6 +1909,14 @@ public Dictionary ConvertServices(PA_Objects paObjects cpServicesDict = new Dictionary(s_cpServicesDict); else cpServicesDict = new Dictionary(); + + Dictionary cpInspectedServicesDict = new Dictionary(); + foreach (string service in cpServicesDict.Keys) + { + cpInspectedServicesDict[service] = InspectService(cpServicesDict[service]); + } + cpServicesDict = cpInspectedServicesDict; + GetPredefinedServices().ForEach(x => cpServicesDict[x.Name] = InspectService(x)); From 16d5c23a30010f7fa15ee82206ff6cd29b9fa2e8 Mon Sep 17 00:00:00 2001 From: AnastasiaIBA Date: Sun, 13 Sep 2020 15:18:26 +0300 Subject: [PATCH 03/55] Added support for FQDN to be inside network groups. --- PaloAltoMigration/PanoramaConverter.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/PaloAltoMigration/PanoramaConverter.cs b/PaloAltoMigration/PanoramaConverter.cs index 32284055..05a5f510 100644 --- a/PaloAltoMigration/PanoramaConverter.cs +++ b/PaloAltoMigration/PanoramaConverter.cs @@ -1524,12 +1524,20 @@ public Dictionary ConvertAddressesGroupsWithIns List s_TagEntries ) { - Dictionary cpNetGroupsList = - ConvertAddressesGroups(paVsysEntry, s_TagEntries, (new List(cpAddressesDict.Values)), s_cpNetGroupsDict); + Dictionary cpNetGroupsDict = + ConvertAddressesGroups(paDeviceGroupEntry, s_TagEntries, (new List(cpAddressesDict.Values)), s_cpNetGroupsDict); + + if (s_cpNetGroupsDict is null) + { + return cpNetGroupsDict;//don't inspect address groups from shared section because they will be inspected further while device-group processing + } + else + { + Dictionary cpNetGroupsResult = InspectAddressGroups(cpAddressesDict, cpNetGroupsDict, null); + + return cpNetGroupsResult; + } - Dictionary cpNetGroupsResult = InspectAddressGroups(cpAddressesDict, cpNetGroupsList, null); - - return cpNetGroupsResult; } From 9036710885bb46fc282ebf2be6b6438c1afbc55f Mon Sep 17 00:00:00 2001 From: AnastasiaIBA Date: Sun, 13 Sep 2020 15:22:41 +0300 Subject: [PATCH 04/55] Problem with NAT rules creation for specific conditions is solved. --- PaloAltoMigration/PanoramaConverter.cs | 37 +++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/PaloAltoMigration/PanoramaConverter.cs b/PaloAltoMigration/PanoramaConverter.cs index 05a5f510..657babb2 100644 --- a/PaloAltoMigration/PanoramaConverter.cs +++ b/PaloAltoMigration/PanoramaConverter.cs @@ -3192,7 +3192,42 @@ public void ConvertNatPolicy(PA_DeviceGroupEntry paDeviceGroupEntry, else if (cpNetGroupsDict.ContainsKey(translatedAddress)) { cpSourceTranslationList.Add(cpNetGroupsDict[translatedAddress]); - } + } + else if (Regex.IsMatch(translatedAddress, RE_NET_ADDRESS)) //create address or network object for translated address if they were not created before + { + if (!translatedAddress.Contains("/") || translatedAddress.Contains(NETWORK_NETMASK_WS)) + { + string ipAddress; + + if (translatedAddress.Contains("/")) + ipAddress = translatedAddress.Substring(0, translatedAddress.IndexOf("/")); + else + ipAddress = translatedAddress.Substring(0); + + CheckPoint_Host cpHostNew = new CheckPoint_Host(); + cpHostNew.Name = "Host_" + ipAddress; + cpHostNew.IpAddress = ipAddress; + cpAddressesDict[translatedAddress] = cpHostNew; + cpSourceTranslationList.Add(cpHostNew); + _warningsList.Add(cpHostNew.Name + " host object is created for NAT rule."); + } + else + { + IPNetwork ipNetwork; + if (IPNetwork.TryParse(translatedAddress, out ipNetwork)) + { + string ipAddress = translatedAddress.Substring(0, translatedAddress.IndexOf("/")); + CheckPoint_Network cpNetworkNew = new CheckPoint_Network(); + cpNetworkNew.Name = "Net_" + ipAddress; + cpNetworkNew.Subnet = ipAddress; + cpNetworkNew.Netmask = ipNetwork.Netmask.ToString(); + cpAddressesDict[translatedAddress] = cpNetworkNew; + cpSourceTranslationList.Add(cpNetworkNew); + _warningsList.Add(cpNetworkNew.Name + " network object is created for NAT rule."); + } + } + } + } } else if (paNatRuleEntry.SourceTranslation.DynamicIpAndPort.InterfaceAddress != null) From 51245a8ef77bd7da153a2ebcc042d005894ced74 Mon Sep 17 00:00:00 2001 From: AnastasiaIBA Date: Sun, 13 Sep 2020 15:25:41 +0300 Subject: [PATCH 05/55] Added logic to remove duplicate 'drop-all' rules and disable 'allow-all' rules. --- PaloAltoMigration/PanoramaConverter.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/PaloAltoMigration/PanoramaConverter.cs b/PaloAltoMigration/PanoramaConverter.cs index 657babb2..9f3a4ace 100644 --- a/PaloAltoMigration/PanoramaConverter.cs +++ b/PaloAltoMigration/PanoramaConverter.cs @@ -2792,7 +2792,16 @@ Dictionary _devicesUIDDict cpAppGroupsDict, //devicesGroupList, cpTargetDeviceUIDList - ); + ); + if (cpRule.IsCleanupRule()) + { + continue; + } + + if (cpRule.IsAllowAnyRule()) + { + cpRule.Enabled = false; + } cpRule.Layer = cpPackage.ParentLayer.Name; From f53423247ce212e945ca7dd164fcef77a0d59fc6 Mon Sep 17 00:00:00 2001 From: AnastasiaIBA Date: Sun, 13 Sep 2020 15:35:28 +0300 Subject: [PATCH 06/55] Handled checkpoint applications with one quote sign (e.g. Desknet's) --- CheckPointObjects/CheckPointObjects.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/CheckPointObjects/CheckPointObjects.cs b/CheckPointObjects/CheckPointObjects.cs index c7d3ba1a..7923ae66 100644 --- a/CheckPointObjects/CheckPointObjects.cs +++ b/CheckPointObjects/CheckPointObjects.cs @@ -90,6 +90,20 @@ protected static string GetSafeName(string name) { return Regex.Replace(name, NameValidityRegex, "_"); } + + //escaping quote sign in script + public List EscapeQuote(List members) + { + List resultList = new List(); + foreach (string member in members) + { + if (member.IndexOf("\'") != -1) + resultList.Add(member.Replace("\'", "\'\\\'\'")); + else + resultList.Add(member); + } + return resultList; + } protected static string WriteParam(string paramName, bool paramValue, bool defaultValue) { @@ -499,8 +513,10 @@ public class CheckPoint_ApplicationGroup : CheckPointObject public override string ToCLIScript() { + List members = EscapeQuote(Members);//escaping quote sign in script + return "add application-site-group " + WriteParam("name", SafeName(), "") + WriteParam("comments", Comments, "") - + WriteListParam("members", Members, false) + + WriteListParam("members", members, false) + WriteListParam("tags", Tags, true); } From c354e8ce142fac0e13809f7c0924b55bfa01c925 Mon Sep 17 00:00:00 2001 From: AnastasiaIBA Date: Sun, 13 Sep 2020 15:42:21 +0300 Subject: [PATCH 07/55] Application and service groups are splitted. --- CheckPointObjects/CheckPointObjects.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/CheckPointObjects/CheckPointObjects.cs b/CheckPointObjects/CheckPointObjects.cs index 7923ae66..7a86195a 100644 --- a/CheckPointObjects/CheckPointObjects.cs +++ b/CheckPointObjects/CheckPointObjects.cs @@ -708,7 +708,7 @@ public override string ToCLIScript() return "add access-rule " + WriteParam("layer", Layer, "") + WriteParam("comments", Comments, "") + WriteListParam("source", (from o in Source select o.Name).ToList(), true) + WriteListParam("destination", (from o in Destination select o.Name).ToList(), true) - + WriteListParam("service", (from o in Service select o.Name).ToList(), true) + + WriteParamWithIndexesForServices() + WriteParamWithIndexesForApplications() + WriteListParam("time", (from o in Time select o.Name).ToList(), true) + WriteParam("action", actionName, "") @@ -829,6 +829,11 @@ protected virtual string WriteParamWithIndexesForApplications() { return null; } + + protected virtual string WriteParamWithIndexesForServices() + { + return WriteListParam("service", (from o in Service select o.Name).ToList(), true); + } //CloneApplicationsToRule will be overridden in the derived class if the class needs specific clone implementation for applications //in this class the function empty because it doesn't handle with applications in services. @@ -865,6 +870,14 @@ protected override string WriteParamWithIndexesForApplications() { return WriteListParamWithIndexes("service", (from o in Application select o.Name).ToList(), false, Service.Count); } + + protected override string WriteParamWithIndexesForServices() + { + if (Application.Count != 0) + return WriteListParamWithIndexes("service", (from o in Service select o.Name).ToList(), false, 0); + else + return WriteListParam("service", (from o in Service select o.Name).ToList(), true); + } //specific extension for cloning applications protected override void CloneApplicationsToRule(CheckPoint_Rule newRule) @@ -891,7 +904,7 @@ protected override bool CompareApplications(CheckPoint_Rule other) //specific extension to check if the applications list contains only ANY parameter. protected override bool IsApplicationsClean() { - return (Application.Count == 1 && Application[0].Name == Any); + return (Application.Count == 1 && Application[0].Name == Any || Application.Count == 0); } } From e4b26ca12ba45715f56e4993675d57277781c048 Mon Sep 17 00:00:00 2001 From: AnastasiaIBA Date: Sun, 13 Sep 2020 15:54:48 +0300 Subject: [PATCH 08/55] Mapping for application 'ghostsurf' is removed. --- PaloAltoMigration/PA_Apps_CP.csv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PaloAltoMigration/PA_Apps_CP.csv b/PaloAltoMigration/PA_Apps_CP.csv index 99f8fe6a..8ab1e3c0 100644 --- a/PaloAltoMigration/PA_Apps_CP.csv +++ b/PaloAltoMigration/PA_Apps_CP.csv @@ -819,7 +819,7 @@ genesys-interaction-server;; genesys-desktop-sharing;InterCall Unified Meeting - desktop sharing; genesys-base;InterCall Unified Meeting; ggp;;ggp -ghostsurf;ghostsurf; +ghostsurf;; gifboom;GifBoom; gigaup;Gigaup; git;git; @@ -2026,7 +2026,7 @@ rockwell-factorytalk;; rohc;; roundcube;Roundcube; rover;Rover; -rpc;;DCE-RPC Protocol +rpc;DCE-RPC Protocol; rpc-over-http;RPC over HTTP; rping;; rsa-securid-mfa-api;; @@ -2251,7 +2251,7 @@ snmpv3;;snmp snmp-base;;snmp snmpv1;;snmp snmpv2;;snmp -snmp-trap;SNMP Trap; +snmp-trap;;snmp-trap snp;; snpp;SNPP Protocol; soap;; From 3de436356fdc0d2e90a0e3402082c2cad14ee4f9 Mon Sep 17 00:00:00 2001 From: AnastasiaIBA Date: Sun, 13 Sep 2020 16:17:18 +0300 Subject: [PATCH 09/55] Additional update to 'drop-all' and 'allow-all' rules --- CheckPointObjects/CheckPointObjects.cs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/CheckPointObjects/CheckPointObjects.cs b/CheckPointObjects/CheckPointObjects.cs index 7a86195a..dd3092f3 100644 --- a/CheckPointObjects/CheckPointObjects.cs +++ b/CheckPointObjects/CheckPointObjects.cs @@ -800,9 +800,9 @@ public bool IsCleanupRule() return true; // sub-policy's automatic cleanup rule } - if ((Source.Count == 1 && Source[0].Name == Any) && - (Destination.Count == 1 && Destination[0].Name == Any) && - (Service.Count == 1 && Service[0].Name == Any) && + if ((Source.Count == 1 && Source[0].Name == Any || Source.Count == 0) && + (Destination.Count == 1 && Destination[0].Name == Any || Destination.Count == 0) && + (Service.Count == 1 && Service[0].Name == Any || Service.Count == 0) && IsApplicationsClean() && (Action == ActionType.Drop)) { @@ -812,6 +812,24 @@ public bool IsCleanupRule() return false; } + /// + /// Verifies if the rule allows all traffic (which means rule has source: Any, destination: Any, service: Any and action: Accept) + /// + /// + public bool IsAllowAnyRule() + { + if ((Source.Count == 1 && Source[0].Name == Any || Source.Count == 0) && + (Destination.Count == 1 && Destination[0].Name == Any || Destination.Count == 0) && + (Service.Count == 1 && Service[0].Name == Any || Service.Count == 0) && + IsApplicationsClean() && + (Action == ActionType.Accept)) + { + return true; // user defined Allow Any rule + } + return false; + } + + protected static bool CompareLists(IEnumerable items1, IEnumerable items2) { var list1 = (from o in items1 select o.Name).ToList(); From 81bdbe68ecaf2b49e5caab6d024fb3985fba4a53 Mon Sep 17 00:00:00 2001 From: AnastasiaIBA Date: Sun, 11 Oct 2020 18:56:07 +0300 Subject: [PATCH 10/55] smartconnector.py is added --- SmartConnector/cpapi/__init__.py | 5 + SmartConnector/cpapi/api_exceptions.py | 14 + SmartConnector/cpapi/api_response.py | 112 +++ SmartConnector/cpapi/mgmt_api.py | 701 ++++++++++++++ SmartConnector/cpapi/utils.py | 13 + SmartConnector/smartconnector.py | 1205 ++++++++++++++++++++++++ 6 files changed, 2050 insertions(+) create mode 100644 SmartConnector/cpapi/__init__.py create mode 100644 SmartConnector/cpapi/api_exceptions.py create mode 100644 SmartConnector/cpapi/api_response.py create mode 100644 SmartConnector/cpapi/mgmt_api.py create mode 100644 SmartConnector/cpapi/utils.py create mode 100644 SmartConnector/smartconnector.py diff --git a/SmartConnector/cpapi/__init__.py b/SmartConnector/cpapi/__init__.py new file mode 100644 index 00000000..a8a53c54 --- /dev/null +++ b/SmartConnector/cpapi/__init__.py @@ -0,0 +1,5 @@ +from .mgmt_api import APIClient +from .mgmt_api import APIClientArgs +from .api_exceptions import APIException +from .api_exceptions import APIClientException +from .api_response import APIResponse diff --git a/SmartConnector/cpapi/api_exceptions.py b/SmartConnector/cpapi/api_exceptions.py new file mode 100644 index 00000000..38f37469 --- /dev/null +++ b/SmartConnector/cpapi/api_exceptions.py @@ -0,0 +1,14 @@ +class APIException(Exception): + """An exception subclass for our API exceptions, also includes the response when available.""" + def __init__(self, value, response): + self.value = value + self.response = response + + def __str__(self): + return str(self.value) + + +class APIClientException(APIException): + def __init__(self, value): + APIException.__init__(self, value, None) + diff --git a/SmartConnector/cpapi/api_response.py b/SmartConnector/cpapi/api_response.py new file mode 100644 index 00000000..37ee3f78 --- /dev/null +++ b/SmartConnector/cpapi/api_response.py @@ -0,0 +1,112 @@ +import json +import sys + +from cpapi.utils import compatible_loads + +# compatible import for python 2 and 3 +from .api_exceptions import APIException +if sys.version_info >= (3, 0): + from http.client import HTTPResponse +else: + from httplib import HTTPResponse + + +# compatible iterator for python 2 and 3 +def iteritems(data): + if sys.version_info >= (3, 0): + return data.items() + else: + return data.iteritems() + + +def extract_error_and_warning_messages(data): + error_message = [] + + # get all errors and warnings as key-value pairs + for key, val in iteritems(data): + error_message.append(str(key) + ": ") + # value can be either string or list with dictionaries + if isinstance(val, list): + for error_or_warning in val: + error_message.append("\n- " + "message: " + error_or_warning["message"] + "\n") + else: + error_message.append(str(val) + "\n") + + return ''.join(error_message) + + +class APIResponse: + """ + An object to represent an API Response. + Contains data, status_code, success, and sometimes error_message + """ + def __repr__(self): + return '%s(%s)' % (type(self).__name__, json.dumps(self.as_dict(), indent=4, sort_keys=True)) + + def __init__(self, json_response, success, status_code=None, err_message=""): + self.status_code = status_code + self.data = None + + if err_message: + self.success = False + self.error_message = err_message + self.res_obj = {} + else: + self.success = success + try: + if isinstance(json_response, dict): + data_dict = json_response + else: + data_dict = compatible_loads(json_response) + except ValueError: + raise APIException("APIResponse received a response which is not a valid JSON.", json_response) + else: + self.data = data_dict + self.res_obj = {"status_code": self.status_code, "data": self.data} + if not self.success: + try: + self.error_message = extract_error_and_warning_messages(self.data) + except KeyError: + raise APIException("Unexpected error format.", json_response) + + def as_dict(self): + attribute_dict = { + "res_obj": self.res_obj, + "success": self.success, + "status_code": self.status_code, + "data": self.data + } + + try: + attribute_dict.update({"error_message": str(self.error_message)}) + except AttributeError: + pass + return attribute_dict + + def response(self): + """ + The response we return as an HTTP response. + Use instead of self.res_obj. + """ + return {"status_code": self.status_code, "data": self.data} + + @classmethod + def from_http_response(cls, http_response, err_message=""): + """ + Generate APIResponse from http_response object + + :param http_response: input HTTP response object + :param err_message: if there is an error message included, we include it in the APIResponse + :return: The APIResponse object we generated + """ + assert isinstance(http_response, HTTPResponse) + return cls(http_response.read(), success=(http_response.status == 200), status_code=http_response.status, + err_message=err_message) + + def set_success_status(self, status): + """ + This method sets the response success status + + :param status: input status + """ + self.success = status diff --git a/SmartConnector/cpapi/mgmt_api.py b/SmartConnector/cpapi/mgmt_api.py new file mode 100644 index 00000000..0ac3162d --- /dev/null +++ b/SmartConnector/cpapi/mgmt_api.py @@ -0,0 +1,701 @@ +# +# cp_management_api.py +# version 1.1 +# +# A library for communicating with Check Point's management server using [2.7.9 < python < 3] +# written by: Check Point software technologies inc. +# October 2016 +# tested with Check Point R80 (tested with take hero2 198) +# + +from __future__ import print_function + +import sys + +# compatible import for python 2 and 3 +from .api_exceptions import APIException, APIClientException +from .api_response import APIResponse +if sys.version_info >= (3, 0): + import http.client as http_client +else: + import httplib as http_client + +import hashlib +import json +import os.path +import ssl +import subprocess +import time + +from cpapi.utils import compatible_loads + + +class APIClientArgs: + """ + This class provides arguments for APIClient configuration. + All the arguments are configured with their default values. + """ + + # port is set to None by default, but it gets replaced with 443 if not specified + # context possible values - web_api (default) or gaia_api + def __init__(self, port=None, fingerprint=None, sid=None, server="127.0.0.1", http_debug_level=0, + api_calls=None, debug_file="", proxy_host=None, proxy_port=8080, + api_version=None, unsafe=False, unsafe_auto_accept=False, context="web_api"): + self.port = port + # management server fingerprint + self.fingerprint = fingerprint + # session-id. + self.sid = sid + # management server name or IP-address + self.server = server + # debug level + self.http_debug_level = http_debug_level + # an array with all the api calls (for debug purposes) + self.api_calls = api_calls if api_calls else [] + # name of debug file. If left empty, debug data will not be saved to disk. + self.debug_file = debug_file + # HTTP proxy server address (without "http://") + self.proxy_host = proxy_host + # HTTP proxy port + self.proxy_port = proxy_port + # Management server's API version + self.api_version = api_version + # Indicates that the client should not check the server's certificate + self.unsafe = unsafe + # Indicates that the client should automatically accept and save the server's certificate + self.unsafe_auto_accept = unsafe_auto_accept + # The context of using the client - defaults to web_api + self.context = context + + +class APIClient: + """ + APIClient encapsulates everything that the user needs to do for communicating with a Check Point management server + """ + + def __init__(self, api_client_args=None): + """Constructor + :param api_client_args: APIClientArgs object containing arguments + """ + # if a client_args is not supplied, make a default one + if api_client_args is None: + api_client_args = APIClientArgs() + # port on management server + self.__port, self.__is_port_default = (api_client_args.port, False) if api_client_args.port else (443, True) + # management server fingerprint + self.fingerprint = api_client_args.fingerprint + # session-id. + self.sid = api_client_args.sid + # management server name or IP-address + self.server = api_client_args.server + # domain to log into in an MDS environment + self.domain = None + # debug level + self.http_debug_level = api_client_args.http_debug_level + # an array with all the api calls (for debug purposes) + self.api_calls = api_client_args.api_calls + # name of debug file. If left empty, debug data will not be saved to disk. + self.debug_file = api_client_args.debug_file + # HTTP proxy server address + self.proxy_host = api_client_args.proxy_host + # HTTP proxy port + self.proxy_port = api_client_args.proxy_port + # Management server's API version + self.api_version = api_client_args.api_version + # Indicates that the client should not check the server's certificate + self.unsafe = api_client_args.unsafe + # Indicates that the client should automatically accept and save the server's certificate + self.unsafe_auto_accept = api_client_args.unsafe_auto_accept + # The context of using the client - defaults to web_api + self.context = api_client_args.context + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + """destructor""" + # if sid is not empty (the login api was called), then call logout + if self.sid: + self.api_call("logout") + # save debug data with api calls to disk + self.save_debug_data() + + def get_port(self): + """returns the port of the API client (int)""" + return self.__port + + def is_port_default(self): + """returns whether the user changed the port (bool)""" + return self.__is_port_default + + def set_port(self, port): + self.__port = port + self.__is_port_default = False + + def save_debug_data(self): + """save debug data with api calls to disk""" + if self.debug_file: + print("\nSaving data to debug file {}\n".format(self.debug_file), file=sys.stderr) + out_file = open(self.debug_file, 'w+') + out_file.write(json.dumps(self.api_calls, indent=4, sort_keys=True)) + + def login(self, username, password, continue_last_session=False, domain=None, read_only=False, + payload=None): + """ + performs a 'login' API call to the management server + + :param username: Check Point admin name + :param password: Check Point admin password + :param continue_last_session: [optional] It is possible to continue the last Check Point session + or to create a new one + :param domain: [optional] The name, UID or IP-Address of the domain to login. + :param read_only: [optional] Login with Read Only permissions. This parameter is not considered in case + continue-last-session is true. + :param payload: [optional] More settings for the login command + :returns: APIResponse object + :side-effects: updates the class's uid and server variables + """ + credentials = {"user": username, "password": password} + + if self.context == "web_api": + credentials.update({"continue-last-session": continue_last_session, + "read-only": read_only}) + + if domain: + credentials.update({"domain": domain}) + if isinstance(payload, dict): + credentials.update(payload) + + login_res = self.api_call("login", credentials) + + if login_res.success: + self.sid = login_res.data["sid"] + self.domain = domain + if self.api_version is None: + self.api_version = login_res.data["api-server-version"] + return login_res + + def login_as_root(self, domain=None, payload=None): + """ + This method allows to login into the management server with root permissions. + In order to use this method the application should be run directly on the management server + and to have super-user privileges. + + :param domain: [optional] name/uid/IP address of the domain you want to log into in an MDS environment + :param payload: [optional] dict of additional parameters for the login command + :return: APIResponse object with the relevant details from the login command. + """ + python_absolute_path = os.path.expandvars("$MDS_FWDIR/Python/bin/python") + api_get_port_absolute_path = os.path.expandvars("$MDS_FWDIR/scripts/api_get_port.py") + mgmt_cli_absolute_path = os.path.expandvars("$CPDIR/bin/mgmt_cli") + + # try to get the management server's port by running a script + if not self.is_port_default(): + port = self.get_port() + else: + try: + port = compatible_loads(subprocess.check_output([python_absolute_path, + api_get_port_absolute_path, "-f", "json"]))["external_port"] + # if can't, default back to what the user wrote or the default (443) + except (ValueError, subprocess.CalledProcessError): + port = self.get_port() + + try: + # This simple dict->cli format works only because the login command doesn't require + # any complex parameters like objects and lists + new_payload = [] + if payload: + for key in payload.keys(): + new_payload += [key, payload[key]] + if domain: + new_payload += ["domain", domain] + login_response = compatible_loads(subprocess.check_output( + [mgmt_cli_absolute_path, "login", "-r", "true", "-f", "json", "--port", str(port)] + new_payload)) + self.sid = login_response["sid"] + self.server = "127.0.0.1" + self.domain = domain + if self.api_version is None: + self.api_version = login_response["api-server-version"] + return APIResponse(login_response, success=True) + except ValueError as err: + raise APIClientException( + "Could not load JSON from login as root command, perhaps no root privileges?\n" + str( + type(err)) + " - " + str(err)) + except (WindowsError, subprocess.CalledProcessError) as err: + raise APIClientException("Could not login as root:\n" + str(type(err)) + " - " + str(err)) + + def api_call(self, command, payload=None, sid=None, wait_for_task=True): + """ + performs a web-service API request to the management server + + :param command: the command is placed in the URL field + :param payload: a JSON object (or a string representing a JSON object) with the command arguments + :param sid: [optional]. The Check Point session-id. when omitted use self.sid. + :param wait_for_task: determines the behavior when the API server responds with a "task-id". + by default, the function will periodically check the status of the task + and will not return until the task is completed. + when wait_for_task=False, it is up to the user to call the "show-task" API and check + the status of the command. + :return: APIResponse object + :side-effects: updates the class's uid and server variables + """ + self.check_fingerprint() + if payload is None: + payload = {} + # Convert the json payload to a string if needed + if isinstance(payload, str): + _data = payload + elif isinstance(payload, dict): + _data = json.dumps(payload, sort_keys=False) + else: + raise TypeError('Invalid payload type - must be dict/string') + # update class members if needed. + if sid is None: + sid = self.sid + + # Set headers + _headers = { + "User-Agent": "python-api-wrapper", + "Accept": "*/*", + "Content-Type": "application/json", + "Content-Length": len(_data) + } + + # In all API calls (except for 'login') a header containing the Check Point session-id is required. + if sid is not None: + _headers["X-chkp-sid"] = sid + + # Create ssl context with no ssl verification, we do it by ourselves + context = ssl.create_default_context() + context.check_hostname = False + context.verify_mode = ssl.CERT_NONE + + # create https connection + if self.proxy_host and self.proxy_port: + conn = HTTPSConnection(self.proxy_host, self.proxy_port, context=context) + conn.set_tunnel(self.server, self.get_port()) + else: + conn = HTTPSConnection(self.server, self.get_port(), context=context) + + # Set fingerprint + conn.fingerprint = self.fingerprint + + # Set debug level + conn.set_debuglevel(self.http_debug_level) + url = "/" + self.context + "/" + (("v" + str(self.api_version) + "/") if self.api_version else "") + command + response = None + try: + # Send the data to the server + conn.request("POST", url, _data, _headers) + # Get the reply from the server + response = conn.getresponse() + res = APIResponse.from_http_response(response) + except ValueError as err: + if err.args[0] == "Fingerprint value mismatch": + err_message = "Error: Fingerprint value mismatch:\n" + " Expecting : {}\n".format( + err.args[1]) + " Got: {}\n".format( + err.args[2]) + "If you trust the new fingerprint, edit the 'fingerprints.txt' file." + res = APIResponse("", False, err_message=err_message) + else: + res = APIResponse("", False, err_message=err) + except Exception as err: + res = APIResponse("", False, err_message=err) + + if response: + res.status_code = response.status + + # When the command is 'login' we'd like to convert the password to "****" so that it + # would not appear as plaintext in the debug file. + if command == "login": + json_data = compatible_loads(_data) + json_data["password"] = "****" + _data = json.dumps(json_data) + + # Store the request and the reply (for debug purpose). + _api_log = { + "request": { + "url": url, + "payload": compatible_loads(_data), + "headers": _headers + }, + "response": res.response() + } + self.api_calls.append(_api_log) + + # If we want to wait for the task to end, wait for it + if wait_for_task is True and res.success and command != "show-task": + if "task-id" in res.data: + res = self.__wait_for_task(res.data["task-id"]) + elif "tasks" in res.data: + res = self.__wait_for_tasks(res.data["tasks"]) + + return res + + def api_query(self, command, details_level="standard", container_key="objects", include_container_key=False, + payload=None): + """ + The APIs that return a list of objects are limited by the number of objects that they return. + To get the full list of objects, there's a need to make repeated API calls each time using a different offset + until all the objects are returned. + This API makes such repeated API calls and return the full list objects. + note: this function calls gen_api_query and iterates over the generator until it gets all the objects, + then returns. + + :param command: name of API command. This command should be an API that returns an array of + objects (for example: show-hosts, show networks, ...) + :param details_level: query APIs always take a details-level argument. + possible values are "standard", "full", "uid" + :param container_key: name of the key that holds the objects in the JSON response (usually "objects"). + :param include_container_key: If set to False the 'data' field of the APIResponse object + will be a list of the wanted objects. + Otherwise, the date field of the APIResponse will be a dictionary in the following + format: { container_key: [ List of the wanted objects], "total": size of the list} + :param payload: a JSON object (or a string representing a JSON object) with the command arguments + :return: if include-container-key is False: + an APIResponse object whose .data member contains a list of the objects requested: [ , , , ...] + if include-container-key is True: + an APIResponse object whose .data member contains a dict: { container_key: [...], "total": n } + """ + api_res = None + for api_res in self.gen_api_query(command, details_level, [container_key], payload=payload): + pass + if api_res and api_res.success and container_key in api_res.data and include_container_key is False: + api_res.data = api_res.data[container_key] + return api_res + + def gen_api_query(self, command, details_level="standard", container_keys=None, payload=None): + """ + This is a generator function that yields the list of wanted objects received so far from the management server. + This is in contrast to normal API calls that return only a limited number of objects. + This function can be used to show progress when requesting many objects (i.e. "Received x/y objects.") + + :param command: name of API command. This command should be an API that returns an array of objects + (for example: show-hosts, show networks, ...) + :param details_level: query APIs always take a details-level argument. Possible values are "standard", "full", "uid" + :param container_keys: the field in the .data dict that contains the objects + :param payload: a JSON object (or a string representing a JSON object) with the command arguments + :yields: an APIResponse object as detailed above + """ + + finished = False # will become true after getting all the data + all_objects = {} # accumulate all the objects from all the API calls + + # default + if container_keys is None: + container_keys = ["objects"] + + # if given a string, make it a list + if sys.version_info >= (3, 0): + if isinstance(container_keys, (str, str)): + container_keys = [container_keys] + else: + if isinstance(container_keys, (str, unicode)): + container_keys = [container_keys] + + for key in container_keys: + all_objects[key] = [] + iterations = 0 # number of times we've made an API call + limit = 50 # page size to get for each api call + if payload is None: + payload = {} + else: + limit = int(payload.get("limit", limit)) + + payload.update({"limit": limit, "offset": iterations * limit, "details-level": details_level}) + api_res = self.api_call(command, payload) + for container_key in container_keys: + if not api_res.data or container_key not in api_res.data or not isinstance(api_res.data[container_key], list) \ + or "total" not in api_res.data or api_res.data["total"] == 0: + finished = True + yield api_res + break + + # are we done? + while not finished: + # make the API call, offset should be increased by 'limit' with each iteration + if api_res.success is False: + raise APIException(api_res.error_message, api_res.data) + + total_objects = api_res.data["total"] # total number of objects + received_objects = api_res.data["to"] # number of objects we got so far + for container_key in container_keys: + all_objects[container_key] += api_res.data[container_key] + api_res.data[container_key] = all_objects[container_key] + # yield the current result + yield api_res + # did we get all the objects that we're supposed to get + if received_objects == total_objects: + break + + iterations += 1 + payload.update({"limit": limit, "offset": iterations * limit, "details-level": details_level}) + api_res = self.api_call(command, payload) + + def get_server_fingerprint(self): + """ + Initiates an HTTPS connection to the server and extracts the SHA1 fingerprint from the server's certificate. + :return: string with SHA1 fingerprint (all uppercase letters) + """ + context = ssl.create_default_context() + context.check_hostname = False + context.verify_mode = ssl.CERT_NONE + + if self.proxy_host and self.proxy_port: + conn = HTTPSConnection(self.proxy_host, self.proxy_port, context=context) + conn.set_tunnel(self.server, self.get_port()) + else: + conn = HTTPSConnection(self.server, self.get_port(), context=context) + + return conn.get_fingerprint_hash() + + def __wait_for_task(self, task_id): + """ + When the server needs to perform an API call that may take a long time (e.g. run-script, install-policy, + publish), the server responds with a 'task-id'. + Using the show-task API it is possible to check on the status of this task until its completion. + Every two seconds, this function will check for the status of the task. + The function will return when the task (and its sub-tasks) are no longer in-progress. + + :param task_id: The task identifier. + :return: APIResponse object (response of show-task command). + :raises APIException + """ + task_complete = False + task_result = None + in_progress = "in progress" + + # As long as there is a task in progress + while not task_complete: + # Check the status of the task + task_result = self.api_call("show-task", {"task-id": task_id, "details-level": "full"}, self.sid, False) + + attempts_counter = 0 + while task_result.success is False: + if attempts_counter < 5: + attempts_counter += 1 + time.sleep(2) + task_result = self.api_call("show-task", {"task-id": task_id, "details-level": "full"}, + self.sid, False) + else: + raise APIException( + "ERROR: Failed to handle asynchronous tasks as synchronous, tasks result is undefined", + task_result) + + # Count the number of tasks that are not in-progress + completed_tasks = sum(1 for task in task_result.data["tasks"] if task["status"] != in_progress) + + # Get the total number of tasks + total_tasks = len(task_result.data["tasks"]) + + # Are we done? + if completed_tasks == total_tasks: + task_complete = True + else: + time.sleep(2) # Wait for two seconds + + self.check_tasks_status(task_result) + return task_result + + def __wait_for_tasks(self, task_objects): + """ + The version of __wait_for_task function for the collection of tasks + + :param task_objects: A list of task objects + :return: APIResponse object (response of show-task command). + """ + + # A list of task ids to be retrieved + tasks = [] + for task_obj in task_objects: + # Retrieve the taskId and wait for the task to be completed + task_id = task_obj["task-id"] + tasks.append(task_id) + self.__wait_for_task(task_id) + + task_result = self.api_call("show-task", {"task-id": tasks, "details-level": "full"}, + self.sid, False) + + APIClient.check_tasks_status(task_result) + return task_result + + @staticmethod + def check_tasks_status(task_result): + """ + This method checks if one of the tasks failed and if so, changes the response status to be False + + :param task_result: api_response returned from "show-task" command + :return: + """ + for task in task_result.data["tasks"]: + if task["status"] == "failed" or task["status"] == "partially succeeded": + task_result.set_success_status(False) + break + + def check_fingerprint(self): + """ + This function checks if the server's certificate is stored in the local fingerprints file. + If the server's fingerprint is not found, an HTTPS connection is made to the server + and the user is asked if he or she accepts the server's fingerprint. + If the fingerprint is trusted, it is stored in the fingerprint file. + + :return: False if the user does not accept the server certificate, True in all other cases. + """ + if self.unsafe: + return True + # Read the fingerprint from the local file + local_fingerprint = self.read_fingerprint_from_file(self.server) + server_fingerprint = self.get_server_fingerprint() + + #Check if fingerprint is passed and matches + if self.fingerprint == server_fingerprint: + return True + + # If the fingerprint is not stored in the local file + if local_fingerprint == "" or \ + local_fingerprint.replace(':', '').upper() != server_fingerprint.replace(':', '').upper(): + # Get the server's fingerprint with a socket. + if server_fingerprint == "": + return False + + if self.unsafe_auto_accept: + self.save_fingerprint_to_file(self.server, server_fingerprint) + return True + + if local_fingerprint == "": + print("You currently do not have a record of this server's fingerprint.", file=sys.stderr) + else: + print( + "The server's fingerprint is different from your local record of this server's fingerprint.\n" + "You maybe a victim to a Man-in-the-Middle attack, please beware.", file=sys.stderr) + print("Server's fingerprint: {}".format(server_fingerprint), file=sys.stderr) + + if self.ask_yes_no_question("Do you accept this fingerprint?"): + if self.save_fingerprint_to_file(self.server, server_fingerprint): + print("Fingerprint saved.", file=sys.stderr) + else: + print("Could not save fingerprint to file. Continuing anyway.", file=sys.stderr) + else: + return False + + self.fingerprint = server_fingerprint # set the actual fingerprint in the class instance + return True + + @staticmethod + def ask_yes_no_question(question): + """ + helper function. Present a question to the user with Y/N options. + + :param question: The question to display to the user + :return: 'True' if the user typed 'Y'. 'False' is the user typed 'N' + """ + if sys.version_info >= (3, 0): + answer = input(question + " [y/n] ") + else: + answer = raw_input(question + " [y/n] ") + if answer.lower() == "y" or answer.lower() == "yes": + return True + else: + return False + + @staticmethod + def save_fingerprint_to_file(server, fingerprint, filename="fingerprints.txt"): + """ + store a server's fingerprint into a local file. + + :param server: the IP address/name of the Check Point management server. + :param fingerprint: A SHA1 fingerprint of the server's certificate. + :param filename: The file in which to store the certificates. The file will hold a JSON structure in which + the key is the server and the value is its fingerprint. + :return: 'True' if everything went well. 'False' if there was some kind of error storing the fingerprint. + """ + if not fingerprint: + return False + + if os.path.isfile(filename): + try: + with open(filename) as f: + json_dict = json.load(f) + except ValueError as e: + if e.message == "No JSON object could be decoded": + print("Corrupt JSON file: " + filename, file=sys.stderr) + else: + print(e.message, file=sys.stderr) + return False + except IOError as e: + print("Couldn't open file: " + filename + "\n" + e.message, file=sys.stderr) + return False + except Exception as e: + print(e, file=sys.stderr) + return False + else: + if server in json_dict and json_dict[server] == fingerprint: + return True + else: + json_dict[server] = fingerprint + else: + json_dict = {server: fingerprint} + + try: + with open(filename, 'w') as filedump: + json.dump(json_dict, filedump, indent=4, sort_keys=True) + filedump.close() + return True + except IOError as e: + print("Couldn't open file: " + filename + " for writing.\n" + e.message, file=sys.stderr) + except Exception as e: + print(e, file=sys.stderr) + return False + + @staticmethod + def read_fingerprint_from_file(server, filename="fingerprints.txt"): + """ + reads a server's fingerprint from a local file. + + :param server: the IP address/name of the Check Point management server. + :param filename: The file in which to store the certificates. The file will hold a JSON structure in which + the key is the server and the value is its fingerprint. + :return: A SHA1 fingerprint of the server's certificate. + """ + if sys.version_info >= (3, 0): + assert isinstance(server, (str, str)) + else: + assert isinstance(server, (str, unicode)) + + if os.path.isfile(filename): + try: + with open(filename) as f: + json_dict = json.load(f) + except ValueError as e: + if e.message == "No JSON object could be decoded": + print("Corrupt JSON file: " + filename, file=sys.stderr) + else: + print(e.message, file=sys.stderr) + except IOError as e: + print("Couldn't open file: " + filename + "\n" + e.message, file=sys.stderr) + except Exception as e: + print(e, file=sys.stderr) + else: + # file is ok and readable. + if server in json_dict: + return json_dict[server] + return "" + + +class HTTPSConnection(http_client.HTTPSConnection): + """ + A class for making HTTPS connections that overrides the default HTTPS checks (e.g. not accepting + self-signed-certificates) and replaces them with a server fingerprint check. + """ + + def connect(self): + http_client.HTTPConnection.connect(self) + self.sock = ssl.wrap_socket(self.sock, self.key_file, self.cert_file, cert_reqs=ssl.CERT_NONE) + + def get_fingerprint_hash(self): + try: + http_client.HTTPConnection.connect(self) + self.sock = ssl.wrap_socket(self.sock, self.key_file, self.cert_file, cert_reqs=ssl.CERT_NONE) + except Exception: + return "" + fingerprint = hashlib.new("SHA1", self.sock.getpeercert(True)).hexdigest() + return fingerprint.upper() diff --git a/SmartConnector/cpapi/utils.py b/SmartConnector/cpapi/utils.py new file mode 100644 index 00000000..640e73bb --- /dev/null +++ b/SmartConnector/cpapi/utils.py @@ -0,0 +1,13 @@ +import json +import sys + + +def compatible_loads(json_data): + """ + Function json.loads in python 3.0 - 3.5 can't handle bytes, so this function handle it. + :param json_data: + :return: unicode (str if it's python 3) + """ + if isinstance(json_data, bytes) and (3, 0) <= sys.version_info < (3, 6): + json_data = json_data.decode("utf-8") + return json.loads(json_data) diff --git a/SmartConnector/smartconnector.py b/SmartConnector/smartconnector.py new file mode 100644 index 00000000..5206ffe0 --- /dev/null +++ b/SmartConnector/smartconnector.py @@ -0,0 +1,1205 @@ +#!/usr/bin/env python + +import sys +import argparse +import json +import os + +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '.'))) +from cpapi import APIClient, APIClientArgs + + +# printing messages to console and log file +# res_action - response from server, used if response is not OK +# message - message to inform user +# error - message with mark to inform user about issue +# --- +# returns: nothing +def printStatus(res_action, message, error=None): + line = "" + if res_action is not None and res_action.success is False: + if 'errors' in res_action.data: + for msg_err in res_action.data['errors']: + line += "WARN:" + "\t" + msg_err['message'] + "\n" + if 'warnings' in res_action.data: + for msg_wrn in res_action.data['warnings']: + line += "WARN:" + "\t" + msg_wrn['message'] + "\n" + if line == "": + line = "WARN:" + "\t" + res_action.data['message'] + "\n" + elif message is not None: + line += "\t" + message + "\n" + elif error is not None: + line += "WARN:" + "\t" + error + "\n" + if line != "": + print(line.rstrip()) + file_log.write(line) + file_log.flush() + + +# printing info message "process..." with delimeters +# objectsType - string of objects type +# --- +# returns: nothing +def printMessageProcessObjects(objectsType): + printStatus(None, "==========") + printStatus(None, "process " + objectsType + " ...") + printStatus(None, "") + + +# publishing to database new updates by condition; increasing counter by 1 +# counter - is number of new updates. if it equals threshold then updates will be published +# isForced - publishing to database anyway +# --- +# returns: updated counter +def publishUpdate(counter, isForced): + if counter < 0: + counter = 0 + counter += 1 + if isForced or counter >= args.threshold: + if not isForced: + printStatus(None, "") + printStatus(None, "----------") + printStatus(None, "publishing to database...") + res_publish = client.api_call("publish", {}) + if res_publish.success: + counter = 0 + printStatus(res_publish, "publish is completed") + printStatus(None, "----------") + if isForced: + printStatus(None, "") + return counter + + +# check if response contains message that name of "new" object exists in database +# res_add_obj - response from server +# --- +# returns: True - if the name is duplicated, False - otherwise +def isNameDuplicated(res_add_obj): + isNameDuplicated = False + if 'errors' in res_add_obj.data: + for msg in res_add_obj.data['errors']: + if msg['message'].startswith("More than one object named") and msg['message'].endswith("exists."): + isNameDuplicated = True + return isNameDuplicated + + +# check if response contains message that IP of "new" object exists in database +# res_add_obj - response from server +# --- +# returns: True - if the IP is duplicated, False - otherwise +def isIpDuplicated(res_add_obj): + isIpDuplicated = False + if 'warnings' in res_add_obj.data: + messagePrefixes = ("Multiple objects have the same IP address",) + messagePrefixes += ("More than one network have the same IP",) + messagePrefixes += ("More than one network has the same IP",) + for msg in res_add_obj.data['warnings']: + if msg['message'].startswith(messagePrefixes): + isIpDuplicated = True + return isIpDuplicated + + +# check if object from server comes from "global" domain +# serverObject - JSON presentation of object +# --- +# returns: True - if object comes from "global" domain, False - otherwise +def isServerObjectGlobal(serverObject): + return serverObject['domain']['domain-type'] == "global domain" + + +# check if object from server comes from "local" domain +# serverObject - JSON presentation of object +# --- +# returns: True - if object comes from "local" domain, False - otherwise +def isServerObjectLocal(serverObject): + return serverObject['domain']['domain-type'] == "domain" + + +# adding "new" object to server +# adjusting the name if object with the name exists at server: _ +# client - client object +# apiCommand - short string which indicates what should be done +# payload - JSON representation of "new" object +# userObjectNamePostfix - postfix as number +# changeName=True - True: to try to add object and adjust the name; False: to try to add object and NOT adjust the name +# --- +# returns: added object from server in JSON format, None - otherwise +def addUserObjectToServer(client, apiCommand, payload, userObjectNamePostfix=1, changeName=True): + isObjectAdded = False + userObjectNameInitial = "" + if changeName: + userObjectNameInitial = payload['name'] + addedObject = None + while not isObjectAdded: + res_add_obj = client.api_call(apiCommand, payload) + printStatus(res_add_obj, None) + if res_add_obj.success is False: + if not changeName: + break + if isNameDuplicated(res_add_obj): + payload['name'] = userObjectNameInitial + '_' + str(userObjectNamePostfix) + userObjectNamePostfix += 1 + else: + break + else: + addedObject = res_add_obj.data + isObjectAdded = True + return addedObject + + +# adding to server the object which contains fields with IP: hosts, networks +# adjusting the name if object with the name exists at server: _ +# using the object from server side if object exsits with the same IP at server +# client - client object +# payload - JSON representation of "new" object +# userObjectType - the type of object: host or network +# userObjectIp - IP which will be used as filter in request to server +# mergedObjectsNamesMap - the map which contains name of user's object (key) and name of resulting object (value) +# --- +# returns: updated mergedObjectsNamesMap +def addCpObjectWithIpToServer(client, payload, userObjectType, userObjectIp, mergedObjectsNamesMap): + printStatus(None, "processing " + userObjectType + ": " + payload['name']) + userObjectNameInitial = payload['name'] + userObjectNamePostfix = 1 + isFinished = False + isIgnoreWarnings = False + while not isFinished: + payload["ignore-warnings"] = isIgnoreWarnings + res_add_obj_with_ip = client.api_call("add-" + userObjectType, payload) + printStatus(res_add_obj_with_ip, "REPORT: " + userObjectNameInitial + " is added as " + payload['name']) + if res_add_obj_with_ip.success is False: + if isIpDuplicated(res_add_obj_with_ip) and not isIgnoreWarnings: + res_get_obj_with_ip = client.api_query("show-objects", payload={"filter": userObjectIp, "ip-only": True, "type": userObjectType}) + printStatus(res_get_obj_with_ip, None) + if res_get_obj_with_ip.success is True: + if len(res_get_obj_with_ip.data) > 0: + for serverObject in res_get_obj_with_ip.data: + if isServerObjectLocal(serverObject) and not isReplaceFromGlobalFirst: + mergedObjectsNamesMap[userObjectNameInitial] = serverObject['name'] + break + if isServerObjectGlobal(serverObject) and isReplaceFromGlobalFirst: + mergedObjectsNamesMap[userObjectNameInitial] = serverObject['name'] + break + mergedObjectsNamesMap[userObjectNameInitial] = serverObject['name'] + printStatus(None, "REPORT: " + "CP object " + mergedObjectsNamesMap[userObjectNameInitial] + " is used instead of " + userObjectNameInitial) + isFinished = True + else: + isIgnoreWarnings = True + else: + isFinished = True + elif isNameDuplicated(res_add_obj_with_ip): + payload['name'] = userObjectNameInitial + '_' + str(userObjectNamePostfix) + userObjectNamePostfix += 1 + else: + isFinished = True + else: + mergedObjectsNamesMap[userObjectNameInitial] = payload['name'] + isFinished = True + return mergedObjectsNamesMap + + +# processing and adding to server the groups which contains list of members +# adjusting the name if group with the name exists at server: _ +# client - client object +# apiCommand - short string which indicates what should be done +# userGroup - group which will be processed and added to server +# mergedObjectsMap - map of objects which will be used for replacing +# mergedGroupsNamesMap - the map which contains name of user's object (key) and name of resulting object (value) +# --- +# returns: updated mergedGroupsNamesMap +def processGroupWithMembers(client, apiCommand, userGroup, mergedObjectsMap, mergedGroupsNamesMap): + for i, userGroupMember in enumerate(userGroup['Members']): + if userGroupMember in mergedObjectsMap: + userGroup['Members'][i] = mergedObjectsMap[userGroupMember] + elif userGroupMember in mergedGroupsNamesMap: + userGroup['Members'][i] = mergedGroupsNamesMap[userGroupMember] + addedGroup = addUserObjectToServer( + client, + apiCommand, + { + "name": userGroup['Name'], + "members": userGroup['Members'], + "comments": userGroup['Comments'], + "tags": userGroup['Tags'] + } + ) + return addedGroup + + +# processing and adding to server the CheckPoint Domains +# adjusting the name if domain with the name exists at server: _ +# client - client object +# userDomains - the list of domains which will be processed and added to server +# --- +# returns: mergedDomainsNamesMap dictionary +# the map contains name of user's object (key) and name of resulting object (value) +def processDomains(client, userDomains): + printMessageProcessObjects("domains...") + publishCounter = 0 + mergedDomainsNamesMap = {} + if len(userDomains) == 0: + return mergedDomainsNamesMap + for userDomain in userDomains: + userDomainNameInitial = userDomain['Name'] + printStatus(None, "processing domain: " + userDomain['Name']) + addedDomain = addUserObjectToServer( + client, + "add-dns-domain", + { + "name": userDomain['Name'], + "is-sub-domain": userDomain['IsSubDomain'], + "comments": userDomain['Comments'], + "tags": userDomain['Tags'] + } + ) + if addedDomain is not None: + mergedDomainsNamesMap[userDomainNameInitial] = addedDomain['name'] + printStatus(None, "REPORT: " + userDomainNameInitial + " is added as " + addedDomain['name']) + publishCounter = publishUpdate(publishCounter, False) + else: + printStatus(None, "REPORT: " + userDomainNameInitial + ' is not added.') + printStatus(None, "") + publishUpdate(publishCounter, True) + return mergedDomainsNamesMap + + +# processing and adding to server the CheckPoint Hosts +# adjusting the name if host with the name exists at server: _ +# if host contains existing IP address then Host object from server will be used instead +# client - client object +# userHosts - the list of hosts which will be processed and added to server +# --- +# returns: mergedHostsNamesMap dictionary +# the map contains name of user's object (key) and name of resulting object (value) +def processHosts(client, userHosts): + printMessageProcessObjects("hosts") + publishCounter = 0 + mergedHostsNamesMap = {} + if len(userHosts) == 0: + return mergedHostsNamesMap + for userHost in userHosts: + payload = { + "name": userHost['Name'], + "ip-address": userHost['IpAddress'], + "comments": userHost['Comments'], + "tags": userHost['Tags'] + } + initialMapLength = len(mergedHostsNamesMap) + mergedHostsNamesMap = addCpObjectWithIpToServer(client, payload, "host", userHost['IpAddress'], mergedHostsNamesMap) + if initialMapLength == len(mergedHostsNamesMap): + printStatus(None, "REPORT: " + userHost['Name'] + ' is not added.') + else: + publishCounter = publishUpdate(publishCounter, False) + printStatus(None, "") + publishUpdate(publishCounter, True) + return mergedHostsNamesMap + + +# processing and adding to server the CheckPoint Networks +# adjusting the name if network with the name exists at server: _ +# if network contains existing IP subnet then Network object from server will be used instead +# client - client object +# userNetworks - the list of networks which will be processed and added to server +# --- +# returns: mergedNetworksNamesMap dictionary +# the map contains name of user's object (key) and name of resulting object (value) +def processNetworks(client, userNetworks): + printMessageProcessObjects("networks") + publishCounter = 0 + mergedNetworksNamesMap = {} + if len(userNetworks) == 0: + return mergedNetworksNamesMap + for userNetwork in userNetworks: + payload = { + "name": userNetwork['Name'], + "subnet4": userNetwork['Subnet'], + "subnet-mask": userNetwork['Netmask'], + "comments": userNetwork['Comments'], + "tags": userNetwork['Tags'] + } + initialMapLength = len(mergedNetworksNamesMap) + mergedNetworksNamesMap = addCpObjectWithIpToServer(client, payload, "network", userNetwork['Subnet'], mergedNetworksNamesMap) + if initialMapLength == len(mergedNetworksNamesMap): + printStatus(None, "REPORT: " + userNetwork['Name'] + ' is not added.') + else: + publishCounter = publishUpdate(publishCounter, False) + printStatus(None, "") + publishUpdate(publishCounter, True) + return mergedNetworksNamesMap + + +# processing and adding to server the CheckPoint Ranges +# adjusting the name if range with the name exists at server: _ +# if range contains existing IP start and end then Range object from server will be used instead +# client - client object +# userRanges - the list of ranges which will be processed and added to server +# --- +# returns: mergedRangesNamesMap dictionary +# the map contains name of user's object (key) and name of resulting object (value) +def processRanges(client, userRanges): + printMessageProcessObjects("ranges") + publishCounter = 0 + mergedRangesNamesMap = {} + if len(userRanges) == 0: + return mergedRangesNamesMap + serverRangesMap = {} + serverRangesMapGlobal = {} + serverRangesMapLocal = {} + printStatus(None, "reading address ranges from server") + res_get_ranges = client.api_query("show-address-ranges") + printStatus(res_get_ranges, None) + for serverRange in res_get_ranges.data: + key = serverRange['ipv4-address-first'] + '_' + serverRange['ipv4-address-last'] + if isServerObjectGlobal(serverRange) and key not in serverRangesMapGlobal: + serverRangesMapGlobal[key] = serverRange['name'] + elif isServerObjectLocal(serverRange) and key not in serverRangesMapLocal: + serverRangesMapLocal[key] = serverRange['name'] + elif key not in serverRangesMapGlobal and key not in serverRangesMapLocal and key not in serverRangesMap: + serverRangesMap[key] = serverRange['name'] + printStatus(None, "") + if sys.version_info >= (3, 0): + serverRangesMap = serverRangesMap.copy() + if isReplaceFromGlobalFirst: + serverRangesMap.update(serverRangesMapLocal) + serverRangesMap.update(serverRangesMapGlobal) + else: + serverRangesMap.update(serverRangesMapGlobal) + serverRangesMap.update(serverRangesMapLocal) + else: + if isReplaceFromGlobalFirst: + serverRangesMap = dict(serverRangesMap.items() + serverRangesMapLocal.items() + serverRangesMapGlobal.items()) + else: + serverRangesMap = dict(serverRangesMap.items() + serverRangesMapGlobal.items() + serverRangesMapLocal.items()) + for userRange in userRanges: + printStatus(None, "processing range: " + userRange['Name']) + userRangeNameInitial = userRange['Name'] + key = userRange['RangeFrom'] + '_' + userRange['RangeTo'] + if key in serverRangesMap: + printStatus(None, None, "More than one range has the same ip: '" + userRange['RangeFrom'] + "' and '" + userRange['RangeTo'] + "'") + mergedRangesNamesMap[userRangeNameInitial] = serverRangesMap[key] + printStatus(None, "REPORT: " + "CP object " + mergedRangesNamesMap[userRangeNameInitial] + " is used instead of " + userRangeNameInitial) + else: + userRangeNamePostfix = 1 + if userRange['Name'] in serverRangesMap.values(): + printStatus(None, None, "More than one object named '" + userRange['Name'] + "' exists.") + while userRange['Name'] in serverRangesMap.values(): + userRange['Name'] = userRangeNameInitial + '_' + str(userRangeNamePostfix) + userRangeNamePostfix += 1 + payload = { + "name": userRange['Name'], + "ip-address-first": userRange['RangeFrom'], + "ip-address-last": userRange['RangeTo'], + "comments": userRange['Comments'], + "tags": userRange['Tags'], + "ignore-warnings": True + } + addedRange = addUserObjectToServer(client, "add-address-range", payload, userRangeNamePostfix) + if addedRange is not None: + mergedRangesNamesMap[userRangeNameInitial] = addedRange['name'] + key = addedRange['ipv4-address-first'] + '_' + addedRange['ipv4-address-last'] + serverRangesMap[key] = addedRange['name'] + printStatus(None, "REPORT: " + userRangeNameInitial + " is added as " + addedRange['name']) + publishCounter = publishUpdate(publishCounter, False) + else: + printStatus(None, "REPORT: " + userRangeNameInitial + ' is not added.') + printStatus(None, "") + publishUpdate(publishCounter, True) + return mergedRangesNamesMap + + +# processing and adding to server the CheckPoint Network Groups +# adjusting the name if network group with the name exists at server: _ +# client - client object +# userNetworkGroups - the list of network groups which will be processed and added to server +# mergedNetworkObjectsMap - map of network objects which will be used for replacing +# --- +# returns: mergedGroupsNamesDict dictionary +# the map contains name of user's object (key) and name of resulting object (value) +def processNetGroups(client, userNetworkGroups, mergedNetworkObjectsMap): + printMessageProcessObjects("network groups") + publishCounter = 0 + mergedGroupsNamesDict = {} + if len(userNetworkGroups) == 0: + return mergedGroupsNamesDict + for userNetworkGroup in userNetworkGroups: + userNetworkGroupNameInitial = userNetworkGroup['Name'] + addedNetworkGroup = None + if userNetworkGroup['TypeName'] == 'CheckPoint_GroupWithExclusion': + printStatus(None, "processing network group with exclusion: " + userNetworkGroup['Name']) + if userNetworkGroup['Include'] in mergedGroupsNamesDict: + userNetworkGroup['Include'] = mergedGroupsNamesDict[userNetworkGroup['Include']] + if userNetworkGroup['Except'] in mergedGroupsNamesDict: + userNetworkGroup['Except'] = mergedGroupsNamesDict[userNetworkGroup['Except']] + addedNetworkGroup = addUserObjectToServer( + client, + "add-group-with-exclusion", + { + "name": userNetworkGroup['Name'], + "include": userNetworkGroup['Include'], + "except": userNetworkGroup['Except'], + "comments": userNetworkGroup['Comments'], + "tags": userNetworkGroup['Tags'] + } + ) + else: + printStatus(None, "processing network group: " + userNetworkGroup['Name']) + addedNetworkGroup = processGroupWithMembers(client, "add-group", userNetworkGroup, mergedNetworkObjectsMap, mergedGroupsNamesDict) + if addedNetworkGroup is not None: + mergedGroupsNamesDict[userNetworkGroupNameInitial] = addedNetworkGroup['name'] + printStatus(None, "REPORT: " + userNetworkGroupNameInitial + " is added as " + addedNetworkGroup['name']) + publishCounter = publishUpdate(publishCounter, False) + else: + printStatus(None, "REPORT: " + userNetworkGroupNameInitial + " is not added.") + printStatus(None, "") + publishUpdate(publishCounter, True) + return mergedGroupsNamesDict + + +# processing and adding to server the CheckPoint Simple Gateways +# adjusting the name if simple gateway with the name exists at server: _ +# client - client object +# userSimpleGateways - the list of simple gateways which will be processed and added to server +# --- +# returns: mergedSimpleGatewaysNamesMap dictionary +# the map contains name of user's object (key) and name of resulting object (value) +def processSimpleGateways(client, userSimpleGateways): + printMessageProcessObjects("simple gateways") + publishCounter = 0 + mergedSimpleGatewaysNamesMap = {} + if len(userSimpleGateways) == 0: + return mergedSimpleGatewaysNamesMap + for userSimpleGateway in userSimpleGateways: + printStatus(None, "processing simple getway: " + userSimpleGateway['Name']) + userSimpleGatewayNameInitial = userSimpleGateway['Name'] + addedSimpleGateway = addUserObjectToServer( + client, + "add-simple-gateway", + { + "name": userSimpleGateway['Name'], + "ip-address": userSimpleGateway['IpAddress'], + "comments": userSimpleGateway['Comments'], + "tags": userSimpleGateway['Tags'] + } + ) + if addedSimpleGateway is not None: + mergedSimpleGatewaysNamesMap[userSimpleGatewayNameInitial] = addedSimpleGateway['name'] + printStatus(None, "REPORT: " + userSimpleGatewayNameInitial + " is added as " + addedSimpleGateway['name']) + publishCounter = publishUpdate(publishCounter, False) + else: + printStatus(None, "REPORT: " + userSimpleGatewayNameInitial + ' is not added.') + printStatus(None, "") + publishUpdate(publishCounter, True) + return mergedSimpleGatewaysNamesMap + + +# processing and adding to server the CheckPoint Zones +# adjusting the name if zone with the name exists at server: _ +# client - client object +# userZones - the list of zones which will be processed and added to server +# --- +# returns: mergedZonesNamesMap dictionary +# the map contains name of user's object (key) and name of resulting object (value) +def processZones(client, userZones): + printMessageProcessObjects("zones") + publishCounter = 0 + mergedZonesNamesMap = {} + if len(userZones) == 0: + return mergedZonesNamesMap + for userZone in userZones: + printStatus(None, "processing zone: " + userZone['Name']) + userZoneNameInitial = userZone['Name'] + addedZone = addUserObjectToServer( + client, + "add-security-zone", + { + "name": userZone['Name'], + "comments": userZone['Comments'], + "tags": userZone['Tags'] + } + ) + if addedZone is not None: + mergedZonesNamesMap[userZoneNameInitial] = addedZone['name'] + printStatus(None, "REPORT: " + userZoneNameInitial + " is added as " + addedZone['name']) + publishCounter = publishUpdate(publishCounter, False) + else: + printStatus(None, "REPORT: " + userZoneNameInitial + ' is not added.') + printStatus(None, "") + publishUpdate(publishCounter, True) + return mergedZonesNamesMap + + +# generate and provide key for Services dictionary +# serverService - service in JSON format +# --- +# returns: string as key +def provideServerServiceKey(serverService): + key = "" + if 'port' in serverService: # key for TCP or UDP or SCTP + key = serverService['port'] + elif 'icmp-type' in serverService: # key for ICMP + key = str(serverService['icmp-type']) + if 'icmp-code' in serverService and serverService['icmp-code'] != 'null': + key += "_" + str(serverService['icmp-code']) + elif 'ip-protocol' in serverService: # key for Other + key = serverService['ip-protocol'] + return key + + +# processing and adding to server the CheckPoint Services (TCP, UDP, SCTP, ICMP or Other) +# adjusting the name if service with the name exists at server: _ +# if service contains existing port then Service object from server will be used instead +# client - client object +# userServices - the list of services which will be processed and added to server +# userServiceType - the type of service which should be processed +# --- +# returns: mergedServicesMap dictionary +# the map contains name of user's object (key) and name of resulting object (value) +def processServices(client, userServices, userServiceType): + printMessageProcessObjects(userServiceType + " services") + publishCounter = 0 + mergedServicesMap = {} + serverServicesMap = {} + serverServicesMapGlobal = {} + serverServicesMapLocal = {} + printStatus(None, "reading " + userServiceType + " services from server") + res_get_services = client.api_query("show-services-" + userServiceType) + printStatus(res_get_services, None) + for serverService in res_get_services.data: + mergedServicesMap[serverService['name']] = serverService['uid'] + key = provideServerServiceKey(serverService) + isServiceReplacing = False + if 'port' in serverService and ('protocol' not in serverService or serverService['protocol'] == 'null'): + isServiceReplacing = True + if isServerObjectGlobal(serverService) and (key not in serverServicesMapGlobal or isServiceReplacing): + serverServicesMapGlobal[key] = (serverService['name'], serverService['uid']) + elif isServerObjectLocal(serverService) and (key not in serverServicesMapLocal or isServiceReplacing): + serverServicesMapLocal[key] = (serverService['name'], serverService['uid']) + elif not isServerObjectGlobal(serverService) and not isServerObjectLocal(serverService) and (key not in serverServicesMap or isServiceReplacing): + serverServicesMap[key] = (serverService['name'], serverService['uid']) + printStatus(None, "") + if sys.version_info >= (3, 0): + serverServicesMap = serverServicesMap.copy() + if isReplaceFromGlobalFirst: + serverServicesMap.update(serverServicesMapLocal) + serverServicesMap.update(serverServicesMapGlobal) + else: + serverServicesMap.update(serverServicesMapGlobal) + serverServicesMap.update(serverServicesMapLocal) + else: + if isReplaceFromGlobalFirst: + serverServicesMap = dict(serverServicesMap.items() + serverServicesMapLocal.items() + serverServicesMapGlobal.items()) + else: + serverServicesMap = dict(serverServicesMap.items() + serverServicesMapGlobal.items() + serverServicesMapLocal.items()) + if len(userServices) == 0: + return mergedServicesMap + for userService in userServices: + printStatus(None, "processing " + userServiceType + " service: " + userService['Name']) + userServiceNameInitial = userService['Name'] + key = "" + duplicationValueMessagePostfix = "" + if 'Port' in userService: + key = userService['Port'] + duplicationValueMessagePostfix = "port: " + userService['Port'] + elif 'Type' in userService: + key = userService['Type'] + duplicationValueMessagePostfix = "type: " + userService['Type'] + if 'Code' in userService and userService['Code'] != 'null': + key += "_" + userService['Code'] + duplicationValueMessagePostfix = "type / code: " + userService['Type'] + " / " + userService['Code'] + elif 'IpProtocol' in userService: + key = userService['IpProtocol'] + duplicationValueMessagePostfix = "ip-protocol: " + userService['IpProtocol'] + if key in serverServicesMap: + printStatus(None, None, "More than one " + userServiceType + " service has the same " + duplicationValueMessagePostfix) + mergedServicesMap[userServiceNameInitial] = serverServicesMap[key][1] + printStatus(None, "REPORT: " + "CP object " + serverServicesMap[key][0] + " is used instead of " + userServiceNameInitial) + else: + userServiceNamePostfix = 1 + serverServicesNames = [serverServiceNameUid[0] for serverServiceNameUid in serverServicesMap.values()] + if userService['Name'] in serverServicesNames: + printStatus(None, None, "More than one object named '" + userService['Name'] + "' exists.") + while userService['Name'] in serverServicesNames: + userService['Name'] = userServiceNameInitial + '_' + str(userServiceNamePostfix) + userServiceNamePostfix += 1 + payload = {} + payload["name"] = userService['Name'] + payload["comments"] = userService['Comments'] + payload["tags"] = userService['Tags'] + payload["ignore-warnings"] = True + if 'Port' in userService: + payload["port"] = userService['Port'] + payload["source-port"] = userService['SourcePort'] + payload["session-timeout"] = userService['SessionTimeout'] + elif 'Type' in userService: + payload["icmp-type"] = userService['Type'] + if 'Code' in userService and userService['Code'] != 'null': + payload["icmp-code"] = userService['Code'] + elif 'IpProtocol' in userService: + payload["ip-protocol"] = userService['IpProtocol'] + payload["match-for-any"] = True + addedService = addUserObjectToServer(client, "add-service-" + userServiceType, payload, userServiceNamePostfix) + if addedService is not None: + mergedServicesMap[userServiceNameInitial] = addedService['uid'] + key = provideServerServiceKey(addedService) + serverServicesMap[key] = (addedService['name'], addedService['uid']) + printStatus(None, "REPORT: " + userServiceNameInitial + " is added as " + addedService['name']) + publishCounter = publishUpdate(publishCounter, False) + else: + printStatus(None, "REPORT: " + userServiceNameInitial + ' is not added.') + printStatus(None, "") + publishUpdate(publishCounter, True) + return mergedServicesMap + + +# processing and adding to server the CheckPoint Service Groups +# adjusting the name if service group with the name exists at server: _ +# client - client object +# userServicesGroups - the list of service groups which will be processed and added to server +# mergedServicesMap - map of service objects which will be used for replacing +# --- +# returns: mergedServicesGroupsNamesMap dictionary +# the map contains name of user's object (key) and name of resulting object (value) +def processServicesGroups(client, userServicesGroups, mergedServicesMap): + printMessageProcessObjects("services groups") + publishCounter = 0 + mergedServicesGroupsNamesMap = {} + if len(userServicesGroups) == 0: + return mergedServicesGroupsNamesMap + for userServicesGroup in userServicesGroups: + printStatus(None, "processing services group: " + userServicesGroup['Name']) + userServicesGroupNameInitial = userServicesGroup['Name'] + addedServicesGroup = processGroupWithMembers(client, "add-service-group", userServicesGroup, mergedServicesMap, mergedServicesGroupsNamesMap) + if addedServicesGroup is not None: + mergedServicesGroupsNamesMap[userServicesGroupNameInitial] = addedServicesGroup['name'] + printStatus(None, "REPORT: " + userServicesGroupNameInitial + " is added as " + addedServicesGroup['name']) + publishCounter = publishUpdate(publishCounter, False) + else: + printStatus(None, "REPORT: " + userServicesGroupNameInitial + " is not added.") + printStatus(None, "") + publishUpdate(publishCounter, True) + return mergedServicesGroupsNamesMap + + +# processing and adding to server the CheckPoint Time Groups +# adjusting the name if time group with the name exists at server: _ +# client - client object +# userTimesGroups - the list of time groups which will be processed and added to server +# --- +# returns: mergedTimesGroupsNamesMap dictionary +# the map contains name of user's object (key) and name of resulting object (value) +def processTimesGroups(client, userTimesGroups): + printMessageProcessObjects("times groups") + publishCounter = 0 + mergedTimesGroupsNamesMap = {} + if len(userTimesGroups) == 0: + return mergedTimesGroupsNamesMap + for userTimesGroup in userTimesGroups: + printStatus(None, "processing times group: " + userTimesGroup['Name']) + userTimesGroupNameInitial = userTimesGroup['Name'] + addedTimesGroup = addUserObjectToServer( + client, + "add-time-group", + { + "name": userTimesGroup['Name'], + "members": userTimesGroup['Members'], + "comments": userTimesGroup['Comments'], + "tags": userTimesGroup['Tags'] + } + ) + if addedTimesGroup is not None: + mergedTimesGroupsNamesMap[userTimesGroupNameInitial] = addedTimesGroup['name'] + printStatus(None, "REPORT: " + userTimesGroupNameInitial + " is added as " + addedTimesGroup['name']) + publishCounter = publishUpdate(publishCounter, False) + else: + printStatus(None, "REPORT: " + userTimesGroupNameInitial + ' is not added.') + printStatus(None, "") + publishUpdate(publishCounter, True) + return mergedTimesGroupsNamesMap + +# processing and adding to server the CheckPoint Time objects +# adjusting the name if time object with the name exists at server: _ +# client - client object +# userTimes - the list of time objects which will be processed and added to server +# --- +# returns: mergedTimesNamesMap dictionary +# the map contains name of user's object (key) and name of resulting object (value) +def processTimes(client, userTimes): + printMessageProcessObjects("times") + publishCounter = 0 + mergedTimesNamesMap = {} + payload = {} + if len(userTimes) == 0: + return mergedTimesNamesMap + weekdays = {0: "Sun", 1: "Mon", 2: "Tue", 3: "Wed", 4: "Thu", 5: "Fri", 6: "Sat"} + for userTime in userTimes: + printStatus(None, "processing time: " + userTime['Name']) + userTimeNameInitial = userTime['Name'] + + payload["name"] = userTime['Name'] + payload["comments"] = userTime['Comments'] + + payload["start-now"] = userTime['StartNow'] + payload["start"] = { + "date": userTime['StartDate'], + "time": userTime['StartTime'] + } + + payload["end-never"] = userTime['EndNever'] + payload["end"] = { + "date": userTime['EndDate'], + "time": userTime['EndTime'] + } + + payload["hours-ranges"] = [ + { + "enabled": userTime['HoursRangesEnabled_1'], + "from": userTime['HoursRangesFrom_1'] if userTime['HoursRangesFrom_1'] is not None else "00:00", + "to": userTime['HoursRangesTo_1'] if userTime['HoursRangesTo_1'] is not None else "00:00", + "index": 1 + }, + { + "enabled": userTime['HoursRangesEnabled_2'], + "from": userTime['HoursRangesFrom_2'] if userTime['HoursRangesFrom_2'] is not None else "00:00", + "to": userTime['HoursRangesTo_2'] if userTime['HoursRangesTo_2'] is not None else "00:00", + "index": 2 + }, + { + "enabled": userTime['HoursRangesEnabled_3'], + "from": userTime['HoursRangesFrom_3'] if userTime['HoursRangesFrom_3'] is not None else "00:00", + "to": userTime['HoursRangesTo_3'] if userTime['HoursRangesTo_3'] is not None else "00:00", + "index": 3 + } + ] + + daysNames = [] #list of weekdays names e.g. "Sun", "Mon"... + # weekdays are presented as [1,2,3.. ] in userTime['RecurrenceWeekdays'] + for day in userTime['RecurrenceWeekdays']: + daysNames.append(weekdays[day]) + + payload["recurrence"] = { + "pattern": "Daily" if userTime['RecurrencePattern'] == 1 else ("Weekly" if userTime['RecurrencePattern'] == 2 else ("Monthly" if userTime['RecurrencePattern'] == 3 else None)), + "weekdays": daysNames + } + + payload["tags"] = userTime['Tags'] + + addedTime = addUserObjectToServer( + client, + "add-time", + payload + ) + + if addedTime is not None: + mergedTimesNamesMap[userTimeNameInitial] = addedTime['name'] + printStatus(None, "REPORT: " + userTimeNameInitial + " is added as " + addedTime['name']) + publishCounter = publishUpdate(publishCounter, False) + else: + printStatus(None, "REPORT: " + userTimeNameInitial + ' is not added.') + printStatus(None, "") + publishUpdate(publishCounter, True) + return mergedTimesNamesMap + + +# processing and adding to server the CheckPoint Access Rules +# the rules is added in back order: the last item of list goes first and the first item goes last +# client - client object +# userRules - the list of access rules which will be processed and added to server +# userLayerName - the name of layer where access rules will be added +# skipCleanUpRule - the flag which indicates to exclude "Clean up" rule from layer or not; "Clean up" rule is the last rule in the layer always +# mergedNetworkObjectsMap - map of all network objects (groups is included) which will be used for replacing +# mergedServiceObjectsMap - map of all services objects (groups is included) which will be used for replacing +# mergedTimesGroupsNamesMap - map of time groups objects which will be used for replacing +# --- +# returns: nothing +def addAccessRules(client, userRules, userLayerName, skipCleanUpRule, mergedNetworkObjectsMap, mergedServiceObjectsMap, mergedTimesGroupsNamesMap, mergedTimesNamesMap): + if userRules is not None: + publishCounter = 0 + printStatus(None, "processing access rules to " + userLayerName + " layer") + printStatus(None, "") + userRulesStartPosition = -2 if skipCleanUpRule else -1 + # userRules[userRulesStartPosition::-1]: + # -1 - minus means to iterate backwards, 1 means step + # userRulesStartPosition - start point, length of list "- userRulesStartPosition" because reverse mode is specified + # end point is not specified - all elements + for i, userRule in enumerate(userRules[userRulesStartPosition::-1]): + printStatus(None, "processing access rule: #" + str(len(userRules) - i) + ", " + (userRule['Name'] if userRule['Name'] is not None else "")) + # JSON access rules contain "action" as number + # "action" number points to the next list of values from SmartMove: + # 0 = Accept + # 1 = Drop + # 2 = Reject + # 3 = SubPolicy + actions = {0: "accept", 1: "drop", 2: "reject", 3: "apply layer"} + sources = [] + for source in userRule['Source']: + sourceName = source['Name'] + sourceName = mergedNetworkObjectsMap[sourceName] if sourceName in mergedNetworkObjectsMap else sourceName + sources.append(sourceName) + destinations = [] + for destination in userRule['Destination']: + destinationName = destination['Name'] + destinationName = mergedNetworkObjectsMap[destinationName] if destinationName in mergedNetworkObjectsMap else destinationName + destinations.append(destinationName) + services = [] + for service in userRule['Service']: + serviceName = service['Name'] + serviceName = mergedServiceObjectsMap[serviceName] if serviceName in mergedServiceObjectsMap else serviceName + services.append(serviceName) + times = [] + for time in userRule['Time']: + timeName = time['Name'] + + #support of time-ranges along with time-groups is added + if timeName in mergedTimesGroupsNamesMap: + timeName = mergedTimesGroupsNamesMap[timeName] + elif timeName in mergedTimesNamesMap: + timeName = mergedTimesNamesMap[timeName] + else: + timeName = timeName + #timeName = mergedTimesGroupsNamesMap[timeName] if timeName in mergedTimesGroupsNamesMap else timeName + + times.append(timeName) + payload = { + "layer": userRule['Layer'], + "position": "top", + "name": userRule['Name'], + "action": actions[userRule['Action']], + "destination": destinations, + "destination-negate": userRule['DestinationNegated'], + "enabled": userRule['Enabled'], + "service": services, + "source": sources, + "source-negate": userRule['SourceNegated'], + "time": times, + "track": {"type": "None" if userRule['Track'] == 0 else "Log"}, + "comments": userRule['Comments'] + } + if userRule['Action'] == 3: + payload["inline-layer"] = userRule['SubPolicyName'] + if userRule['ConversionComments'].strip() != "": + payload["custom-fields"] = {"field-1": userRule['ConversionComments']} + addedRule = addUserObjectToServer(client, "add-access-rule", payload, changeName=False) + if addedRule is not None: + printStatus(None, "REPORT: access rule is added") + publishCounter = publishUpdate(publishCounter, False) + else: + printStatus(None, "REPORT: access rule is not added") + printStatus(None, "") + publishUpdate(publishCounter, True) + + +# processing and adding to server the CheckPoint Package with Layers and Access Rules +# client - client object +# userPackage - the package which contains layers and access rules +# mergedNetworkObjectsMap - map of all network objects (groups is included) which will be used for replacing +# mergedServiceObjectsMap - map of all services objects (groups is included) which will be used for replacing +# mergedTimesGroupsNamesMap - map of time groups objects which will be used for replacing +# --- +# returns: added package in JSON format +def processPackage(client, userPackage, mergedNetworkObjectsMap, mergedServiceObjectsMap, mergedTimesGroupsNamesMap, mergedTimesNamesMap): + printMessageProcessObjects("package") + addedPackage = None + if userPackage is not None: + publishCounter = 0 + printStatus(None, "processing package: " + userPackage['Name']) + addedPackage = addUserObjectToServer( + client, + "add-package", + { + "name": userPackage['Name'], + "threat-prevention": False, + "tags": userPackage['Tags'] + }, + changeName=False + ) + if addedPackage is None: + printStatus(None, "REPORT: " + userPackage['Name'] + " package is not added") + return addedPackage + printStatus(None, "REPORT: " + userPackage['Name'] + " package is added") + printStatus(None, "") + publishCounter = publishUpdate(publishCounter, True) + if userPackage['SubPolicies'] is not None: + for userSubLayer in userPackage['SubPolicies']: + printStatus(None, "processing access layer: " + userSubLayer['Name']) + addedSubLayer = addUserObjectToServer( + client, + "add-access-layer", + { + "name": userSubLayer['Name'], + "add-default-rule": False, + "applications-and-url-filtering": userSubLayer['ApplicationsAndUrlFiltering'], + "comments": userSubLayer['Comments'], + "tags": userSubLayer['Tags'] + }, + changeName=False + ) + if addedSubLayer is None: + printStatus(None, "REPORT: " + userSubLayer['Name'] + " layer is not added") + continue + printStatus(None, "REPORT: " + userSubLayer['Name'] + " layer is added") + printStatus(None, "") + publishCounter = publishUpdate(publishCounter, True) + addAccessRules(client, userSubLayer['Rules'], userSubLayer['Name'], False, mergedNetworkObjectsMap, mergedServiceObjectsMap, mergedTimesGroupsNamesMap, mergedTimesNamesMap) + if userPackage['ParentLayer'] is not None: + addAccessRules(client, userPackage['ParentLayer']['Rules'], "parent", True, mergedNetworkObjectsMap, mergedServiceObjectsMap, mergedTimesGroupsNamesMap, mergedTimesNamesMap) + return addedPackage + + +# processing and adding to server the CheckPoint NAT rules +# NAT rules are added if package has been added +# client - client object +# addedPackage - added package in JSON format +# userNatRules - the list of NAT rules which will be processed and added to server +# mergedNetworkObjectsMap - map of all network objects (groups is included) which will be used for replacing +# mergedServiceObjectsMap - map of all services objects (groups is included) which will be used for replacing +# --- +# returns: nothing +def processNatRules(client, addedPackage, userNatRules, mergedNetworkObjectsMap, mergedServiceObjectsMap): + printMessageProcessObjects("nat rules") + if addedPackage is None: + printStatus(None, "REPORT: nat rules can not been added because package was not added") + return + publishCounter = 0 + for i, userNatRule in enumerate(userNatRules): + printStatus(None, "processing nat rule: #" + str(i)) + sourceOrig = "" + if userNatRule['Source'] is not None: + sourceOrig = userNatRule['Source']['Name'] + sourceOrig = mergedNetworkObjectsMap[sourceOrig] if sourceOrig in mergedNetworkObjectsMap else sourceOrig + destinationOrig = "" + if userNatRule['Destination'] is not None: + destinationOrig = userNatRule['Destination']['Name'] + destinationOrig = mergedNetworkObjectsMap[destinationOrig] if destinationOrig in mergedNetworkObjectsMap else destinationOrig + serviceOrig = "" + if userNatRule['Service'] is not None: + serviceOrig = userNatRule['Service']['Name'] + serviceOrig = mergedServiceObjectsMap[serviceOrig] if serviceOrig in mergedServiceObjectsMap else serviceOrig + sourceTrans = "" + if userNatRule['TranslatedSource'] is not None: + sourceTrans = userNatRule['TranslatedSource']['Name'] + sourceTrans = mergedNetworkObjectsMap[sourceTrans] if sourceTrans in mergedNetworkObjectsMap else sourceTrans + destinationTrans = "" + if userNatRule['TranslatedDestination'] is not None: + destinationTrans = userNatRule['TranslatedDestination']['Name'] + destinationTrans = mergedNetworkObjectsMap[destinationTrans] if destinationTrans in mergedNetworkObjectsMap else destinationTrans + serviceTrans = "" + if userNatRule['TranslatedService'] is not None: + serviceTrans = userNatRule['TranslatedService']['Name'] + serviceTrans = mergedServiceObjectsMap[serviceTrans] if serviceTrans in mergedServiceObjectsMap else serviceTrans + payload = { + "package": userNatRule['Package'], + "position": "bottom", + "comments": userNatRule['Comments'], + "enabled": userNatRule['Enabled'], + "method": "static" if userNatRule['Method'] == 0 else "hide", + "original-source": sourceOrig, + "original-destination": destinationOrig, + "original-service": serviceOrig, + "translated-source": sourceTrans, + "translated-destination": destinationTrans, + "translated-service": serviceTrans + } + addedNatRule = addUserObjectToServer(client, "add-nat-rule", payload, changeName=False) + if addedNatRule is not None: + printStatus(None, "REPORT: nat rule is added") + publishCounter = publishUpdate(publishCounter, False) + else: + printStatus(None, "REPORT: nat rule is not added") + printStatus(None, "") + publishCounter = publishUpdate(publishCounter, True) + +# START + +args_parser = argparse.ArgumentParser() + +args_parser._optionals.title = "arguments" + +args_parser.add_argument('-r', '--root', action="store_true", + help="If administrator logged into the management server and wants to receive SuperUser permissions, 'login-as-root' feature might be used. " + + "In this case providing additional login credentials is not required.") +args_parser.add_argument('-m', '--management', default='127.0.0.1', + help="Management server IP address or name. Default: 127.0.0.1") +args_parser.add_argument('--port', type=int, + help="Server port. Default: 443") +args_parser.add_argument('-u', '--user', + help="User name") +args_parser.add_argument('-p', '--password', + help="User password") +args_parser.add_argument('-f', '--file', default='cp_objects.json', + help="JSON file with CheckPoint Objects. Default: cp_objects.json") +args_parser.add_argument('-t', '--threshold', type=int, default=100, + help="Parameter specifies maximum number of Check Point objects/rules to add before starting publish operation. Default: 100") +args_parser.add_argument('-d', '--domain', default=None, + help="The name/uid of the domain you want to log into in an MDS environment.") +args_parser.add_argument('--replace-from-global-first', default="false", + help="The argument indicates that SmartConnector should use 'Global' objects at first, by default it uses 'Local' objects. [true, false]") + +args = args_parser.parse_args() + +file_name_log = "smartconnector" +if args.file != "cp_objects.json": + file_name_log += "_" + os.path.splitext(args.file)[0] +file_name_log += ".log" +if os.path.exists(file_name_log): + os.remove(file_name_log) +file_log = open(file_name_log, "w+") + +if not args.root and args.user is None: + print("") + printStatus(None, None, "No user or root option is specified.") + print("") + args_parser.print_help() +elif args.root and args.user is not None: + print("") + printStatus(None, None, "Command contains ambiguous parameters. User is unexpected when logging in as root.") + print("") + args_parser.print_help() +elif args.root and args.management != '127.0.0.1': + print("") + printStatus(None, None, "Command contains ambiguous parameters. Management is unexpected when logging in as root.") + print("") + args_parser.print_help() +elif not args.root and args.password is None: + print("") + printStatus(None, None, "No password option is specified.") + print("") + args_parser.print_help() +elif not os.path.isfile(args.file): + print("") + printStatus(None, None, "The file does not exists") + print("") + args_parser.print_help() +elif args.replace_from_global_first.lower() != "true" and args.replace_from_global_first.lower() != "false": + print("") + printStatus(None, None, "smartconnector.py: error: argument --replace-from-global-first: invalid boolean value: '" + args.replace_from_global_first + "'") + print("") + args_parser.print_help() +else: + if args.replace_from_global_first.lower() == "true": + isReplaceFromGlobalFirst = True + elif args.replace_from_global_first.lower() == "false": + isReplaceFromGlobalFirst = False + printStatus(None, "Input arguments:") + printStatus(None, "root flag is set" if args.root else "root flag is not set") + printStatus(None, "management: " + args.management) + printStatus(None, "port: " + str(args.port) if args.port is not None else "port: is not set, default value will be used") + printStatus(None, "domain: " + args.domain if args.domain is not None else "domain: is not set") + printStatus(None, "user: " + args.user if args.user is not None else "user: is not set") + printStatus(None, "password: ***" if args.password is not None else "password: is not set") + printStatus(None, "file: " + args.file) + printStatus(None, "threshold: " + str(args.threshold)) + printStatus(None, "replace-from-global-first: " + str(isReplaceFromGlobalFirst)) + printStatus(None, "===========================================") + printStatus(None, "reading and parsing processes are started for JSON file: " + args.file) + with open(args.file) as json_file: + json_data = json.load(json_file) + # define lists of CheckPoint Objects + userDomains = [] + userHosts = [] + userNetworks = [] + userRanges = [] + userNetGroups = [] + userSimpleGateways = [] + userZones = [] + userServicesTcp = [] + userServicesUdp = [] + userServicesSctp = [] # is not used in Cisco + userServicesIcmp = [] # is not used in Cisco + userServicesOther = [] + userServicesGroups = [] + userTimesGroups = [] + userTimes = [] + userPackage = None + userNatRules = [] + for jsonObject in json_data: + if jsonObject is None or 'TypeName' not in jsonObject: + continue + if jsonObject['TypeName'] == 'CheckPoint_Domain': + userDomains.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_Host': + userHosts.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_Network': + userNetworks.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_Range': + userRanges.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_NetworkGroup' or jsonObject['TypeName'] == 'CheckPoint_GroupWithExclusion': + userNetGroups.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_SimpleGateway': + userSimpleGateways.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_Zone': + userZones.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_TcpService': + userServicesTcp.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_UdpService': + userServicesUdp.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_SctpService': + userServicesSctp.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_IcmpService': + userServicesIcmp.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_OtherService': + userServicesOther.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_ServiceGroup': + userServicesGroups.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_TimeGroup': + userTimesGroups.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_Time': + userTimes.append(jsonObject) + if jsonObject['TypeName'] == 'CheckPoint_Package': + userPackage = jsonObject + if jsonObject['TypeName'] == 'CheckPoint_NAT_Rule': + userNatRules.append(jsonObject) + + printStatus(None, "reading and parsing processes are completed for JSON file: " + args.file) + client_args = None + if args.port is not None: + client_args = APIClientArgs(server=args.management, port=args.port) + else: + client_args = APIClientArgs(server=args.management) + with APIClient(client_args) as client: + client.debug_file = "api_calls.json" + printStatus(None, "checking fingerprint") + if client.check_fingerprint() is False: + printStatus(None, "Could not get the server's fingerprint - Check connectivity with the server.") + else: + if args.root: + msg = "login as root to " + if args.domain is not None: + msg += args.domain + " domain of local server" + else: + msg += "local server" + printStatus(None, msg) + login_res = client.login_as_root(domain=args.domain) + else: + msg = "login as " + args.user + " to " + if args.domain is not None: + msg += args.domain + " domain of " + args.management + " server" + else: + msg += args.management + " server" + printStatus(None, msg) + login_res = client.login(args.user, args.password, domain=args.domain) + if login_res.success is False: + printStatus(None, "Login failed: {}".format(login_res.error_message)) + else: + printStatus(None, "") + mergedNetworkObjectsMap = {} + mergedNetworkObjectsMap.update(processDomains(client, userDomains)) + mergedNetworkObjectsMap.update(processHosts(client, userHosts)) + mergedNetworkObjectsMap.update(processNetworks(client, userNetworks)) + mergedNetworkObjectsMap.update(processRanges(client, userRanges)) + mergedNetworkObjectsMap.update(processNetGroups(client, userNetGroups, mergedNetworkObjectsMap)) + mergedNetworkObjectsMap.update(processSimpleGateways(client, userSimpleGateways)) + mergedNetworkObjectsMap.update(processZones(client, userZones)) + mergedServicesObjectsMap = {} + mergedServicesObjectsMap.update(processServices(client, userServicesTcp, "tcp")) + mergedServicesObjectsMap.update(processServices(client, userServicesUdp, "udp")) + mergedServicesObjectsMap.update(processServices(client, userServicesSctp, "sctp")) + mergedServicesObjectsMap.update(processServices(client, userServicesIcmp, "icmp")) + mergedServicesObjectsMap.update(processServices(client, userServicesOther, "other")) + mergedServicesObjectsMap.update(processServicesGroups(client, userServicesGroups, mergedServicesObjectsMap)) + mergedTimesGroupsMap = processTimesGroups(client, userTimesGroups) + mergedTimesMap = processTimes(client, userTimes) + addedPackage = processPackage(client, userPackage, mergedNetworkObjectsMap, mergedServicesObjectsMap, mergedTimesGroupsMap, mergedTimesMap) + processNatRules(client, addedPackage, userNatRules, mergedNetworkObjectsMap, mergedServicesObjectsMap) + printStatus(None, "==========") +file_log.close() +# END From 5d9fe969813bf70cc88ec34da39cbd60ce2920be Mon Sep 17 00:00:00 2001 From: AnastasiaIBA Date: Mon, 19 Oct 2020 21:22:16 +0300 Subject: [PATCH 11/55] .csproj files are modified --- PaloAltoMigration/PaloAltoMigration.csproj | 3 ++ SmartMove/SmartMove.csproj | 42 ++++++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/PaloAltoMigration/PaloAltoMigration.csproj b/PaloAltoMigration/PaloAltoMigration.csproj index 41bb3824..f2e0b797 100644 --- a/PaloAltoMigration/PaloAltoMigration.csproj +++ b/PaloAltoMigration/PaloAltoMigration.csproj @@ -48,6 +48,9 @@ + + + diff --git a/SmartMove/SmartMove.csproj b/SmartMove/SmartMove.csproj index d3e724dd..b5c794df 100644 --- a/SmartMove/SmartMove.csproj +++ b/SmartMove/SmartMove.csproj @@ -5,7 +5,7 @@ Debug AnyCPU {CF7E7724-6EBF-4A54-B27C-FD56877A8FF4} - WinExe + Exe Properties SmartMove SmartMove @@ -13,6 +13,21 @@ 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true AnyCPU @@ -36,11 +51,23 @@ Resources\Conversion_Icon.ico + + SmartMove.Program + + + ..\packages\System.Windows.Interactivity.WPF.2.0.20525\lib\net40\Microsoft.Expression.Interactions.dll + + + ..\packages\Microsoft.Xaml.Behaviors.Wpf.1.1.19\lib\net45\Microsoft.Xaml.Behaviors.dll + + + ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll + - + @@ -58,6 +85,8 @@ MSBuild:Compile Designer + + Designer @@ -114,7 +143,7 @@ ResXFileCodeGenerator Resources.Designer.cs - + SettingsSingleFileGenerator Settings.Designer.cs @@ -175,6 +204,13 @@ PreserveNewest + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The system cannot find the required files. Please download the files from + + here + + and extract them into this path inside your project: SmartMove\SmartMove\compressors\. + + + + + + + + + + + + + + + + - - - - - - - - - - - - - The system cannot find the required files. Please download the files from - - here - - and extract them into this path inside your project: SmartMove\SmartMove\compressors\. - - - - - - - - - - - - - - - -