From c1d4c23c00ae5400929759edb4ca7016eb00c43e Mon Sep 17 00:00:00 2001 From: Kanstantsin Sharsniou Date: Fri, 6 Nov 2020 10:34:08 +0300 Subject: [PATCH 01/64] IPv6 support was added for Cisco; add IPv6 validations to the NetworkUtils --- CheckPointObjects/CheckPointObjects.cs | 72 +- CiscoMigration/CiscoCommands.cs | 4763 ++++++++++++----------- CiscoMigration/CiscoConverter.cs | 132 +- CommonUtils/NetworkUtils.cs | 62 +- JuniperMigration/JuniperObjects.cs | 36 +- NetScreenMigration/ScreenOSCommands.cs | 22 +- NetScreenMigration/ScreenOSConverter.cs | 6 +- 7 files changed, 2582 insertions(+), 2511 deletions(-) diff --git a/CheckPointObjects/CheckPointObjects.cs b/CheckPointObjects/CheckPointObjects.cs index fc391e4f..d0aee06d 100644 --- a/CheckPointObjects/CheckPointObjects.cs +++ b/CheckPointObjects/CheckPointObjects.cs @@ -1,4 +1,4 @@ -/******************************************************************** +/******************************************************************** Copyright (c) 2017, Check Point Software Technologies Ltd. All rights reserved. @@ -90,15 +90,15 @@ protected static string GetSafeName(string name) { return Regex.Replace(name, NameValidityRegex, "_"); } - - //escaping quote sign in script + + //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("\'", "\'\\\'\'")); + resultList.Add(member.Replace("\'", "\'\\\'\'")); else resultList.Add(member); } @@ -251,6 +251,7 @@ public class CheckPoint_Network : CheckPointObject { public string Subnet { get; set; } public string Netmask { get; set; } + public string MaskLenght { get; set; } public override IPRanges GetIPRanges() { @@ -261,13 +262,14 @@ public override string ToCLIScript() { return "add network " + WriteParam("name", SafeName(), "") + WriteParam("comments", Comments, "") + WriteParam("subnet", Subnet, "") - + WriteParam("subnet-mask", Netmask , "") + + WriteParam("subnet-mask", Netmask, "") + + WriteParam("mask-length", MaskLenght, "") + WriteListParam("tags", Tags, true); } public override string ToCLIScriptInstruction() { - return "create network [" + Name + "]: subnet [" + Subnet + "] mask [" + Netmask + "]"; + return "create network [" + Name + "]: subnet [" + Subnet + "] mask [" + Netmask + "] mask-lenght [" + MaskLenght + "]"; } } @@ -298,8 +300,8 @@ public override string ToCLIScriptInstruction() public class CheckPoint_NetworkGroup : CheckPointObject { public List Members = new List(); - - public bool IsPanoramaDeviceGroup = false; + + public bool IsPanoramaDeviceGroup = false; /// /// This property is used to overcome the problematic order of objects creation for @@ -540,7 +542,7 @@ public enum RecurrencePatternEnum { None, Daily, Weekly, Monthly }; public string EndDate { get; set; } public string EndTime { get; set; } public double EndPosix { get; set; } - + public bool HoursRangesEnabled_1 { get; set; } public string HoursRangesFrom_1 { get; set; } public string HoursRangesTo_1 { get; set; } @@ -560,25 +562,25 @@ public enum RecurrencePatternEnum { None, Daily, Weekly, Monthly }; public override string ToCLIScript() { return "add time " + WriteParam("name", SafeName(), "") + WriteParam("comments", Comments, "") - - + WriteParam("start-now", StartNow.ToString().ToLower(), "") - + WriteParam("start.date", StartDate, "") + + + WriteParam("start-now", StartNow.ToString().ToLower(), "") + + WriteParam("start.date", StartDate, "") + WriteParam("start.time", StartTime, "") + WriteParam("start.posix", (StartPosix > 0 ? "" + StartPosix : ""), "") - + WriteParam("end-never", EndNever.ToString().ToLower(), "") - + WriteParam("end.date", EndDate, "") + + WriteParam("end-never", EndNever.ToString().ToLower(), "") + + WriteParam("end.date", EndDate, "") + WriteParam("end.time", EndTime, "") + WriteParam("end.posix", (EndPosix > 0 ? "" + EndPosix : ""), "") - + WriteParam("hours-ranges.1.enabled", (HoursRangesEnabled_1 ? HoursRangesEnabled_1.ToString().ToLower() : ""), "") - + WriteParam("hours-ranges.1.from", HoursRangesFrom_1, "") + + WriteParam("hours-ranges.1.enabled", (HoursRangesEnabled_1 ? HoursRangesEnabled_1.ToString().ToLower() : ""), "") + + WriteParam("hours-ranges.1.from", HoursRangesFrom_1, "") + WriteParam("hours-ranges.1.to", HoursRangesTo_1, "") + WriteParam("hours-ranges.2.enabled", (HoursRangesEnabled_2 ? HoursRangesEnabled_2.ToString().ToLower() : ""), "") + WriteParam("hours-ranges.2.from", HoursRangesFrom_2, "") - + WriteParam("hours-ranges.2.to", HoursRangesTo_2, "") - + + WriteParam("hours-ranges.2.to", HoursRangesTo_2, "") + + WriteParam("hours-ranges.3.enabled", (HoursRangesEnabled_3 ? HoursRangesEnabled_3.ToString().ToLower() : ""), "") + WriteParam("hours-ranges.3.from", HoursRangesFrom_3, "") + WriteParam("hours-ranges.3.to", HoursRangesTo_3, "") @@ -595,11 +597,11 @@ public override string ToCLIScriptInstruction() { return "create time [" + Name + "]"; } - - public CheckPoint_Time Clone() + + public CheckPoint_Time Clone() { var newTime = new CheckPoint_Time(); - + newTime.Name = Name; newTime.Comments = Comments; newTime.StartNow = StartNow; @@ -660,7 +662,7 @@ public class CheckPoint_AccessRole : CheckPointObject public override string ToCLIScript() { - if(Networks.Count == 0) + if (Networks.Count == 0) { Networks.Add("any"); } @@ -717,7 +719,7 @@ public CheckPoint_Rule() DestinationNegated = false; ConversionComments = ""; } - + public override string ToCLIScript() { string actionName = ""; @@ -752,7 +754,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) + + WriteListParam("install-on", (from o in Target select o).ToList(), true) + WriteParam("custom-fields.field-1", ConversionComments.Substring(0, Math.Min(ConversionComments.Length, 150)), ""); } @@ -776,7 +778,7 @@ public CheckPoint_Rule Clone() newRule.ConvertedCommandId = ConvertedCommandId; newRule.ConversionIncidentType = ConversionIncidentType; - foreach(CheckPointObject obj in Source) + foreach (CheckPointObject obj in Source) { newRule.Source.Add(obj); } @@ -804,7 +806,7 @@ public CheckPoint_Rule Clone() public bool CompareTo(CheckPoint_Rule other) { if (Enabled != other.Enabled || - Action != other.Action || + Action != other.Action || Track != other.Track || SourceNegated != other.SourceNegated || DestinationNegated != other.DestinationNegated) @@ -874,7 +876,7 @@ protected virtual string WriteParamWithIndexesForApplications() { return null; } - + protected virtual string WriteServicesParams() { return WriteListParam("service", (from o in Service select o.Name).ToList(), true); @@ -915,16 +917,17 @@ protected override string WriteParamWithIndexesForApplications() { return WriteListParamWithIndexes("service", (from o in Application select o.Name).ToList(), false, Service.Count); } - - protected override string WriteServicesParams() - { + + protected override string WriteServicesParams() + { return WriteListParamWithIndexes("service", (from o in Service select o.Name).ToList(), true, 0);//add indexes to services in case applications present as well } //specific extension for cloning applications protected override void CloneApplicationsToRule(CheckPoint_Rule newRule) { - if (newRule is CheckPoint_RuleWithApplication) { + if (newRule is CheckPoint_RuleWithApplication) + { foreach (CheckPointObject obj in Application) { ((CheckPoint_RuleWithApplication)newRule).Application.Add(obj); @@ -939,7 +942,7 @@ protected override bool CompareApplications(CheckPoint_Rule other) { return CompareLists(Application, ((CheckPoint_RuleWithApplication)other).Application); } - + return false; } @@ -1040,8 +1043,8 @@ public CheckPoint_NAT_Rule Clone() public class CheckPoint_Package : CheckPointObject { - public string NameOfAccessLayer - { + public string NameOfAccessLayer + { get { return Name + " Network"; } } @@ -1071,3 +1074,4 @@ public int TotalRules() } } } + diff --git a/CiscoMigration/CiscoCommands.cs b/CiscoMigration/CiscoCommands.cs index f9cbffc3..5cd5733e 100644 --- a/CiscoMigration/CiscoCommands.cs +++ b/CiscoMigration/CiscoCommands.cs @@ -1,2375 +1,2388 @@ -/******************************************************************** -Copyright (c) 2017, Check Point Software Technologies Ltd. -All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -********************************************************************/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using CommonUtils; - -namespace CiscoMigration -{ - public enum ProtocolType { NA, Ip, Icmp, Udp, Tcp, KnownOtherIpProtocol, ReferenceObject }; - public enum TcpUdpPortOperatorType { NA, All, Lt, Gt, Eq, Neq, Range, ReferenceObject }; - public enum ServiceDirection { Source, Destination }; - - public interface ICiscoCommand - { - string Name(); - void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases); - } - - /// - /// Represents a basic Cisco command. - /// Each derived command auto-parses the appropriate configuration line text according to its "name" (via reflection mechanism). - /// Some commands may have child commands (network group commad has child network object commands). - /// The "Id" property is the configuration line number. - /// The "ParentId" property is the parent configuration line number. - /// The "CiscoId" property is the user defined name of the command. - /// - public class CiscoCommand : ICiscoCommand - { - public const string InterfacePrefix = "Interface_"; - public const string Any = "any"; - - private string _text = ""; - private string[] _words; - - public string Text - { - get { return _text; } - set - { - _text = value; - - string trimmedText = _text.Trim(); - char[] delimiterChars = { ' ', '\t' }; - - // Replace multiple spaces with a single space - trimmedText = Regex.Replace(trimmedText, @"\s+", " "); - - _words = trimmedText.Split(delimiterChars); - } - } - - public int IndentationLevel - { - get - { - if (Text.Length == 0) - { - return 0; - } - - int pos = 0; - while (Text.Substring(pos, 1) == " ") - { - pos++; - } - return pos; - } - } - - public string FirstWord - { - get - { - if (_words != null && _words.Any()) - { - // This is a special handling!!! - // There are several commands that have the first word "ip"... - if (_words[0] == "ip") - { - if (_words.Count() > 1 && _words[1] == "address") - { - return _words[0] + " " + _words[1]; - } - if (_words.Count() > 3 && _words[1] == "verify" && _words[2] == "reverse-path" && _words[3] == "interface") - { - return _words[0] + " " + _words[1] + " " + _words[2] + " " + _words[3]; - } - } - else - { - return _words[0]; - } - } - - return ""; - } - } - - public int Id { get; set; } - public int? ParentId { get; set; } - public string CiscoId { get; set; } - public string Description { get; set; } - public string Tag { get; set; } - public string DataForNextElement { get; set; } - public bool KnownCommand { get; set; } - public bool NotAnInterestingCommand { get; set; } - public ConversionIncidentType ConversionIncidentType { get; set; } - public string ConversionIncidentMessage { get; set; } - public List Children { get; set; } - - public CiscoCommand() - { - CiscoId = ""; - Description = ""; - DataForNextElement = ""; - } - - public string GetParam(int pos) - { - if (_words == null || _words.Length <= pos) - { - return ""; - } - - return _words[pos]; - } - - public List GetParams(int pos) - { - var res = new List(); - - if (_words == null || !_words.Any()) - { - return res; - } - - for (int i = 0; i < _words.Length; i++) - { - if (i >= pos) - { - res.Add(_words[i]); - } - } - - return res; - } - - public int GetParamPosition(string paramName) - { - if (_words == null || !_words.Any()) - { - return -1; - } - - int pos = 0; - foreach (string word in _words) - { - if (word == paramName) - { - return pos; - } - pos++; - } - - return -1; - } - - public List Flatten() - { - var res = new List(); - res.Add(this); - - if (Children != null) - { - foreach (CiscoCommand child in Children) - { - foreach (CiscoCommand flattenchild in child.Flatten()) - { - res.Add(flattenchild); - } - } - } - - return res; - } - - public virtual string Name() { return ""; } - - public virtual void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - if (command.Children != null) - { - foreach (CiscoCommand child in command.Children) - { - if (child.Name() == "description") - { - Description = child.Description; - } - } - } - - ConversionIncidentType = ConversionIncidentType.None; - ConversionIncidentMessage = ""; - } - } - - public class Cisco_Description : CiscoCommand - { - public Cisco_Description() - { - NotAnInterestingCommand = true; - } - - public override string Name() { return "description"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - if (!string.IsNullOrEmpty(command.Text)) - { - Description = command.Text.Trim().Substring(Name().Length + 1); - } - - } - } - - public class Cisco_ASA : CiscoCommand - { - public string Version { get; set; } - - public override string Name() { return "ASA"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - const string version = "version"; - if (!string.IsNullOrEmpty(command.Text) && command.GetParam(1).ToLower() == version) - { - Version = command.Text.Trim().Substring(Name().Length + version.Length + 2); - } - else - { - Version = ""; - } - } - } - - public class Cisco_Alias : CiscoCommand - { - public override string Name() { return "name"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - string real = command.GetParam(1); - string alias = command.GetParam(2); - - if (!string.IsNullOrEmpty(alias) && !string.IsNullOrEmpty(real) && !aliases.ContainsKey(alias)) - { - aliases.Add(alias, real); - } - } - } - - public class Cisco_SSH : CiscoCommand - { - public string IpAddress { get; set; } - public string Netmask { get; set; } - public string Interface { get; set; } - - public override string Name() { return "ssh"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - IpAddress = ""; - Netmask = ""; - Interface = ""; - - string commandParam = command.GetParam(1); - if (NetworkUtils.IsValidIp(commandParam)) - { - IpAddress = commandParam; - } - else - { - ConversionIncidentType = ConversionIncidentType.Informative; - ConversionIncidentMessage = "IPv4 address was expected, but '" + commandParam + "' was found."; - return; - } - - commandParam = command.GetParam(2); - if (NetworkUtils.IsValidNetmask(commandParam)) - { - Netmask = commandParam; - } - else - { - IpAddress = ""; - ConversionIncidentType = ConversionIncidentType.Informative; - ConversionIncidentMessage = "IPv4 netmask was expected, but " + commandParam + " was found."; - return; - } - - Interface = command.GetParam(3); - } - } - - public class Cisco_Hostname : CiscoCommand - { - public string HostName { get; set; } - - public override string Name() { return "hostname"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - HostName = command.GetParam(1); - } - } - - public class Cisco_Object : CiscoCommand - { - public enum ObjectTypes { NA, Fqdn, Host, Network, Range, TcpService, UdpService, IcmpService, KnownOtherService }; - - public ObjectTypes ObjectType { get; set; } - public string Fqdn { get; set; } - public string HostAddress { get; set; } - public string Network { get; set; } - public string Netmask { get; set; } - public string RangeFrom { get; set; } - public string RangeTo { get; set; } - public bool IsDestination { get; set; } - public string ServiceProtocol { get; set; } - public string ServiceOperator { set; get; } - public string ServicePort { get; set; } - - public override string Name() { return "object"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - CiscoId = command.GetParam(2); - ObjectType = ObjectTypes.NA; - - switch (command.GetParam(1)) - { - case "network": - ParseNetworks(); - break; - - case "service": - ParseServices(); - break; - - default: - ConversionIncidentType = ConversionIncidentType.Informative; - ConversionIncidentMessage = "Unrecognized object type (" + command.GetParam(1) + ")"; - break; - } - } - - private void ParseNetworks() - { - if (Children == null) - { - return; - } - - int found = 0; - - foreach (CiscoCommand child in Children) - { - switch (child.Name()) - { - case "fqdn": - ObjectType = ObjectTypes.Fqdn; - Fqdn = ((Cisco_Fqdn)child).Fqdn; - found++; - break; - - case "host": - ObjectType = ObjectTypes.Host; - HostAddress = ((Cisco_Host)child).HostAddress; - found++; - break; - - case "subnet": - ObjectType = ObjectTypes.Network; - Network = ((Cisco_Subnet)child).Network; - Netmask = ((Cisco_Subnet)child).Netmask; - found++; - break; - - case "range": - ObjectType = ObjectTypes.Range; - RangeFrom = ((Cisco_Range)child).RangeFrom; - RangeTo = ((Cisco_Range)child).RangeTo; - found++; - break; - } - - if (found == 1) - { - if (child.ConversionIncidentType != ConversionIncidentType.None) - { - ConversionIncidentType = child.ConversionIncidentType; - ConversionIncidentMessage = child.ConversionIncidentMessage; - } - } - } - - if (found > 1) - { - ConversionIncidentType = ConversionIncidentType.Informative; - ConversionIncidentMessage = "An Object (network) can only hold one fqdn, host, range or subnet"; - Console.WriteLine(ConversionIncidentMessage); - } - } - - private void ParseServices() - { - if (Children == null) - { - return; - } - - int found = 0; - - foreach (CiscoCommand child in Children) - { - if (child.Name() == "service") - { - found++; - - var service = (Cisco_Service)child; - ServiceProtocol = service.Protocol; - ServiceOperator = service.Operator; - ServicePort = service.Port; - IsDestination = service.IsDestination; - - if (service.ConversionIncidentType != ConversionIncidentType.None) - { - ConversionIncidentType = service.ConversionIncidentType; - ConversionIncidentMessage = service.ConversionIncidentMessage; - } - - switch (ServiceProtocol) - { - case "ip": - // Predefined "any" object. No special handling... - break; - - case "icmp": - ObjectType = ObjectTypes.IcmpService; - break; - - case "tcp": - ObjectType = ObjectTypes.TcpService; - break; - - case "udp": - ObjectType = ObjectTypes.UdpService; - break; - - default: - // No need to check also for CiscoKnownServices.IsKnownServiceNumber here, - // because it is already done in Cisco_Service class!!! - if (CiscoKnownServices.IsKnownService(ServiceProtocol)) - { - ObjectType = ObjectTypes.KnownOtherService; - } - else - { - ConversionIncidentType = ConversionIncidentType.ManualActionRequired; - ConversionIncidentMessage = "Unrecognized service protocol (" + ServiceProtocol + ")"; - Console.WriteLine(ConversionIncidentMessage); - } - break; - } - } - } - - if (found > 1) - { - ConversionIncidentType = ConversionIncidentType.Informative; - ConversionIncidentMessage = "An Object (service) can only hold one service"; - Console.WriteLine(ConversionIncidentMessage); - } - } - } - - public class Cisco_Fqdn : CiscoCommand - { - public string Fqdn { get; set; } - - public override string Name() { return "fqdn"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - Fqdn = (command.GetParam(1) == "v4") ? command.GetParam(2) : command.GetParam(1); - } - } - - public class Cisco_Host : CiscoCommand - { - public string HostAddress { get; set; } - - public override string Name() { return "host"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - HostAddress = command.GetParam(1); - if (!NetworkUtils.IsValidIp(HostAddress)) - { - ConversionIncidentType = ConversionIncidentType.ManualActionRequired; - ConversionIncidentMessage = "Invalid host IP address (" + HostAddress + "). Using IP 1.1.1.1."; - Console.WriteLine(ConversionIncidentMessage); - - HostAddress = "1.1.1.1"; - } - } - } - - public class Cisco_Subnet : CiscoCommand - { - public string Network { get; set; } - public string Netmask { get; set; } - - public override string Name() { return "subnet"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - Network = command.GetParam(1); - Netmask = command.GetParam(2); - - if (!NetworkUtils.IsValidIp(Network) || !NetworkUtils.IsValidNetmask(Netmask)) - { - ConversionIncidentType = ConversionIncidentType.ManualActionRequired; - ConversionIncidentMessage = "Invalid IP subnet (" + Network + "/" + Netmask + "). Using IP subnet 1.1.1.0/255.255.255.0."; - Console.WriteLine(ConversionIncidentMessage); - - Network = "1.1.1.0"; - Netmask = "255.255.255.0"; - } - } - } - - public class Cisco_Range : CiscoCommand - { - public string RangeFrom { get; set; } - public string RangeTo { get; set; } - - public override string Name() { return "range"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - RangeFrom = command.GetParam(1); - if (!NetworkUtils.IsValidIp(RangeFrom)) - { - ConversionIncidentType = ConversionIncidentType.ManualActionRequired; - ConversionIncidentMessage = "Invalid range starting IP address (" + RangeFrom + "). Using IP 0.0.0.0."; - Console.WriteLine(ConversionIncidentMessage); - - RangeFrom = "0.0.0.0"; - } - - RangeTo = command.GetParam(2); - if (!NetworkUtils.IsValidIp(RangeTo)) - { - ConversionIncidentType = ConversionIncidentType.ManualActionRequired; - ConversionIncidentMessage = "Invalid range ending IP address (" + RangeTo + "). Using IP 255.255.255.255."; - Console.WriteLine(ConversionIncidentMessage); - - RangeTo = "255.255.255.255"; - } - } - } - - public class Cisco_Service : CiscoCommand - { - public string Protocol { get; set; } - public bool IsDestination { get; set; } - public string Port { get; set; } - public string Operator { get; set; } - - public override string Name() { return "service"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - // Parsing Options: - //----------------- - // 1. service protocol_name_or_number - // 2. service {icmp | icmp6} [icmp-type] - // 3. service {tcp | udp} [source operator port] [destination operator port] - //----------------- - - Protocol = command.GetParam(1); - - IsDestination = false; - Port = ""; - Operator = ""; - - switch (Protocol) - { - case "ip": - IsDestination = true; - break; - - case "icmp": - case "icmp6": - IsDestination = true; - Protocol = "icmp"; - Operator = "eq"; - Port = CiscoKnownServices.ConvertIcmpServiceToType(command.GetParam(2)); - break; - - case "tcp": - case "udp": - IsDestination = (command.GetParam(2) == "destination"); - Operator = command.GetParam(3); - Port = CiscoKnownServices.ConvertServiceToPort(command.GetParam(4)); - - int nextParamId = 5; // we need this because of 'range' operator - - if (Operator == "range") - { - Operator = "eq"; - Port = Port + "-" + CiscoKnownServices.ConvertServiceToPort(command.GetParam(5)); - nextParamId = 6; // !!! - } - - if (!IsDestination && command.GetParam(nextParamId) == "destination") - { - // "service tcp source eq ssh destination eq ssh" ---> wrong!!! ---> ignore source!!! - ConversionIncidentType = ConversionIncidentType.Informative; - ConversionIncidentMessage = "Cannot convert a service defined as both source service and destination service. Ignoring source service."; - Console.WriteLine(ConversionIncidentMessage); - - IsDestination = true; - Operator = command.GetParam(nextParamId + 1); - Port = CiscoKnownServices.ConvertServiceToPort(command.GetParam(nextParamId + 2)); - - if (Operator == "range") - { - Operator = "eq"; - Port = Port + "-" + CiscoKnownServices.ConvertServiceToPort(command.GetParam(nextParamId + 3)); - } - } - - if (string.IsNullOrEmpty(Operator) || string.IsNullOrEmpty(Port)) - { - // Use ALL tcp/udp ports if nothing specified!!! - IsDestination = true; - Operator = "all"; - Port = "1-65535"; - } - break; - - default: - IsDestination = true; - - string serviceName; - if (CiscoKnownServices.IsKnownService(Protocol)) - { - Port = CiscoKnownServices.ConvertServiceToPort(Protocol); - } - else if (CiscoKnownServices.IsKnownServiceNumber(Protocol, out serviceName)) // protocol number is used!!! - { - Port = Protocol; - Protocol = serviceName; - } - else - { - ConversionIncidentType = ConversionIncidentType.ManualActionRequired; - ConversionIncidentMessage = "Unrecognized service protocol (" + Protocol + ")"; - Console.WriteLine(ConversionIncidentMessage); - } - break; - } - } - } - - public class Cisco_NetworkObject : CiscoCommand - { - public string IpAddress { get; set; } - public string Netmask { get; set; } - public string ReferencedObject { get; set; } - - public override string Name() { return "network-object"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - IpAddress = ""; - Netmask = ""; - ReferencedObject = ""; - - switch (command.GetParam(1)) - { - case "object": - ReferencedObject = command.GetParam(2); - break; - - case "host": - string ipAddressOrObjectName = command.GetParam(2); - if (ciscoIds.ContainsKey(ipAddressOrObjectName)) - { - ReferencedObject = ipAddressOrObjectName; - } - else - { - IpAddress = aliases.ContainsKey(ipAddressOrObjectName) ? aliases[ipAddressOrObjectName] : ipAddressOrObjectName; - if (!NetworkUtils.IsValidIp(IpAddress)) - { - ConversionIncidentType = ConversionIncidentType.ManualActionRequired; - ConversionIncidentMessage = "Invalid IP address (" + IpAddress + "). Using IP 1.1.1.1."; - Console.WriteLine(ConversionIncidentMessage); - - IpAddress = "1.1.1.1"; - } - - Netmask = "255.255.255.255"; - } - break; - - default: - // subnet - IpAddress = command.GetParam(1); - if (aliases.ContainsKey((IpAddress))) - { - IpAddress = aliases[IpAddress]; - } - Netmask = command.GetParam(2); - - if (!NetworkUtils.IsValidIp(IpAddress) || !NetworkUtils.IsValidNetmask(Netmask)) - { - ConversionIncidentType = ConversionIncidentType.ManualActionRequired; - ConversionIncidentMessage = "Invalid IP subnet (" + IpAddress + "/" + Netmask + "). Using IP subnet 1.1.1.0/255.255.255.0."; - Console.WriteLine(ConversionIncidentMessage); - - IpAddress = "1.1.1.0"; - Netmask = "255.255.255.0"; - } - break; - } - } - } - - public class Cisco_ProtocolObject : CiscoCommand - { - public string ProtocolName { get; set; } - - public override string Name() { return "protocol-object"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - ProtocolName = command.GetParam(1); - } - } - - public class Cisco_PortObject : CiscoCommand - { - public string Port { get; set; } - - public override string Name() { return "port-object"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - Port = ""; - - string portOperator = command.GetParam(1); - - switch (portOperator) - { - case "eq": - Port = CiscoKnownServices.ConvertServiceToPort(command.GetParam(2)); - break; - - case "range": - Port = CiscoKnownServices.ConvertServiceToPort(command.GetParam(2)) + "-" + CiscoKnownServices.ConvertServiceToPort(command.GetParam(3)); - break; - } - } - } - - public class Cisco_ServiceObject : CiscoCommand - { - public string Protocol { get; set; } - public bool IsDestination { get; set; } - public string Port { get; set; } - public string Operator { get; set; } - public string RefObjectName { get; set; } - - public override string Name() { return "service-object"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - // Parsing Options: - //----------------- - // 1. service-object object object_name - // 2. service-object protocol_name_or_number - // 3. service-object {icmp | icmp6} [icmp-type] - // 4. service-object {tcp | udp | tcp-udp} [source operator port] [destination operator port] - //----------------- - - Protocol = command.GetParam(1); - - IsDestination = false; - Port = ""; - Operator = ""; - RefObjectName = ""; - - switch (Protocol) - { - case "object": - RefObjectName = command.GetParam(2); - Protocol = ""; - break; - - case "ip": - IsDestination = true; - break; - - case "icmp": - case "icmp6": - IsDestination = true; - Protocol = "icmp"; - Operator = "eq"; - Port = CiscoKnownServices.ConvertIcmpServiceToType(command.GetParam(2)); - break; - - case "tcp": - case "udp": - case "tcp-udp": - IsDestination = (command.GetParam(2) == "destination"); - Operator = command.GetParam(3); - Port = CiscoKnownServices.ConvertServiceToPort(command.GetParam(4)); - - int nextParamId = 5; // we need this because of 'range' operator - - if (Operator == "range") - { - Operator = "eq"; - Port = Port + "-" + CiscoKnownServices.ConvertServiceToPort(command.GetParam(5)); - nextParamId = 6; // !!! - } - - if (!IsDestination && command.GetParam(nextParamId) == "destination") - { - // "service-object tcp source eq ssh destination eq ssh" ---> wrong!!! ---> ignore source!!! - ConversionIncidentType = ConversionIncidentType.Informative; - ConversionIncidentMessage = "Cannot convert a service defined as both source service and destination service. Ignoring source service."; - Console.WriteLine(ConversionIncidentMessage); - - IsDestination = true; - Operator = command.GetParam(nextParamId + 1); - Port = CiscoKnownServices.ConvertServiceToPort(command.GetParam(nextParamId + 2)); - - if (Operator == "range") - { - Operator = "eq"; - Port = Port + "-" + CiscoKnownServices.ConvertServiceToPort(command.GetParam(nextParamId + 3)); - } - } - - if (string.IsNullOrEmpty(Operator) || string.IsNullOrEmpty(Port)) - { - // Use ALL tcp/udp ports if nothing specified!!! - IsDestination = true; - Operator = "all"; - Port = "1-65535"; - } - break; - - default: - IsDestination = true; - - string serviceName; - if (CiscoKnownServices.IsKnownService(Protocol)) - { - Port = CiscoKnownServices.ConvertServiceToPort(Protocol); - } - else if (CiscoKnownServices.IsKnownServiceNumber(Protocol, out serviceName)) // protocol number is used!!! - { - Port = Protocol; - Protocol = serviceName; - } - else - { - ConversionIncidentType = ConversionIncidentType.ManualActionRequired; - ConversionIncidentMessage = "Unrecognized service protocol (" + Protocol + ")"; - Console.WriteLine(ConversionIncidentMessage); - } - break; - } - } - } - - public class Cisco_IcmpObject : CiscoCommand - { - public string IcmpType { get; set; } - - public override string Name() { return "icmp-object"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - IcmpType = command.GetParam(1); - } - } - - public class Cisco_ReferenceGroupObject : CiscoCommand - { - public string ReferenceId { get; set; } - - public override string Name() { return "group-object"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - ReferenceId = command.GetParam(1); - } - } - - public class Cisco_GroupObject : CiscoCommand - { - public enum Group_Type { NA, Service, Protocol, Icmp, Network }; - - private Dictionary _ciscoIds; - - public Group_Type GroupType { get; set; } - public string ServiceProtocol { get; set; } - - public List Protocols = new List(); - public List IcmpTypes = new List(); - public List MembersGroupNames = new List(); - public List MemberObjects = new List(); - - public override string Name() { return "object-group"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - _ciscoIds = ciscoIds; - - CiscoId = command.GetParam(2); - ServiceProtocol = ""; - - switch (command.GetParam(1)) - { - case "service": - GroupType = Group_Type.Service; - break; - - case "protocol": - GroupType = Group_Type.Protocol; - break; - - case "icmp-type": - GroupType = Group_Type.Icmp; - break; - - case "network": - GroupType = Group_Type.Network; - break; - - default: - GroupType = Group_Type.NA; - ConversionIncidentType = ConversionIncidentType.Informative; - ConversionIncidentMessage = "Unrecognized group type (" + command.GetParam(1) + ")"; - return; - } - - if (GroupType == Group_Type.Service) - { - ServiceProtocol = command.GetParam(3); - } - - if (command.Children == null) - { - return; - } - - foreach (CiscoCommand child in command.Children) - { - bool hasValidChild = true; - - switch (child.Name()) - { - case "protocol-object": - Protocols.Add(((Cisco_ProtocolObject)child).ProtocolName); - break; - - case "port-object": - MemberObjects.Add((Cisco_PortObject)child); - break; - - case "icmp-object": - IcmpTypes.Add(((Cisco_IcmpObject)child).IcmpType); - break; - - case "group-object": - MembersGroupNames.Add(((Cisco_ReferenceGroupObject)child).ReferenceId); - break; - - case "network-object": - MemberObjects.Add((Cisco_NetworkObject)child); - break; - - case "service-object": - MemberObjects.Add((Cisco_ServiceObject)child); - break; - - default: - hasValidChild = false; - break; - } - - if (hasValidChild) - { - if (child.ConversionIncidentType != ConversionIncidentType.None) - { - ConversionIncidentType = child.ConversionIncidentType; - ConversionIncidentMessage = child.ConversionIncidentMessage; - } - } - } - } - - public List GetChildServices() - { - var services = new List(); - - if (Children != null) - { - foreach (CiscoCommand child in Children) - { - if (child.Name() == "service-object") - { - services.Add((Cisco_ServiceObject)child); - } - else if (child.Name() == "group-object") - { - if (_ciscoIds.ContainsKey(((Cisco_ReferenceGroupObject)child).ReferenceId)) - { - var referencedGroupObject = (Cisco_GroupObject)_ciscoIds[((Cisco_ReferenceGroupObject)child).ReferenceId]; - var referencedGroupServices = referencedGroupObject.GetChildServices(); - - foreach (Cisco_ServiceObject referencedService in referencedGroupServices) - { - if (!services.Contains(referencedService)) - { - services.Add(referencedService); - } - } - } - } - } - } - - return services; - } - - public List GetChildPorts() - { - var ports = new List(); - - if (Children != null) - { - foreach (CiscoCommand child in Children) - { - if (child.Name() == "port-object") - { - ports.Add((Cisco_PortObject)child); - } - else if (child.Name() == "group-object") - { - if (_ciscoIds.ContainsKey(((Cisco_ReferenceGroupObject)child).ReferenceId)) - { - var referencedGroupObject = (Cisco_GroupObject)_ciscoIds[((Cisco_ReferenceGroupObject)child).ReferenceId]; - var referencedGroupPorts = referencedGroupObject.GetChildPorts(); - - foreach (Cisco_PortObject referencedPort in referencedGroupPorts) - { - if (!ports.Contains(referencedPort)) - { - ports.Add(referencedPort); - } - } - } - } - } - } - - return ports; - } - } - - public class Cisco_SecurityLevel : CiscoCommand - { - public string Value { get; set; } - - public override string Name() { return "security-level"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - Value = command.GetParam(1); - } - } - - public class Cisco_NameIf : CiscoCommand - { - public string Value { get; set; } - - public override string Name() { return "nameif"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - Value = InterfacePrefix + command.GetParam(1); - } - } - - public class Cisco_VLan : CiscoCommand - { - public string Value { get; set; } - - public override string Name() { return "vlan"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - Value = command.GetParam(1); - } - } - - public class Cisco_IP : CiscoCommand - { - public string IpAddress { get; set; } - public string Netmask { get; set; } - - public override string Name() { return "ip address"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - IpAddress = ""; - Netmask = ""; - - if (command.GetParam(1) == "address") - { - IpAddress = command.GetParam(2); - Netmask = command.GetParam(3); - } - } - } - - public class Cisco_Shutdown : CiscoCommand - { - public bool IsShutdown { get; set; } - - public override string Name() { return "shutdown"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - IsShutdown = (command.GetParam(0) == "shutdown"); - } - } - - public class Cisco_ManagementOnly : CiscoCommand - { - public bool IsManagementOnly { get; set; } - - public override string Name() { return "management-only"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - IsManagementOnly = (command.GetParam(0) == "management-only"); - } - } - - public class Cisco_TimeRange : CiscoCommand - { - public enum Weekdays { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }; - - private string _timeRangeName; - - private string _startDateTime; - private string _endDateTime; - - private List _periodicsList; - - public string TimeRangeName - { - get { return _timeRangeName; } - } - - public string StartDateTime - { - get { return _startDateTime; } - } - - public string EndDateTime - { - get { return _endDateTime; } - } - - public List PeriodicsList - { - get { return _periodicsList; } - } - - public override string Name() { return "time-range"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - _periodicsList = new List(); - - _timeRangeName = this.GetParam(1); - - foreach(CiscoCommand child in Children) - { - if(child.FirstWord.Equals("absolute")) - { - int startIndex = child.Text.IndexOf("start"); - int endIndex = child.Text.IndexOf("end"); - if(startIndex > -1 && endIndex > -1) - { - _startDateTime = child.Text.Substring("absolute".Length + "start".Length + 2, endIndex - startIndex - "start".Length).Trim(); - _endDateTime = child.Text.Substring(endIndex + "end".Length).Trim(); - } - else if (startIndex > -1 && endIndex == -1) - { - _startDateTime = child.Text.Substring("absolute".Length + "start".Length + 2).Trim(); - } - else if(startIndex == -1 && endIndex > -1) - { - _endDateTime = child.Text.Substring("absolute".Length + "end".Length + 2).Trim(); - } - } - - if (child.FirstWord.Equals("periodic")) - { - string period = child.Text.Substring("periodic".Length + 1).Trim(); - - string[] daysTimes = period.Trim().Split(new string[] { "to" }, StringSplitOptions.RemoveEmptyEntries); - - string[] daysTimes_1 = daysTimes[0].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); - string[] daysTimes_2 = daysTimes[1].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); - - if (daysTimes_1.Length == 2 && daysTimes_2.Length == 2) - { - int startWdIndex = (int)Enum.Parse(typeof(Weekdays), daysTimes_1[0]); - int endWdIndex = (int)Enum.Parse(typeof(Weekdays), daysTimes_2[0]); - - if (startWdIndex < endWdIndex) - { - _periodicsList.Add((Weekdays)startWdIndex + " " + daysTimes_1[1] + " to 23:59"); - - for (int i = startWdIndex+1; i <= endWdIndex-1; i++) - { - _periodicsList.Add((Weekdays)i + " 0:00 to 23:59"); - } - - _periodicsList.Add((Weekdays)endWdIndex + " 0:00 to " + daysTimes_2[1]); - } - else - { - int firstWdIndex = (int)Enum.GetValues(typeof(Weekdays)).Cast().First(); - int lastWdIndex = (int)Enum.GetValues(typeof(Weekdays)).Cast().Last(); - - _periodicsList.Add((Weekdays)startWdIndex + " " + daysTimes_1[1] + " to 23:59"); - - for (int i = startWdIndex + 1; i <= lastWdIndex; i++) - { - _periodicsList.Add((Weekdays)i + " 0:00 to 23:59"); - } - - for (int i = firstWdIndex; i <= endWdIndex-1; i++) - { - _periodicsList.Add((Weekdays)i + " 0:00 to 23:59"); - } - - _periodicsList.Add((Weekdays)endWdIndex + " 0:00 to " + daysTimes_2[1]); - } - } - else - { - _periodicsList.Add(period); - } - } - } - } - } - - public class Cisco_Interface : CiscoCommand - { - public string InterfaceName { get; set; } - public int SecurityLevel { get; set; } - public string VLan { get; set; } - public string IpAddress { get; set; } - public string Netmask { get; set; } - public bool Shutdown { get; set; } - public bool ManagementOnly { get; set; } - public bool LeadsToInternet { get; set; } - - public class Subnet - { - public string Network { get; private set; } - public string Netmask { get; private set; } - - public Subnet (string sIp, string sMask) - { - Network = sIp; - Netmask = sMask; - } - } - - public List Topology = new List(); - - public override string Name() { return "interface"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - InterfaceName = command.GetParam(1); - SecurityLevel = 0; - VLan = ""; - IpAddress = ""; - Netmask = ""; - Shutdown = false; - ManagementOnly = false; - LeadsToInternet = false; - - if (command.Children == null) - { - return; - } - - foreach (CiscoCommand child in command.Children) - { - switch (child.Name()) - { - case "security-level": - int securityLevel; - if (int.TryParse(((Cisco_SecurityLevel)child).Value, out securityLevel)) - { - SecurityLevel = securityLevel; - } - break; - - case "nameif": - CiscoId = ((Cisco_NameIf)child).Value; - break; - - case "vlan": - VLan = ((Cisco_VLan)child).Value; - break; - - case "shutdown": - Shutdown = ((Cisco_Shutdown)child).IsShutdown; - break; - - case "management-only": - ManagementOnly = ((Cisco_ManagementOnly)child).IsManagementOnly; - break; - - case "ip address": - IpAddress = ((Cisco_IP)child).IpAddress; - Netmask = ((Cisco_IP)child).Netmask; - - if (NetworkUtils.IsValidIp(IpAddress) && NetworkUtils.IsValidNetmask(Netmask)) - { - Topology.Add(new Subnet(NetworkUtils.GetNetwork(IpAddress, Netmask), Netmask)); - } - else - { - ConversionIncidentType = ConversionIncidentType.ManualActionRequired; - ConversionIncidentMessage = "Invalid IP subnet (" + IpAddress + "/" + Netmask + ")."; - Console.WriteLine(ConversionIncidentMessage); - } - break; - } - } - } - - public bool HasValidIpAddress() - { - return NetworkUtils.IsValidIp(IpAddress) && NetworkUtils.IsValidNetmask(Netmask); - } - } - - public class Cisco_Route : CiscoCommand - { - public string InterfaceName { get; set; } - public bool DefaultRoute { get; set; } - public string DestinationIp { get; set; } - public string DestinationNetmask { get; set; } - public string Gateway { get; set; } - - public override string Name() { return "route"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - DefaultRoute = false; - InterfaceName = command.GetParam(1); - DestinationIp = command.GetParam(2); - DestinationNetmask = command.GetParam(3); - Gateway = command.GetParam(4); - - bool destinationIpResolved = false; - - if (ciscoIds.ContainsKey(DestinationIp)) - { - var refObj = (Cisco_Object)ciscoIds[DestinationIp]; - if (refObj != null) - { - switch (refObj.ObjectType) - { - case Cisco_Object.ObjectTypes.Host: - DestinationIp = refObj.HostAddress; - destinationIpResolved = true; - break; - - case Cisco_Object.ObjectTypes.Network: - DestinationIp = refObj.Network; - destinationIpResolved = true; - break; - } - } - } - else - { - DestinationIp = aliases.ContainsKey(DestinationIp) ? aliases[DestinationIp] : DestinationIp; - destinationIpResolved = true; - } - - if (!destinationIpResolved) - { - ConversionIncidentType = ConversionIncidentType.ManualActionRequired; - ConversionIncidentMessage = "Cannot resolve route destination IP address (" + command.GetParam(2) + "). Using IP 1.1.1.1."; - Console.WriteLine(ConversionIncidentMessage); - - DestinationIp = "1.1.1.1"; - DestinationNetmask = "255.255.255.255"; - } - - if (!NetworkUtils.IsValidIp(DestinationIp)) - { - ConversionIncidentType = ConversionIncidentType.ManualActionRequired; - ConversionIncidentMessage = "Invalid IP address (" + DestinationIp + "). Using IP 1.1.1.1."; - Console.WriteLine(ConversionIncidentMessage); - - DestinationIp = "1.1.1.1"; - DestinationNetmask = "255.255.255.255"; - } - - if (DestinationIp == "0.0.0.0" && DestinationNetmask == "0.0.0.0") - { - DefaultRoute = true; - } - } - } - - public class Cisco_AntiSpoofing : CiscoCommand - { - public string InterfaceName { get; set; } - - public override string Name() { return "ip verify reverse-path interface"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - if (command.GetParam(1) == "verify" && command.GetParam(2) == "reverse-path" && command.GetParam(3) == "interface") - { - InterfaceName = command.GetParam(4); - } - } - } - - public class Cisco_SameSecurityTraffic : CiscoCommand - { - public enum InterfaceTrafficType { NA, Inter, Intra }; - - public InterfaceTrafficType TrafficType { get; set; } - - public override string Name() { return "same-security-traffic"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - if (command.GetParam(1) == "permit") - { - switch (command.GetParam(2)) - { - case "inter-interface": - TrafficType = InterfaceTrafficType.Inter; - break; - - case "intra-interface": - TrafficType = InterfaceTrafficType.Intra; - break; - } - } - } - } - - public class Cisco_Nat : CiscoCommand - { - public bool Inactive { get; set; } - public string RealInterface { get; set; } - public string MappedInterface { get; set; } - public bool IsStatic { get; set; } - public bool IsHideBehindInterface { get; set; } - public bool IsUnidirectional { get; set; } - public bool IsAutoAfter { get; set; } - public string StaticNatIpAddressOrObjectName { get; set; } - public string DynamicNatIpAddressOrObjectName { get; set; } - public string SourceId { get; set; } - public string TranslatedSourceId { get; set; } - public string DestinationId { get; set; } - public string TranslatedDestinationId { get; set; } - public string ServiceProtocol { get; set; } - public string ServiceId { get; set; } - public string TranslatedServiceId { get; set; } - - public override string Name() { return "nat"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - /************************************************************************************** - * There are two types of NAT: - * 1. Object NAT - child object of a Network Object - this is the commonly used NAT - * 2. Regular NAT - twice or manual NAT rule - more scalable, enables extra features over Object NAT - * - * Each of these two types may be Static or Dynamic. - * Static NAT allows bidirectional traffic (mirrored rules). - * - * Each NAT command is started as follows: - * --------------------------------------- - * nat [(real_interface, mapped_interface)] ... - * - **************************************************************************************/ - - base.Parse(command, prevCommand, ciscoIds, aliases); - - string param = command.GetParam(1).Trim(new char[] { '(', ')' }); - string[] interfaces = param.Split(','); - - if (interfaces.Length > 0) - { - RealInterface = interfaces[0]; - MappedInterface = (interfaces.Length > 1) ? interfaces[1] : ""; - } - else - { - RealInterface = ""; - MappedInterface = ""; - } - - Inactive = false; - IsStatic = false; - IsHideBehindInterface = false; - IsUnidirectional = false; - StaticNatIpAddressOrObjectName = ""; - DynamicNatIpAddressOrObjectName = ""; - SourceId = ""; - TranslatedSourceId = ""; - DestinationId = ""; - TranslatedDestinationId = ""; - ServiceProtocol = ""; - ServiceId = ""; - TranslatedServiceId = ""; - - if (command.IndentationLevel > 0) - { - ParseObjectNatCommand(command, prevCommand, ciscoIds); - } - else - { - ParseRegularNatCommand(command, prevCommand, ciscoIds); - } - - if (command.GetParamPosition("unidirectional") > 0/* || command.GetParamPosition("no-proxy-arp") > 0*/) // commented due to A.R. suggestion... - { - IsUnidirectional = true; - } - - if (command.GetParamPosition("inactive") > 0) - { - Inactive = true; - } - } - - private void ParseObjectNatCommand(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds) - { - /******************************************************** - * Parsing options for Object NAT: - * ------------------------------- - * ... static {mapped_host_ip_address | mapped_object_name | interface} [service {tcp | udp} real_port mapped_port] - * - * ... dynamic {mapped_host_ip_address | mapped_object_name | interface} - * - * + mapped_object may be a host or network or range - */ - - switch (command.GetParam(2)) - { - case "static": - IsStatic = true; - - if (command.GetParam(3) == "interface") - { - IsHideBehindInterface = true; // Static NAT with port-translation - } - else - { - // static hide behind an arbitrary ip/network - StaticNatIpAddressOrObjectName = command.GetParam(3); - } - - int servicePos = command.GetParamPosition("service"); - if (servicePos > 0) - { - ServiceProtocol = command.GetParam(servicePos + 1); - if (ServiceProtocol == "tcp" || ServiceProtocol == "udp") - { - ServiceId = CiscoKnownServices.ConvertServiceToPort(command.GetParam(servicePos + 2)); - TranslatedServiceId = CiscoKnownServices.ConvertServiceToPort(command.GetParam(servicePos + 3)); - } - else - { - ServiceProtocol = ""; - - ConversionIncidentType = ConversionIncidentType.ManualActionRequired; - ConversionIncidentMessage = "Unrecognized service protocol (" + ServiceProtocol + ")"; - Console.WriteLine(ConversionIncidentMessage); - } - } - break; - - case "dynamic": - if (command.GetParam(3) == "interface") - { - IsHideBehindInterface = true; - } - else - { - // dynamic hide behind an arbitrary ip/network - DynamicNatIpAddressOrObjectName = command.GetParam(3); - } - - // Check for interface fall-back configuration - if (command.GetParam(4) == "interface") - { - ConversionIncidentType = ConversionIncidentType.Informative; - ConversionIncidentMessage = "Interface fall-back for dynamic object NAT is not supported"; - Console.WriteLine(ConversionIncidentMessage); - } - break; - } - } - - private void ParseRegularNatCommand(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds) - { - /******************************************************** - * Parsing options for regular (manual or twice) NAT: - * -------------------------------------------------- - * ... [after-object] source static real_object_name [mapped_object_name | interface] [destination static mapped_object_name real_object_name] [service real_service_name mapped_service_name] - * - * ... [after-auto] source dynamic {real_object_name | any} {mapped_object_name | interface} [destination static mapped_object_name real_object_name] [service mapped_service_name real_service_name] - * - * + real_object/mapped_object may be a host or network - */ - - int sourcePos = 2; - - if (command.GetParam(2) == "after-auto" || command.GetParam(2) == "after-object") - { - IsAutoAfter = true; - sourcePos = 3; - } - - if (command.GetParam(sourcePos) == "source") - { - if (command.GetParam(sourcePos + 1) == "static") - { - IsStatic = true; - } - - SourceId = command.GetParam(sourcePos + 2); - TranslatedSourceId = command.GetParam(sourcePos + 3); - if (TranslatedSourceId == "interface") - { - IsHideBehindInterface = true; - } - - int destPos = command.GetParamPosition("destination"); - if (destPos > 0) // twice-NAT - { - // check sanity - if (command.GetParam(destPos + 1) != "static") - { - ConversionIncidentType = ConversionIncidentType.Informative; - ConversionIncidentMessage = "Not handling NAT with dynamic destination"; - Console.WriteLine(ConversionIncidentMessage); - return; - } - - DestinationId = command.GetParam(destPos + 2); - TranslatedDestinationId = command.GetParam(destPos + 3); - } - - int servicePos = command.GetParamPosition("service"); - if (servicePos > 0) - { - ServiceId = command.GetParam(servicePos + 1); - TranslatedServiceId = command.GetParam(servicePos + 2); - } - } - else - { - ConversionIncidentType = ConversionIncidentType.Informative; - ConversionIncidentMessage = "Not handling NAT with dynamic source"; - Console.WriteLine(ConversionIncidentMessage); - } - } - } - - public class Cisco_AccessGroup : CiscoCommand - { - public enum DirectionType { Inbound, Outbound, Global }; - - public DirectionType Direction { get; set; } - public string AccessListName { get; set; } - public string InterfaceName { get; set; } - - public override string Name() { return "access-group"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - // Parsing Options: - //----------------- - // access-group access_list_name {{in | out} interface interface_name | global} - //----------------- - - base.Parse(command, prevCommand, ciscoIds, aliases); - - AccessListName = command.GetParam(1); - InterfaceName = (command.GetParam(3) == "interface") ? command.GetParam(4) : ""; - - switch (command.GetParam(2)) - { - case "in": - Direction = DirectionType.Inbound; - break; - - case "out": - Direction = DirectionType.Outbound; - break; - - case "global": - Direction = DirectionType.Global; - break; - - default: - Console.WriteLine("Error: unknown access-group traffic direction (" + command.GetParam(2) + ")."); - break; - } - - if (Direction != DirectionType.Inbound && Direction != DirectionType.Global) - { - ConversionIncidentType = ConversionIncidentType.Informative; - ConversionIncidentMessage = "Outbound ACLs will not be converted"; - Console.WriteLine(ConversionIncidentMessage); - } - } - } - - public class Cisco_AccessList : CiscoCommand - { - public enum ActionType { NA, Deny, Permit }; - - public class SourceDest - { - public enum SourceDestType { NA, Any, Any6, ReferenceObject, Host, SubnetAndMask }; - - public SourceDestType Type { get; set; } - public string HostIp { get; set; } - public string Subnet { get; set; } - public string Netmask { get; set; } - public string RefObjectName { get; set; } - public int WordsCount { get; set; } - - public SourceDest() - { - Type = SourceDestType.NA; - HostIp = ""; - Subnet = ""; - Netmask = ""; - RefObjectName = ""; - WordsCount = -1; - } - - public SourceDest(List words) : this() - { - if (!words.Any()) - { - WordsCount = 0; - return; - } - - switch (words[0]) - { - case "any": - case "any4": - Type = SourceDestType.Any; - WordsCount = 1; - break; - - case "any6": - Type = SourceDestType.Any6; - WordsCount = 1; - break; - - case "host": - Type = SourceDestType.Host; - if (words.Count > 1) - { - HostIp = words[1]; - WordsCount = 2; - } - break; - - case "object-group": - case "object": - Type = SourceDestType.ReferenceObject; - if (words.Count > 1) - { - RefObjectName = words[1]; - WordsCount = 2; - } - break; - - case "interface": - Type = SourceDestType.ReferenceObject; - if (words.Count > 1) - { - RefObjectName = InterfacePrefix + words[1]; - WordsCount = 2; - } - break; - - default: - // both the ip_address and ip_mask are specified - Type = SourceDestType.SubnetAndMask; - if (words.Count > 1) - { - Subnet = words[0]; - Netmask = words[1]; - WordsCount = 2; - } - break; - } - } - } - - public class ProtocolProperties - { - private Dictionary _ciscoIds; - - public ProtocolType Protocol { get; set; } - public TcpUdpPortOperatorType TcpUdpPortOperator { get; set; } - public ServiceDirection Where { get; set; } - public string TcpUdpPortValue { get; set; } - public int WordsCount { get; set; } - - public ProtocolProperties() - { - Protocol = ProtocolType.NA; - TcpUdpPortOperator = TcpUdpPortOperatorType.NA; - Where = ServiceDirection.Destination; - TcpUdpPortValue = ""; - WordsCount = -1; - } - - public ProtocolProperties(ProtocolType protocol, List words, Dictionary ciscoIds, ServiceDirection where) : this() - { - _ciscoIds = ciscoIds; - Protocol = protocol; - Where = where; - WordsCount = 0; - - if (protocol == ProtocolType.Ip || - protocol == ProtocolType.Tcp || - protocol == ProtocolType.Udp || - protocol == ProtocolType.ReferenceObject) - { - TcpUdpPortOperator = TcpUdpPortOperatorType.All; - - if (words.Count > 0) - { - switch (words[0]) - { - case "range": - TcpUdpPortOperator = TcpUdpPortOperatorType.Range; - if (words.Count > 2) - { - TcpUdpPortValue = CiscoKnownServices.ConvertServiceToPort(words[1]) + "-" + - CiscoKnownServices.ConvertServiceToPort(words[2]); - WordsCount = 3; - } - break; - - case "lt": - TcpUdpPortOperator = TcpUdpPortOperatorType.Lt; - if (words.Count > 1) - { - TcpUdpPortValue = CiscoKnownServices.ConvertServiceToPort(words[1]); - WordsCount = 2; - } - break; - - case "gt": - TcpUdpPortOperator = TcpUdpPortOperatorType.Gt; - if (words.Count > 1) - { - TcpUdpPortValue = CiscoKnownServices.ConvertServiceToPort(words[1]); - WordsCount = 2; - } - break; - - case "eq": - TcpUdpPortOperator = TcpUdpPortOperatorType.Eq; - if (words.Count > 1) - { - TcpUdpPortValue = CiscoKnownServices.ConvertServiceToPort(words[1]); - WordsCount = 2; - } - break; - - case "neq": - TcpUdpPortOperator = TcpUdpPortOperatorType.Neq; - if (words.Count > 1) - { - TcpUdpPortValue = CiscoKnownServices.ConvertServiceToPort(words[1]); - WordsCount = 2; - } - break; - - - case "object": - if (words.Count > 1 && IsServiceObject(words[1])) - { - TcpUdpPortOperator = TcpUdpPortOperatorType.ReferenceObject; - TcpUdpPortValue = words[1]; - WordsCount = 2; - } - break; - - case "object-group": - if (words.Count > 1 && IsServiceGroup(words[1])) - { - TcpUdpPortOperator = TcpUdpPortOperatorType.ReferenceObject; - TcpUdpPortValue = words[1]; - WordsCount = 2; - } - break; - } - } - } - else if (protocol == ProtocolType.Icmp) - { - if (words.Count > 0) - { - switch (words[0]) - { - case "object-group": - if (words.Count > 1 && IsServiceGroup(words[1])) - { - TcpUdpPortOperator = TcpUdpPortOperatorType.ReferenceObject; - TcpUdpPortValue = words[1]; - WordsCount = 2; - } - break; - - default: - if (CiscoKnownServices.IsKnownIcmpService(words[0])) - { - TcpUdpPortOperator = TcpUdpPortOperatorType.Eq; - TcpUdpPortValue = CiscoKnownServices.ConvertIcmpServiceToType(words[0]); - WordsCount = 1; - } - break; - } - } - } - else if (protocol == ProtocolType.KnownOtherIpProtocol) - { - } - } - - private bool IsServiceGroup(string name) - { - if (_ciscoIds.ContainsKey(name) && _ciscoIds[name].Name() == "object-group") - { - var group = (Cisco_GroupObject)_ciscoIds[name]; - if (group.GroupType == Cisco_GroupObject.Group_Type.Service || group.GroupType == Cisco_GroupObject.Group_Type.Icmp) - { - return true; - } - } - - return false; - } - - private bool IsServiceObject(string name) - { - if (_ciscoIds.ContainsKey(name) && _ciscoIds[name].Name() == "object") - { - var obj = (Cisco_Object)_ciscoIds[name]; - if (obj.ObjectType == Cisco_Object.ObjectTypes.TcpService || - obj.ObjectType == Cisco_Object.ObjectTypes.UdpService || - obj.ObjectType == Cisco_Object.ObjectTypes.IcmpService) - { - return true; - } - } - - return false; - } - } - - public string ACLName { get; set; } - public bool Inactive { get; set; } - public ActionType Action { get; set; } - public ProtocolType Protocol { get; set; } - public string ProtocolReference { get; set; } - public string Remark { get; set; } - public bool IsRemark { get; set; } - public bool IsTimeRangeSpecified { get; set; } - public string TimeRangeName { get; set; } - public SourceDest Source { get; set; } - public SourceDest Destination { get; set; } - public ProtocolProperties SourceProperties { get; set; } - public ProtocolProperties DestinationProperties { get; set; } - - public override string Name() { return "access-list"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - /* - * OPTION I - REMARK format - the easiest option: - * - access-list access_list_name remark text - Example: - hostname(config)# access-list ACL_OUT remark - this is the inside admin address - * - * OPTION II - STANDARD format - used for a limited number of features, such as route maps or VPN filters. - * uses IPv4 addresses only, and defines destination addresses only. - * - access-list access_list_name standard {deny | permit} {any/any4 | host ip_address | ip_address ip_mask} - Example: - hostname(config)# access-list OSPF standard permit 192.168.1.0 255.255.255.0 - * - * OPTION III.I - EXTENDED format - for ICMP based traffic matching - * - access-list access_list_name extended {deny | permit} icmp source_address_argument dest_address_argument [icmp_argument] [time-range time_range_name] [inactive] - Example: - hostname(config)# access-list ACL_IN extended permit icmp any any echo - * - * OPTION III.II - EXTENDED format - for TCP and UDP based traffic matching, with ports - * - access-list access_list_name extended {deny | permit} {tcp | udp} source_address_argument [port_argument] dest_address_argument [port_argument] [time-range time_range_name] [inactive] - Example: - hostname(config)# access-list ACL_IN extended deny tcp any host 209.165.201.29 eq www - hostname(config)# access-list ACL_IN extended deny tcp 192.168.1.0 255.255.255.0 209.165.201.0 255.255.255.224 - * - * OPTION III.III - EXTENDED format - for general IP address and FQDN based matching - * - access-list access_list_name extended {deny | permit} protocol_argument source_address_argument dest_address_argument [time-range time_range_name] [inactive] - Example: - hostname(config)# access-list ACL_IN extended permit ip any any - * - * ********************** - * ACL COMMAND ARGUMENTS: - * - * protocol_argument specification: one of the following options: - * -------------------------------------------------------------- - * protocol_name/protocol_number - * object service_object_id --> may be also a icmp service object - * object-group service_group_id - * object-group protocol_group_id - * - * source_address_argument/dest_address_argument specification: one of the following options: - * ------------------------------------------------------------------------------------------ - * any/any4/any6 - * host ip_address - * interface interface_name - * object network_object_id - * object-group network_group_id - * ip_address ip_mask - * - * icmp_argument specification: one of the following options: - * ---------------------------------------------------------- - * icmp_type - * object-group icmp_group_id --> object-group icmp-type command - * - * port_argument specification: one of the following options: - * ---------------------------------------------------------- - * operator port --> where operator can be one of: lt, gt, eq, neq, range; port can be number or name of a TCP or UDP port - * object-group service_group_id - * - */ - - base.Parse(command, prevCommand, ciscoIds, aliases); - - ACLName = command.GetParam(1); - Inactive = false; - Action = ActionType.NA; - Protocol = ProtocolType.NA; - ProtocolReference = ""; - Remark = ""; - IsRemark = false; - IsTimeRangeSpecified = false; - - var prevAclCommand = prevCommand as Cisco_AccessList; - - if (command.GetParam(2) == "remark") - { - IsRemark = true; - - // Note that there may be several consecutive remark lines, so we need to aggregate to a single remark - string dataForNextElement = ""; - if (prevAclCommand != null && prevAclCommand.IsRemark && !string.IsNullOrEmpty(prevAclCommand.DataForNextElement)) - { - dataForNextElement = prevAclCommand.DataForNextElement; - } - - string text = command.Text.Trim(); - int offset = text.IndexOf("remark") + 7; - - if (!string.IsNullOrEmpty(dataForNextElement)) - { - dataForNextElement += ", "; - } - - dataForNextElement += text.Substring(offset).Trim(); - DataForNextElement = dataForNextElement; - - return; - } - - if (prevAclCommand != null && ACLName.Equals(prevAclCommand.ACLName) && !string.IsNullOrEmpty(prevAclCommand.DataForNextElement)) - { - Remark = prevAclCommand.DataForNextElement; - - if (CiscoParser.SpreadAclRemarks) - { - DataForNextElement = Remark; - } - } - - int denyPosition = command.GetParamPosition("deny"); - int permitPosition = command.GetParamPosition("permit"); - int protocolPosition = Math.Max(denyPosition, permitPosition) + 1; // protocol field should follow the action field (either deny or permit) - int sourcePosition = protocolPosition + 1; - - if (denyPosition > 0) - { - Action = ActionType.Deny; - } - - if (permitPosition > 0) - { - Action = ActionType.Permit; - } - - if (command.GetParam(2) == "standard") - { - Protocol = ProtocolType.Ip; - - Source = new SourceDest - { - Type = SourceDest.SourceDestType.Any - }; - - SourceProperties = new ProtocolProperties - { - Protocol = Protocol, - TcpUdpPortOperator = TcpUdpPortOperatorType.All - }; - - Destination = new SourceDest(command.GetParams(4)); - - DestinationProperties = new ProtocolProperties - { - Protocol = Protocol, - TcpUdpPortOperator = TcpUdpPortOperatorType.All - }; - - return; - } - - if (command.GetParamPosition("time-range") > 0) - { - IsTimeRangeSpecified = true; - int indexTimeRange = command.GetParamPosition("time-range"); - TimeRangeName = command.GetParam(indexTimeRange + 1); - } - - if (command.GetParamPosition("inactive") > 0) - { - Inactive = true; - } - - string strProtocol = command.GetParam(protocolPosition); - switch (strProtocol) - { - case "ip": - Protocol = ProtocolType.Ip; - break; - - case "icmp": - case "icmp6": - Protocol = ProtocolType.Icmp; - break; - - case "udp": - Protocol = ProtocolType.Udp; - break; - - case "tcp": - Protocol = ProtocolType.Tcp; - break; - - case "object-group": - case "object": - Protocol = ProtocolType.ReferenceObject; - ProtocolReference = command.GetParam(protocolPosition + 1); - sourcePosition++; - break; - - default: - string serviceName; - if (CiscoKnownServices.IsKnownService(strProtocol)) - { - Protocol = ProtocolType.KnownOtherIpProtocol; - } - else if (CiscoKnownServices.IsKnownServiceNumber(strProtocol, out serviceName)) // protocol number is used!!! - { - Protocol = ProtocolType.KnownOtherIpProtocol; - strProtocol = serviceName; - } - else - { - ProtocolReference = strProtocol; - ConversionIncidentType = ConversionIncidentType.ManualActionRequired; - ConversionIncidentMessage = "Unrecognized service protocol (" + strProtocol + ")"; - Console.WriteLine(ConversionIncidentMessage); - } - break; - } - - Source = new SourceDest(command.GetParams(sourcePosition)); - SourceProperties = new ProtocolProperties(Protocol, command.GetParams(sourcePosition + Source.WordsCount), ciscoIds, ServiceDirection.Source); - Destination = new SourceDest(command.GetParams(sourcePosition + Source.WordsCount + SourceProperties.WordsCount)); - DestinationProperties = new ProtocolProperties(Protocol, command.GetParams(sourcePosition + Source.WordsCount + SourceProperties.WordsCount + Destination.WordsCount), ciscoIds, ServiceDirection.Destination); - - if (Protocol == ProtocolType.KnownOtherIpProtocol) - { - // This information is needed in order to create/query appropriate service objects - DestinationProperties.TcpUdpPortValue = strProtocol; - DestinationProperties.WordsCount = 1; - } - } - } - - public class Cisco_ClassMap : CiscoCommand - { - public string ClassMapName; - public List MatchedAclNames = new List(); - - public override string Name() { return "class-map"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - base.Parse(command, prevCommand, ciscoIds, aliases); - - ClassMapName = command.GetParam(1); - - if (command.Children == null) - { - return; - } - - foreach (CiscoCommand child in command.Children) - { - if (child.Name() == "match" && !string.IsNullOrEmpty(((Cisco_Match_AccessList)child).AccessListName)) - { - MatchedAclNames.Add(((Cisco_Match_AccessList)child).AccessListName); - } - } - } - } - - public class Cisco_Match_AccessList : CiscoCommand - { - public string AccessListName { get; set; } - - public override string Name() { return "match"; } - - public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) - { - // Parsing Options: - //----------------- - // match access-list access_list_name - //----------------- - - base.Parse(command, prevCommand, ciscoIds, aliases); - - AccessListName = (command.GetParam(1) == "access-list") ? command.GetParam(2) : ""; - } - } -} +/******************************************************************** +Copyright (c) 2017, Check Point Software Technologies Ltd. +All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +********************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using CommonUtils; + +namespace CiscoMigration +{ + public enum ProtocolType { NA, Ip, Icmp, Udp, Tcp, KnownOtherIpProtocol, ReferenceObject }; + public enum TcpUdpPortOperatorType { NA, All, Lt, Gt, Eq, Neq, Range, ReferenceObject }; + public enum ServiceDirection { Source, Destination }; + + public interface ICiscoCommand + { + string Name(); + void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases); + } + + /// + /// Represents a basic Cisco command. + /// Each derived command auto-parses the appropriate configuration line text according to its "name" (via reflection mechanism). + /// Some commands may have child commands (network group commad has child network object commands). + /// The "Id" property is the configuration line number. + /// The "ParentId" property is the parent configuration line number. + /// The "CiscoId" property is the user defined name of the command. + /// + public class CiscoCommand : ICiscoCommand + { + public const string InterfacePrefix = "Interface_"; + public const string Any = "any"; + + private string _text = ""; + private string[] _words; + + public string Text + { + get { return _text; } + set + { + _text = value; + + string trimmedText = _text.Trim(); + char[] delimiterChars = { ' ', '\t' }; + + // Replace multiple spaces with a single space + trimmedText = Regex.Replace(trimmedText, @"\s+", " "); + + _words = trimmedText.Split(delimiterChars); + } + } + + public int IndentationLevel + { + get + { + if (Text.Length == 0) + { + return 0; + } + + int pos = 0; + while (Text.Substring(pos, 1) == " ") + { + pos++; + } + return pos; + } + } + + public string FirstWord + { + get + { + if (_words != null && _words.Any()) + { + // This is a special handling!!! + // There are several commands that have the first word "ip"... + if (_words[0] == "ip") + { + if (_words.Count() > 1 && _words[1] == "address") + { + return _words[0] + " " + _words[1]; + } + if (_words.Count() > 3 && _words[1] == "verify" && _words[2] == "reverse-path" && _words[3] == "interface") + { + return _words[0] + " " + _words[1] + " " + _words[2] + " " + _words[3]; + } + } + else + { + return _words[0]; + } + } + + return ""; + } + } + + public int Id { get; set; } + public int? ParentId { get; set; } + public string CiscoId { get; set; } + public string Description { get; set; } + public string Tag { get; set; } + public string DataForNextElement { get; set; } + public bool KnownCommand { get; set; } + public bool NotAnInterestingCommand { get; set; } + public ConversionIncidentType ConversionIncidentType { get; set; } + public string ConversionIncidentMessage { get; set; } + public List Children { get; set; } + + public CiscoCommand() + { + CiscoId = ""; + Description = ""; + DataForNextElement = ""; + } + + public string GetParam(int pos) + { + if (_words == null || _words.Length <= pos) + { + return ""; + } + + return _words[pos]; + } + + public List GetParams(int pos) + { + var res = new List(); + + if (_words == null || !_words.Any()) + { + return res; + } + + for (int i = 0; i < _words.Length; i++) + { + if (i >= pos) + { + res.Add(_words[i]); + } + } + + return res; + } + + public int GetParamPosition(string paramName) + { + if (_words == null || !_words.Any()) + { + return -1; + } + + int pos = 0; + foreach (string word in _words) + { + if (word == paramName) + { + return pos; + } + pos++; + } + + return -1; + } + + public List Flatten() + { + var res = new List(); + res.Add(this); + + if (Children != null) + { + foreach (CiscoCommand child in Children) + { + foreach (CiscoCommand flattenchild in child.Flatten()) + { + res.Add(flattenchild); + } + } + } + + return res; + } + + public virtual string Name() { return ""; } + + public virtual void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + if (command.Children != null) + { + foreach (CiscoCommand child in command.Children) + { + if (child.Name() == "description") + { + Description = child.Description; + } + } + } + + ConversionIncidentType = ConversionIncidentType.None; + ConversionIncidentMessage = ""; + } + } + + public class Cisco_Description : CiscoCommand + { + public Cisco_Description() + { + NotAnInterestingCommand = true; + } + + public override string Name() { return "description"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + if (!string.IsNullOrEmpty(command.Text)) + { + Description = command.Text.Trim().Substring(Name().Length + 1); + } + + } + } + + public class Cisco_ASA : CiscoCommand + { + public string Version { get; set; } + + public override string Name() { return "ASA"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + const string version = "version"; + if (!string.IsNullOrEmpty(command.Text) && command.GetParam(1).ToLower() == version) + { + Version = command.Text.Trim().Substring(Name().Length + version.Length + 2); + } + else + { + Version = ""; + } + } + } + + public class Cisco_Alias : CiscoCommand + { + public override string Name() { return "name"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + string real = command.GetParam(1); + string alias = command.GetParam(2); + + if (!string.IsNullOrEmpty(alias) && !string.IsNullOrEmpty(real) && !aliases.ContainsKey(alias)) + { + aliases.Add(alias, real); + } + } + } + + public class Cisco_SSH : CiscoCommand + { + public string IpAddress { get; set; } + public string Netmask { get; set; } + public string Interface { get; set; } + + public override string Name() { return "ssh"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + IpAddress = ""; + Netmask = ""; + Interface = ""; + + string commandParam = command.GetParam(1); + if (NetworkUtils.IsValidIp(commandParam)) + { + IpAddress = commandParam; + } + else + { + ConversionIncidentType = ConversionIncidentType.Informative; + ConversionIncidentMessage = "IPv4 address was expected, but '" + commandParam + "' was found."; + return; + } + + commandParam = command.GetParam(2); + if (NetworkUtils.IsValidNetmaskv4(commandParam)) + { + Netmask = commandParam; + } + else + { + IpAddress = ""; + ConversionIncidentType = ConversionIncidentType.Informative; + ConversionIncidentMessage = "IPv4 netmask was expected, but " + commandParam + " was found."; + return; + } + + Interface = command.GetParam(3); + } + } + + public class Cisco_Hostname : CiscoCommand + { + public string HostName { get; set; } + + public override string Name() { return "hostname"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + HostName = command.GetParam(1); + } + } + + public class Cisco_Object : CiscoCommand + { + public enum ObjectTypes { NA, Fqdn, Host, Network, Range, TcpService, UdpService, IcmpService, KnownOtherService }; + + public ObjectTypes ObjectType { get; set; } + public string Fqdn { get; set; } + public string HostAddress { get; set; } + public string Network { get; set; } + public string Netmask { get; set; } + public string MaskPrefix { get; set; } + public string RangeFrom { get; set; } + public string RangeTo { get; set; } + public bool IsDestination { get; set; } + public string ServiceProtocol { get; set; } + public string ServiceOperator { set; get; } + public string ServicePort { get; set; } + + public override string Name() { return "object"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + CiscoId = command.GetParam(2); + ObjectType = ObjectTypes.NA; + + switch (command.GetParam(1)) + { + case "network": + ParseNetworks(); + break; + + case "service": + ParseServices(); + break; + + default: + ConversionIncidentType = ConversionIncidentType.Informative; + ConversionIncidentMessage = "Unrecognized object type (" + command.GetParam(1) + ")"; + break; + } + } + + private void ParseNetworks() + { + if (Children == null) + { + return; + } + + int found = 0; + + foreach (CiscoCommand child in Children) + { + switch (child.Name()) + { + case "fqdn": + ObjectType = ObjectTypes.Fqdn; + Fqdn = ((Cisco_Fqdn)child).Fqdn; + found++; + break; + + case "host": + ObjectType = ObjectTypes.Host; + HostAddress = ((Cisco_Host)child).HostAddress; + found++; + break; + + case "subnet": + ObjectType = ObjectTypes.Network; + Network = ((Cisco_Subnet)child).Network; + Netmask = ((Cisco_Subnet)child).Netmask; + MaskPrefix = ((Cisco_Subnet)child).MaskPrefix; + found++; + break; + + case "range": + ObjectType = ObjectTypes.Range; + RangeFrom = ((Cisco_Range)child).RangeFrom; + RangeTo = ((Cisco_Range)child).RangeTo; + found++; + break; + } + + if (found == 1) + { + if (child.ConversionIncidentType != ConversionIncidentType.None) + { + ConversionIncidentType = child.ConversionIncidentType; + ConversionIncidentMessage = child.ConversionIncidentMessage; + } + } + } + + if (found > 1) + { + ConversionIncidentType = ConversionIncidentType.Informative; + ConversionIncidentMessage = "An Object (network) can only hold one fqdn, host, range or subnet"; + Console.WriteLine(ConversionIncidentMessage); + } + } + + private void ParseServices() + { + if (Children == null) + { + return; + } + + int found = 0; + + foreach (CiscoCommand child in Children) + { + if (child.Name() == "service") + { + found++; + + var service = (Cisco_Service)child; + ServiceProtocol = service.Protocol; + ServiceOperator = service.Operator; + ServicePort = service.Port; + IsDestination = service.IsDestination; + + if (service.ConversionIncidentType != ConversionIncidentType.None) + { + ConversionIncidentType = service.ConversionIncidentType; + ConversionIncidentMessage = service.ConversionIncidentMessage; + } + + switch (ServiceProtocol) + { + case "ip": + // Predefined "any" object. No special handling... + break; + + case "icmp": + ObjectType = ObjectTypes.IcmpService; + break; + + case "tcp": + ObjectType = ObjectTypes.TcpService; + break; + + case "udp": + ObjectType = ObjectTypes.UdpService; + break; + + default: + // No need to check also for CiscoKnownServices.IsKnownServiceNumber here, + // because it is already done in Cisco_Service class!!! + if (CiscoKnownServices.IsKnownService(ServiceProtocol)) + { + ObjectType = ObjectTypes.KnownOtherService; + } + else + { + ConversionIncidentType = ConversionIncidentType.ManualActionRequired; + ConversionIncidentMessage = "Unrecognized service protocol (" + ServiceProtocol + ")"; + Console.WriteLine(ConversionIncidentMessage); + } + break; + } + } + } + + if (found > 1) + { + ConversionIncidentType = ConversionIncidentType.Informative; + ConversionIncidentMessage = "An Object (service) can only hold one service"; + Console.WriteLine(ConversionIncidentMessage); + } + } + } + + public class Cisco_Fqdn : CiscoCommand + { + public string Fqdn { get; set; } + + public override string Name() { return "fqdn"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + Fqdn = (command.GetParam(1) == "v4") ? command.GetParam(2) : command.GetParam(1); + } + } + + public class Cisco_Host : CiscoCommand + { + public string HostAddress { get; set; } + + public override string Name() { return "host"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + HostAddress = command.GetParam(1); + if (!NetworkUtils.IsValidIp(HostAddress)) + { + ConversionIncidentType = ConversionIncidentType.ManualActionRequired; + ConversionIncidentMessage = "Invalid host IP address (" + HostAddress + "). Using IP 1.1.1.1."; + Console.WriteLine(ConversionIncidentMessage); + + HostAddress = "1.1.1.1"; + } + } + } + + public class Cisco_Subnet : CiscoCommand + { + public string Network { get; set; } + public string Netmask { get; set; } + public string MaskPrefix { get; set; } + + public override string Name() { return "subnet"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + Network = command.GetParam(1); + Netmask = command.GetParam(2); + if (NetworkUtils.TryParseNetwortWithPrefix(Network, out string sNetwork, out string sMaskLength)) + { + Network = sNetwork; + MaskPrefix = sMaskLength; + } + else if (!NetworkUtils.IsValidIpv4(Network) || !NetworkUtils.IsValidNetmaskv4(Netmask)) + { + ConversionIncidentType = ConversionIncidentType.ManualActionRequired; + ConversionIncidentMessage = "Invalid IP subnet (" + Network + "/" + Netmask + "). Using IP subnet 1.1.1.0/255.255.255.0."; + Console.WriteLine(ConversionIncidentMessage); + + Network = "1.1.1.0"; + Netmask = "255.255.255.0"; + } + } + } + + public class Cisco_Range : CiscoCommand + { + public string RangeFrom { get; set; } + public string RangeTo { get; set; } + + public override string Name() { return "range"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + RangeFrom = command.GetParam(1); + if (!NetworkUtils.IsValidIp(RangeFrom)) + { + ConversionIncidentType = ConversionIncidentType.ManualActionRequired; + ConversionIncidentMessage = "Invalid range starting IP address (" + RangeFrom + "). Using IP 0.0.0.0."; + Console.WriteLine(ConversionIncidentMessage); + + RangeFrom = "0.0.0.0"; + } + + RangeTo = command.GetParam(2); + if (!NetworkUtils.IsValidIp(RangeTo)) + { + ConversionIncidentType = ConversionIncidentType.ManualActionRequired; + ConversionIncidentMessage = "Invalid range ending IP address (" + RangeTo + "). Using IP 255.255.255.255."; + Console.WriteLine(ConversionIncidentMessage); + + RangeTo = "255.255.255.255"; + } + } + } + + public class Cisco_Service : CiscoCommand + { + public string Protocol { get; set; } + public bool IsDestination { get; set; } + public string Port { get; set; } + public string Operator { get; set; } + + public override string Name() { return "service"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + // Parsing Options: + //----------------- + // 1. service protocol_name_or_number + // 2. service {icmp | icmp6} [icmp-type] + // 3. service {tcp | udp} [source operator port] [destination operator port] + //----------------- + + Protocol = command.GetParam(1); + + IsDestination = false; + Port = ""; + Operator = ""; + + switch (Protocol) + { + case "ip": + IsDestination = true; + break; + + case "icmp": + case "icmp6": + IsDestination = true; + Protocol = "icmp"; + Operator = "eq"; + Port = CiscoKnownServices.ConvertIcmpServiceToType(command.GetParam(2)); + break; + + case "tcp": + case "udp": + IsDestination = (command.GetParam(2) == "destination"); + Operator = command.GetParam(3); + Port = CiscoKnownServices.ConvertServiceToPort(command.GetParam(4)); + + int nextParamId = 5; // we need this because of 'range' operator + + if (Operator == "range") + { + Operator = "eq"; + Port = Port + "-" + CiscoKnownServices.ConvertServiceToPort(command.GetParam(5)); + nextParamId = 6; // !!! + } + + if (!IsDestination && command.GetParam(nextParamId) == "destination") + { + // "service tcp source eq ssh destination eq ssh" ---> wrong!!! ---> ignore source!!! + ConversionIncidentType = ConversionIncidentType.Informative; + ConversionIncidentMessage = "Cannot convert a service defined as both source service and destination service. Ignoring source service."; + Console.WriteLine(ConversionIncidentMessage); + + IsDestination = true; + Operator = command.GetParam(nextParamId + 1); + Port = CiscoKnownServices.ConvertServiceToPort(command.GetParam(nextParamId + 2)); + + if (Operator == "range") + { + Operator = "eq"; + Port = Port + "-" + CiscoKnownServices.ConvertServiceToPort(command.GetParam(nextParamId + 3)); + } + } + + if (string.IsNullOrEmpty(Operator) || string.IsNullOrEmpty(Port)) + { + // Use ALL tcp/udp ports if nothing specified!!! + IsDestination = true; + Operator = "all"; + Port = "1-65535"; + } + break; + + default: + IsDestination = true; + + string serviceName; + if (CiscoKnownServices.IsKnownService(Protocol)) + { + Port = CiscoKnownServices.ConvertServiceToPort(Protocol); + } + else if (CiscoKnownServices.IsKnownServiceNumber(Protocol, out serviceName)) // protocol number is used!!! + { + Port = Protocol; + Protocol = serviceName; + } + else + { + ConversionIncidentType = ConversionIncidentType.ManualActionRequired; + ConversionIncidentMessage = "Unrecognized service protocol (" + Protocol + ")"; + Console.WriteLine(ConversionIncidentMessage); + } + break; + } + } + } + + public class Cisco_NetworkObject : CiscoCommand + { + public string IpAddress { get; set; } + public string Netmask { get; set; } + public string MaskPrefix { get; set; } + public string ReferencedObject { get; set; } + + public override string Name() { return "network-object"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + IpAddress = ""; + Netmask = ""; + ReferencedObject = ""; + + switch (command.GetParam(1)) + { + case "object": + ReferencedObject = command.GetParam(2); + break; + + case "host": + string ipAddressOrObjectName = command.GetParam(2); + if (ciscoIds.ContainsKey(ipAddressOrObjectName)) + { + ReferencedObject = ipAddressOrObjectName; + } + else + { + IpAddress = aliases.ContainsKey(ipAddressOrObjectName) ? aliases[ipAddressOrObjectName] : ipAddressOrObjectName; + if (!NetworkUtils.IsValidIp(IpAddress)) + { + ConversionIncidentType = ConversionIncidentType.ManualActionRequired; + ConversionIncidentMessage = "Invalid IP address (" + IpAddress + "). Using IP 1.1.1.1."; + Console.WriteLine(ConversionIncidentMessage); + + IpAddress = "1.1.1.1"; + } + + Netmask = "255.255.255.255"; + } + break; + + default: + // subnet + IpAddress = command.GetParam(1); + if (aliases.ContainsKey((IpAddress))) + { + IpAddress = aliases[IpAddress]; + } + Netmask = command.GetParam(2); + + if (NetworkUtils.TryParseNetwortWithPrefix(IpAddress, out string sIp, out string sMaskLenth)) + { + IpAddress = sIp; + MaskPrefix = sMaskLenth; + } + else if (!NetworkUtils.IsValidIpv4(IpAddress) || !NetworkUtils.IsValidNetmaskv4(Netmask)) + { + ConversionIncidentType = ConversionIncidentType.ManualActionRequired; + ConversionIncidentMessage = "Invalid IP subnet (" + IpAddress + "/" + Netmask + "). Using IP subnet 1.1.1.0/255.255.255.0."; + Console.WriteLine(ConversionIncidentMessage); + + IpAddress = "1.1.1.0"; + Netmask = "255.255.255.0"; + } + break; + } + } + } + + public class Cisco_ProtocolObject : CiscoCommand + { + public string ProtocolName { get; set; } + + public override string Name() { return "protocol-object"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + ProtocolName = command.GetParam(1); + } + } + + public class Cisco_PortObject : CiscoCommand + { + public string Port { get; set; } + + public override string Name() { return "port-object"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + Port = ""; + + string portOperator = command.GetParam(1); + + switch (portOperator) + { + case "eq": + Port = CiscoKnownServices.ConvertServiceToPort(command.GetParam(2)); + break; + + case "range": + Port = CiscoKnownServices.ConvertServiceToPort(command.GetParam(2)) + "-" + CiscoKnownServices.ConvertServiceToPort(command.GetParam(3)); + break; + } + } + } + + public class Cisco_ServiceObject : CiscoCommand + { + public string Protocol { get; set; } + public bool IsDestination { get; set; } + public string Port { get; set; } + public string Operator { get; set; } + public string RefObjectName { get; set; } + + public override string Name() { return "service-object"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + // Parsing Options: + //----------------- + // 1. service-object object object_name + // 2. service-object protocol_name_or_number + // 3. service-object {icmp | icmp6} [icmp-type] + // 4. service-object {tcp | udp | tcp-udp} [source operator port] [destination operator port] + //----------------- + + Protocol = command.GetParam(1); + + IsDestination = false; + Port = ""; + Operator = ""; + RefObjectName = ""; + + switch (Protocol) + { + case "object": + RefObjectName = command.GetParam(2); + Protocol = ""; + break; + + case "ip": + IsDestination = true; + break; + + case "icmp": + case "icmp6": + IsDestination = true; + Protocol = "icmp"; + Operator = "eq"; + Port = CiscoKnownServices.ConvertIcmpServiceToType(command.GetParam(2)); + break; + + case "tcp": + case "udp": + case "tcp-udp": + IsDestination = (command.GetParam(2) == "destination"); + Operator = command.GetParam(3); + Port = CiscoKnownServices.ConvertServiceToPort(command.GetParam(4)); + + int nextParamId = 5; // we need this because of 'range' operator + + if (Operator == "range") + { + Operator = "eq"; + Port = Port + "-" + CiscoKnownServices.ConvertServiceToPort(command.GetParam(5)); + nextParamId = 6; // !!! + } + + if (!IsDestination && command.GetParam(nextParamId) == "destination") + { + // "service-object tcp source eq ssh destination eq ssh" ---> wrong!!! ---> ignore source!!! + ConversionIncidentType = ConversionIncidentType.Informative; + ConversionIncidentMessage = "Cannot convert a service defined as both source service and destination service. Ignoring source service."; + Console.WriteLine(ConversionIncidentMessage); + + IsDestination = true; + Operator = command.GetParam(nextParamId + 1); + Port = CiscoKnownServices.ConvertServiceToPort(command.GetParam(nextParamId + 2)); + + if (Operator == "range") + { + Operator = "eq"; + Port = Port + "-" + CiscoKnownServices.ConvertServiceToPort(command.GetParam(nextParamId + 3)); + } + } + + if (string.IsNullOrEmpty(Operator) || string.IsNullOrEmpty(Port)) + { + // Use ALL tcp/udp ports if nothing specified!!! + IsDestination = true; + Operator = "all"; + Port = "1-65535"; + } + break; + + default: + IsDestination = true; + + string serviceName; + if (CiscoKnownServices.IsKnownService(Protocol)) + { + Port = CiscoKnownServices.ConvertServiceToPort(Protocol); + } + else if (CiscoKnownServices.IsKnownServiceNumber(Protocol, out serviceName)) // protocol number is used!!! + { + Port = Protocol; + Protocol = serviceName; + } + else + { + ConversionIncidentType = ConversionIncidentType.ManualActionRequired; + ConversionIncidentMessage = "Unrecognized service protocol (" + Protocol + ")"; + Console.WriteLine(ConversionIncidentMessage); + } + break; + } + } + } + + public class Cisco_IcmpObject : CiscoCommand + { + public string IcmpType { get; set; } + + public override string Name() { return "icmp-object"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + IcmpType = command.GetParam(1); + } + } + + public class Cisco_ReferenceGroupObject : CiscoCommand + { + public string ReferenceId { get; set; } + + public override string Name() { return "group-object"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + ReferenceId = command.GetParam(1); + } + } + + public class Cisco_GroupObject : CiscoCommand + { + public enum Group_Type { NA, Service, Protocol, Icmp, Network }; + + private Dictionary _ciscoIds; + + public Group_Type GroupType { get; set; } + public string ServiceProtocol { get; set; } + + public List Protocols = new List(); + public List IcmpTypes = new List(); + public List MembersGroupNames = new List(); + public List MemberObjects = new List(); + + public override string Name() { return "object-group"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + _ciscoIds = ciscoIds; + + CiscoId = command.GetParam(2); + ServiceProtocol = ""; + + switch (command.GetParam(1)) + { + case "service": + GroupType = Group_Type.Service; + break; + + case "protocol": + GroupType = Group_Type.Protocol; + break; + + case "icmp-type": + GroupType = Group_Type.Icmp; + break; + + case "network": + GroupType = Group_Type.Network; + break; + + default: + GroupType = Group_Type.NA; + ConversionIncidentType = ConversionIncidentType.Informative; + ConversionIncidentMessage = "Unrecognized group type (" + command.GetParam(1) + ")"; + return; + } + + if (GroupType == Group_Type.Service) + { + ServiceProtocol = command.GetParam(3); + } + + if (command.Children == null) + { + return; + } + + foreach (CiscoCommand child in command.Children) + { + bool hasValidChild = true; + + switch (child.Name()) + { + case "protocol-object": + Protocols.Add(((Cisco_ProtocolObject)child).ProtocolName); + break; + + case "port-object": + MemberObjects.Add((Cisco_PortObject)child); + break; + + case "icmp-object": + IcmpTypes.Add(((Cisco_IcmpObject)child).IcmpType); + break; + + case "group-object": + MembersGroupNames.Add(((Cisco_ReferenceGroupObject)child).ReferenceId); + break; + + case "network-object": + MemberObjects.Add((Cisco_NetworkObject)child); + break; + + case "service-object": + MemberObjects.Add((Cisco_ServiceObject)child); + break; + + default: + hasValidChild = false; + break; + } + + if (hasValidChild) + { + if (child.ConversionIncidentType != ConversionIncidentType.None) + { + ConversionIncidentType = child.ConversionIncidentType; + ConversionIncidentMessage = child.ConversionIncidentMessage; + } + } + } + } + + public List GetChildServices() + { + var services = new List(); + + if (Children != null) + { + foreach (CiscoCommand child in Children) + { + if (child.Name() == "service-object") + { + services.Add((Cisco_ServiceObject)child); + } + else if (child.Name() == "group-object") + { + if (_ciscoIds.ContainsKey(((Cisco_ReferenceGroupObject)child).ReferenceId)) + { + var referencedGroupObject = (Cisco_GroupObject)_ciscoIds[((Cisco_ReferenceGroupObject)child).ReferenceId]; + var referencedGroupServices = referencedGroupObject.GetChildServices(); + + foreach (Cisco_ServiceObject referencedService in referencedGroupServices) + { + if (!services.Contains(referencedService)) + { + services.Add(referencedService); + } + } + } + } + } + } + + return services; + } + + public List GetChildPorts() + { + var ports = new List(); + + if (Children != null) + { + foreach (CiscoCommand child in Children) + { + if (child.Name() == "port-object") + { + ports.Add((Cisco_PortObject)child); + } + else if (child.Name() == "group-object") + { + if (_ciscoIds.ContainsKey(((Cisco_ReferenceGroupObject)child).ReferenceId)) + { + var referencedGroupObject = (Cisco_GroupObject)_ciscoIds[((Cisco_ReferenceGroupObject)child).ReferenceId]; + var referencedGroupPorts = referencedGroupObject.GetChildPorts(); + + foreach (Cisco_PortObject referencedPort in referencedGroupPorts) + { + if (!ports.Contains(referencedPort)) + { + ports.Add(referencedPort); + } + } + } + } + } + } + + return ports; + } + } + + public class Cisco_SecurityLevel : CiscoCommand + { + public string Value { get; set; } + + public override string Name() { return "security-level"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + Value = command.GetParam(1); + } + } + + public class Cisco_NameIf : CiscoCommand + { + public string Value { get; set; } + + public override string Name() { return "nameif"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + Value = InterfacePrefix + command.GetParam(1); + } + } + + public class Cisco_VLan : CiscoCommand + { + public string Value { get; set; } + + public override string Name() { return "vlan"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + Value = command.GetParam(1); + } + } + + public class Cisco_IP : CiscoCommand + { + public string IpAddress { get; set; } + public string Netmask { get; set; } + + public override string Name() { return "ip address"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + IpAddress = ""; + Netmask = ""; + + if (command.GetParam(1) == "address") + { + IpAddress = command.GetParam(2); + Netmask = command.GetParam(3); + } + } + } + + public class Cisco_Shutdown : CiscoCommand + { + public bool IsShutdown { get; set; } + + public override string Name() { return "shutdown"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + IsShutdown = (command.GetParam(0) == "shutdown"); + } + } + + public class Cisco_ManagementOnly : CiscoCommand + { + public bool IsManagementOnly { get; set; } + + public override string Name() { return "management-only"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + IsManagementOnly = (command.GetParam(0) == "management-only"); + } + } + + public class Cisco_TimeRange : CiscoCommand + { + public enum Weekdays { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }; + + private string _timeRangeName; + + private string _startDateTime; + private string _endDateTime; + + private List _periodicsList; + + public string TimeRangeName + { + get { return _timeRangeName; } + } + + public string StartDateTime + { + get { return _startDateTime; } + } + + public string EndDateTime + { + get { return _endDateTime; } + } + + public List PeriodicsList + { + get { return _periodicsList; } + } + + public override string Name() { return "time-range"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + _periodicsList = new List(); + + _timeRangeName = this.GetParam(1); + + foreach (CiscoCommand child in Children) + { + if (child.FirstWord.Equals("absolute")) + { + int startIndex = child.Text.IndexOf("start"); + int endIndex = child.Text.IndexOf("end"); + if (startIndex > -1 && endIndex > -1) + { + _startDateTime = child.Text.Substring("absolute".Length + "start".Length + 2, endIndex - startIndex - "start".Length).Trim(); + _endDateTime = child.Text.Substring(endIndex + "end".Length).Trim(); + } + else if (startIndex > -1 && endIndex == -1) + { + _startDateTime = child.Text.Substring("absolute".Length + "start".Length + 2).Trim(); + } + else if (startIndex == -1 && endIndex > -1) + { + _endDateTime = child.Text.Substring("absolute".Length + "end".Length + 2).Trim(); + } + } + + if (child.FirstWord.Equals("periodic")) + { + string period = child.Text.Substring("periodic".Length + 1).Trim(); + + string[] daysTimes = period.Trim().Split(new string[] { "to" }, StringSplitOptions.RemoveEmptyEntries); + + string[] daysTimes_1 = daysTimes[0].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); + string[] daysTimes_2 = daysTimes[1].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); + + if (daysTimes_1.Length == 2 && daysTimes_2.Length == 2) + { + int startWdIndex = (int)Enum.Parse(typeof(Weekdays), daysTimes_1[0]); + int endWdIndex = (int)Enum.Parse(typeof(Weekdays), daysTimes_2[0]); + + if (startWdIndex < endWdIndex) + { + _periodicsList.Add((Weekdays)startWdIndex + " " + daysTimes_1[1] + " to 23:59"); + + for (int i = startWdIndex + 1; i <= endWdIndex - 1; i++) + { + _periodicsList.Add((Weekdays)i + " 0:00 to 23:59"); + } + + _periodicsList.Add((Weekdays)endWdIndex + " 0:00 to " + daysTimes_2[1]); + } + else + { + int firstWdIndex = (int)Enum.GetValues(typeof(Weekdays)).Cast().First(); + int lastWdIndex = (int)Enum.GetValues(typeof(Weekdays)).Cast().Last(); + + _periodicsList.Add((Weekdays)startWdIndex + " " + daysTimes_1[1] + " to 23:59"); + + for (int i = startWdIndex + 1; i <= lastWdIndex; i++) + { + _periodicsList.Add((Weekdays)i + " 0:00 to 23:59"); + } + + for (int i = firstWdIndex; i <= endWdIndex - 1; i++) + { + _periodicsList.Add((Weekdays)i + " 0:00 to 23:59"); + } + + _periodicsList.Add((Weekdays)endWdIndex + " 0:00 to " + daysTimes_2[1]); + } + } + else + { + _periodicsList.Add(period); + } + } + } + } + } + + public class Cisco_Interface : CiscoCommand + { + public string InterfaceName { get; set; } + public int SecurityLevel { get; set; } + public string VLan { get; set; } + public string IpAddress { get; set; } + public string Netmask { get; set; } + public bool Shutdown { get; set; } + public bool ManagementOnly { get; set; } + public bool LeadsToInternet { get; set; } + + public class Subnet + { + public string Network { get; private set; } + public string Netmask { get; private set; } + + public Subnet(string sIp, string sMask) + { + Network = sIp; + Netmask = sMask; + } + } + + public List Topology = new List(); + + public override string Name() { return "interface"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + InterfaceName = command.GetParam(1); + SecurityLevel = 0; + VLan = ""; + IpAddress = ""; + Netmask = ""; + Shutdown = false; + ManagementOnly = false; + LeadsToInternet = false; + + if (command.Children == null) + { + return; + } + + foreach (CiscoCommand child in command.Children) + { + switch (child.Name()) + { + case "security-level": + int securityLevel; + if (int.TryParse(((Cisco_SecurityLevel)child).Value, out securityLevel)) + { + SecurityLevel = securityLevel; + } + break; + + case "nameif": + CiscoId = ((Cisco_NameIf)child).Value; + break; + + case "vlan": + VLan = ((Cisco_VLan)child).Value; + break; + + case "shutdown": + Shutdown = ((Cisco_Shutdown)child).IsShutdown; + break; + + case "management-only": + ManagementOnly = ((Cisco_ManagementOnly)child).IsManagementOnly; + break; + + case "ip address": + IpAddress = ((Cisco_IP)child).IpAddress; + Netmask = ((Cisco_IP)child).Netmask; + + if (NetworkUtils.IsValidIpv4(IpAddress) && NetworkUtils.IsValidNetmaskv4(Netmask)) + { + Topology.Add(new Subnet(NetworkUtils.GetNetwork(IpAddress, Netmask), Netmask)); + } + else + { + ConversionIncidentType = ConversionIncidentType.ManualActionRequired; + ConversionIncidentMessage = "Invalid IP subnet (" + IpAddress + "/" + Netmask + ")."; + Console.WriteLine(ConversionIncidentMessage); + } + break; + } + } + } + + public bool HasValidIpAddress() + { + return NetworkUtils.IsValidIp(IpAddress) && NetworkUtils.IsValidNetmaskv4(Netmask); + } + } + + public class Cisco_Route : CiscoCommand + { + public string InterfaceName { get; set; } + public bool DefaultRoute { get; set; } + public string DestinationIp { get; set; } + public string DestinationNetmask { get; set; } + public string Gateway { get; set; } + + public override string Name() { return "route"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + DefaultRoute = false; + InterfaceName = command.GetParam(1); + DestinationIp = command.GetParam(2); + DestinationNetmask = command.GetParam(3); + Gateway = command.GetParam(4); + + bool destinationIpResolved = false; + + if (ciscoIds.ContainsKey(DestinationIp)) + { + var refObj = (Cisco_Object)ciscoIds[DestinationIp]; + if (refObj != null) + { + switch (refObj.ObjectType) + { + case Cisco_Object.ObjectTypes.Host: + DestinationIp = refObj.HostAddress; + destinationIpResolved = true; + break; + + case Cisco_Object.ObjectTypes.Network: + DestinationIp = refObj.Network; + destinationIpResolved = true; + break; + } + } + } + else + { + DestinationIp = aliases.ContainsKey(DestinationIp) ? aliases[DestinationIp] : DestinationIp; + destinationIpResolved = true; + } + + if (!destinationIpResolved) + { + ConversionIncidentType = ConversionIncidentType.ManualActionRequired; + ConversionIncidentMessage = "Cannot resolve route destination IP address (" + command.GetParam(2) + "). Using IP 1.1.1.1."; + Console.WriteLine(ConversionIncidentMessage); + + DestinationIp = "1.1.1.1"; + DestinationNetmask = "255.255.255.255"; + } + + if (!NetworkUtils.IsValidIp(DestinationIp)) + { + ConversionIncidentType = ConversionIncidentType.ManualActionRequired; + ConversionIncidentMessage = "Invalid IP address (" + DestinationIp + "). Using IP 1.1.1.1."; + Console.WriteLine(ConversionIncidentMessage); + + DestinationIp = "1.1.1.1"; + DestinationNetmask = "255.255.255.255"; + } + + if (DestinationIp == "0.0.0.0" && DestinationNetmask == "0.0.0.0") + { + DefaultRoute = true; + } + } + } + + public class Cisco_AntiSpoofing : CiscoCommand + { + public string InterfaceName { get; set; } + + public override string Name() { return "ip verify reverse-path interface"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + if (command.GetParam(1) == "verify" && command.GetParam(2) == "reverse-path" && command.GetParam(3) == "interface") + { + InterfaceName = command.GetParam(4); + } + } + } + + public class Cisco_SameSecurityTraffic : CiscoCommand + { + public enum InterfaceTrafficType { NA, Inter, Intra }; + + public InterfaceTrafficType TrafficType { get; set; } + + public override string Name() { return "same-security-traffic"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + if (command.GetParam(1) == "permit") + { + switch (command.GetParam(2)) + { + case "inter-interface": + TrafficType = InterfaceTrafficType.Inter; + break; + + case "intra-interface": + TrafficType = InterfaceTrafficType.Intra; + break; + } + } + } + } + + public class Cisco_Nat : CiscoCommand + { + public bool Inactive { get; set; } + public string RealInterface { get; set; } + public string MappedInterface { get; set; } + public bool IsStatic { get; set; } + public bool IsHideBehindInterface { get; set; } + public bool IsUnidirectional { get; set; } + public bool IsAutoAfter { get; set; } + public string StaticNatIpAddressOrObjectName { get; set; } + public string DynamicNatIpAddressOrObjectName { get; set; } + public string SourceId { get; set; } + public string TranslatedSourceId { get; set; } + public string DestinationId { get; set; } + public string TranslatedDestinationId { get; set; } + public string ServiceProtocol { get; set; } + public string ServiceId { get; set; } + public string TranslatedServiceId { get; set; } + + public override string Name() { return "nat"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + /************************************************************************************** + * There are two types of NAT: + * 1. Object NAT - child object of a Network Object - this is the commonly used NAT + * 2. Regular NAT - twice or manual NAT rule - more scalable, enables extra features over Object NAT + * + * Each of these two types may be Static or Dynamic. + * Static NAT allows bidirectional traffic (mirrored rules). + * + * Each NAT command is started as follows: + * --------------------------------------- + * nat [(real_interface, mapped_interface)] ... + * + **************************************************************************************/ + + base.Parse(command, prevCommand, ciscoIds, aliases); + + string param = command.GetParam(1).Trim(new char[] { '(', ')' }); + string[] interfaces = param.Split(','); + + if (interfaces.Length > 0) + { + RealInterface = interfaces[0]; + MappedInterface = (interfaces.Length > 1) ? interfaces[1] : ""; + } + else + { + RealInterface = ""; + MappedInterface = ""; + } + + Inactive = false; + IsStatic = false; + IsHideBehindInterface = false; + IsUnidirectional = false; + StaticNatIpAddressOrObjectName = ""; + DynamicNatIpAddressOrObjectName = ""; + SourceId = ""; + TranslatedSourceId = ""; + DestinationId = ""; + TranslatedDestinationId = ""; + ServiceProtocol = ""; + ServiceId = ""; + TranslatedServiceId = ""; + + if (command.IndentationLevel > 0) + { + ParseObjectNatCommand(command, prevCommand, ciscoIds); + } + else + { + ParseRegularNatCommand(command, prevCommand, ciscoIds); + } + + if (command.GetParamPosition("unidirectional") > 0/* || command.GetParamPosition("no-proxy-arp") > 0*/) // commented due to A.R. suggestion... + { + IsUnidirectional = true; + } + + if (command.GetParamPosition("inactive") > 0) + { + Inactive = true; + } + } + + private void ParseObjectNatCommand(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds) + { + /******************************************************** + * Parsing options for Object NAT: + * ------------------------------- + * ... static {mapped_host_ip_address | mapped_object_name | interface} [service {tcp | udp} real_port mapped_port] + * + * ... dynamic {mapped_host_ip_address | mapped_object_name | interface} + * + * + mapped_object may be a host or network or range + */ + + switch (command.GetParam(2)) + { + case "static": + IsStatic = true; + + if (command.GetParam(3) == "interface") + { + IsHideBehindInterface = true; // Static NAT with port-translation + } + else + { + // static hide behind an arbitrary ip/network + StaticNatIpAddressOrObjectName = command.GetParam(3); + } + + int servicePos = command.GetParamPosition("service"); + if (servicePos > 0) + { + ServiceProtocol = command.GetParam(servicePos + 1); + if (ServiceProtocol == "tcp" || ServiceProtocol == "udp") + { + ServiceId = CiscoKnownServices.ConvertServiceToPort(command.GetParam(servicePos + 2)); + TranslatedServiceId = CiscoKnownServices.ConvertServiceToPort(command.GetParam(servicePos + 3)); + } + else + { + ServiceProtocol = ""; + + ConversionIncidentType = ConversionIncidentType.ManualActionRequired; + ConversionIncidentMessage = "Unrecognized service protocol (" + ServiceProtocol + ")"; + Console.WriteLine(ConversionIncidentMessage); + } + } + break; + + case "dynamic": + if (command.GetParam(3) == "interface") + { + IsHideBehindInterface = true; + } + else + { + // dynamic hide behind an arbitrary ip/network + DynamicNatIpAddressOrObjectName = command.GetParam(3); + } + + // Check for interface fall-back configuration + if (command.GetParam(4) == "interface") + { + ConversionIncidentType = ConversionIncidentType.Informative; + ConversionIncidentMessage = "Interface fall-back for dynamic object NAT is not supported"; + Console.WriteLine(ConversionIncidentMessage); + } + break; + } + } + + private void ParseRegularNatCommand(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds) + { + /******************************************************** + * Parsing options for regular (manual or twice) NAT: + * -------------------------------------------------- + * ... [after-object] source static real_object_name [mapped_object_name | interface] [destination static mapped_object_name real_object_name] [service real_service_name mapped_service_name] + * + * ... [after-auto] source dynamic {real_object_name | any} {mapped_object_name | interface} [destination static mapped_object_name real_object_name] [service mapped_service_name real_service_name] + * + * + real_object/mapped_object may be a host or network + */ + + int sourcePos = 2; + + if (command.GetParam(2) == "after-auto" || command.GetParam(2) == "after-object") + { + IsAutoAfter = true; + sourcePos = 3; + } + + if (command.GetParam(sourcePos) == "source") + { + if (command.GetParam(sourcePos + 1) == "static") + { + IsStatic = true; + } + + SourceId = command.GetParam(sourcePos + 2); + TranslatedSourceId = command.GetParam(sourcePos + 3); + if (TranslatedSourceId == "interface") + { + IsHideBehindInterface = true; + } + + int destPos = command.GetParamPosition("destination"); + if (destPos > 0) // twice-NAT + { + // check sanity + if (command.GetParam(destPos + 1) != "static") + { + ConversionIncidentType = ConversionIncidentType.Informative; + ConversionIncidentMessage = "Not handling NAT with dynamic destination"; + Console.WriteLine(ConversionIncidentMessage); + return; + } + + DestinationId = command.GetParam(destPos + 2); + TranslatedDestinationId = command.GetParam(destPos + 3); + } + + int servicePos = command.GetParamPosition("service"); + if (servicePos > 0) + { + ServiceId = command.GetParam(servicePos + 1); + TranslatedServiceId = command.GetParam(servicePos + 2); + } + } + else + { + ConversionIncidentType = ConversionIncidentType.Informative; + ConversionIncidentMessage = "Not handling NAT with dynamic source"; + Console.WriteLine(ConversionIncidentMessage); + } + } + } + + public class Cisco_AccessGroup : CiscoCommand + { + public enum DirectionType { Inbound, Outbound, Global }; + + public DirectionType Direction { get; set; } + public string AccessListName { get; set; } + public string InterfaceName { get; set; } + + public override string Name() { return "access-group"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + // Parsing Options: + //----------------- + // access-group access_list_name {{in | out} interface interface_name | global} + //----------------- + + base.Parse(command, prevCommand, ciscoIds, aliases); + + AccessListName = command.GetParam(1); + InterfaceName = (command.GetParam(3) == "interface") ? command.GetParam(4) : ""; + + switch (command.GetParam(2)) + { + case "in": + Direction = DirectionType.Inbound; + break; + + case "out": + Direction = DirectionType.Outbound; + break; + + case "global": + Direction = DirectionType.Global; + break; + + default: + Console.WriteLine("Error: unknown access-group traffic direction (" + command.GetParam(2) + ")."); + break; + } + + if (Direction != DirectionType.Inbound && Direction != DirectionType.Global) + { + ConversionIncidentType = ConversionIncidentType.Informative; + ConversionIncidentMessage = "Outbound ACLs will not be converted"; + Console.WriteLine(ConversionIncidentMessage); + } + } + } + + public class Cisco_AccessList : CiscoCommand + { + public enum ActionType { NA, Deny, Permit }; + + public class SourceDest + { + public enum SourceDestType { NA, Any, Any6, ReferenceObject, Host, SubnetAndMask }; + + public SourceDestType Type { get; set; } + public string HostIp { get; set; } + public string Subnet { get; set; } + public string Netmask { get; set; } + public string RefObjectName { get; set; } + public int WordsCount { get; set; } + + public SourceDest() + { + Type = SourceDestType.NA; + HostIp = ""; + Subnet = ""; + Netmask = ""; + RefObjectName = ""; + WordsCount = -1; + } + + public SourceDest(List words) : this() + { + if (!words.Any()) + { + WordsCount = 0; + return; + } + + switch (words[0]) + { + case "any": + case "any4": + Type = SourceDestType.Any; + WordsCount = 1; + break; + + case "any6": + Type = SourceDestType.Any6; + WordsCount = 1; + break; + + case "host": + Type = SourceDestType.Host; + if (words.Count > 1) + { + HostIp = words[1]; + WordsCount = 2; + } + break; + + case "object-group": + case "object": + Type = SourceDestType.ReferenceObject; + if (words.Count > 1) + { + RefObjectName = words[1]; + WordsCount = 2; + } + break; + + case "interface": + Type = SourceDestType.ReferenceObject; + if (words.Count > 1) + { + RefObjectName = InterfacePrefix + words[1]; + WordsCount = 2; + } + break; + + default: + // both the ip_address and ip_mask are specified + Type = SourceDestType.SubnetAndMask; + if (words.Count > 1) + { + Subnet = words[0]; + Netmask = words[1]; + WordsCount = 2; + } + break; + } + } + } + + public class ProtocolProperties + { + private Dictionary _ciscoIds; + + public ProtocolType Protocol { get; set; } + public TcpUdpPortOperatorType TcpUdpPortOperator { get; set; } + public ServiceDirection Where { get; set; } + public string TcpUdpPortValue { get; set; } + public int WordsCount { get; set; } + + public ProtocolProperties() + { + Protocol = ProtocolType.NA; + TcpUdpPortOperator = TcpUdpPortOperatorType.NA; + Where = ServiceDirection.Destination; + TcpUdpPortValue = ""; + WordsCount = -1; + } + + public ProtocolProperties(ProtocolType protocol, List words, Dictionary ciscoIds, ServiceDirection where) : this() + { + _ciscoIds = ciscoIds; + Protocol = protocol; + Where = where; + WordsCount = 0; + + if (protocol == ProtocolType.Ip || + protocol == ProtocolType.Tcp || + protocol == ProtocolType.Udp || + protocol == ProtocolType.ReferenceObject) + { + TcpUdpPortOperator = TcpUdpPortOperatorType.All; + + if (words.Count > 0) + { + switch (words[0]) + { + case "range": + TcpUdpPortOperator = TcpUdpPortOperatorType.Range; + if (words.Count > 2) + { + TcpUdpPortValue = CiscoKnownServices.ConvertServiceToPort(words[1]) + "-" + + CiscoKnownServices.ConvertServiceToPort(words[2]); + WordsCount = 3; + } + break; + + case "lt": + TcpUdpPortOperator = TcpUdpPortOperatorType.Lt; + if (words.Count > 1) + { + TcpUdpPortValue = CiscoKnownServices.ConvertServiceToPort(words[1]); + WordsCount = 2; + } + break; + + case "gt": + TcpUdpPortOperator = TcpUdpPortOperatorType.Gt; + if (words.Count > 1) + { + TcpUdpPortValue = CiscoKnownServices.ConvertServiceToPort(words[1]); + WordsCount = 2; + } + break; + + case "eq": + TcpUdpPortOperator = TcpUdpPortOperatorType.Eq; + if (words.Count > 1) + { + TcpUdpPortValue = CiscoKnownServices.ConvertServiceToPort(words[1]); + WordsCount = 2; + } + break; + + case "neq": + TcpUdpPortOperator = TcpUdpPortOperatorType.Neq; + if (words.Count > 1) + { + TcpUdpPortValue = CiscoKnownServices.ConvertServiceToPort(words[1]); + WordsCount = 2; + } + break; + + + case "object": + if (words.Count > 1 && IsServiceObject(words[1])) + { + TcpUdpPortOperator = TcpUdpPortOperatorType.ReferenceObject; + TcpUdpPortValue = words[1]; + WordsCount = 2; + } + break; + + case "object-group": + if (words.Count > 1 && IsServiceGroup(words[1])) + { + TcpUdpPortOperator = TcpUdpPortOperatorType.ReferenceObject; + TcpUdpPortValue = words[1]; + WordsCount = 2; + } + break; + } + } + } + else if (protocol == ProtocolType.Icmp) + { + if (words.Count > 0) + { + switch (words[0]) + { + case "object-group": + if (words.Count > 1 && IsServiceGroup(words[1])) + { + TcpUdpPortOperator = TcpUdpPortOperatorType.ReferenceObject; + TcpUdpPortValue = words[1]; + WordsCount = 2; + } + break; + + default: + if (CiscoKnownServices.IsKnownIcmpService(words[0])) + { + TcpUdpPortOperator = TcpUdpPortOperatorType.Eq; + TcpUdpPortValue = CiscoKnownServices.ConvertIcmpServiceToType(words[0]); + WordsCount = 1; + } + break; + } + } + } + else if (protocol == ProtocolType.KnownOtherIpProtocol) + { + } + } + + private bool IsServiceGroup(string name) + { + if (_ciscoIds.ContainsKey(name) && _ciscoIds[name].Name() == "object-group") + { + var group = (Cisco_GroupObject)_ciscoIds[name]; + if (group.GroupType == Cisco_GroupObject.Group_Type.Service || group.GroupType == Cisco_GroupObject.Group_Type.Icmp) + { + return true; + } + } + + return false; + } + + private bool IsServiceObject(string name) + { + if (_ciscoIds.ContainsKey(name) && _ciscoIds[name].Name() == "object") + { + var obj = (Cisco_Object)_ciscoIds[name]; + if (obj.ObjectType == Cisco_Object.ObjectTypes.TcpService || + obj.ObjectType == Cisco_Object.ObjectTypes.UdpService || + obj.ObjectType == Cisco_Object.ObjectTypes.IcmpService) + { + return true; + } + } + + return false; + } + } + + public string ACLName { get; set; } + public bool Inactive { get; set; } + public ActionType Action { get; set; } + public ProtocolType Protocol { get; set; } + public string ProtocolReference { get; set; } + public string Remark { get; set; } + public bool IsRemark { get; set; } + public bool IsTimeRangeSpecified { get; set; } + public string TimeRangeName { get; set; } + public SourceDest Source { get; set; } + public SourceDest Destination { get; set; } + public ProtocolProperties SourceProperties { get; set; } + public ProtocolProperties DestinationProperties { get; set; } + + public override string Name() { return "access-list"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + /* + * OPTION I - REMARK format - the easiest option: + * + access-list access_list_name remark text + Example: + hostname(config)# access-list ACL_OUT remark - this is the inside admin address + * + * OPTION II - STANDARD format - used for a limited number of features, such as route maps or VPN filters. + * uses IPv4 addresses only, and defines destination addresses only. + * + access-list access_list_name standard {deny | permit} {any/any4 | host ip_address | ip_address ip_mask} + Example: + hostname(config)# access-list OSPF standard permit 192.168.1.0 255.255.255.0 + * + * OPTION III.I - EXTENDED format - for ICMP based traffic matching + * + access-list access_list_name extended {deny | permit} icmp source_address_argument dest_address_argument [icmp_argument] [time-range time_range_name] [inactive] + Example: + hostname(config)# access-list ACL_IN extended permit icmp any any echo + * + * OPTION III.II - EXTENDED format - for TCP and UDP based traffic matching, with ports + * + access-list access_list_name extended {deny | permit} {tcp | udp} source_address_argument [port_argument] dest_address_argument [port_argument] [time-range time_range_name] [inactive] + Example: + hostname(config)# access-list ACL_IN extended deny tcp any host 209.165.201.29 eq www + hostname(config)# access-list ACL_IN extended deny tcp 192.168.1.0 255.255.255.0 209.165.201.0 255.255.255.224 + * + * OPTION III.III - EXTENDED format - for general IP address and FQDN based matching + * + access-list access_list_name extended {deny | permit} protocol_argument source_address_argument dest_address_argument [time-range time_range_name] [inactive] + Example: + hostname(config)# access-list ACL_IN extended permit ip any any + * + * ********************** + * ACL COMMAND ARGUMENTS: + * + * protocol_argument specification: one of the following options: + * -------------------------------------------------------------- + * protocol_name/protocol_number + * object service_object_id --> may be also a icmp service object + * object-group service_group_id + * object-group protocol_group_id + * + * source_address_argument/dest_address_argument specification: one of the following options: + * ------------------------------------------------------------------------------------------ + * any/any4/any6 + * host ip_address + * interface interface_name + * object network_object_id + * object-group network_group_id + * ip_address ip_mask + * + * icmp_argument specification: one of the following options: + * ---------------------------------------------------------- + * icmp_type + * object-group icmp_group_id --> object-group icmp-type command + * + * port_argument specification: one of the following options: + * ---------------------------------------------------------- + * operator port --> where operator can be one of: lt, gt, eq, neq, range; port can be number or name of a TCP or UDP port + * object-group service_group_id + * + */ + + base.Parse(command, prevCommand, ciscoIds, aliases); + + ACLName = command.GetParam(1); + Inactive = false; + Action = ActionType.NA; + Protocol = ProtocolType.NA; + ProtocolReference = ""; + Remark = ""; + IsRemark = false; + IsTimeRangeSpecified = false; + + var prevAclCommand = prevCommand as Cisco_AccessList; + + if (command.GetParam(2) == "remark") + { + IsRemark = true; + + // Note that there may be several consecutive remark lines, so we need to aggregate to a single remark + string dataForNextElement = ""; + if (prevAclCommand != null && prevAclCommand.IsRemark && !string.IsNullOrEmpty(prevAclCommand.DataForNextElement)) + { + dataForNextElement = prevAclCommand.DataForNextElement; + } + + string text = command.Text.Trim(); + int offset = text.IndexOf("remark") + 7; + + if (!string.IsNullOrEmpty(dataForNextElement)) + { + dataForNextElement += ", "; + } + + dataForNextElement += text.Substring(offset).Trim(); + DataForNextElement = dataForNextElement; + + return; + } + + if (prevAclCommand != null && ACLName.Equals(prevAclCommand.ACLName) && !string.IsNullOrEmpty(prevAclCommand.DataForNextElement)) + { + Remark = prevAclCommand.DataForNextElement; + + if (CiscoParser.SpreadAclRemarks) + { + DataForNextElement = Remark; + } + } + + int denyPosition = command.GetParamPosition("deny"); + int permitPosition = command.GetParamPosition("permit"); + int protocolPosition = Math.Max(denyPosition, permitPosition) + 1; // protocol field should follow the action field (either deny or permit) + int sourcePosition = protocolPosition + 1; + + if (denyPosition > 0) + { + Action = ActionType.Deny; + } + + if (permitPosition > 0) + { + Action = ActionType.Permit; + } + + if (command.GetParam(2) == "standard") + { + Protocol = ProtocolType.Ip; + + Source = new SourceDest + { + Type = SourceDest.SourceDestType.Any + }; + + SourceProperties = new ProtocolProperties + { + Protocol = Protocol, + TcpUdpPortOperator = TcpUdpPortOperatorType.All + }; + + Destination = new SourceDest(command.GetParams(4)); + + DestinationProperties = new ProtocolProperties + { + Protocol = Protocol, + TcpUdpPortOperator = TcpUdpPortOperatorType.All + }; + + return; + } + + if (command.GetParamPosition("time-range") > 0) + { + IsTimeRangeSpecified = true; + int indexTimeRange = command.GetParamPosition("time-range"); + TimeRangeName = command.GetParam(indexTimeRange + 1); + } + + if (command.GetParamPosition("inactive") > 0) + { + Inactive = true; + } + + string strProtocol = command.GetParam(protocolPosition); + switch (strProtocol) + { + case "ip": + Protocol = ProtocolType.Ip; + break; + + case "icmp": + case "icmp6": + Protocol = ProtocolType.Icmp; + break; + + case "udp": + Protocol = ProtocolType.Udp; + break; + + case "tcp": + Protocol = ProtocolType.Tcp; + break; + + case "object-group": + case "object": + Protocol = ProtocolType.ReferenceObject; + ProtocolReference = command.GetParam(protocolPosition + 1); + sourcePosition++; + break; + + default: + string serviceName; + if (CiscoKnownServices.IsKnownService(strProtocol)) + { + Protocol = ProtocolType.KnownOtherIpProtocol; + } + else if (CiscoKnownServices.IsKnownServiceNumber(strProtocol, out serviceName)) // protocol number is used!!! + { + Protocol = ProtocolType.KnownOtherIpProtocol; + strProtocol = serviceName; + } + else + { + ProtocolReference = strProtocol; + ConversionIncidentType = ConversionIncidentType.ManualActionRequired; + ConversionIncidentMessage = "Unrecognized service protocol (" + strProtocol + ")"; + Console.WriteLine(ConversionIncidentMessage); + } + break; + } + + Source = new SourceDest(command.GetParams(sourcePosition)); + SourceProperties = new ProtocolProperties(Protocol, command.GetParams(sourcePosition + Source.WordsCount), ciscoIds, ServiceDirection.Source); + Destination = new SourceDest(command.GetParams(sourcePosition + Source.WordsCount + SourceProperties.WordsCount)); + DestinationProperties = new ProtocolProperties(Protocol, command.GetParams(sourcePosition + Source.WordsCount + SourceProperties.WordsCount + Destination.WordsCount), ciscoIds, ServiceDirection.Destination); + + if (Protocol == ProtocolType.KnownOtherIpProtocol) + { + // This information is needed in order to create/query appropriate service objects + DestinationProperties.TcpUdpPortValue = strProtocol; + DestinationProperties.WordsCount = 1; + } + } + } + + public class Cisco_ClassMap : CiscoCommand + { + public string ClassMapName; + public List MatchedAclNames = new List(); + + public override string Name() { return "class-map"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + base.Parse(command, prevCommand, ciscoIds, aliases); + + ClassMapName = command.GetParam(1); + + if (command.Children == null) + { + return; + } + + foreach (CiscoCommand child in command.Children) + { + if (child.Name() == "match" && !string.IsNullOrEmpty(((Cisco_Match_AccessList)child).AccessListName)) + { + MatchedAclNames.Add(((Cisco_Match_AccessList)child).AccessListName); + } + } + } + } + + public class Cisco_Match_AccessList : CiscoCommand + { + public string AccessListName { get; set; } + + public override string Name() { return "match"; } + + public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dictionary ciscoIds, Dictionary aliases) + { + // Parsing Options: + //----------------- + // match access-list access_list_name + //----------------- + + base.Parse(command, prevCommand, ciscoIds, aliases); + + AccessListName = (command.GetParam(1) == "access-list") ? command.GetParam(2) : ""; + } + } +} diff --git a/CiscoMigration/CiscoConverter.cs b/CiscoMigration/CiscoConverter.cs index a57b6478..87a2d841 100644 --- a/CiscoMigration/CiscoConverter.cs +++ b/CiscoMigration/CiscoConverter.cs @@ -54,29 +54,27 @@ private class CiscoNetwork public int CiscoCommandId { get; private set; } public string IpAddress { get; private set; } public string NetMask { get; private set; } + public string MaskPrefix { get; set; } - public CiscoNetwork(int ciscoCommandId, string sIp) + public CiscoNetwork(int ciscoCommandId, string sIp) : this(ciscoCommandId, sIp, "") { } + public CiscoNetwork(int ciscoCommandId, string sIp, string sMask) : this(ciscoCommandId, sIp, sMask, "") { } + public CiscoNetwork(int ciscoCommandId, string sIp, string sMask, string sMaskPrefix) { CiscoCommandId = ciscoCommandId; IpAddress = sIp; - NetMask = "255.255.255.255"; - } - - public CiscoNetwork(int ciscoCommandId, string sIp, string sMask) - { - CiscoCommandId = ciscoCommandId; - IpAddress = sIp; - NetMask = string.IsNullOrEmpty(sMask) ? "255.255.255.255" : sMask; + NetMask = string.IsNullOrEmpty(sMask) && string.IsNullOrEmpty(sMaskPrefix) ? "255.255.255.255" : sMask; + MaskPrefix = sMaskPrefix; } public bool IsHost() { - return NetworkUtils.IsValidIp(IpAddress) && (NetworkUtils.GetMaskLength(NetMask) == 32); + return NetworkUtils.IsValidIpv4(IpAddress) && (NetworkUtils.GetMaskLength(NetMask) == 32) || NetworkUtils.IsValidIpv6(IpAddress) && string.IsNullOrEmpty(MaskPrefix); } public bool IsNetwork() { - return NetworkUtils.IsValidIp(IpAddress) && NetworkUtils.IsValidNetmask(NetMask) && (NetworkUtils.GetMaskLength(NetMask) < 32); + return NetworkUtils.IsValidIpv4(IpAddress) && NetworkUtils.IsValidNetmaskv4(NetMask) && (NetworkUtils.GetMaskLength(NetMask) < 32) || + NetworkUtils.IsValidIpv6(IpAddress) && !string.IsNullOrEmpty(MaskPrefix); } public string AutoGeneratedName() @@ -88,7 +86,10 @@ public string AutoGeneratedName() if (IsNetwork()) { - return "network_" + IpAddress + "_" + NetworkUtils.GetMaskLength(NetMask); + if (!string.IsNullOrEmpty(NetMask)) + return "network_" + IpAddress + "_" + NetworkUtils.GetMaskLength(NetMask); + else + return "network_" + IpAddress + "_" + MaskPrefix; } Console.WriteLine("Error: unrecognized network object - Ip={0}, Mask={1}", IpAddress, NetMask); @@ -97,12 +98,15 @@ public string AutoGeneratedName() public string AutoGeneratedNetworkName() { - if (NetworkUtils.IsValidIp(IpAddress) && NetworkUtils.IsValidNetmask(NetMask)) + if (IsNetwork()) { - return "network_" + IpAddress + "_" + NetworkUtils.GetMaskLength(NetMask); + if (!string.IsNullOrEmpty(NetMask)) + return "network_" + IpAddress + "_" + NetworkUtils.GetMaskLength(NetMask); + else + return "network_" + IpAddress + "_" + MaskPrefix; } - Console.WriteLine("Error: unrecognized network object - Ip={0}, Mask={1}", IpAddress, NetMask); + Console.WriteLine("Error: unrecognized network object - Ip={0}, Mask={1}, Prefix={2}", IpAddress, NetMask, MaskPrefix); return "_Err_in_network-line_" + CiscoCommandId; } @@ -119,12 +123,12 @@ public override bool Equals(object obj) return false; } - return (other.IpAddress == IpAddress && other.NetMask == NetMask); + return (other.IpAddress == IpAddress && other.NetMask == NetMask && other.MaskPrefix == MaskPrefix); } public override int GetHashCode() { - string hash = IpAddress + "," + NetMask; + string hash = IpAddress + "," + NetMask + "," + MaskPrefix; return hash.GetHashCode(); } } @@ -447,7 +451,7 @@ public static bool CheckServicesPortRangesOverlapping(CheckPointObject subsetSer int subsetTcpPortFrom, subsetTcpPortTo; int supersetTcpPortFrom, supersetTcpPortTo; - if (subsetService.GetType() == typeof (CheckPoint_TcpService) && supersetService.GetType() == typeof (CheckPoint_TcpService)) + if (subsetService.GetType() == typeof(CheckPoint_TcpService) && supersetService.GetType() == typeof(CheckPoint_TcpService)) { var subsetTcp = (CheckPoint_TcpService)subsetService; var supersetTcp = (CheckPoint_TcpService)supersetService; @@ -455,7 +459,7 @@ public static bool CheckServicesPortRangesOverlapping(CheckPointObject subsetSer GetServicePortRanges(subsetTcp.Port, out subsetTcpPortFrom, out subsetTcpPortTo); GetServicePortRanges(supersetTcp.Port, out supersetTcpPortFrom, out supersetTcpPortTo); } - else if (subsetService.GetType() == typeof (CheckPoint_UdpService) && supersetService.GetType() == typeof (CheckPoint_UdpService)) + else if (subsetService.GetType() == typeof(CheckPoint_UdpService) && supersetService.GetType() == typeof(CheckPoint_UdpService)) { var subsetUdp = (CheckPoint_UdpService)subsetService; var supersetUdp = (CheckPoint_UdpService)supersetService; @@ -975,7 +979,7 @@ private void PopulateCiscoNetworkObjects() // The referenced object will be created on its own!!! if (string.IsNullOrEmpty(ciscoNetwork.ReferencedObject)) { - var network = new CiscoNetwork(command.Id, ciscoNetwork.IpAddress, ciscoNetwork.Netmask); + var network = new CiscoNetwork(command.Id, ciscoNetwork.IpAddress, ciscoNetwork.Netmask, ciscoNetwork.MaskPrefix); _ciscoNetworkObjects.Add(network); } } @@ -1076,6 +1080,7 @@ private void Add_Networks() cpNetwork.Name = network.AutoGeneratedName(); cpNetwork.Subnet = network.IpAddress; cpNetwork.Netmask = network.NetMask; + cpNetwork.MaskLenght = network.MaskPrefix; cpNetwork.ConvertedCommandId = network.CiscoCommandId; AddCheckPointObject(cpNetwork); } @@ -1116,6 +1121,7 @@ private void Add_Objects() cpNetwork.Comments = ciscoObject.Description; cpNetwork.Subnet = ciscoObject.Network; cpNetwork.Netmask = ciscoObject.Netmask; + cpNetwork.MaskLenght = ciscoObject.MaskPrefix; ApplyConversionIncidentOnCheckPointObject(cpNetwork, ciscoObject); CheckObjectNameValidity(cpNetwork, ciscoObject); AddCheckPointObject(cpNetwork); @@ -1201,7 +1207,7 @@ private void Add_NetworkGroups() } else { - string memberName = (new CiscoNetwork(ciscoMember.Id, ciscoMember.IpAddress, ciscoMember.Netmask)).AutoGeneratedName(); + string memberName = (new CiscoNetwork(ciscoMember.Id, ciscoMember.IpAddress, ciscoMember.Netmask, ciscoMember.MaskPrefix)).AutoGeneratedName(); if (memberName.Contains(AutoGeneratedNameWithError)) { ciscoMember.ConversionIncidentType = ConversionIncidentType.ManualActionRequired; @@ -1692,7 +1698,7 @@ private void Add_TimeRanges() List cpTimeRangesNamesUniq = new List(); int cpTimeNamePostfixInt = 1; - foreach(CiscoCommand command in caTimesList) + foreach (CiscoCommand command in caTimesList) { if (command.GetType() == typeof(Cisco_TimeRange)) { @@ -1721,7 +1727,7 @@ private void Add_TimeRanges() cpTimeRangesNamesUniq.Add(cpTimeRangeName); } - if(isRenamed) + if (isRenamed) cpTimeNamePostfixInt += 1; } else @@ -1754,7 +1760,7 @@ private void Add_TimeRange(int caTimeId, string caTimeRangeName, string cpTimeRa new ConversionIncident( caTimeId, "TITLE: object is renamed", - "DESCRIPTION: object renamed from " + caTimeRangeName + " to " + cpTimeRangeName, + "DESCRIPTION: object renamed from " + caTimeRangeName + " to " + cpTimeRangeName, ConversionIncidentType.Informative)); } @@ -2274,9 +2280,9 @@ private void Add_Layers_And_Rules(CheckPoint_Package package) } private void Add_Global_Rules(CheckPoint_Package package) - { + { if (_ciscoGlobalAclCommands.Count > 0) - { + { // remove clenup rule of each sublayer if global rules exist because cleanup rule should be added after global-rules foreach (var subpolicy in package.SubPolicies) { @@ -2284,7 +2290,7 @@ private void Add_Global_Rules(CheckPoint_Package package) { var lastRule = subpolicy.Rules[subpolicy.Rules.Count - 1]; if (lastRule.IsCleanupRule()) - subpolicy.Rules.Remove(lastRule); + subpolicy.Rules.Remove(lastRule); } } @@ -2292,13 +2298,13 @@ private void Add_Global_Rules(CheckPoint_Package package) if (package.ParentLayer.Rules.Count > 0) { var lastRule = package.ParentLayer.Rules[package.ParentLayer.Rules.Count - 1]; - if (lastRule.IsCleanupRule()) - package.ParentLayer.Rules.Remove(lastRule); + if (lastRule.IsCleanupRule()) + package.ParentLayer.Rules.Remove(lastRule); } CheckPoint_Rule cpRule4GlobalLayer = new CheckPoint_Rule(); cpRule4GlobalLayer.Name = ""; - cpRule4GlobalLayer.Layer = package.NameOfAccessLayer; + cpRule4GlobalLayer.Layer = package.NameOfAccessLayer; cpRule4GlobalLayer.Source.Add(_cpObjects.GetObject(CheckPointObject.Any)); cpRule4GlobalLayer.Destination.Add(_cpObjects.GetObject(CheckPointObject.Any)); cpRule4GlobalLayer.Action = CheckPoint_Rule.ActionType.SubPolicy; @@ -2313,13 +2319,13 @@ private void Add_Global_Rules(CheckPoint_Package package) cpSubLayer4GlobalRules.ApplicationsAndUrlFiltering = true; cpSubLayer4GlobalRules.Shared = true; cpSubLayer4GlobalRules.Name = cpRule4GlobalLayer.SubPolicyName; - + package.SubPolicies.Insert(0, cpSubLayer4GlobalRules); // insert at the begging becuase Global Rules should be created before all policy foreach (var globalPolicyRule in _ciscoGlobalAclCommands) { // Append the global policy rules BELOW the existing sub-policies. - CheckPoint_Rule cpRule = Acl_To_CPRule(globalPolicyRule, cpSubLayer4GlobalRules.Name); + CheckPoint_Rule cpRule = Acl_To_CPRule(globalPolicyRule, cpSubLayer4GlobalRules.Name); cpSubLayer4GlobalRules.Rules.Add(cpRule); } @@ -2341,10 +2347,10 @@ private void Add_Global_Rules(CheckPoint_Package package) cpCleanupRule.Layer = cpSubLayer4GlobalRules.Name; cpSubLayer4GlobalRules.Rules.Add(cpCleanupRule); } - + // Fill in the shared layer with global policy rules INSIDE the existing sub-policies. foreach (CheckPoint_Layer subPolicy in package.SubPolicies) - { + { if (subPolicy.Name.Equals(cpSubLayer4GlobalRules.Name)) { continue; @@ -2353,7 +2359,7 @@ private void Add_Global_Rules(CheckPoint_Package package) CheckPoint_Rule cpSubRule4GlobalLayer = cpRule4GlobalLayer.Clone(); cpSubRule4GlobalLayer.Name = "Global Layer"; cpSubRule4GlobalLayer.Layer = subPolicy.Name; - subPolicy.Rules.Add(cpSubRule4GlobalLayer); + subPolicy.Rules.Add(cpSubRule4GlobalLayer); } @@ -2378,11 +2384,11 @@ private void Add_Global_Rules(CheckPoint_Package package) { // This is done to avoid duplication of incident reporting over all matched sub-policy rules. ConversionIncidentType aclConversionIncident = ciscoAcl.ConversionIncidentType; - ciscoAcl.ConversionIncidentType = ConversionIncidentType.None; + ciscoAcl.ConversionIncidentType = ConversionIncidentType.None; var cpRule = Acl_To_CPRule(ciscoAcl, subPolicy.Name); - - cpRule.Layer = subPolicy.Name; + + cpRule.Layer = subPolicy.Name; if (!string.IsNullOrEmpty(subPolicy.Tag) && subPolicy.Tag == "InterfaceDisabled") { @@ -2407,21 +2413,21 @@ private void Add_Global_Rules(CheckPoint_Package package) } } } - } - } - } + } + } + } } private CheckPoint_Rule Acl_To_CPRule(Cisco_AccessList ciscoAcl, string layerName) { - var cpRule = new CheckPoint_Rule(); - cpRule.Name = ciscoAcl.Description; - cpRule.Enabled = !ciscoAcl.Inactive; - if (layerName != null) - cpRule.Layer = layerName; - else + var cpRule = new CheckPoint_Rule(); + cpRule.Name = ciscoAcl.Description; + cpRule.Enabled = !ciscoAcl.Inactive; + if (layerName != null) + cpRule.Layer = layerName; + else cpRule.Layer = ciscoAcl.ACLName; - + cpRule.Comments = ciscoAcl.Remark; cpRule.ConversionComments = ciscoAcl.Id + ") " + ciscoAcl.Text; @@ -3381,7 +3387,7 @@ private void Add_object_NAT() case Cisco_Object.ObjectTypes.Network: { - var network = new CiscoNetwork(ciscoNat.Id, ciscoNetwork.Network, ciscoNetwork.Netmask); + var network = new CiscoNetwork(ciscoNat.Id, ciscoNetwork.Network, ciscoNetwork.Netmask, ciscoNetwork.MaskPrefix); var cpNetworkTranslated = new CheckPoint_Network(); cpNetworkTranslated.Name = network.AutoGeneratedName(); @@ -4053,11 +4059,11 @@ private void MatchNATRulesIntoFirewallPolicy() { continue; } - - if (cpParentRule.Source[0] is CheckPoint_PredifinedObject && cpParentRule.Source[0].Name.Equals(CheckPointObject.Any)) + + if (cpParentRule.Source[0] is CheckPoint_PredifinedObject && cpParentRule.Source[0].Name.Equals(CheckPointObject.Any)) { if (cpParentRule.SubPolicyName != GlobalRulesSubpolicyName) - { + { continue; } } @@ -4412,7 +4418,7 @@ private void Add_Optimized_Package() foreach (CheckPoint_Layer layer in regularPackage.SubPolicies) { string optimizedSubPolicyName = layer.Name + "_opt"; - + CheckPoint_Layer optimizedLayer = RuleBaseOptimizer.Optimize(layer, optimizedSubPolicyName); foreach (CheckPoint_Rule subSubRule in optimizedLayer.Rules) { @@ -4738,7 +4744,7 @@ public override void ExportPolicyPackagesAsHtml() file.WriteLine(" "); if (isSubPolicy) { - file.WriteLine(" " + + file.WriteLine(" " + string.Format(HtmlSubPolicyArrowImageTagFormat, curParentRuleId + "_img", HtmlDownArrowImageSourceData) + ruleNumber + ""); } else @@ -4751,7 +4757,7 @@ public override void ExportPolicyPackagesAsHtml() file.WriteLine(" "); if (isSubPolicy) { - file.WriteLine(" " + + file.WriteLine(" " + string.Format(HtmlSubPolicyArrowImageTagFormat, curParentRuleId + "_img", HtmlDownArrowImageSourceData) + ruleNumber + HtmlDisabledImageTag + ""); } else @@ -4793,7 +4799,7 @@ public override void ExportPolicyPackagesAsHtml() subActionStyle = subRule.Action.ToString().ToLower(); break; - case CheckPoint_Rule.ActionType.SubPolicy: + case CheckPoint_Rule.ActionType.SubPolicy: isSubSubPolicy = true; subAction = "Sub-policy: " + subRule.SubPolicyName; subActionStyle = ""; @@ -4817,16 +4823,16 @@ public override void ExportPolicyPackagesAsHtml() var sbCurRuleNumberColumnTag = new StringBuilder(); sbCurRuleNumberColumnTag.Append(" "); if (isSubSubPolicy) - { + { sbCurRuleNumberColumnTag.Append(" " + string.Format(HtmlSubPolicyArrowImageTagFormat, curRuleId + "_img", HtmlDownArrowImageSourceData) + curRuleNumber); } else - { + { sbCurRuleNumberColumnTag.Append(" "); sbCurRuleNumberColumnTag.Append(curRuleNumber); - } - + } + if (isInspectedRule) { sbCurRuleNumberColumnTag.Append(BuildInspectedRuleInfo(subRule.Tag)); @@ -4856,7 +4862,7 @@ public override void ExportPolicyPackagesAsHtml() file.WriteLine(" "); if (isSubSubPolicy) - { + { foreach (CheckPoint_Layer subSubPolicy in package.SubPolicies) { int subSubRuleNumber = 1; @@ -4865,7 +4871,7 @@ public override void ExportPolicyPackagesAsHtml() { //if (subSubRule.Layer == subRule.SubPolicyName || subSubRule.Layer == subRule.SubPolicyName + "_opt") if (subSubRule.Layer == subRule.SubPolicyName) - { + { var subRuleConversionIncidentType = ConversionIncidentType.None; string subCurRuleNumber = ruleNumber + "." + subRuleNumber + "." + subSubRuleNumber; string subCurRuleId = ruleIdPrefix + subCurRuleNumber; @@ -4920,7 +4926,7 @@ public override void ExportPolicyPackagesAsHtml() rulesWithConversionInfos.Add(subCurRuleId, subSubRule); } } - } + } } } } diff --git a/CommonUtils/NetworkUtils.cs b/CommonUtils/NetworkUtils.cs index 78c71daa..d421b758 100644 --- a/CommonUtils/NetworkUtils.cs +++ b/CommonUtils/NetworkUtils.cs @@ -26,25 +26,73 @@ namespace CommonUtils /// public static class NetworkUtils { + public static bool IsValidIpv4(string sIp) + { + return IsValidIp(sIp, new AddressFamily[] { AddressFamily.InterNetwork }); + } + public static bool IsValidIpv6(string sIp) + { + return IsValidIp(sIp, new AddressFamily[] { AddressFamily.InterNetworkV6 }); + } + public static bool IsValidIp(string sIp) { - IPAddress ip; - if (IPAddress.TryParse(sIp, out ip) && (ip.AddressFamily == AddressFamily.InterNetwork)) + return IsValidIp(sIp, new AddressFamily[] { AddressFamily.InterNetwork, AddressFamily.InterNetworkV6 }); + } + + private static bool IsValidIp(String sIp, AddressFamily[] allowedAddressFamilies) + { + if (allowedAddressFamilies == null || allowedAddressFamilies.Length == 0) { - return true; + return false; } + if (IPAddress.TryParse(sIp, out IPAddress ip) && Array.Exists(allowedAddressFamilies, e => e == ip.AddressFamily)) + { + return true; + } return false; } + public static bool IsValidNetmaskv4(string sNetmask) + { + return IsValidNetmask(sNetmask, new AddressFamily[] { AddressFamily.InterNetwork }); + } + + public static bool IsValidNetmaskv6(string sNetmask) + { + return IsValidNetmask(sNetmask, new AddressFamily[] { AddressFamily.InterNetworkV6 }); + } + public static bool IsValidNetmask(string sNetmask) { - IPAddress netmask; - if (IPAddress.TryParse(sNetmask, out netmask) && (netmask.AddressFamily == AddressFamily.InterNetwork)) + return IsValidNetmask(sNetmask, new AddressFamily[] { AddressFamily.InterNetwork, AddressFamily.InterNetworkV6 }); + } + + private static bool IsValidNetmask(String sNetmask, AddressFamily[] allowedAddressFamilies) + { + if (allowedAddressFamilies == null || allowedAddressFamilies.Length == 0) { - return IPNetwork.ValidNetmask(netmask); + return false; } + if (IPAddress.TryParse(sNetmask, out IPAddress netmask) && Array.Exists(allowedAddressFamilies, e => e == netmask.AddressFamily)) + { + return IPNetwork.ValidNetmask(netmask); + } + return false; + } + public static bool TryParseNetwortWithPrefix(String sNetwork, out String sIp, out String sMaskLenght) + { + sIp = ""; + sMaskLenght = ""; + String[] splitedNetwork = sNetwork.Split('/'); + if (splitedNetwork.Length == 2 && IPAddress.TryParse(splitedNetwork[0], out IPAddress ipAddr) && int.TryParse(splitedNetwork[1], out int maskLengthNum)) + { + sMaskLenght = Convert.ToString(maskLengthNum); + sIp = Convert.ToString(ipAddr); + return true; + } return false; } @@ -158,7 +206,7 @@ public static string Number2Ip(UInt32 number) string oct1 = ((number & 0xff000000) >> 24).ToString(); string oct2 = ((number & 0x00ff0000) >> 16).ToString(); string oct3 = ((number & 0x0000ff00) >> 08).ToString(); - string oct4 = ((number & 0x000000ff) ).ToString(); + string oct4 = ((number & 0x000000ff)).ToString(); return oct1 + "." + oct2 + "." + oct3 + "." + oct4; } diff --git a/JuniperMigration/JuniperObjects.cs b/JuniperMigration/JuniperObjects.cs index baeab1f1..2e97fb8a 100644 --- a/JuniperMigration/JuniperObjects.cs +++ b/JuniperMigration/JuniperObjects.cs @@ -150,7 +150,7 @@ public override void Parse(XElement objectNode, string zoneName) int pos = ipPrefixText.IndexOf('/'); IpAddress = (pos == -1) ? ipPrefixText : ipPrefixText.Substring(0, pos); - if (!NetworkUtils.IsValidIp(IpAddress)) + if (!NetworkUtils.IsValidIpv4(IpAddress)) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid IP address '{0}' for host object. Using IP 1.1.1.1.", IpAddress); @@ -183,7 +183,7 @@ public override void Parse(XElement objectNode, string zoneName) IpAddress = ipPrefixParts[0]; - if (!NetworkUtils.IsValidIp(IpAddress)) + if (!NetworkUtils.IsValidIpv4(IpAddress)) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid IP address '{0}' for network object. Using subnet 1.1.1.0/255.255.255.0.", IpAddress); @@ -235,7 +235,7 @@ public override void Parse(XElement objectNode, string zoneName) { RangeFrom = fromNode.Value; - if (!NetworkUtils.IsValidIp(RangeFrom)) + if (!NetworkUtils.IsValidIpv4(RangeFrom)) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid starting IP range '{0}' for range object. Using IP 0.0.0.0.", RangeFrom); @@ -253,7 +253,7 @@ public override void Parse(XElement objectNode, string zoneName) { RangeTo = toNode.Value; - if (!NetworkUtils.IsValidIp(RangeTo)) + if (!NetworkUtils.IsValidIpv4(RangeTo)) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid ending IP range '{0}' for range object. Using IP 255.255.255.255.", RangeTo); @@ -336,7 +336,7 @@ public override void Parse(XElement objectNode, string zoneName) } string[] ipInfo = ipNode.Value.Split('/'); - if (ipInfo.Length != 2 || !NetworkUtils.IsValidIp(ipInfo[0])) + if (ipInfo.Length != 2 || !NetworkUtils.IsValidIpv4(ipInfo[0])) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid IPv4 address '{0}' for interface object.", ipNode.Value); @@ -415,7 +415,7 @@ public override void Parse(XElement objectNode, string zoneName) } string[] ipInfo = ipNode.Value.Split('/'); - if (ipInfo.Length != 2 || !NetworkUtils.IsValidIp(ipInfo[0])) + if (ipInfo.Length != 2 || !NetworkUtils.IsValidIpv4(ipInfo[0])) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid IPv4 address '{0}' for route object. Using IP 1.1.1.1.", ipNode.Value); @@ -431,7 +431,7 @@ public override void Parse(XElement objectNode, string zoneName) if (nextHopNode != null) { - if (!string.IsNullOrEmpty(nextHopNode.Value) && NetworkUtils.IsValidIp(nextHopNode.Value)) + if (!string.IsNullOrEmpty(nextHopNode.Value) && NetworkUtils.IsValidIpv4(nextHopNode.Value)) { nextHopAddress = nextHopNode.Value; } @@ -445,7 +445,7 @@ public override void Parse(XElement objectNode, string zoneName) } else if (qualifiedNextHopNode != null) { - if (!string.IsNullOrEmpty(qualifiedNextHopNode.Value) && NetworkUtils.IsValidIp(qualifiedNextHopNode.Value)) + if (!string.IsNullOrEmpty(qualifiedNextHopNode.Value) && NetworkUtils.IsValidIpv4(qualifiedNextHopNode.Value)) { nextHopAddress = qualifiedNextHopNode.Value; } @@ -974,7 +974,7 @@ protected PoolAddress ParseAddress(XElement addressNode, bool isSourceNat) } string[] ipInfo = ipNode.Value.Split('/'); - if (ipInfo.Length != 2 || !NetworkUtils.IsValidIp(ipInfo[0])) + if (ipInfo.Length != 2 || !NetworkUtils.IsValidIpv4(ipInfo[0])) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid IPv4 address '{0}' for NAT pool object.", ipNode.Value); @@ -1014,7 +1014,7 @@ protected PoolAddress ParseAddress(XElement addressNode, bool isSourceNat) else { string[] rangeToInfo = rangeToNode.Value.Split('/'); - if (rangeToInfo.Length != 2 || !NetworkUtils.IsValidIp(rangeToInfo[0]) || rangeToInfo[1] != "32") + if (rangeToInfo.Length != 2 || !NetworkUtils.IsValidIpv4(rangeToInfo[0]) || rangeToInfo[1] != "32") { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid ending IP range '{0}' for destination NAT pool object. Using IP 255.255.255.255.", rangeToNode.Value); @@ -1056,7 +1056,7 @@ public override void Parse(XElement objectNode, string zoneName) if (hostAddressBaseNode != null && !string.IsNullOrEmpty(hostAddressBaseNode.Value)) { string[] ipInfo = hostAddressBaseNode.Value.Split('/'); - if (ipInfo.Length == 2 && NetworkUtils.IsValidIp(ipInfo[0])) + if (ipInfo.Length == 2 && NetworkUtils.IsValidIpv4(ipInfo[0])) { HostAddressBase = ipInfo[0]; } @@ -1160,7 +1160,7 @@ public override void Parse(XElement objectNode, string zoneName) foreach (var sourceAddressNode in sourceAddressNodes) { string[] ipInfo = sourceAddressNode.Value.Split('/'); - if (ipInfo.Length != 2 || !NetworkUtils.IsValidIp(ipInfo[0])) + if (ipInfo.Length != 2 || !NetworkUtils.IsValidIpv4(ipInfo[0])) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid IPv4 address '{0}' for source NAT rule's source address object.", sourceAddressNode.Value); @@ -1191,7 +1191,7 @@ public override void Parse(XElement objectNode, string zoneName) foreach (var destAddressNode in destAddressNodes) { string[] ipInfo = destAddressNode.Value.Split('/'); - if (ipInfo.Length != 2 || !NetworkUtils.IsValidIp(ipInfo[0])) + if (ipInfo.Length != 2 || !NetworkUtils.IsValidIpv4(ipInfo[0])) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid IPv4 address '{0}' for source NAT rule's destination address object.", destAddressNode.Value); @@ -1286,7 +1286,7 @@ public override void Parse(XElement objectNode, string zoneName) foreach (var sourceAddressNode in sourceAddressNodes) { string[] ipInfo = sourceAddressNode.Value.Split('/'); - if (ipInfo.Length != 2 || !NetworkUtils.IsValidIp(ipInfo[0])) + if (ipInfo.Length != 2 || !NetworkUtils.IsValidIpv4(ipInfo[0])) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid IPv4 address '{0}' for destination NAT rule's source address object.", sourceAddressNode.Value); @@ -1311,7 +1311,7 @@ public override void Parse(XElement objectNode, string zoneName) foreach (var destAddressNode in destAddressNodes) { string[] ipInfo = destAddressNode.Value.Split('/'); - if (ipInfo.Length != 2 || !NetworkUtils.IsValidIp(ipInfo[0])) + if (ipInfo.Length != 2 || !NetworkUtils.IsValidIpv4(ipInfo[0])) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid IPv4 address '{0}' for destination NAT rule's destination address object.", destAddressNode.Value); @@ -1401,7 +1401,7 @@ public override void Parse(XElement objectNode, string zoneName) foreach (var sourceAddressNode in sourceAddressNodes) { string[] ipInfo = sourceAddressNode.Value.Split('/'); - if (ipInfo.Length != 2 || !NetworkUtils.IsValidIp(ipInfo[0])) + if (ipInfo.Length != 2 || !NetworkUtils.IsValidIpv4(ipInfo[0])) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid IPv4 address '{0}' for static NAT rule's source address object.", sourceAddressNode.Value); @@ -1436,7 +1436,7 @@ public override void Parse(XElement objectNode, string zoneName) foreach (var destAddressNode in destAddressNodes) { string[] ipInfo = destAddressNode.Value.Split('/'); - if (ipInfo.Length != 2 || !NetworkUtils.IsValidIp(ipInfo[0])) + if (ipInfo.Length != 2 || !NetworkUtils.IsValidIpv4(ipInfo[0])) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid IPv4 address '{0}' for static NAT rule's destination address object.", destAddressNode.Value); @@ -1465,7 +1465,7 @@ public override void Parse(XElement objectNode, string zoneName) if (prefixNode != null) { string[] ipInfo = prefixNode.Value.Split('/'); - if (ipInfo.Length != 2 || !NetworkUtils.IsValidIp(ipInfo[0])) + if (ipInfo.Length != 2 || !NetworkUtils.IsValidIpv4(ipInfo[0])) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = string.Format("Invalid IPv4 address '{0}' for static NAT rule's prefix object.", prefixNode.Value); diff --git a/NetScreenMigration/ScreenOSCommands.cs b/NetScreenMigration/ScreenOSCommands.cs index a21f6efb..f43645f3 100644 --- a/NetScreenMigration/ScreenOSCommands.cs +++ b/NetScreenMigration/ScreenOSCommands.cs @@ -253,7 +253,7 @@ public bool IsWildCardMask { get { - if (string.IsNullOrEmpty(_mask) || NetworkUtils.IsValidNetmask(_mask)) + if (string.IsNullOrEmpty(_mask) || NetworkUtils.IsValidNetmaskv4(_mask)) { return false; } @@ -319,7 +319,7 @@ public override void Parse(ScreenOSCommand command) ObjectName = command.GetParam(3); string commandParam = command.GetParam(5); - if (NetworkUtils.IsValidNetmask(commandParam) || NetworkUtils.IsWildCardNetmask(commandParam)) + if (NetworkUtils.IsValidNetmaskv4(commandParam) || NetworkUtils.IsWildCardNetmask(commandParam)) { Netmask = commandParam; if (NetworkUtils.GetMaskLength(Netmask) == 32) @@ -333,7 +333,7 @@ public override void Parse(ScreenOSCommand command) IpAddress = NetworkUtils.GetNetwork(command.GetParam(4), Netmask); } } - else if (NetworkUtils.IsValidIp(commandParam)) + else if (NetworkUtils.IsValidIpv4(commandParam)) { // Complex wild card not supported, e.g 0.255.0.255 AddressType = AddressTypeEnum.Network; @@ -675,8 +675,8 @@ public override void Parse(ScreenOSCommand command) IpAddressFirst = command.GetParam(3); IpAddressLast = command.GetParam(4); - if (!NetworkUtils.IsValidIp(IpAddressFirst) || - !NetworkUtils.IsValidIp(IpAddressLast) || + if (!NetworkUtils.IsValidIpv4(IpAddressFirst) || + !NetworkUtils.IsValidIpv4(IpAddressLast) || NetworkUtils.Ip2Number(IpAddressLast) < NetworkUtils.Ip2Number(IpAddressFirst)) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; @@ -917,7 +917,7 @@ public override void Parse(ScreenOSCommand command) } else if (commandParam.Length == 1) { - if (NetworkUtils.IsValidIp(commandParam[0])) + if (NetworkUtils.IsValidIpv4(commandParam[0])) { IP = commandParam[0]; Mask = command.GetParam(5); @@ -1024,7 +1024,7 @@ public override void Parse(ScreenOSCommand command) Network = commandParam[0]; Mask = NetworkUtils.MaskLength2Netmask(int.Parse(commandParam[1])); - if (!NetworkUtils.IsValidIp(Network)) + if (!NetworkUtils.IsValidIpv4(Network)) { ConversionIncidentType = ConversionIncidentType.ManualActionRequired; ConversionIncidentMessage = "ScreenOS route object network or mask is invalid. Ignoring this command"; @@ -1325,7 +1325,7 @@ private PolicyNatTypeEnum ParseNatPart(ScreenOSCommand command, ref int baseInde DestNatIp.Add(commandString); commandString = command.GetParam(++baseIndex); - if (NetworkUtils.IsValidIp(commandString)) + if (NetworkUtils.IsValidIpv4(commandString)) { DestNatIp.Add(commandString); commandString = command.GetParam(++baseIndex); @@ -1534,7 +1534,7 @@ public override void Parse(ScreenOSCommand command) // Get Mip string commandParam = command.GetParam(++paramIndex); - if (NetworkUtils.IsValidIp(commandParam)) + if (NetworkUtils.IsValidIpv4(commandParam)) { Mip = commandParam; } @@ -1548,7 +1548,7 @@ public override void Parse(ScreenOSCommand command) // Get IP paramIndex += 2; commandParam = command.GetParam(paramIndex); - if (NetworkUtils.IsValidIp(commandParam)) + if (NetworkUtils.IsValidIpv4(commandParam)) { Ip = commandParam; } @@ -1562,7 +1562,7 @@ public override void Parse(ScreenOSCommand command) // Get Mask paramIndex += 2; commandParam = command.GetParam(paramIndex); - if (NetworkUtils.IsValidNetmask(commandParam)) + if (NetworkUtils.IsValidNetmaskv4(commandParam)) { Mask = commandParam; } diff --git a/NetScreenMigration/ScreenOSConverter.cs b/NetScreenMigration/ScreenOSConverter.cs index d3068804..108f67bf 100644 --- a/NetScreenMigration/ScreenOSConverter.cs +++ b/NetScreenMigration/ScreenOSConverter.cs @@ -51,19 +51,19 @@ public class ScreenOSNetworkUtil public static bool IsMask(string maskLength) { int n; - return (int.TryParse(maskLength, out n) && NetworkUtils.IsValidNetmask(NetworkUtils.MaskLength2Netmask(n))); + return (int.TryParse(maskLength, out n) && NetworkUtils.IsValidNetmaskv4(NetworkUtils.MaskLength2Netmask(n))); } public static bool IsHost(string host) { string[] hostArray = host.Split('/'); - return (hostArray.Length == 2 && NetworkUtils.IsValidIp(hostArray[0]) && IsMask(hostArray[1]) && int.Parse(hostArray[1]) == 32); + return (hostArray.Length == 2 && NetworkUtils.IsValidIpv4(hostArray[0]) && IsMask(hostArray[1]) && int.Parse(hostArray[1]) == 32); } public static bool IsNetwork(string host) { string[] hostArray = host.Split('/'); - return (hostArray.Length == 2 && NetworkUtils.IsValidIp(hostArray[0]) && IsMask(hostArray[1]) && int.Parse(hostArray[1]) < 32); + return (hostArray.Length == 2 && NetworkUtils.IsValidIpv4(hostArray[0]) && IsMask(hostArray[1]) && int.Parse(hostArray[1]) < 32); } public static bool IsIPv6(string ip) From 6aee0e0f7e2dc40988cc7a881fc0fe03df67bcda Mon Sep 17 00:00:00 2001 From: Kanstantsin Sharsniou Date: Mon, 9 Nov 2020 17:59:57 +0300 Subject: [PATCH 02/64] use actual host and network names in NAT from cisco configuration --- CiscoMigration/CiscoConverter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CiscoMigration/CiscoConverter.cs b/CiscoMigration/CiscoConverter.cs index 87a2d841..aad073c3 100644 --- a/CiscoMigration/CiscoConverter.cs +++ b/CiscoMigration/CiscoConverter.cs @@ -3376,7 +3376,7 @@ private void Add_object_NAT() var network = new CiscoNetwork(ciscoNat.Id, ciscoNetwork.HostAddress); var cpHostTranslated = new CheckPoint_Host(); - cpHostTranslated.Name = network.AutoGeneratedName(); + cpHostTranslated.Name = ciscoNetworkObjectName; cpHostTranslated.IpAddress = network.IpAddress; ApplyConversionIncidentOnCheckPointObject(cpHostTranslated, ciscoNat); AddCheckPointObject(cpHostTranslated); @@ -3390,7 +3390,7 @@ private void Add_object_NAT() var network = new CiscoNetwork(ciscoNat.Id, ciscoNetwork.Network, ciscoNetwork.Netmask, ciscoNetwork.MaskPrefix); var cpNetworkTranslated = new CheckPoint_Network(); - cpNetworkTranslated.Name = network.AutoGeneratedName(); + cpNetworkTranslated.Name = ciscoNetworkObjectName; cpNetworkTranslated.Subnet = network.IpAddress; cpNetworkTranslated.Netmask = network.NetMask; ApplyConversionIncidentOnCheckPointObject(cpNetworkTranslated, ciscoNat); From b15e8f3c4dc200f6da8eab4c0a13e59e87f177e2 Mon Sep 17 00:00:00 2001 From: Kanstantsin Sharsniou Date: Wed, 11 Nov 2020 15:08:11 +0300 Subject: [PATCH 03/64] propper IPRange creation based on network; prevent NPE --- CheckPointObjects/CheckPointObjects.cs | 9 ++++++++- CommonUtils/IPRange.cs | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/CheckPointObjects/CheckPointObjects.cs b/CheckPointObjects/CheckPointObjects.cs index d0aee06d..477f3661 100644 --- a/CheckPointObjects/CheckPointObjects.cs +++ b/CheckPointObjects/CheckPointObjects.cs @@ -255,7 +255,14 @@ public class CheckPoint_Network : CheckPointObject public override IPRanges GetIPRanges() { - return new IPRanges(new IPRange(IPNetwork.Parse(Subnet, Netmask))); + if (!string.IsNullOrEmpty(Netmask)) + { + return new IPRanges(new IPRange(IPNetwork.Parse(Subnet, Netmask))); + } + else + { + return new IPRanges(new IPRange(IPNetwork.Parse($"{Subnet}/{MaskLenght}"))); + } } public override string ToCLIScript() diff --git a/CommonUtils/IPRange.cs b/CommonUtils/IPRange.cs index e80d1671..8d6bbe0c 100644 --- a/CommonUtils/IPRange.cs +++ b/CommonUtils/IPRange.cs @@ -30,7 +30,7 @@ public class IPRange #region Constants public const string Any = "any"; - + #endregion #region Private Members @@ -39,7 +39,7 @@ public class IPRange private IPAddress _toIP; private UInt32 _minimum; private UInt32 _maximum; - + #endregion #region Properties @@ -68,7 +68,7 @@ public UInt32 Maximum _toIP = IPAddress.Parse(NetworkUtils.Number2Ip(_maximum)); } } - + #endregion #region Construction @@ -104,7 +104,7 @@ public IPRange(IPNetwork ip) _fromIP = ip.Network; _toIP = ip.Broadcast; _minimum = NetworkUtils.Ip2Number(_fromIP); - _maximum = NetworkUtils.Ip2Number(_toIP); + _maximum = NetworkUtils.Ip2Number(_toIP == null ? _fromIP : _toIP); } public IPRange(IPAddress from, IPAddress to) @@ -122,7 +122,7 @@ public IPRange(UInt32 min, UInt32 max) _minimum = min; _maximum = max; } - + #endregion #region Methods @@ -146,7 +146,7 @@ public override string ToString() { return string.Format("[{0} - {1}]", _fromIP, _toIP); } - + #endregion } @@ -158,7 +158,7 @@ public class IPRanges #region Private Members private List _ranges = null; - + #endregion #region Properties @@ -167,7 +167,7 @@ public List Ranges { get { return _ranges ?? (_ranges = new List()); } } - + #endregion #region Construction @@ -185,7 +185,7 @@ public IPRanges(List ranges) { Ranges.AddRange(ranges); } - + #endregion #region Methods @@ -329,7 +329,7 @@ public static IPRanges Negate(IPRange r1, IPRanges negatedRanges) return new IPRanges(res); } - + #endregion } } From 69226c437a7f147dba49c3c1647441ac1d3d299f Mon Sep 17 00:00:00 2001 From: Roman Shibalov Date: Thu, 11 Feb 2021 12:10:31 +0300 Subject: [PATCH 04/64] add compatibility with c# 6 --- .gitignore | 362 ++++++++++++++++++++++++++++++++ CiscoMigration/CiscoCommands.cs | 8 +- CommonUtils/NetworkUtils.cs | 10 +- 3 files changed, 375 insertions(+), 5 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..3a8542dc --- /dev/null +++ b/.gitignore @@ -0,0 +1,362 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/CiscoMigration/CiscoCommands.cs b/CiscoMigration/CiscoCommands.cs index 5cd5733e..0bcbefa6 100644 --- a/CiscoMigration/CiscoCommands.cs +++ b/CiscoMigration/CiscoCommands.cs @@ -563,7 +563,9 @@ public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dicti Network = command.GetParam(1); Netmask = command.GetParam(2); - if (NetworkUtils.TryParseNetwortWithPrefix(Network, out string sNetwork, out string sMaskLength)) + string sNetwork; + string sMaskLength; + if (NetworkUtils.TryParseNetwortWithPrefix(Network, out sNetwork, out sMaskLength)) { Network = sNetwork; MaskPrefix = sMaskLength; @@ -773,7 +775,9 @@ public override void Parse(CiscoCommand command, CiscoCommand prevCommand, Dicti } Netmask = command.GetParam(2); - if (NetworkUtils.TryParseNetwortWithPrefix(IpAddress, out string sIp, out string sMaskLenth)) + string sIp; + string sMaskLenth; + if (NetworkUtils.TryParseNetwortWithPrefix(IpAddress, out sIp, out sMaskLenth)) { IpAddress = sIp; MaskPrefix = sMaskLenth; diff --git a/CommonUtils/NetworkUtils.cs b/CommonUtils/NetworkUtils.cs index d421b758..2b2fcc9c 100644 --- a/CommonUtils/NetworkUtils.cs +++ b/CommonUtils/NetworkUtils.cs @@ -47,7 +47,8 @@ private static bool IsValidIp(String sIp, AddressFamily[] allowedAddressFamilies return false; } - if (IPAddress.TryParse(sIp, out IPAddress ip) && Array.Exists(allowedAddressFamilies, e => e == ip.AddressFamily)) + IPAddress ip; + if (IPAddress.TryParse(sIp, out ip) && Array.Exists(allowedAddressFamilies, e => e == ip.AddressFamily)) { return true; } @@ -76,7 +77,8 @@ private static bool IsValidNetmask(String sNetmask, AddressFamily[] allowedAddre return false; } - if (IPAddress.TryParse(sNetmask, out IPAddress netmask) && Array.Exists(allowedAddressFamilies, e => e == netmask.AddressFamily)) + IPAddress netmask = null; + if (IPAddress.TryParse(sNetmask, out netmask) && Array.Exists(allowedAddressFamilies, e => e == netmask.AddressFamily)) { return IPNetwork.ValidNetmask(netmask); } @@ -87,7 +89,9 @@ public static bool TryParseNetwortWithPrefix(String sNetwork, out String sIp, ou sIp = ""; sMaskLenght = ""; String[] splitedNetwork = sNetwork.Split('/'); - if (splitedNetwork.Length == 2 && IPAddress.TryParse(splitedNetwork[0], out IPAddress ipAddr) && int.TryParse(splitedNetwork[1], out int maskLengthNum)) + IPAddress ipAddr = null; + int maskLengthNum = 0; + if (splitedNetwork.Length == 2 && IPAddress.TryParse(splitedNetwork[0], out ipAddr) && int.TryParse(splitedNetwork[1], out maskLengthNum)) { sMaskLenght = Convert.ToString(maskLengthNum); sIp = Convert.ToString(ipAddr); From 2fe11ffba2b20e7c2fb13b4cc948b933dad662e5 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 15 Feb 2021 16:15:21 +0300 Subject: [PATCH 05/64] Delete .gitignore --- .gitignore | 362 ----------------------------------------------------- 1 file changed, 362 deletions(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 3a8542dc..00000000 --- a/.gitignore +++ /dev/null @@ -1,362 +0,0 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Mono auto generated files -mono_crash.* - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Ww][Ii][Nn]32/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ -[Ll]ogs/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUnit -*.VisualState.xml -TestResult.xml -nunit-*.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# ASP.NET Scaffolding -ScaffoldingReadMe.txt - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Coverlet is a free, cross platform Code Coverage Tool -coverage*.json -coverage*.xml -coverage*.info - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# NuGet Symbol Packages -*.snupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx -*.appxbundle -*.appxupload - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- [Bb]ackup.rdl -*- [Bb]ackup ([0-9]).rdl -*- [Bb]ackup ([0-9][0-9]).rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# BeatPulse healthcheck temp database -healthchecksdb - -# Backup folder for Package Reference Convert tool in Visual Studio 2017 -MigrationBackup/ - -# Ionide (cross platform F# VS Code tools) working folder -.ionide/ - -# Fody - auto-generated XML schema -FodyWeavers.xsd \ No newline at end of file From 84e4327bedf5ab7d162afa24ea52e80d4200e589 Mon Sep 17 00:00:00 2001 From: Roman Shibalov Date: Mon, 15 Feb 2021 17:22:34 +0300 Subject: [PATCH 06/64] fix with support string.format --- CheckPointObjects/CheckPointObjects.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CheckPointObjects/CheckPointObjects.cs b/CheckPointObjects/CheckPointObjects.cs index 477f3661..925a1c49 100644 --- a/CheckPointObjects/CheckPointObjects.cs +++ b/CheckPointObjects/CheckPointObjects.cs @@ -261,7 +261,7 @@ public override IPRanges GetIPRanges() } else { - return new IPRanges(new IPRange(IPNetwork.Parse($"{Subnet}/{MaskLenght}"))); + return new IPRanges(new IPRange(IPNetwork.Parse(String.Format("{0}/{1}", Subnet, MaskLenght)))); } } From 3a99a269c5b9b926e507ab6db6eeccb13a790d7d Mon Sep 17 00:00:00 2001 From: Kanstantsin Sharsniou Date: Fri, 13 Nov 2020 10:15:00 +0300 Subject: [PATCH 07/64] add pagination for big network and service groups in result .sh files --- CheckPointObjects/CheckPointObjects.cs | 43 +++++++++-------- MigrationBase/VendorConverter.cs | 67 +++++++++++++++++--------- 2 files changed, 67 insertions(+), 43 deletions(-) diff --git a/CheckPointObjects/CheckPointObjects.cs b/CheckPointObjects/CheckPointObjects.cs index fc7f99ac..e393afd6 100644 --- a/CheckPointObjects/CheckPointObjects.cs +++ b/CheckPointObjects/CheckPointObjects.cs @@ -19,6 +19,7 @@ limitations under the License. using System.Collections.Generic; using System.Linq; using System.Net; +using System.Text; using System.Text.RegularExpressions; using CommonUtils; @@ -112,7 +113,12 @@ protected static string WriteParam(string paramName, string paramValue, string d protected static string WriteListParam(string paramName, List paramValues, bool useSafeNames) { - if (paramValues.Count == 0) + return WriteListParam(paramName, paramValues, useSafeNames, 0, paramValues.Count); + } + + protected static string WriteListParam(string paramName, List paramValues, bool useSafeNames, int firstIndex, int maxSize) + { + if (paramValues.Count == 0 || firstIndex >= paramValues.Count || maxSize <= 0) { return ""; } @@ -122,22 +128,15 @@ protected static string WriteListParam(string paramName, List paramValue return WriteParam(paramName, paramValues[0], ""); } - string str = ""; - int i = 0; - - foreach (string paramValue in paramValues) + var sb = new StringBuilder(""); + int maxIndex = ((firstIndex + maxSize) < paramValues.Count) ? (firstIndex + maxSize) : paramValues.Count; + for (int i = firstIndex; i < maxIndex; i++) { - string val = paramValue; - if (useSafeNames) - { - val = GetSafeName(paramValue); - } - - str += string.Format("{0}.{1} \"{2}\" ", paramName, i, val); - i++; + string value = useSafeNames ? paramValues[i] : GetSafeName(paramValues[i]); + sb.AppendFormat("{0}.{1} \"{2}\" ", paramName, i, value); } - return str; + return sb.ToString(); } protected static string WriteListParamWithIndexes(string paramName, List paramValues, bool useSafeNames, int i = 0) @@ -289,17 +288,19 @@ public class CheckPoint_NetworkGroup : CheckPointObject /// GroupWithExclusion and NetworkGroup types cross-referencing each other. /// public bool CreateAfterGroupsWithExclusion { get; set; } + public int MembersPublishIndex { get; set; } = 0; + public int MembersMaxPublishSize { get; set; } = Int32.MaxValue; public override string ToCLIScript() { - return "add group " + WriteParam("name", SafeName(), "") + WriteParam("comments", Comments, "") - + WriteListParam("members", Members, true) + return (MembersPublishIndex == 0 ? "add " : "set ") + "group " + WriteParam("name", SafeName(), "") + WriteParam("comments", Comments, "") + + WriteListParam("members", Members, true, MembersPublishIndex, MembersMaxPublishSize) + WriteListParam("tags", Tags, true); } public override string ToCLIScriptInstruction() { - return "create network group [" + Name + "]: " + Members.Count + " members"; + return (MembersPublishIndex == 0 ? "create " : "update ") + "network group [" + Name + "]: " + Members.Count + " members"; } } @@ -476,17 +477,19 @@ public override string ToCLIScriptInstruction() public class CheckPoint_ServiceGroup : CheckPointObject { public List Members = new List(); + public int MembersPublishIndex { get; set; } = 0; + public int MembersMaxPublishSize { get; set; } = Int32.MaxValue; public override string ToCLIScript() { - return "add service-group " + WriteParam("name", SafeName(), "") + WriteParam("comments", Comments, "") - + WriteListParam("members", Members, true) + return (MembersPublishIndex == 0 ? "add " : "set ") + "service-group " + WriteParam("name", SafeName(), "") + WriteParam("comments", Comments, "") + + WriteListParam("members", Members, true, MembersPublishIndex, MembersMaxPublishSize) + WriteListParam("tags", Tags, true); } public override string ToCLIScriptInstruction() { - return "create service group [" + Name + "]: " + Members.Count + " members"; + return (MembersPublishIndex == 0 ? "create " : "update ") + "service group [" + Name + "]: " + Members.Count + " members"; } } diff --git a/MigrationBase/VendorConverter.cs b/MigrationBase/VendorConverter.cs index 4dd29563..c5d3e209 100644 --- a/MigrationBase/VendorConverter.cs +++ b/MigrationBase/VendorConverter.cs @@ -122,7 +122,7 @@ protected void RaiseConversionProgress(int progress, string title) ConversionProgress(progress, title); } } - + #endregion #region Methods @@ -216,7 +216,7 @@ public void CleanCheckPointObjectsLists() public abstract void ExportConfigurationAsHtml(); public abstract void ExportPolicyPackagesAsHtml(); protected abstract string GetVendorName(); - + #endregion public void ExportNatLayerAsHtml() @@ -534,7 +534,7 @@ public void ExportNatLayerAsHtml() file.WriteLine(""); file.WriteLine(""); } - + } protected virtual bool AddCheckPointObject(CheckPointObject cpObject) @@ -733,7 +733,7 @@ protected List Add_or_Modify_InterfaceNetworkGroups(List= range1[0]) && (range2[0] <= range1[1])) || + if (((range2[0] >= range1[0]) && (range2[0] <= range1[1])) || ((range1[0] >= range2[0]) && (range1[0] <= range2[1]))) { if (range1[1] - range1[0] > range2[1] - range2[0]) @@ -835,6 +835,7 @@ protected IPRanges GetGroupWithExclusionRanges(CheckPoint_NetworkGroup includeGr protected void CreateObjectsScript() { const int publishLatency = 100; + const int groupsMaxBulkSize = 100; using (var file = new StreamWriter(ObjectsScriptFile, false)) { @@ -970,12 +971,18 @@ protected void CreateObjectsScript() continue; } - file.WriteLine(CLIScriptBuilder.GenerateObjectScript(obj)); - - objectsCount++; - if (objectsCount % publishLatency == 0) + obj.MembersMaxPublishSize = groupsMaxBulkSize; + for (int i = 0; i < obj.Members.Count; i += groupsMaxBulkSize) { - file.WriteLine(CLIScriptBuilder.GeneratePublishScript()); + obj.MembersPublishIndex = i; + + file.WriteLine(CLIScriptBuilder.GenerateObjectScript(obj)); + + objectsCount++; + if (objectsCount % publishLatency == 0) + { + file.WriteLine(CLIScriptBuilder.GeneratePublishScript()); + } } } file.WriteLine(CLIScriptBuilder.GeneratePublishScript()); @@ -1173,13 +1180,27 @@ protected void CreateObjectsScript() int objectsCount = 0; foreach (CheckPoint_ServiceGroup obj in _cpServiceGroups) { - file.WriteLine(CLIScriptBuilder.GenerateObjectScript(obj)); + obj.MembersMaxPublishSize = groupsMaxBulkSize; + for (int i = 0; i < obj.Members.Count; i += groupsMaxBulkSize) + { + obj.MembersPublishIndex = i; + + file.WriteLine(CLIScriptBuilder.GenerateObjectScript(obj)); + + objectsCount++; + if (objectsCount % publishLatency == 0) + { + file.WriteLine(CLIScriptBuilder.GeneratePublishScript()); + } + } + + /* file.WriteLine(CLIScriptBuilder.GenerateObjectScript(obj)); objectsCount++; if (objectsCount % publishLatency == 0) { file.WriteLine(CLIScriptBuilder.GeneratePublishScript()); - } + } */ } file.WriteLine(CLIScriptBuilder.GeneratePublishScript()); } @@ -1260,12 +1281,12 @@ protected void CreateObjectsScript() for (int i = 0; i < obj.Users.Count; i++) { var sb_set = new StringBuilder(); - + sb_set.Append("cmd='mgmt_cli ") .Append("set access-role ") .Append("name " + "\"" + obj.SafeName() + "\" "); - if(obj.Networks.Count == 0) + if (obj.Networks.Count == 0) { sb_set.Append("networks \"any\" "); } @@ -1279,7 +1300,7 @@ protected void CreateObjectsScript() .Append("users.add.selection." + i + " \"" + obj.Users[i].Name + "\" ") .Append(!(string.IsNullOrWhiteSpace(obj.Users[i].BaseDn)) ? "users.add.base-dn \"" + obj.Users[i].BaseDn + "\"" : "") .Append(" ignore-warnings true -s id.txt --user-agent mgmt_cli_smartmove'"); - + file.WriteLine(" " + sb_set.ToString()); file.WriteLine(" " + "run_command"); } @@ -1349,15 +1370,15 @@ protected void CreatePackagesScript() file.WriteLine(CLIScriptBuilder.GeneratePublishScript()); // Enabling Applications and URL Filtering in parent layer - if(package.ParentLayer.ApplicationsAndUrlFiltering) + if (package.ParentLayer.ApplicationsAndUrlFiltering) { file.WriteLine("echo 'Enabling Applications and URL Filtering in parent layer vsys1_policy Network'"); - file.WriteLine("cmd='mgmt_cli set access-layer " + - "name \"" + package.ParentLayer.Name + "\" " + - "applications-and-url-filtering \"true\" " + + file.WriteLine("cmd='mgmt_cli set access-layer " + + "name \"" + package.ParentLayer.Name + "\" " + + "applications-and-url-filtering \"true\" " + "ignore-warnings true -s id.txt --user-agent mgmt_cli_smartmove'"); file.WriteLine("run_command"); - file.WriteLine(CLIScriptBuilder.GeneratePublishScript()); + file.WriteLine(CLIScriptBuilder.GeneratePublishScript()); } file.WriteLine(CLIScriptBuilder.GenerateInstructionScript(string.Format("Add rules to parent layer {0}", package.NameOfAccessLayer))); // !!! Attention !!! -- the rules are created in the reverse order but will be inserted at the TOP (!!!) position, @@ -1580,7 +1601,7 @@ protected void CreateObjectsHtml() var sb_add = new StringBuilder(); sb_add.Append("add access-role ") .Append("name " + "\"" + obj.SafeName() + "\" "); - + if (obj.Networks.Count == 0) { sb_add.Append("networks \"any\" "); @@ -1600,7 +1621,7 @@ protected void CreateObjectsHtml() for (int i = 0; i < obj.Users.Count; i++) { file.WriteLine("
"); - + var sb_set = new StringBuilder(); sb_set.Append("set access-role ") .Append("name " + "\"" + obj.SafeName() + "\" "); @@ -1619,9 +1640,9 @@ protected void CreateObjectsHtml() .Append("users.add.selection." + i + " \"" + obj.Users[i].Name + "\" ") .Append(!(string.IsNullOrWhiteSpace(obj.Users[i].BaseDn)) ? "users.add.base-dn \"" + obj.Users[i].BaseDn + "\"" : ""); - + file.WriteLine(sb_set.ToString()); - + file.WriteLine("
"); } } From d6d4c39965b32b59f0e0977cad9eb77e875b48b8 Mon Sep 17 00:00:00 2001 From: Roman Shibalov Date: Fri, 19 Feb 2021 12:00:36 +0300 Subject: [PATCH 08/64] validate max packages layers number --- CiscoMigration/CiscoConverter.cs | 3 +++ FortinetMigration/FortiGateConverter.cs | 2 ++ JuniperMigration/JuniperConverter.cs | 3 +++ MigrationBase/VendorConverter.cs | 12 ++++++++++++ NetScreenMigration/ScreenOSConverter.cs | 7 +++++-- PaloAltoMigration/PaloAltoConverter.cs | 1 + PaloAltoMigration/PanoramaConverter.cs | 10 +++++++++- 7 files changed, 35 insertions(+), 3 deletions(-) diff --git a/CiscoMigration/CiscoConverter.cs b/CiscoMigration/CiscoConverter.cs index 28116ddd..4cf5796d 100644 --- a/CiscoMigration/CiscoConverter.cs +++ b/CiscoMigration/CiscoConverter.cs @@ -2275,6 +2275,7 @@ private void Add_Layers_And_Rules(CheckPoint_Package package) } package.SubPolicies.Add(cpLayer); + validatePackage(package); } } } @@ -3175,6 +3176,7 @@ private void Add_Layers_And_Rules_For_Other_Zones(CheckPoint_Package package) cpLayer.Rules.Add(cpCleanupRule); package.SubPolicies.Add(cpLayer); + validatePackage(package); } } } @@ -4433,6 +4435,7 @@ private void Add_Optimized_Package() { regular2OptimizedLayers.Add(layer.Name, optimizedSubPolicyName); optimizedPackage.SubPolicies.Add(optimizedLayer); + validatePackage(optimizedPackage); } } diff --git a/FortinetMigration/FortiGateConverter.cs b/FortinetMigration/FortiGateConverter.cs index dcfcebeb..83de468f 100644 --- a/FortinetMigration/FortiGateConverter.cs +++ b/FortinetMigration/FortiGateConverter.cs @@ -2725,6 +2725,7 @@ public void Add_ParentLayer(CheckPoint_Package package, List fgComman cpRuleLayer.Name = cpRuleZone.SubPolicyName; package.SubPolicies.Add(cpRuleLayer); + validatePackage(package); CheckPoint_Rule cpSubRuleZone = new CheckPoint_Rule(); cpSubRuleZone.Name = ""; //"intrazone_sr_" + cpZoneIntra.Name; @@ -3290,6 +3291,7 @@ public void Add_ParentLayer(CheckPoint_Package package, List fgComman cpLayer.Rules.Add(cpRuleCU); package.SubPolicies.Add(cpLayer); + validatePackage(package); } } else diff --git a/JuniperMigration/JuniperConverter.cs b/JuniperMigration/JuniperConverter.cs index 124b48e3..06e09cd8 100644 --- a/JuniperMigration/JuniperConverter.cs +++ b/JuniperMigration/JuniperConverter.cs @@ -1071,6 +1071,7 @@ private void Add_Layers_And_Rules(CheckPoint_Package package) } package.SubPolicies.Add(cpLayer); + validatePackage(package); } } @@ -1108,6 +1109,7 @@ private void Add_Global_Rules(CheckPoint_Package package) cpSubLayer4GlobalRules.Name = cpRule4GlobalLayer.SubPolicyName; package.SubPolicies.Insert(0, cpSubLayer4GlobalRules); // insert at the begging becuase Global Rules should be created before all policy + validatePackage(package); foreach (var globalPolicyRule in _juniperParser.GetGlobalPolicyRules()) { @@ -1256,6 +1258,7 @@ private void Add_Global_Rules(CheckPoint_Package package) cpLayer.Tag = ","; // this info is needed later for global policy rules - in this case this sub-policy will be skipped!!! package.SubPolicies.Add(cpLayer); + validatePackage(package); // 3. Create a new rule and add to this sub-policy var cpRule = Juniper_To_CPRule(globalPolicyRule, cpLayer.Name, sourceZone, destZone); diff --git a/MigrationBase/VendorConverter.cs b/MigrationBase/VendorConverter.cs index 27224b13..beddb38b 100644 --- a/MigrationBase/VendorConverter.cs +++ b/MigrationBase/VendorConverter.cs @@ -51,6 +51,7 @@ public abstract class VendorConverter protected const string HtmlSubPolicyArrowImageTagFormat = ""; protected const string HtmlToolLogoImageSource = "src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAgCAYAAACcuBHKAAAACXBIWXMAAAsSAAALEgHS3X78AAABkElEQVRYw+2XvXGDQBCFv/MoNx2YbEPRgZhRA+rA6sC4A7kD1IFUgdUAY9wBhJvJHeAKcMDJw2AQf5JwoBcecLx7b/exmDzPmRoP/APcSVyHRGR8IrMjMs7USjwDMZFxp7ZjDiRExp+6Jh6BDyITtN1oWnOi8HcFdJHXtXZUsQcClnnWn0RkNkBgTzUWKbBimR+rF2ZnCOwaTnVxzBoIBDUEUiABjrexIzJZyYJvK2PcKSfgo7L6yjIP+ylRbFSugW4E/qIz+fYWHUYgBbzTs6q6UlXvljmxB/xTF6jqGngH4iYidYWZ2JPM7Ya/UNUQyERkc0a1qnLrUnit7P4tShQV7NuCWtuXO6oaAy8DlHGGtWhBJLQEPOAAPPV9u6q6VtGyyv1qwvoZjyBwqCzHvWLb+l8n/2fTZqXAcoFFZX0rIkEnEqrq2BMsLtgxqYjctEWpUcAb9CkfYccJGXAQkeOoecIWZliJ8bfGnLjGoCsiO5sZX5NO2yKSAJ61YbqRX0QyEfGB7TVImPu/6J1EBT9qv6X93O05TAAAAABJRU5ErkJggg=='"; protected const string HtmlCPLogoImageSource = "src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHYAAAAUCAYAAABYm8lAAAAACXBIWXMAAAsSAAALEgHS3X78AAAHwklEQVRo3u1aaWwUZRh+tpwC7Q5Xg1KWxRhDgaYrECoe7DSgQcGw1ggKMSxREtBEy79CSLokGggkspKYEmLS5Sj+IWSbICEQZIoVoQJOQUCOyDKAIJI6WxoRsLv+6Ptt3375Zo/W/WH0TSY7813z3tes67dP6gwAfuQHKketWWFIY14AIQBLpfFGGjfpOUhXNRvLF/gAhAFE6MoWjAxzYQB2jueZRHNvQBPv659uVfsDFy786ko9Fw0GSosTPdacsAoAABWeRLYMNAC4AVwDECVEAgAWANDpMkkB/IRsvkGjdxk57hMG0SSdVU5zAaI51/OQozL4AQynewNAtaNgb8RdWLK3EO+8OwmaeyDs+EOcPduGs4fbYFkdcLsHoqxsBCyrA5bVgYa3H2YSrsaEuoq0WUCIrloSthf/LtAVXskgAQdz8AKVOVq4DLYwBEfBbmnuD9+MMaipcVa4DetNLF7yFOrqzuP8xTOZBBskoTZKQuXCDRAzZEZxzY8pGOWl8wVEaJ28JsA8QCwLhgdpn0kKly3EiMbNkpLKFizjqdOzybxXiOHB8fZK49U8lDgKdu+P/VDz2ggAwO6GK7CsDtSs7ilka/8xxOd74HYPxL0/MxIbYAJMt8bLCAMxqFzBcJ3d10vztQCWMcGp1ghm6A64RCgPaHVQxFxdfVThamU8a8mtRwivWvr1K0JalOah2IsCFRYX7nQNa+6BAICxo77H48O2YXfDFTRv2ottn57EvHkHcOfM1R6uO8v4YWbQdENyR+VEvAvABIrNfiJOJ4G10pyL3FmchKGRogjBiHOGExPKHRIVLlS9F+7Ry86N0b3fAc/6NMolhFhJe56hPR8RHyvpTOHGU7QoBdtO1ldW1mWx350uReWCjbhy7DJ27riMc+d+x6JXirFo5Uz8dHxVtoLtLXzGNJq7T40REmAuzaBxN1lqgO7Xsb02zTUpkjMh1MYchGqwKwbgKoDxxPQIw1NX4AkpjKi8isGMIiIloraUUcPRFY91J7uj8Y02nDr+S9fDoYMYrc/Gc7O2Ysqs7fB4pmLypE4sXNiJlusF+RJsNIM2QxErNWleVZrEmKXojIlutr43iUyMeZ4w4eAmJbIVtNVnSBZjigQpIyilUcIEG6o5huVvlaBmtQ+jq5dj6tzJ2LX/A3g8wwAA586/iTlzxmbzrlYFs2UIA0jmUMeNT5MdCkbmkmGL5E7kAtnu1RVXiGepafDMCzgmT6XFSdy69QceFGqoeHUiAGDl+5MAAFVVE3omUVZHtvWWiGnBDAmWwe7TQRPFLl1hsT4pvmlpGgJR1iQJsNIrkiH+ZQMmi7uqWJwXcPSfFZ4EIpFLqKt7AW5KonrE4faH+Lb5NlavbkFNTUs27xIJzFIHwYbIApty6DQZzIXKcekICclMs0YWuMlwaaX56j7y2KazxivoDmcRbnLpnmW22OD0v7Cl+SZemtaAQWNG9phrbr6dsuonipKYPS4Jv56x8xSjrLSeriATjEjp4zkyMkzrNzML9ZLyxMnibCZEkeDwNU4uNwjgB5qPKmJdLiAUrZ4lUDrLlCN9VByh5KlEzVGwJe4kNs57hBNWJ05Y93HprgsPhxThmtVBmTdw4Y4LF+64UnXv2gMDsHb2I7xR1ok0taFNzPJL9VlTL/rCNjEoLPWexVk2Uxyxxs9ifpApg8qFrvuHXLJB5YiMZyPh0JdYGyb8y7nVuuSPADfiLhy63A+HLhWg5XoBViw5iC/3zcfrVV6MGTMEG9Z38X3X5i1Ys2kxAGDFkoOp+6opndg471GqRab4CCDHQcHEvCUS/0XoEWM/PjwA+tZBMB97ErcSCcycdgvX4++hpGRolwv+5nZq7ec756Jw6H18uGw/mk9OzKVRwa3N6ENZ8T9kkxW3P3AhcrJfaqKwcACGFI6CxzMM06cOwI2LO2BZc7rbQaUxFI+M4+tjU7D/yNTUeNHgjK01jcUrHz2bUgLQCaAf29cGwGKJjihjYqwF6aXLlp55bcnHbKnmNVmnymD4mAxvTXqOKWjg9AmvZEs02rRGY++XcfVJYcnLcPZJvBkh1+opwd5kljbO/QVeDK7FqdN38dU+i8qZZ1FafA8zxnXVuKePdgt5xrgEStxJlLiTeOnpRLqsLcQ6RgGKX60swQgRch0AhtH8OvIsPzMmRhmDxJmiIa5JJUaMdYR44zwiJXBtAI6ysBCk+KWz9qXOvIzOerStUu85JGXZ49H1RUuj9Y2s1NIVuIaYgvDulMESL8EbTQprvh6CLS1OYGxREjfbXWjY8zIqWo5jUnEC659PoLQqiaJByb56B5tZl0holpGQTEkL9xABtUSkjwj0sr1RdH8cDyo8g52mPNIV+0YwpnmZ9YYY00WtbWdBg84YHWDvWobuL01mmk6T5lAGxVidHWJZu620WABoWvkgn25fYy22ICPeJI3ugPojABjT+L8rIkxTfVKvlLs/M0OpYkjuzovuT2CCWT7mMoOsXaiigYcLoRw6exbr/QoaTeq8iaZJlJVx2TRCYhnr2DyAyayumrnDpQC2A7gCoATO/2LgQtdYB8tgcY8nY2FWSkTS1Ioh5kZNhqcpWYHO6AizvVGJhrVMeFGqhePME4jS6Zqibha4CqusloQaZnW5U6PDABD6G0N6q38NHi2bAAAAAElFTkSuQmCC'"; + protected const int SubPoliciesMaxNumber = 249; #endregion @@ -1308,6 +1309,16 @@ protected void CreateObjectsScript() } } + protected void validatePackage(CheckPoint_Package package) + { + if (package?.SubPolicies != null && package.SubPolicies.Count > SubPoliciesMaxNumber) + { + throw new InvalidDataException(String.Format("{1} {2}{0}{3}", Environment.NewLine + "\t", "SmartMove is unable to convert the provided policy.", + "Reason: Policy exceeds the maximum number of supported policy layers.", + "To assure the smooth conversion of your data, it is recommended to contact Check Point Professional Services by sending an e-mail to ps@checkpoint.com")); + } + } + protected void CreatePackagesScript() { const int publishLatency = 100; @@ -1315,6 +1326,7 @@ protected void CreatePackagesScript() foreach (CheckPoint_Package package in _cpPackages) { + validatePackage(package); ++packageNumber; string filename = _targetFolder + "\\" + package.Name + ".sh"; diff --git a/NetScreenMigration/ScreenOSConverter.cs b/NetScreenMigration/ScreenOSConverter.cs index 108f67bf..d30cc12b 100644 --- a/NetScreenMigration/ScreenOSConverter.cs +++ b/NetScreenMigration/ScreenOSConverter.cs @@ -1250,7 +1250,7 @@ private CheckPointObject GetCheckPointObjByIpRange(string startIp, string endIp, return cpRange; } - private CheckPointObject GetSrcObjectByNameFromPolicy(string srcName, PolicyCommandSimplifier policy, bool isNAT= false) + private CheckPointObject GetSrcObjectByNameFromPolicy(string srcName, PolicyCommandSimplifier policy, bool isNAT = false) { CheckPointObject cpObject; string sourceName = srcName; @@ -1311,7 +1311,7 @@ private CheckPointObject GetSrcObjectFromPolicyForNAT(PolicyCommandSimplifier po } else { - srcOrig = GetSrcObjectByNameFromPolicy(policy.SrcAddr.First(), policy,true); + srcOrig = GetSrcObjectByNameFromPolicy(policy.SrcAddr.First(), policy, true); } return srcOrig; @@ -2366,6 +2366,7 @@ private void Add_IntraZoneRules(CheckPoint_Package package) cpLayer.Value.Rules.Add(cpInterBlockRule); package.SubPolicies.Add(cpLayer.Value); + validatePackage(package); } } @@ -2424,6 +2425,7 @@ private void Add_InterZoneRules(CheckPoint_Package package) cpLayer.Rules.Add(cpCleanupRule); package.SubPolicies.Add(cpLayer); + validatePackage(package); } } @@ -3503,6 +3505,7 @@ private void Add_NatPolicy2RegularPolicy() } cpLayer.Rules.Last().Name = "Sub-Policy Cleanup rule"; _cpPackages[0].SubPolicies.Insert(firstGlobal,cpLayer); + validatePackage(_cpPackages[0]); } } } diff --git a/PaloAltoMigration/PaloAltoConverter.cs b/PaloAltoMigration/PaloAltoConverter.cs index 5a7ffd34..e1bb6e4e 100644 --- a/PaloAltoMigration/PaloAltoConverter.cs +++ b/PaloAltoMigration/PaloAltoConverter.cs @@ -2584,6 +2584,7 @@ public void ConvertSecurityPolicy(PA_VsysEntry paVsysEntry, cpLayer.ApplicationsAndUrlFiltering = false; cpPackage.SubPolicies.Add(cpLayer); + validatePackage(cpPackage); CheckPoint_Rule cpGroupRule = new CheckPoint_Rule(); cpGroupRule.Name = cpGroupRuleName; diff --git a/PaloAltoMigration/PanoramaConverter.cs b/PaloAltoMigration/PanoramaConverter.cs index 36016eb4..6d33bf70 100644 --- a/PaloAltoMigration/PanoramaConverter.cs +++ b/PaloAltoMigration/PanoramaConverter.cs @@ -1352,7 +1352,14 @@ public Dictionary ConvertAddresses(PA_Objects paObject cpNetwork.Comments = paAddressEntry.Description; cpNetwork.Tags = paAddressEntry.TagMembers; cpNetwork.Subnet = paAddressEntry.IpNetmask.Substring(0, indexSlash); - cpNetwork.Netmask = IPNetwork.Parse(paAddressEntry.IpNetmask).Netmask.ToString(); + if (NetworkUtils.IsValidIpv6(cpNetwork.Subnet)) + { + cpNetwork.MaskLenght = paAddressEntry.IpNetmask.Substring(indexSlash + 1); + } + else + { + cpNetwork.Netmask = IPNetwork.Parse(paAddressEntry.IpNetmask).Netmask.ToString(); + } cpAddressesDict[paAddressEntry.Name] = cpNetwork; } else if (indexSlash == -1) @@ -2873,6 +2880,7 @@ Dictionary _devicesUIDDict cpLayer.ApplicationsAndUrlFiltering = false; cpPackage.SubPolicies.Add(cpLayer); + validatePackage(cpPackage); CheckPoint_Rule cpGroupRule = new CheckPoint_Rule(); cpGroupRule.Name = cpGroupRuleName; From a4951076c3f915e4fa18068562f446dfc73b18d6 Mon Sep 17 00:00:00 2001 From: Roman Shibalov Date: Fri, 19 Feb 2021 12:06:29 +0300 Subject: [PATCH 09/64] upd newtonsoft json and proper max layers number situation processing with proper message format --- CheckPointObjects/CheckPointObjects.csproj | 5 +++++ CheckPointObjects/packages.config | 4 ++++ CiscoMigration/CiscoMigration.csproj | 6 ++++-- CiscoMigration/packages.config | 4 ++++ CommonUtils/CommonUtils.csproj | 7 +++++++ CommonUtils/packages.config | 4 ++++ FortinetMigration/FortiGateMigration.csproj | 8 ++++++-- FortinetMigration/packages.config | 4 ++++ JuniperMigration/JuniperMigration.csproj | 6 ++++-- JuniperMigration/packages.config | 4 ++++ MigrationBase/MigrationBase.csproj | 8 ++++++-- MigrationBase/VendorConverter.cs | 4 +--- MigrationBase/packages.config | 4 ++++ NetScreenMigration/NetScreenMigration.csproj | 7 ++++--- NetScreenMigration/packages.config | 4 ++++ PaloAltoMigration/PaloAltoMigration.csproj | 7 ++++--- PaloAltoMigration/packages.config | 4 ++++ SmartMove/CommandLine.cs | 13 +++++++++++-- SmartMove/MainWindow.xaml.cs | 12 +++++++++++- SmartMove/SmartMove.csproj | 6 ++++-- SmartMove/packages.config | 4 ++++ 21 files changed, 103 insertions(+), 22 deletions(-) create mode 100644 CheckPointObjects/packages.config create mode 100644 CiscoMigration/packages.config create mode 100644 CommonUtils/packages.config create mode 100644 FortinetMigration/packages.config create mode 100644 JuniperMigration/packages.config create mode 100644 MigrationBase/packages.config create mode 100644 NetScreenMigration/packages.config create mode 100644 PaloAltoMigration/packages.config create mode 100644 SmartMove/packages.config diff --git a/CheckPointObjects/CheckPointObjects.csproj b/CheckPointObjects/CheckPointObjects.csproj index 872f8916..c7f5f6b1 100644 --- a/CheckPointObjects/CheckPointObjects.csproj +++ b/CheckPointObjects/CheckPointObjects.csproj @@ -30,6 +30,10 @@ 4 + + ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll + True + @@ -71,6 +75,7 @@ PreserveNewest +