def parse(src_format, src_config, routing_info=""):

    logger.log(
        2,
        "DirectFire.Converter.parse: loading parser module for " + src_format)

    if src_format == "ciscoasa":  ## Cisco ASA
        from DirectFire.Converter.parsers.ciscoasa import parse

    elif src_format == "ciscoasa_pre83":  ## Cisco ASA pre 8.3
        from DirectFire.Converter.parsers.ciscoasa_pre83 import parse

    elif src_format == "fortigate":  ## Fortinet FortiGate
        from DirectFire.Converter.parsers.fortigate import parse

    elif src_format == "junipersrx":  ## Juniper SRX (JunOS)
        from DirectFire.Converter.parsers.junipersrx import parse

    elif src_format == "watchguard":  ## WatchGuard
        from DirectFire.Converter.parsers.watchguard import parse

    else:
        logger.log(
            2,
            "DirectFire.Converter.parse: failed to load parser module for " +
            src_format,
        )

        print(
            f"{Fore.RED}Error: failed to load parser module.{Style.RESET_ALL}")

        exit()

    logger.log(
        2,
        "DirectFire.Converter.parse: loaded parser module for " + src_format)

    logger.log(
        2,
        "DirectFire.Converter.parse: starting parse of source configuration")

    parsed_data = parse(logger, src_config, routing_info)

    logger.log(
        2,
        "DirectFire.Converter.parse: completed parse of source configuration")

    return parsed_data
def generate(dst_format, parsed_data):

    logger.log(
        2, "DirectFire.Converter.generate: loading generator module for " +
        dst_format)

    if dst_format == "ciscoasa":  ## Cisco ASA post 8.3
        from DirectFire.Converter.generators.ciscoasa import generate

    elif dst_format == "data":  ## JSON Data
        from DirectFire.Converter.generators.data import generate

    elif dst_format == "fortigate":  ## Fortinet FortiGate
        from DirectFire.Converter.generators.fortigate import generate

    else:
        logger.log(
            2,
            "DirectFire.Converter.parse: failed to load generator module for "
            + dst_format,
        )

        print(
            f"{Fore.RED}Error: failed to load generator module.{Style.RESET_ALL}"
        )

        exit()

    logger.log(
        2, "DirectFire.Converter.generate: loaded generator module for " +
        dst_format)

    logger.log(
        2,
        "DirectFire.Converter.generate: starting generation of destination output"
    )

    dst_config = generate(logger, parsed_data)

    logger.log(
        2,
        "DirectFire.Converter.generate: completed generation of destination output"
    )

    return dst_config
Ejemplo n.º 3
0
def generate(logger, parsed_data):

    logger.log(2, __name__ + ": generator module started")

    # Initialise variables

    dst_config = []

    # Generator specific variables

    """
    Generator specific variables
    """

    # Generate data

    logger.log(2, __name__ + ": generate data")

    formatted_data = json.dumps(parsed_data, indent=2)
    dst_config.append(formatted_data)

    # Return generated data

    logger.log(2, __name__ + ": generator module finished")

    return dst_config
def parse(logger, src_config, routing_info=""):

    logger.log(2, __name__ + ": parser module started")

    # Initialise data
    """
    May need to process XML to ET, JSON etc here
    """

    # Initialise variables

    data = {}

    data["system"] = {}

    data["interfaces"] = {}
    data["zones"] = {}

    data["routes"] = []
    data["routes6"] = []

    data["network_objects"] = {}
    data["network6_objects"] = {}
    data["network_groups"] = {}
    data["network6_groups"] = {}

    data["service_objects"] = {}
    data["service_groups"] = {}

    data["policies"] = []

    data["nat"] = []

    # Parser specific variables
    """
    Parser specific variables
    """

    # Parse system

    logger.log(2, __name__ + ": parse system")

    re_match = re.search('(?:set hostname "(.*?)"\n)', src_config)
    data["system"]["hostname"] = re_match.group(1)

    # Parse interfaces

    logger.log(2, __name__ + ": parse interfaces - not yet supported")
    """
    Parse interfaces
    """

    # Parse zones

    logger.log(2, __name__ + ": parse zones - not yet supported")
    """
    Parse zones
    """

    # Parse static routes

    logger.log(2, __name__ + ": parse static routes")

    re_match = re.search("\nconfig router static\n(?:.*?)\nend", src_config,
                         re.DOTALL)
    routes_block = re_match.group(0).strip()

    for route_match in re.finditer("    edit [0-9]{1,}\n(?:.*?)\n    next",
                                   routes_block, re.DOTALL):

        route_config = route_match.group(0)

        if ("set virtual-wan-link enable"
                not in route_config):  ### need to add vwl support

            route = {}

            re_match = re.search(
                "set dst (" + common.common_regex.ipv4_address + ") (" +
                common.common_regex.ipv4_mask + ")\n",
                route_config,
            )

            route["network"] = re_match.group(1)
            route["mask"] = re_match.group(2)

            re_match = re.search(
                "set gateway ([0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3})\n",
                route_config,
            )

            route["gateway"] = re_match.group(1)

            re_match = re.search('set device "?(.*?)"?\n', route_config)
            route["interface"] = re_match.group(1)

            re_match = re.search("set distance ([0-9]{1,})\n", route_config)
            route["distance"] = re_match.group(1)

            route["source"] = []

            route["type"] = "static"

            data["routes"].append(route)

    # Parse IPv4 network objects

    logger.log(2, __name__ + ": parse IPv4 network objects")

    re_match = re.search("\nconfig firewall address\n(?:.*?)\nend", src_config,
                         re.DOTALL)

    network_objects_block = re_match.group(0).strip()

    for network_object_match in re.finditer(
            '    edit "?(.*?)"?\n(?:.*?)?\n?    next', network_objects_block,
            re.DOTALL):

        network_object = network_object_match.group(0)
        network_object_name = network_object_match.group(1)

        data["network_objects"][network_object_name] = {}

        re_match = re.search("set type (.*?)\n", network_object)

        if re_match:

            network_object_type = re_match.group(1)

            if network_object_type == "fqdn":

                data["network_objects"][network_object_name]["type"] = "fqdn"

                re_match = re.search(
                    'set fqdn "?(' + common.common_regex.fqdn + ')"?\n',
                    network_object)

                data["network_objects"][network_object_name][
                    "fqdn"] = re_match.group(1)

            elif network_object_type == "geography":

                data["network_objects"][network_object_name][
                    "type"] = "geography"

                re_match = re.search(
                    "set country (" + common.common_regex.country_code + ")\n",
                    network_object,
                )

                data["network_objects"][network_object_name][
                    "country_code"] = re_match.group(1)

            elif network_object_type == "ipmask":

                re_match = re.search(
                    "set subnet (" + common.common_regex.ipv4_address + ") (" +
                    common.common_regex.ipv4_mask + ")\n",
                    network_object,
                )

                if re_match:  # if a subnet is found

                    network_object_network = re_match.group(1)
                    network_object_mask = re_match.group(2)

                    if (network_object_mask == "255.255.255.255"
                        ):  # if mask is 255.255.255.255 then its a host

                        data["network_objects"][network_object_name][
                            "type"] = "host"
                        data["network_objects"][network_object_name][
                            "network"] = network_object_network
                        data["network_objects"][network_object_name][
                            "mask"] = network_object_mask

                    else:  # else its a network

                        data["network_objects"][network_object_name][
                            "type"] = "network"
                        data["network_objects"][network_object_name][
                            "network"] = network_object_network
                        data["network_objects"][network_object_name][
                            "mask"] = network_object_mask

                else:  # default is 0.0.0.0 0.0.0.0

                    network_object_network = re_match.group(1)
                    network_object_mask = re_match.group(2)

                    data["network_objects"][network_object_name][
                        "type"] = "network"
                    data["network_objects"][network_object_name][
                        "network"] = network_object_network
                    data["network_objects"][network_object_name][
                        "mask"] = network_object_mask

            elif network_object_type == "iprange":

                data["network_objects"][network_object_name]["type"] = "range"

                re_match = re.search(
                    "set start-ip (" + common.common_regex.ipv4_address +
                    ")\n",
                    network_object,
                )

                data["network_objects"][network_object_name][
                    "address_first"] = re_match.group(1)

                re_match = re.search(
                    "set end-ip (" + common.common_regex.ipv4_address + ")\n",
                    network_object,
                )

                data["network_objects"][network_object_name][
                    "address_last"] = re_match.group(1)

            elif network_object_type == "mac":

                data["network_objects"][network_object_name]["type"] = "mac"

                re_match = re.search(
                    "set start-mac (" + common.common_regex.mac_address +
                    ")\n",
                    network_object,
                )

                data["network_objects"][network_object_name][
                    "mac_first"] = re_match.group(1)

                re_match = re.search(
                    "set end-mac (" + common.common_regex.mac_address + ")\n",
                    network_object,
                )

                data["network_objects"][network_object_name][
                    "mac_last"] = re_match.group(1)

            ### add support for other types - dynamic, interface-subnet, wildcard

        else:  # default type is ipmask

            re_match = re.search(
                "set subnet (" + common.common_regex.ipv4_address + ") (" +
                common.common_regex.ipv4_mask + ")\n",
                network_object,
            )

            if re_match:  # if a subnet is found

                network_object_network = re_match.group(1)
                network_object_mask = re_match.group(2)

                if (network_object_network != "0.0.0.0"
                        and network_object_mask == "255.255.255.255"
                    ):  # if mask is 255.255.255.255 then its a host

                    data["network_objects"][network_object_name][
                        "type"] = "host"
                    data["network_objects"][network_object_name][
                        "network"] = network_object_network
                    data["network_objects"][network_object_name][
                        "mask"] = network_object_mask

                else:  # else its a network

                    data["network_objects"][network_object_name][
                        "type"] = "network"
                    data["network_objects"][network_object_name][
                        "network"] = network_object_network
                    data["network_objects"][network_object_name][
                        "mask"] = network_object_mask

            else:  # default is 0.0.0.0 0.0.0.0

                data["network_objects"][network_object_name][
                    "type"] = "network"
                data["network_objects"][network_object_name][
                    "network"] = "0.0.0.0"
                data["network_objects"][network_object_name][
                    "mask"] = "0.0.0.0"

    # Parse IPv6 network objects

    logger.log(2, __name__ + ": parse IPv6 network objects")

    re_match = re.search("\nconfig firewall address6\n(?:.*?)\nend",
                         src_config, re.DOTALL)

    network6_objects_block = re_match.group(0).strip()

    for network6_object_match in re.finditer(
            '    edit "?(.*?)"?\n(?:.*?)?\n?    next', network6_objects_block,
            re.DOTALL):

        network6_object = network6_object_match.group(0)
        network6_object_name = network6_object_match.group(1)

        data["network6_objects"][network6_object_name] = {}

        re_match = re.search("set type (.*?)\n", network6_object)

        if re_match:

            network6_object_type = re_match.group(1)

            if network6_object_type == "fqdn":

                data["network6_objects"][network6_object_name]["type"] = "fqdn"

                re_match = re.search(
                    'set fqdn "?(' + common.common_regex.fqdn + ')"?\n',
                    network6_object)

                data["network6_objects"][network6_object_name][
                    "fqdn"] = re_match.group(1)

            elif network6_object_type == "ipprefix":

                re_match = re.search(
                    "set ip6 (" + common.common_regex.ipv6_address + ")(" +
                    common.common_regex.ipv6_mask + ")\n",
                    network6_object,
                )

                if re_match:  # if a subnet is found

                    network6_object_network = re_match.group(1)
                    network6_object_mask = re_match.group(2)

                    data["network6_objects"][network6_object_name][
                        "type"] = "network"
                    data["network6_objects"][network6_object_name][
                        "network"] = network6_object_network
                    data["network6_objects"][network6_object_name][
                        "mask"] = network6_object_mask

                else:  # ::/0 is default

                    data["network6_objects"][network6_object_name][
                        "type"] = "network"
                    data["network6_objects"][network6_object_name][
                        "network"] = "::"
                    data["network6_objects"][network6_object_name][
                        "mask"] = "/0"

            elif network6_object_type == "iprange":

                data["network6_objects"][network6_object_name][
                    "type"] = "range"

                re_match = re.search(
                    "set start-ip (" + common.common_regex.ipv6_address +
                    ")\n",
                    network6_object,
                )

                data["network6_objects"][network6_object_name][
                    "address_first"] = re_match.group(1)

                re_match = re.search(
                    "set end-ip (" + common.common_regex.ipv6_address + ")\n",
                    network6_object,
                )

                data["network6_objects"][network6_object_name][
                    "address_last"] = re_match.group(1)

            ### add support for other types - dynamic, template

        else:  # default type is ipprefix

            re_match = re.search(
                "set ip6 (" + common.common_regex.ipv6_address + ")(" +
                common.common_regex.ipv6_mask + ")\n",
                network6_object,
            )

            if re_match:  # if a subnet is found

                network6_object_network = re_match.group(1)
                network6_object_mask = re_match.group(2)

                data["network6_objects"][network6_object_name][
                    "type"] = "network"
                data["network6_objects"][network6_object_name][
                    "network"] = network6_object_network
                data["network6_objects"][network6_object_name][
                    "mask"] = network6_object_mask

            else:  # ::/0 is default

                data["network6_objects"][network6_object_name][
                    "type"] = "network"
                data["network6_objects"][network6_object_name][
                    "network"] = "::"
                data["network6_objects"][network6_object_name]["mask"] = "/0"

    # Parse IPv4 network groups

    logger.log(2, __name__ + ": parse IPv4 network groups")

    re_match = re.search("\nconfig firewall addrgrp\n(?:.*?)\nend", src_config,
                         re.DOTALL)

    network_groups_block = re_match.group(0).strip()

    for network_group_match in re.finditer(
            '    edit "?(.*?)"?\n(?:.*?)?\n?    next', network_groups_block,
            re.DOTALL):

        network_group = network_group_match.group(0)
        network_group_name = network_group_match.group(1)

        data["network_groups"][network_group_name] = {}

        data["network_groups"][network_group_name]["type"] = "group"

        re_match = re.search('set member(?: "?(?:.*?)"?){1,}\n', network_group)

        if re_match:

            network_group_members = (re_match.group(0).replace(
                "set member ", "").replace('"', "").rstrip().split(" "))

            data["network_groups"][network_group_name][
                "members"] = network_group_members

    # Parse IPv6 network groups

    logger.log(2, __name__ + ": parse IPv6 network groups")

    re_match = re.search("\nconfig firewall addrgrp6\n(?:.*?)(?:\n)?end",
                         src_config, re.DOTALL)

    network6_groups_block = re_match.group(0).strip()

    for network6_group_match in re.finditer(
            '    edit "?(.*?)"?\n(?:.*?)?\n?    next', network6_groups_block,
            re.DOTALL):

        network6_group = network6_group_match.group(0)
        network6_group_name = network6_group_match.group(1)

        data["network6_groups"][network6_group_name] = {}

        data["network6_groups"][network6_group_name]["type"] = "group"

        re_match = re.search('set member(?: "?(?:.*?)"?){1,}\n',
                             network6_group)

        if re_match:

            network6_group_members = (re_match.group(0).replace(
                "set member ", "").replace('"', "").rstrip().split(" "))

            data["network6_groups"][network6_group_name][
                "members"] = network6_group_members

    # Parse service objects

    logger.log(2, __name__ + ": parse service objects - not yet supported")
    """
    Parse service objects
    """

    # Parse service groups

    logger.log(2, __name__ + ": parse service groups - not yet supported")
    """
    Parse service groups
    """

    # Parse firewall policies

    logger.log(2, __name__ + ": parse firewall policies - not yet supported")
    """
    Parse firewall policies
    """

    # Parse NAT

    logger.log(2, __name__ + ": parse NAT - not yet supported")
    """
    Parse NAT policies
    """

    # Return parsed data

    logger.log(2, __name__ + ": parser module finished")

    return data
def generate(logger, parsed_data):

    logger.log(2, __name__ + ": generator module started")

    # Initialise variables

    dst_config = []

    # Generator specific variables
    """
    Generator specific variables
    """

    # Generate system

    logger.log(2, __name__ + ": generate system")
    """
    Generate system objects such as hostname, DNS
    """

    # Generate interfaces

    logger.log(2, __name__ + ": generate interfaces")
    """
    Generate interfaces
    """

    # Generate zones

    logger.log(2, __name__ + ": generate zones")
    """
    Generate zones
    """

    # Generate static routes

    logger.log(2, __name__ + ": generate static routes")
    """
    Generate static routes
    """

    # Generate network objects

    logger.log(2, __name__ + ": generate network objects")
    """
    Generate network objects
    """

    # Generate network groups

    logger.log(2, __name__ + ": generate network groups")
    """
    Generate network groups
    """

    # Generate service objects

    logger.log(2, __name__ + ": generate service objects")
    """
    Generate service objects
    """

    # Generate service groups

    logger.log(2, __name__ + ": generate service groups")
    """
    Generate service groups
    """

    # Generate policies

    logger.log(2, __name__ + ": generate policies")
    """
    Generate firewall policies
    """

    # Generate NAT

    logger.log(2, __name__ + ": generate NAT")
    """
    Generate NAT policies
    """

    # Return generated config

    logger.log(2, __name__ + ": generator module finished")

    return dst_config
def main(src_format, dst_format, routing_info=""):

    # Load source configuration file

    logger.log(
        2, "DirectFire.Converter.main: loading source configuration from " +
        args.config)

    try:

        with open(args.config) as config_file:
            src_config = config_file.read()

    except:

        logger.log(
            4,
            "DirectFire.Converter.main: source file either not found or not readable "
            + args.config,
        )

        print(
            f"{Fore.RED}Error: source file either not found or not readable.{Style.RESET_ALL}"
        )

        exit()

    if routing_info:

        try:

            with open(args.routing) as routing_file:
                routing_info = routing_file.read()

        except:

            logger.log(
                4,
                "DirectFire.Converter.main: routing file either not found or not readable "
                + args.config,
            )

            print(
                f"{Fore.RED}Error: routing file either not found or not readable.{Style.RESET_ALL}"
            )

            exit()

    # Run configuration parser

    logger.log(2, "DirectFire.Converter.main: running configuration parser")

    parsed_data = parse(src_format=src_format,
                        src_config=src_config,
                        routing_info=routing_info)

    logger.log(2, "DirectFire.Converter.main: configuration parser finished")

    # Output

    logger.log(2, "DirectFire.Converter.main: running configuration generator")

    dst_config = generate(dst_format=dst_format, parsed_data=parsed_data)

    for line in dst_config:
        print(line)

    ### add support for output to file

    logger.log(2,
               "DirectFire.Converter.main: configuration generator finished")

    logger.log(2, "DirectFire.Converter.main: converter exiting")
    help="destination format",
    required=True,
)

arg_parser.add_argument(
    "-r",
    "--routing",
    help="path to supplemental routing information csv file")

args = arg_parser.parse_args()

# Initiate logging

logger = logger(args.source, args.destination)

logger.log(2, "DirectFire.Converter.main: converter starting")
logger.log(2, "DirectFire.Converter.main: source format is " + args.source)


def parse(src_format, src_config, routing_info=""):

    logger.log(
        2,
        "DirectFire.Converter.parse: loading parser module for " + src_format)

    if src_format == "ciscoasa":  ## Cisco ASA
        from DirectFire.Converter.parsers.ciscoasa import parse

    elif src_format == "ciscoasa_pre83":  ## Cisco ASA pre 8.3
        from DirectFire.Converter.parsers.ciscoasa_pre83 import parse
Ejemplo n.º 8
0
def generate(logger, parsed_data):

    logger.log(2, __name__ + ": generator module started")

    # Initialise variables

    dst_config = []

    # Generator specific variables
    """
    Generator specific variables
    """

    # Generate system

    logger.log(2, __name__ + ": generate system")

    try:
        dst_config.append("hostname " + parsed_data["system"]["hostname"])
    except:
        logger.log(3, __name__ + ": hostname not found in parsed data")
        pass

    try:
        dst_config.append("domain-name " + data["system"]["domain"])
    except:
        logger.log(3, __name__ + ": domain name not found in parsed data")
        pass

    # Generate interfaces

    logger.log(3, __name__ + ": generate interfaces - not yet supported")
    """
    Generate interfaces
    """

    # Generate zones

    logger.log(3, __name__ + ": generate zones - not yet supported")
    """
    Generate zones
    """

    # Generate static routes

    logger.log(2, __name__ + ": generate static routes")

    for route_id, attributes in enumerate(parsed_data["routes"]):

        if attributes["gateway"] != "0.0.0.0":
            dst_config.append("route " + attributes["interface"] + " " +
                              attributes["network"] + " " +
                              attributes["mask"] + " " +
                              attributes["gateway"] + " " +
                              attributes["distance"])

    # Generate network objects

    logger.log(2, __name__ + ": generate network objects")

    for address, attributes in parsed_data["network_objects"].items():

        if attributes["type"] == "host":

            dst_config.append("object network " + address)
            dst_config.append(" host " + attributes["host"])

        elif attributes["type"] == "network":

            dst_config.append("object network " + address)
            dst_config.append(" subnet " + attributes["network"] + " " +
                              attributes["mask"])

        elif attributes["type"] == "range":

            dst_config.append("object network " + address)
            dst_config.append(" range " + attributes["address_first"] + " " +
                              attributes["address_last"])

        elif attributes["type"] == "domain":

            dst_config.append("object network " + address)
            dst_config.append(" fqdn " + attributes["fqdn"])

    # Generate network groups

    logger.log(2, __name__ + ": generate network groups")

    for group, attributes in parsed_data["network_groups"].items():

        dst_config.append("object-group network " + group)

        for member in attributes["members"]:
            dst_config.append(" network-object object " + member)

    # Generate service objects

    logger.log(2, __name__ + ": generate service objects")

    for service, attributes in parsed_data["service_objects"].items():

        if attributes["type"] == "service":

            if attributes["protocol"] == "6":

                dst_config.append("object service " + service)
                dst_config.append(" service tcp destination eq " +
                                  attributes["dst_port"])

            elif attributes["protocol"] == "17":

                dst_config.append("object service " + service)
                dst_config.append(" service udp destination eq " +
                                  attributes["dst_port"])

            elif attributes["protocol"] == "1":

                dst_config.append("object service " + service)
                dst_config.append(" service icmp " + attributes["icmp_type"] +
                                  " " + attributes["icmp_code"])

        elif attributes["type"] == "range":

            if attributes["protocol"] == "6":

                dst_config.append("object service " + service)
                dst_config.append(" service tcp destination range " +
                                  attributes["dst_port_first"] + " " +
                                  attributes["dst_port_last"])

            elif attributes["protocol"] == "17":

                dst_config.append("object service " + service)
                dst_config.append(" service udp destination range " +
                                  attributes["dst_port_first"] + " " +
                                  attributes["dst_port_last"])

    # Generate service groups

    logger.log(2, __name__ + ": generate service groups")

    for group, attributes in parsed_data["service_groups"].items():

        dst_config.append("object-group service " + group)

        for member in attributes["members"]:
            dst_config.append(" service-object object " + member)

    # Generate policies

    logger.log(2, __name__ + ": generate policies - not yet supported")

    # access_lists = {}

    for policy_id, attributes in enumerate(parsed_data["policies"]):

        rule_command = ""

        if attributes["action"] == "allow":
            rule_action = "permit"
        else:
            rule_action = "deny"

        rule_command = "extended " + rule_action

        ## generate destination services

        if len(attributes["dst_services"]) == 1:

            if attributes["dst_services"][0]["name"] == "any":
                rule_command = rule_command + " ip"
            else:
                if attributes["dst_services"][0]["type"] == "service":
                    rule_command = (rule_command + " object " +
                                    attributes["dst_services"][0]["name"])
                ### range needed here?
                elif attributes["dst_services"][0]["type"] == "group":
                    rule_command = (rule_command + " object-group " +
                                    attributes["dst_services"][0]["name"])

        else:

            ## need to create object group and reference here
            pass

        ## generate source address

        if len(attributes["src_addresses"]) == 1:

            if attributes["src_addresses"][0]["name"] == "any":
                rule_command = rule_command + " any"
            elif attributes["dst_services"][0]["type"] == "host":
                rule_command = (rule_command + " object " +
                                attributes["src_addresses"][0]["name"])
            elif attributes["dst_services"][0]["type"] == "range":
                rule_command = (rule_command + " object " +
                                attributes["src_addresses"][0]["name"])
            elif attributes["dst_services"][0]["type"] == "network":
                rule_command = (rule_command + " object " +
                                attributes["src_addresses"][0]["name"])
            elif attributes["dst_services"][0]["type"] == "group":
                rule_command = (rule_command + " object-group " +
                                attributes["src_addresses"][0]["name"])

        else:

            ## need to create object group and reference here
            pass

        ## generate destination address

        if len(attributes["src_addresses"]) == 1:

            if attributes["dst_addresses"][0]["name"] == "any":
                rule_command = rule_command + " any"
            elif attributes["dst_addresses"][0]["type"] == "host":
                rule_command = (rule_command + " object " +
                                attributes["dst_addresses"][0]["name"])
            elif attributes["dst_addresses"][0]["type"] == "range":
                rule_command = (rule_command + " object " +
                                attributes["dst_addresses"][0]["name"])
            elif attributes["dst_addresses"][0]["type"] == "network":
                rule_command = (rule_command + " object " +
                                attributes["dst_addresses"][0]["name"])
            elif attributes["dst_addresses"][0]["type"] == "group":
                rule_command = (rule_command + " object-group " +
                                attributes["dst_addresses"][0]["name"])

        else:

            ## need to create object group and reference here
            pass

        ## generate policy flags

        if attributes["logging"] == True:
            rule_command = rule_command + " log"

        if attributes["enabled"] == False:
            rule_command = rule_command + " inactive"

        ## add to acl

        if attributes["policy_set"]:

            rule_command = ("access-list " + attributes["policy_set"] + " " +
                            rule_command)

            dst_config.append(rule_command)

        else:

            for interface in attributes["src_interfaces"]:

                rule_command = "access-list " + interface + "_in " + rule_command

                dst_config.append(rule_command)

    #     if attributes["src_interface"] not in access_lists:
    #         access_lists[attributes["src_interface"]] = []

    #     access_lists[attributes["src_interface"]].append(rule_command)

    # for access_list, commands in access_lists.items():
    #     for command in commands:
    #         dst_config.append(command)

    # for access_list in access_lists.keys():
    #     dst_config.append(
    #         "access-group " + access_list + "_in in interface " + access_list
    #     )

    # Generate NAT

    logger.log(3, __name__ + ": generate NAT - not yet supported")
    """
    Generate NAT policies
    """

    # Return generated config

    logger.log(2, __name__ + ": generator module finished")

    return dst_config
def parse(logger, src_config, routing_info=""):

    logger.log(2, __name__ + ": parser module started")

    # Initialise data
    """
    May need to process XML to ET, JSON etc here
    """

    # Initialise variables

    data = {}

    data["system"] = {}

    data["interfaces"] = {}
    data["zones"] = {}

    data["routes"] = []
    data["routes6"] = []

    data["network_objects"] = {}
    data["network6_objects"] = {}
    data["network_groups"] = {}
    data["network6_groups"] = {}

    data["service_objects"] = {}
    data["service_groups"] = {}

    data["policies"] = []

    data["nat"] = []

    # Parser specific variables
    """
    Parser specific variables
    """

    # Parse system

    logger.log(2, __name__ + ": parse system")
    """
    Parse system objects such as hostname, DNS
    """

    # Parse interfaces

    logger.log(2, __name__ + ": parse interfaces")
    """
    Parse interfaces
    """

    # Parse zones

    logger.log(2, __name__ + ": parse zones")
    """
    Parse zones
    """

    # Parse static routes

    logger.log(2, __name__ + ": parse static routes")
    """
    Parse static routes
    """

    # Parse IPv4 network objects

    logger.log(2, __name__ + ": parse IPv4 network objects")
    """
    Parse IPv4 network objects
    """

    # Parse IPv6 network objects

    logger.log(2, __name__ + ": parse IPv6 network objects")
    """
    Parse IPv6 network objects
    """

    # Parse IPv4 network groups

    logger.log(2, __name__ + ": parse IPv4 network groups")
    """
    Parse IPv4 network groups
    """

    # Parse IPv6 network groups

    logger.log(2, __name__ + ": parse IPv6 network groups")
    """
    Parse IPv6 network groups
    """

    # Parse service objects

    logger.log(2, __name__ + ": parse service objects")
    """
    Parse service objects
    """

    # Parse service groups

    logger.log(2, __name__ + ": parse service groups")
    """
    Parse service groups
    """

    # Parse firewall policies

    logger.log(2, __name__ + ": parse firewall policies")
    """
    Parse firewall policies
    """

    # Parse NAT

    logger.log(2, __name__ + ": parse NAT")
    """
    Parse NAT policies
    """

    # Return parsed data

    logger.log(2, __name__ + ": parser module finished")

    return data
Ejemplo n.º 10
0
def parse(logger, src_config, routing_info=""):

    logger.log(2, __name__ + ": parser module started")

    # Initialise data

    src_config_xml = ET.ElementTree(ET.fromstring(src_config))

    # Initialise variables

    data = {}

    data["system"] = {}

    data["interfaces"] = {}
    data["zones"] = {}

    data["routes"] = []
    data["routes6"] = []

    data["network_objects"] = {}
    data["network6_objects"] = {}
    data["network_groups"] = {}
    data["network6_groups"] = {}

    data["service_objects"] = {}
    data["service_groups"] = {}

    data["policies"] = []

    data["nat"] = []

    # Parser specific variables
    """
    Parser specific variables
    """

    # Parse system

    logger.log(2, __name__ + ": parse system")

    src_system = src_config_xml.find("system-parameters").find("device-conf")

    data["system"]["hostname"] = src_system.find("system-name").text
    data["system"]["domain"] = src_system.find("domain-name").text

    # Parse interfaces

    logger.log(2, __name__ + ": parse interfaces")

    interface_routes = []

    interfaces = src_config_xml.findall("./interface-list/interface")

    for interface in interfaces:

        interface_name = interface.find("name").text

        data["interfaces"][interface_name] = {}
        data["interfaces"][interface_name]["enabled"] = True
        data["interfaces"][interface_name]["description"] = (
            interface.find("description").text
            if interface.find("description") else "")
        data["interfaces"][interface_name]["ipv4_config"] = []
        data["interfaces"][interface_name]["mtu"] = ""
        data["interfaces"][interface_name]["physical_interfaces"] = []
        data["interfaces"][interface_name]["type"] = "interface"
        data["interfaces"][interface_name]["vlan_id"] = ""
        data["interfaces"][interface_name]["vlan_name"] = ""

        if interface_name not in [
                "Any",
                "Any-BOVPN",
                "Any-External",
                "Any-Multicast",
                "Any-MUVPN",
                "Any-Optional",
                "Any-Trusted",
                "Any-VPN",
                "Firebox",
                "Tunnel-Switch",
        ]:

            data["interfaces"][interface_name] = {}
            data["interfaces"][interface_name]["enabled"] = True
            data["interfaces"][interface_name]["description"] = (
                interface.find("description").text
                if interface.find("description") else "")
            data["interfaces"][interface_name]["ipv4_config"] = []
            data["interfaces"][interface_name]["ipv6_config"] = []
            data["interfaces"][interface_name]["mtu"] = ""
            data["interfaces"][interface_name]["physical_interfaces"] = []
            data["interfaces"][interface_name]["vlan_id"] = ""
            data["interfaces"][interface_name]["vlan_name"] = ""

            interface_items = interface.findall("./if-item-list/item")

            for item in interface_items:

                physical_interface = item.find("physical-if")

                if physical_interface:

                    # find interface enabled

                    if physical_interface.find("mtu").text == "0":
                        data["interfaces"][interface_name]["enabled"] = False
                    else:
                        data["interfaces"][interface_name]["enabled"] = True

                    # if ipv4

                    if physical_interface.find(
                            "ip-node-type").text == "IP4_ONLY":

                        # find interface primary ip config

                        interface_ip_member = {}
                        interface_ip_member[
                            "ip_address"] = physical_interface.find("ip").text
                        interface_ip_member["mask"] = physical_interface.find(
                            "netmask").text
                        interface_ip_member["type"] = "primary"

                        if interface_ip_member["ip_address"] not in [
                                "", "0.0.0.0"
                        ]:
                            data["interfaces"][interface_name][
                                "ipv4_config"].append(interface_ip_member)

                        # find interface secondary ip config

                        secondary_ip = physical_interface.findall(
                            "./secondary-ip-list/secondary-ip")

                        for ipv4_config in secondary_ip:

                            interface_ip_member = {}
                            interface_ip_member[
                                "ip_address"] = ipv4_config.find("ip").text
                            interface_ip_member["mask"] = ipv4_config.find(
                                "netmask").text

                            if (len(data["interfaces"][interface_name]
                                    ["ipv4_config"]) == 0):
                                interface_ip_member["type"] = "primary"
                            else:
                                interface_ip_member["type"] = "secondary"

                            if interface_ip_member["ip_address"] not in [
                                    "", "0.0.0.0"
                            ]:
                                data["interfaces"][interface_name][
                                    "ipv4_config"].append(interface_ip_member)

                    ### need to add ipv6 support

                    # find interface mtu

                    data["interfaces"][interface_name][
                        "mtu"] = physical_interface.find("mtu").text

                    # if an external interface add an interface route

                    external_interface = physical_interface.find("external-if")

                    if external_interface:

                        interface_route = {}
                        interface_route["gateway"] = physical_interface.find(
                            "default-gateway").text
                        interface_route["interface"] = interface_name

                        interface_routes.append(interface_route)

                    # set type

                    data["interfaces"][interface_name]["type"] = "interface"

                else:

                    # probably a VPN tunnel interface

                    data["interfaces"][interface_name]["type"] = "vpn"

    # Parse zones

    logger.log(2, __name__ + ": parse zones - not yet supported")
    """
    Parse zones
    """

    # Parse static routes

    logger.log(2, __name__ + ": parse static routes")

    src_routes = src_config_xml.findall(
        "./system-parameters/route/route-entry")

    for interface_route_config in interface_routes:

        route = {}
        route["network"] = "0.0.0.0"
        route["mask"] = "0.0.0.0"
        route["gateway"] = interface_route_config["gateway"]
        route["interface"] = interface_route_config["interface"]
        route["distance"] = "1"

        data["routes"].append(route)

    for route_config in src_routes:

        route_gateway = route_config.find("gateway-ip").text

        route = {}
        route["network"] = route_config.find("dest-address").text
        route["mask"] = route_config.find("mask").text
        route["gateway"] = route_gateway
        route["interface"] = interface_lookup(route_gateway,
                                              data["interfaces"],
                                              data["routes"])
        route["distance"] = route_config.find("metric").text

        data["routes"].append(route)

    # Parse network groups

    logger.log(2, __name__ + ": parse network groups")

    src_addr_grp = src_config_xml.findall("./address-group-list/address-group")

    for addr_grp in src_addr_grp:

        grp_name = cleanse_names(addr_grp.find("name").text)

        data["network_groups"][grp_name] = {}
        data["network_groups"][grp_name]["type"] = "group"
        data["network_groups"][grp_name]["description"] = addr_grp.find(
            "description").text
        data["network_groups"][grp_name]["members"] = []

        members = addr_grp.findall("./addr-group-member/member")

        for member in members:

            mbr_type = member.find("type").text

            if mbr_type == "1":  # host

                mbr_host = member.find("host-ip-addr").text
                mbr_name = "host_" + mbr_host

                data["network_objects"][mbr_name] = {}
                data["network_objects"][mbr_name]["type"] = "host"
                data["network_objects"][mbr_name]["host"] = mbr_host
                data["network_objects"][mbr_name]["description"] = ""

                data["network_groups"][grp_name]["members"].append(mbr_name)

            elif mbr_type == "2":  # network

                mbr_network = member.find("ip-network-addr").text
                mbr_mask = member.find("ip-mask").text
                mbr_name = "net_" + mbr_network + "_" + mbr_mask

                data["network_objects"][mbr_name] = {}
                data["network_objects"][mbr_name]["type"] = "network"
                data["network_objects"][mbr_name]["network"] = mbr_network
                data["network_objects"][mbr_name]["mask"] = mbr_mask
                data["network_objects"][mbr_name]["description"] = ""

                data["network_groups"][grp_name]["members"].append(mbr_name)

            elif mbr_type == "3":  # ip range

                mbr_address_first = member.find("start-ip-addr").text
                mbr_address_last = member.find("end-ip-addr").text
                mbr_name = "range_" + mbr_address_first + "-" + mbr_address_last

                data["network_objects"][mbr_name] = {}
                data["network_objects"][mbr_name]["type"] = "range"
                data["network_objects"][mbr_name][
                    "address_first"] = mbr_address_first
                data["network_objects"][mbr_name][
                    "address_last"] = mbr_address_last
                data["network_objects"][mbr_name]["description"] = ""

                data["network_groups"][grp_name]["members"].append(mbr_name)

    # Parse service groups

    logger.log(2, __name__ + ": parse service groups")

    src_services = src_config_xml.findall("./service-list/service")

    for svc_group in src_services:

        grp_name = cleanse_names(svc_group.find("name").text)

        data["service_groups"][grp_name] = {}
        data["service_groups"][grp_name]["type"] = "group"
        data["service_groups"][grp_name]["description"] = svc_group.find(
            "description").text
        data["service_groups"][grp_name]["members"] = []

        members = svc_group.findall("./service-item/member")

        protocols_with_ports = ["6", "17"]

        for member in members:

            mbr_protocol = member.find("protocol").text
            mbr_type = member.find("type").text

            if mbr_protocol in protocols_with_ports:

                if mbr_type == "1":  # single port

                    mbr_port = member.find("server-port").text
                    mbr_name = "svc_" + mbr_protocol + "_" + mbr_port

                    data["service_objects"][mbr_name] = {}
                    data["service_objects"][mbr_name]["type"] = "service"
                    data["service_objects"][mbr_name][
                        "protocol"] = mbr_protocol
                    data["service_objects"][mbr_name]["dst_port"] = mbr_port
                    data["service_objects"][mbr_name]["description"] = ""

                    data["service_groups"][grp_name]["members"].append(
                        mbr_name)

                elif mbr_type == "2":  # port range

                    mbr_port_first = member.find("start-server-port").text
                    mbr_port_last = member.find("end-server-port").text
                    mbr_name = ("svc_" + mbr_protocol + "_" + mbr_port_first +
                                "-" + mbr_port_last)

                    data["service_objects"][mbr_name] = {}
                    data["service_objects"][mbr_name]["type"] = "range"
                    data["service_objects"][mbr_name][
                        "protocol"] = mbr_protocol
                    data["service_objects"][mbr_name][
                        "dst_port_first"] = mbr_port_first
                    data["service_objects"][mbr_name][
                        "dst_port_last"] = mbr_port_last
                    data["service_objects"][mbr_name]["description"] = ""

                    data["service_groups"][grp_name]["members"].append(
                        mbr_name)

            elif mbr_protocol == "1":

                if mbr_type == "1":  # single type / code

                    mbr_icmp_type = member.find("icmp_type").text
                    mbr_icmp_code = member.find("icmp_code").text
                    mbr_name = ("svc_" + mbr_protocol + "_" + mbr_icmp_type +
                                "_" + mbr_icmp_code)

                    data["service_objects"][mbr_name] = {}
                    data["service_objects"][mbr_name]["type"] = "service"
                    data["service_objects"][mbr_name][
                        "protocol"] = mbr_protocol
                    data["service_objects"][mbr_name][
                        "icmp_type"] = mbr_icmp_type
                    data["service_objects"][mbr_name][
                        "icmp_code"] = mbr_icmp_code
                    data["service_objects"][mbr_name]["description"] = ""

                    data["service_groups"][grp_name]["members"].append(
                        mbr_name)

    # Parse firewall policies

    logger.log(2, __name__ + ": parse firewall policies")

    src_policies = src_config_xml.findall("./policy-list/policy")

    for policy_config in src_policies:

        policy = {}

        policy["action"] = ""
        policy["description"] = policy_config.find("description").text
        policy["dst_addresses"] = []
        policy["dst_interfaces"] = []
        policy["dst_services"] = []
        policy["enabled"] = False if policy_config.find(
            "enable").text == "0" else True
        policy["logging"] = False if policy_config.find(
            "log").text == "0" else True
        policy["name"] = policy_config.find("name").text
        policy[
            "nat"] = ""  ### many values here - nat, global-1to1-nat, global-dnat
        policy["policy_set"] = ""
        policy["protocol"] = "any"
        policy["schedule"] = policy_config.find("schedule").text
        policy["src_addresses"] = []
        policy["src_interfaces"] = []
        policy["src_services"] = ["any"]
        policy["type"] = "policy"
        policy["users_excluded"] = []
        policy["users_included"] = []

        ## find desination addresses

        for dst_alias_name in policy_config.find("to-alias-list").findall(
                "alias"):

            if dst_alias_name.text == "Any":

                dst_address = {}
                dst_address["name"] = "any"
                dst_address["type"] = "any"

                policy["dst_addresses"].append(dst_address)

            else:

                dst_address = {}
                dst_address["name"] = dst_alias_name.text
                dst_address["type"] = "network"  ## need to check if a group

                policy["dst_addresses"].append(dst_address)

        ## find desination services

        for dst_service_name in policy_config.findall("service"):

            if dst_service_name.text == "Any":

                dst_service = {}
                dst_service["name"] = "any"
                dst_service["type"] = "any"

                policy["dst_services"].append(dst_service)

            else:

                dst_service = {}
                dst_service["name"] = dst_service_name.text
                dst_service["type"] = "network"  ## need to check if a group

                policy["dst_services"].append(dst_service)

        ## find source addresses

        for src_alias_name in policy_config.find("from-alias-list").findall(
                "alias"):

            if src_alias_name.text == "Any":

                src_address = {}
                src_address["name"] = "any"
                src_address["type"] = "any"

                policy["src_addresses"].append(src_address)

            else:

                src_address = {}
                src_address["name"] = src_alias_name.text
                src_address["type"] = "network"  ## need to check if a group

                policy["src_addresses"].append(src_address)

        ### need to lookup interface for destination alias

        ### need to lookup interface for source alias

        data["policies"].append(policy)

    # Parse NAT

    logger.log(3, __name__ + ": parse NAT - not yet supported")

    # Return parsed data

    logger.log(2, __name__ + ": parser module finished")

    return data
def generate(logger, parsed_data):

    logger.log(2, __name__ + ": generator module started")

    # Initialise variables

    dst_config = []

    # Generator specific variables

    cfglvl1 = "  "
    cfglvl2 = "    "
    cfglvl3 = "      "
    cfglvl4 = "        "
    cfglvl5 = "          "

    # Generate system

    logger.log(2, __name__ + ": generate system")

    dst_config.append("config system global")

    if "hostname" in parsed_data["system"]:
        dst_config.append(cfglvl1 + "set hostname " + parsed_data["system"]["hostname"])
    else:
        logger.log(3, __name__ + ": hostname not found in parsed data")

    dst_config.append("end")

    dst_config.append("config system dns")

    if "domain" in parsed_data["system"]:
        dst_config.append(cfglvl1 + "set domain " + parsed_data["system"]["domain"])
    else:
        logger.log(3, __name__ + ": domain name not found in parsed data")

    dst_config.append("end")

    # Generate interfaces

    logger.log(2, __name__ + ": generate interfaces")

    dst_config.append("config system interface")

    for interface, attributes in parsed_data["interfaces"].items():

        if attributes["type"] == "interface":

            dst_config.append(cfglvl1 + "edit " + interface)
            dst_config.append(cfglvl2 + "set vdom root")

            if attributes["ipv4_config"]:

                dst_config.append(cfglvl2 + "set mode static")

                last_ipv4 = len(attributes["ipv4_config"]) - 1

                for i in range(len(attributes["ipv4_config"])):

                    if i == 0:

                        dst_config.append(
                            cfglvl2
                            + "set ip "
                            + attributes["ipv4_config"][i]["ip_address"]
                            + " "
                            + attributes["ipv4_config"][i]["mask"]
                        )

                    else:

                        if i == 1:

                            dst_config.append(cfglvl2 + "set secondary-IP enable")
                            dst_config.append(cfglvl2 + "config secondaryip")

                        dst_config.append(cfglvl3 + "edit " + str(i))
                        dst_config.append(
                            cfglvl4
                            + "set ip "
                            + attributes["ipv4_config"][i]["ip_address"]
                            + " "
                            + attributes["ipv4_config"][i]["mask"]
                        )
                        dst_config.append(cfglvl3 + "next")

                        if i == last_ipv4:

                            dst_config.append(cfglvl2 + "end")

            dst_config.append(cfglvl1 + "next")

        ### need to add support for sub interfaces and switch interfaces

    dst_config.append("end")

    # Generate zones

    logger.log(3, __name__ + ": generate zones - not yet supported")

    """
    Generate zones
    """

    # Generate static routes

    logger.log(2, __name__ + ": generate static routes")

    dst_config.append("config router static")

    for route_id, attributes in enumerate(parsed_data["routes"]):

        dst_config.append(cfglvl1 + "edit " + str(route_id))
        dst_config.append(
            cfglvl2 + "set dst " + attributes["network"] + " " + attributes["mask"]
        )
        dst_config.append(cfglvl2 + "set device " + attributes["interface"])
        dst_config.append(cfglvl2 + "set gateway " + attributes["gateway"])
        dst_config.append(cfglvl2 + "set distance " + attributes["distance"])
        dst_config.append(cfglvl1 + "next")

    dst_config.append("end")

    # Generate network objects

    logger.log(2, __name__ + ": generate network objects")

    dst_config.append("config firewall address")

    for address, attributes in parsed_data["network_objects"].items():

        dst_config.append(cfglvl1 + 'edit "' + address + '"')

        if attributes["type"] == "host":

            dst_config.append(cfglvl2 + "set type ipmask")
            dst_config.append(
                cfglvl2 + "set subnet " + attributes["host"] + " 255.255.255.255"
            )

        elif attributes["type"] == "network":

            dst_config.append(cfglvl2 + "set type ipmask")
            dst_config.append(
                cfglvl2
                + "set subnet "
                + attributes["network"]
                + " "
                + attributes["mask"]
            )

        elif attributes["type"] == "range":

            dst_config.append(cfglvl2 + "set type iprange")
            dst_config.append(cfglvl2 + "set start-ip " + attributes["address_first"])
            dst_config.append(cfglvl2 + "set end-ip " + attributes["address_last"])

        dst_config.append(cfglvl1 + "next")

    dst_config.append("end")

    # Generate network groups

    logger.log(2, __name__ + ": generate network groups")

    dst_config.append("config firewall addrgrp")

    for group, attributes in parsed_data["network_groups"].items():

        grp_members = ""

        if attributes["type"] == "group":

            dst_config.append('  edit "' + group + '"')

            for member in attributes["members"]:
                grp_members = grp_members + ' "' + member + '"'

            if grp_members:
                dst_config.append(cfglvl2 + "set member" + grp_members)

            dst_config.append(cfglvl1 + "next")

    dst_config.append("end")

    # Generate service objects

    logger.log(2, __name__ + ": generate service objects")

    dst_config.append("config firewall service custom")

    for service, attributes in parsed_data["service_objects"].items():

        dst_config.append('  edit "' + service + '"')

        if attributes["type"] == "service":

            if attributes["protocol"] in ["1", "icmp", "Icmp", "ICMP"]:

                dst_config.append(cfglvl2 + "set protocol ICMP")

                if attributes["icmp_type"]:
                    dst_config.append(
                        cfglvl2 + "set icmptype " + attributes["icmp_type"]
                    )

                if attributes["icmp_code"]:
                    dst_config.append(
                        cfglvl2 + "set icmpcode " + attributes["icmp_code"]
                    )

            elif attributes["protocol"] in ["6", "tcp", "Tcp", "TCP"]:

                dst_config.append(cfglvl2 + "set protocol TCP/UDP/SCTP")

                if attributes["dst_port"]:
                    dst_config.append(
                        cfglvl2 + "set tcp-portrange " + attributes["dst_port"]
                    )

            elif attributes["protocol"] in ["17", "udp", "Udp", "UDP"]:

                dst_config.append(cfglvl2 + "set protocol TCP/UDP/SCTP")

                if attributes["dst_port"]:
                    dst_config.append(
                        cfglvl2 + "set udp-portrange " + attributes["dst_port"]
                    )

            else:

                dst_config.append(cfglvl2 + "set protocol IP")
                dst_config.append(
                    cfglvl2 + "set protocol-number " + attributes["protocol"]
                )

        if attributes["type"] == "range":

            if attributes["protocol"] in ["6", "tcp", "Tcp", "TCP"]:

                dst_config.append(cfglvl2 + "set protocol TCP/UDP/SCTP")
                dst_config.append(
                    cfglvl2
                    + "set tcp-portrange "
                    + attributes["dst_port_first"]
                    + "-"
                    + attributes["dst_port_last"]
                )

            elif attributes["protocol"] in ["17", "udp", "Udp", "UDP"]:

                dst_config.append(cfglvl2 + "set protocol TCP/UDP/SCTP")
                dst_config.append(
                    cfglvl2
                    + "set udp-portrange "
                    + attributes["dst_port_first"]
                    + "-"
                    + attributes["dst_port_last"]
                )

        dst_config.append(cfglvl1 + "next")

    dst_config.append("end")

    # Generate service groups

    logger.log(2, __name__ + ": generate service groups")

    dst_config.append("config firewall service group")

    for group, attributes in parsed_data["service_groups"].items():

        grp_members = ""

        if attributes["type"] == "group":

            dst_config.append('  edit "' + group + '"')

            for member in attributes["members"]:
                grp_members = grp_members + ' "' + member + '"'

            if grp_members:
                dst_config.append(cfglvl2 + "set member" + grp_members)

            dst_config.append(cfglvl1 + "next")

    dst_config.append("end")

    # Generate policies

    logger.log(3, __name__ + ": generate policies - not yet supported")

    dst_config.append("config firewall policy")

    for policy_id, attributes in enumerate(parsed_data["policies"]):

        dst_config.append(cfglvl1 + "edit " + str(policy_id))

        dst_config.append(
            cfglvl2
            + "set srcintf "
            + " ".join(list(map(str, attributes["src_interfaces"])))
        )

        dst_config.append(
            cfglvl2
            + "set dstintf "
            + " ".join(list(map(str, attributes["dst_interfaces"])))
        )

        # dst_config.append(
        #     cfglvl2
        #     + "set srcaddr "
        #     + " ".join(list(map(str, attributes["src_addresses"])))
        # )

        # dst_config.append(
        #     cfglvl2
        #     + "set dstaddr "
        #     + " ".join(list(map(str, attributes["dst_addresses"])))
        # )

        if attributes["description"]:
            dst_config.append(cfglvl2 + "set description " + attributes["description"])

        dst_config.append(cfglvl1 + "next")

    dst_config.append("end")

    # Generate NAT

    logger.log(3, __name__ + ": generate NAT - not yet supported")

    # Return generated config

    logger.log(2, __name__ + ": generator module finished")

    return dst_config