Exemple #1
0
	def validate_members(self):
		if self.members.get(IFACE_KEY_INDEX) is None:
			exit_NaCl(self.ctx.value(), "An index needs to be specified for all Ifaces")

		config = self.members.get(IFACE_KEY_CONFIG)
		if config is not None and (config.value_name() is None or config.value_name().getText().lower() not in PREDEFINED_CONFIG_TYPES):
			exit_NaCl(config, "Invalid config value " + config.getText())

		vlan = self.members.get(IFACE_KEY_VLAN)
		# If this is a vlan, require a network configuration:
		if vlan is not None:
			if (config is None or config.value_name().getText().lower() != DHCP_CONFIG) and \
				(self.members.get(IFACE_KEY_ADDRESS) is None or \
				self.members.get(IFACE_KEY_NETMASK) is None):
				exit_NaCl(self.ctx.value(), "The members " + IFACE_KEY_ADDRESS + " and " + IFACE_KEY_NETMASK + \
					" must be set for every Iface if the Iface configuration hasn't been set to " + DHCP_CONFIG)
			elif config is not None and config.value_name().getText().lower() == DHCP_CONFIG and \
				(self.members.get(IFACE_KEY_ADDRESS) is not None or \
				self.members.get(IFACE_KEY_NETMASK) is not None or \
				self.members.get(IFACE_KEY_GATEWAY) is not None or \
				self.members.get(IFACE_KEY_DNS) is not None):
				exit_NaCl(config.value_name(), "An Iface with config set to dhcp should not specify " + IFACE_KEY_ADDRESS + \
					", " + IFACE_KEY_NETMASK + ", " + IFACE_KEY_GATEWAY + " or " + IFACE_KEY_DNS)

			# It is not allowed (yet) to set buffer_limit or send_queue_limit on a vlan
			if self.members.get(IFACE_KEY_BUFFER_LIMIT) is not None or self.members.get(IFACE_KEY_SEND_QUEUE_LIMIT) is not None:
				exit_NaCl(self.ctx.value(), "The members send_queue_limit and buffer_limit can not be set on an Iface that is a vlan")
Exemple #2
0
	def add_push(self, chain, functions):
		# chain: string with name of chain
		# functions: list containing value_name ctxs, where each name corresponds to the name of a NaCl function

		add_auto_natting = False
		function_names = []
		num_functions = len(functions)
		for i, function in enumerate(functions):
			name = function.getText()
			element = self.nacl_state.elements.get(name)
			if element is None or element.base_type != BASE_TYPE_FUNCTION:
				exit_NaCl(function, "No function with the name " + name + " exists")

			# If a Nat function is pushed onto an Iface's chain,
			# push the snat_translate lambda in cpp_template.mustache
			# onto the same Iface's postrouting chain
			# and push the dnat_translate lambda in cpp_template.mustache
			# onto the same Iface's prerouting chain
			if element.type_t.lower() == TYPE_NAT:
				add_auto_natting = True

			function_names.append({TEMPLATE_KEY_FUNCTION_NAME: name, TEMPLATE_KEY_COMMA: (i < (num_functions - 1))})

		if add_auto_natting:
			self.nacl_state.append_to_pystache_data_list(TEMPLATE_KEY_AUTO_NATTING_IFACES, {
				TEMPLATE_KEY_IFACE: self.name
			})

		self.nacl_state.append_to_pystache_data_list(TEMPLATE_KEY_IFACE_PUSHES, {
			TEMPLATE_KEY_NAME:				self.name,
			TEMPLATE_KEY_CHAIN: 			chain,
			TEMPLATE_KEY_FUNCTION_NAMES: 	function_names
		})
Exemple #3
0
    def transpile_body_elements(self, type_t, subtype, body_elements):
        content = ""

        for e in body_elements:
            if e.conditional() is not None:
                content += self.transpile_conditional(type_t, subtype,
                                                      e.conditional())
            elif e.action() is not None:
                content += self.action_transpiler.transpile(
                    type_t, subtype, e.action())
            elif e.function() is not None:
                # Validate if valid type_t and subtype
                nested_type_t = e.function().type_t().getText()
                nested_subtype = e.function().subtype().getText()

                # Can only nest functions of the same type_t
                if type_t.lower() != nested_type_t.lower():
                    exit_NaCl(e.function().type_t(), "You cannot create a function of type " + \
                     nested_type_t + " inside a function of type " + type_t)

                # If this is a function, we have to validate that the subtype is legal based on the subtype of
                # the parent function
                if nested_subtype.lower() not in legal_nested_subtypes[
                        subtype.lower()]:
                    exit_NaCl(e.function().subtype(), "You cannot create a function of subtype " + \
                     nested_subtype + " inside a function of subtype " + subtype)

                content += self.transpile(nested_type_t, nested_subtype,
                                          e.function(), subtype)

        return content
Exemple #4
0
    def add_timer(self):
        pystache_obj = {
            TEMPLATE_KEY_INTERVAL: self.members.get(TIMER_KEY_INTERVAL)
        }

        data = self.members.get(TIMER_KEY_DATA)
        if not isinstance(data, list):
            exit_NaCl(self.ctx, "Invalid value of Timer member " + TIMER_KEY_DATA + \
                ". It needs to be a list containing one or more of these values: " + ", ".join(VALID_TIMER_DATA))

        for val in data:
            if val == TIMER_DATA_VALUE_TIMESTAMP:
                pystache_obj[TEMPLATE_KEY_HAS_TIMESTAMP] = True
            elif val == TIMER_DATA_VALUE_STATS:
                pystache_obj[TEMPLATE_KEY_HAS_STATS] = True
            elif val == TIMER_DATA_VALUE_MEMORY:
                pystache_obj[TEMPLATE_KEY_HAS_MEMORY] = True
            elif val == TIMER_DATA_VALUE_CPU:
                pystache_obj[TEMPLATE_KEY_HAS_CPU] = True
            # elif val == TIMER_DATA_VALUE_STORAGE:
            #    pystache_obj[TEMPLATE_KEY_HAS_STORAGE] = True
            elif val == TIMER_DATA_VALUE_LB:
                pystache_obj[TEMPLATE_KEY_HAS_LB] = True
            elif val == TIMER_DATA_VALUE_STACK_SAMPLING:
                pystache_obj[TEMPLATE_KEY_HAS_STACK_SAMPLING] = True
            elif val == TIMER_DATA_VALUE_TIMERS:
                pystache_obj[TEMPLATE_KEY_TIMER_HAS_TIMERS] = True
            else:
                exit_NaCl(self.ctx, "Invalid value of Timer member " + TIMER_KEY_DATA + \
                    ". Valid values are: " + ", ".join(VALID_TIMER_DATA))

        self.nacl_state.append_to_pystache_data_list(TEMPLATE_KEY_TIMERS,
                                                     pystache_obj)
Exemple #5
0
    def transpile(self, type_t, subtype, action_ctx):
        # def transpile_action_cpp(self, type_t, subtype, action_ctx):
        parameters = [] if action_ctx.value_list(
        ) is None else action_ctx.value_list().value()  # list
        name = action_ctx.name().getText()
        name_lower = name.lower()

        if name_lower not in self.actions:
            # Then the action name could be the name of a function
            element = self.nacl_state.elements.get(name)
            if element is None or element.base_type != BASE_TYPE_FUNCTION:
                exit_NaCl(action_ctx,
                          "Couldn't identify action or function name " + name)
            return self.transpile_function_call(name, parameters, type_t,
                                                subtype, action_ctx)

        # If get here, name is the name of an action in self.actions

        actions = self.legal_actions[type_t.lower()]

        if name_lower not in actions:
            exit_NaCl(action_ctx, "Error transpiling action " + name + ": Legal actions for a function of type " + \
             type_t + " are: " + ", ".join(actions))

        return self.actions[name_lower](parameters, subtype, action_ctx)
Exemple #6
0
    def add_push(self, chain, functions):
        # chain: string with name of chain
        # functions: list containing value_name ctxs, where each name corresponds to the name of a NaCl function

        function_names = []
        num_functions = len(functions)
        for i, function in enumerate(functions):
            name = function.getText()
            element = self.nacl_state.elements.get(name)
            if element is None or element.base_type != BASE_TYPE_FUNCTION:
                exit_NaCl(function,
                          "No function with the name " + name + " exists")

            if element.type_t.lower() == TYPE_NAT:
                exit_NaCl(
                    function,
                    "A Nat function cannot be pushed onto a Gateway's forward chain"
                )

            function_names.append({
                TEMPLATE_KEY_FUNCTION_NAME: name,
                TEMPLATE_KEY_COMMA: (i < (num_functions - 1))
            })

        router_obj_name = INCLUDEOS_ROUTER_OBJ_NAME if self.nacl_state.language == CPP else exit_NaCl(self.ctx, \
            "Gateway can not transpile to other languages than C++")
        self.pushes.append({
            TEMPLATE_KEY_NAME: router_obj_name,
            TEMPLATE_KEY_CHAIN: chain,
            TEMPLATE_KEY_FUNCTION_NAMES: function_names
        })
Exemple #7
0
    def transpile_nat(self, type_nat, parameter_ctx_list, subtype, action_ctx):
        if type_nat != SNAT and type_nat != DNAT:
            exit_NaCl_internal_error(
                "Internal error in transpile_nat_cpp: Invalid NAT type " +
                type_nat)

        # pckt_name = self.nacl_state.subtranspilers[VALUE_TRANSPILER].get_pckt_name(subtype)

        parameters = ""
        num_params = len(parameter_ctx_list)
        if num_params == 1:
            first = self.nacl_state.transpile_value(parameter_ctx_list[0])
            # parameters = pckt_name + ", " + INCLUDEOS_CT_ENTRY + ", " + str(first)
            parameters = INCLUDEOS_DEREFERENCE_OP + IP_PCKT + ", " + INCLUDEOS_CT_ENTRY + ", " + str(
                first)
        elif num_params > 1:
            first = self.nacl_state.transpile_value(parameter_ctx_list[0])
            second = self.nacl_state.transpile_value(parameter_ctx_list[1])
            # parameters = pckt_name + ", " + INCLUDEOS_CT_ENTRY + ", {" + str(first) + ", " + str(second) + "}"
            parameters = INCLUDEOS_DEREFERENCE_OP + IP_PCKT + ", " + INCLUDEOS_CT_ENTRY + ", {" + str(
                first) + ", " + str(second) + "}"
        else:
            exit_NaCl(action_ctx, "No arguments provided to " + type_nat)

        return INCLUDEOS_NAT_OBJ_NAME + ARROW + type_nat + "(" + parameters + ");\n" + \
         self.transpile_accept([], subtype, action_ctx)
Exemple #8
0
    def transpile_log(self, parameter_ctx_list, subtype, action_ctx):
        content = "std::cout << "

        if len(parameter_ctx_list) > 0:
            for i, p in enumerate(parameter_ctx_list):
                if p.string() is not None:
                    content += self.nacl_state.transpile_value(p, subtype)
                else:
                    t = self.nacl_state.subtranspilers[
                        VALUE_TRANSPILER].get_cout_convert_to_type(p)
                    if t == TO_UNSIGNED:
                        content += "static_cast<unsigned>(" + self.nacl_state.transpile_value(
                            p, subtype) + ")"
                    elif t == TO_STRING:
                        content += self.nacl_state.transpile_value(
                            p, subtype) + ".to_string()"
                    else:
                        exit_NaCl(
                            p, "Internal error: std::cout conversion for " +
                            t + " has not been implemented")

                if i < (len(parameter_ctx_list) - 1):
                    content += " << "

        return content + ";\n"
Exemple #9
0
    def validate_dictionary_key(self, key, parent_key, level, value_ctx):
        class_name = self.get_class_name()

        if level == 1:
            if key.lower() not in PREDEFINED_TIMER_KEYS:
                exit_NaCl(value_ctx,
                          "Invalid " + class_name + " member " + key)
        else:
            exit_NaCl(value_ctx, "Invalid " + class_name + " member " + key)
Exemple #10
0
    def transpile_numeric_value(self, numeric_value):
        if numeric_value.ipv4_addr() is not None:
            return self.transpile_ip4_addr(numeric_value.ipv4_addr())

        if numeric_value.integer() is not None or \
        numeric_value.decimal() is not None:
            return numeric_value.getText()

        exit_NaCl(numeric_value,
                  "Undefined numeric value " + numeric_value.getText())
Exemple #11
0
    def get_cast(self, cast_to_proto, pckt_name, ctx):
        proto = cast_to_proto.lower()
        if proto not in cpp_pckt_classes:
            exit_NaCl(ctx, "Invalid protocol " + cast_to_proto)

        cpp_pckt_class = cpp_pckt_classes[proto]

        if proto != ICMP and pckt_name != ICMP_PCKT:
            return "static_cast<" + cpp_pckt_class + INCLUDEOS_REFERENCE_OP + ">(" + INCLUDEOS_DEREFERENCE_OP + pckt_name + ");"
        else:
            return INCLUDEOS_ICMP_PCKT_CLASS + "(std::move(" + IP_PCKT + "));"
Exemple #12
0
    def validate_and_process_not_route_members(self):
        for key, value_ctx in self.not_route_members.iteritems():
            if key == GATEWAY_KEY_SEND_TIME_EXCEEDED:
                resolved_value = self.nacl_state.transpile_value(value_ctx)
                self.not_route_members[key] = resolved_value

                if resolved_value != TRUE and resolved_value != FALSE:
                    exit_NaCl(value_ctx, "Invalid value of " + key + " (" + resolved_value + \
                        "). Must be set to " + TRUE + " or " + FALSE)
            elif key == GATEWAY_KEY_FORWARD:
                self.process_push(key, value_ctx)
Exemple #13
0
    def add_syslog(self):
        addr = self.members.get(SYSLOG_KEY_ADDRESS)
        port = self.members.get(SYSLOG_KEY_PORT)

        if addr is None or port is None:
            exit_NaCl(self.ctx,
                      "Syslog address and/or port have not been specified")

        self.nacl_state.append_to_pystache_data_list(TEMPLATE_KEY_SYSLOGS, {
            TEMPLATE_KEY_ADDRESS: addr,
            TEMPLATE_KEY_PORT: port
        })
Exemple #14
0
    def resolve_element_values(self, element, ctx):
        # value in a function is the name of an element - resolve all values in this element

        # Base types:
        # UNTYPED_INIT
        # TYPED_INIT
        # FUNCTION

        if element.base_type == BASE_TYPE_FUNCTION:
            exit_NaCl(ctx, "The name of a function (" + element.name + \
             ") cannot be used as a value name in a comparison")

        return self.transpile(element.ctx.value())
Exemple #15
0
    def transpile(self, val_ctx, subtype=""):
        if val_ctx is None:
            return ""

        # value: primitive_type | rng | string | value_name | obj | list_t;

        val = val_ctx.getText()

        if val_ctx.value_name() is not None:
            return self.transpile_value_name(val_ctx, subtype)

        if val_ctx.primitive_type() is not None:
            if val_ctx.primitive_type().numeric_type() is not None:
                return self.transpile_numeric_value(
                    val_ctx.primitive_type().numeric_type())

            if val_ctx.primitive_type().bool_val() is not None:
                return val.lower()

            if val_ctx.primitive_type().ipv4_cidr() is not None:
                return self.transpile_ip4_cidr(
                    val_ctx.primitive_type().ipv4_cidr())

        if val_ctx.rng() is not None:
            numeric_vals = val_ctx.rng().numeric_type()  # list
            from_val = numeric_vals[0]
            to_val = numeric_vals[1]

            # For now we have three numeric_types: ipv4_addr, integer, decimal
            if (from_val.ipv4_addr() is not None and to_val.ipv4_addr() is not None) or \
            (from_val.integer() is not None and to_val.integer() is not None) or \
            (from_val.decimal() is not None and to_val.decimal() is not None):
                from_transpiled = self.transpile_numeric_value(from_val)
                to_transpiled = self.transpile_numeric_value(to_val)
                return [from_transpiled, to_transpiled]
            else:
                exit_NaCl(
                    val_ctx, "A range's values need to be of the same type (" +
                    val + ")")

        if val_ctx.string() is not None:
            return val_ctx.parser.getTokenStream().getText(
                interval=(val_ctx.start.tokenIndex, val_ctx.stop.tokenIndex))

        if val_ctx.obj() is not None:
            return self.resolve_object(val_ctx.obj())

        if val_ctx.list_t() is not None:
            return self.resolve_list_t(val_ctx.list_t())

        exit_NaCl(val_ctx, "Undefined value " + val_ctx.getText())
Exemple #16
0
    def process_assignment(self, element_key):
        # print "process assignment Common"

        element = self.nacl_state.elements.get(element_key)

        name_parts = element_key.split(DOT)
        orig_member = name_parts[1]
        member = orig_member.lower()

        if len(name_parts) != 2:
            exit_NaCl(
                element.ctx,
                "Invalid " + self.get_class_name() + " member " + element.name)

        try:
            self.validate_key(orig_member)
        except NaCl_exception as e:
            exit_NaCl(element.ctx, e.value)

        if self.members.get(member) is not None:
            exit_NaCl(element.ctx,
                      "Member " + member + " has already been set")

        found_element_value = element.ctx.value()
        try:
            self.add_member(member, found_element_value)
        except NaCl_exception as e:
            exit_NaCl(element.ctx, e.value)
Exemple #17
0
    def transpile_function_call(self, name, parameter_ctx_list, type_t,
                                subtype, action_ctx):
        # This was the name of a function, and a function takes no parameters:
        if len(parameter_ctx_list) > 0:
            exit_NaCl(action_ctx, "A function call takes no parameters")

        element = self.nacl_state.elements.get(name)
        if element is None or element.base_type != BASE_TYPE_FUNCTION:
            exit_NaCl(action_ctx,
                      "No function with the name " + name + " exists")

        # element is a Function

        # A function of type Filter can only call functions of type Filter,
        # a function of type Nat can only call functions of type Nat, etc.
        if element.type_t.lower() != type_t.lower():
            exit_NaCl(
                action_ctx,
                "Error transpiling call to " + name + ": A function of type " +
                type_t + " can only call functions of the same type")

        if element.subtype.lower() not in legal_nested_subtypes[
                subtype.lower()]:
            exit_NaCl(
                action_ctx, "Cannot call a function of subtype " +
                element.subtype + " inside a function of subtype " + subtype)

        # return e.process()
        # Cannot call this and use the element's process method and res attribute because
        # the pckt name will be affected of/be different based on the subtype of the parent function
        # Therefore:
        return self.nacl_state.subtranspilers[FUNCTION_TRANSPILER].transpile(
            element.type_t, element.subtype, element.ctx, subtype)
Exemple #18
0
    def add_conntrack(self):
        timeout = self.members.get(CONNTRACK_KEY_TIMEOUT)
        timeouts = []

        if timeout is not None:
            class_name = self.get_class_name()

            if not isinstance(timeout, dict):
                exit_NaCl(
                    self.ctx, "Invalid " + CONNTRACK_KEY_TIMEOUT +
                    " value of " + class_name + " (needs to be an object)")

            for conntrack_type in timeout:
                t = timeout.get(conntrack_type)

                if not isinstance(t, dict):
                    exit_NaCl(
                        self.ctx, "Invalid " + conntrack_type + " value of " +
                        class_name + " (needs to be an object)")

                tcp_timeout = t.get(TCP)
                udp_timeout = t.get(UDP)
                icmp_timeout = t.get(ICMP)

                timeouts.append({
                    TEMPLATE_KEY_CONNTRACK_TYPE: conntrack_type,
                    TCP: tcp_timeout,
                    UDP: udp_timeout,
                    ICMP: icmp_timeout
                })

        stateful = False
        stateful_tcp = self.members.get(CONNTRACK_KEY_STATEFUL_TCP)
        if stateful_tcp is not None and stateful_tcp == TRUE:
            stateful = True

        self.nacl_state.append_to_pystache_data_list(
            TEMPLATE_KEY_CONNTRACKS, {
                TEMPLATE_KEY_NAME:
                self.name,
                TEMPLATE_KEY_CONNTRACK_LIMIT:
                self.members.get(CONNTRACK_KEY_LIMIT),
                TEMPLATE_KEY_CONNTRACK_RESERVE:
                self.members.get(CONNTRACK_KEY_RESERVE),
                TEMPLATE_KEY_CONNTRACK_STATEFUL:
                stateful,
                TEMPLATE_KEY_CONNTRACK_TIMEOUTS:
                timeouts
            })
Exemple #19
0
    def transpile_ip4_addr(self, ip_addr_ctx):
        parts = ip_addr_ctx.Number()  # list
        part0 = parts[0].getText()
        part1 = parts[1].getText()
        part2 = parts[2].getText()
        part3 = parts[3].getText()

        if int(part0) > BYTE_LIMIT or int(part1) > BYTE_LIMIT or int(
                part2) > BYTE_LIMIT or int(part3) > BYTE_LIMIT:
            exit_NaCl(
                ip_addr_ctx, "IPv4 addr " + ip_addr_ctx.getText() +
                " contains bytes greater than " + str(BYTE_LIMIT))

        return INCLUDEOS_IP4_ADDR_CLASS + "{" + ip_addr_ctx.getText().replace(
            ".", ",") + "}"
Exemple #20
0
    def process_push(self, chain, value_ctx):
        functions = []
        if value_ctx.list_t() is not None:
            # More than one function pushed onto chain
            for list_value in value_ctx.list_t().value_list().value():
                if list_value.value_name() is None:
                    exit_NaCl(list_value,
                              "This is not supported: " + value_ctx.getText())
                functions.append(list_value.value_name())
        elif value_ctx.value_name() is not None:
            # Only one function pushed onto chain
            functions = [value_ctx.value_name()]
        else:
            exit_NaCl(value_ctx,
                      "This is not supported: " + value_ctx.getText())

        self.add_push(chain, functions)
Exemple #21
0
    def get_pckt_cast(self, subtype, ctx):
        subtype_lower = subtype.lower()
        if subtype_lower == IP:
            return ""  # Already have (IP) pckt as input to Filter's operator() method

        pckt_name = pckt_names.get(subtype_lower)

        if pckt_name is not None:
            if pckt_name != ICMP_PCKT:
                return AUTO + INCLUDEOS_REFERENCE_OP + " " + pckt_name + " = " + self.get_cast(
                    subtype_lower, IP_PCKT, ctx)
            else:
                return AUTO + " " + pckt_name + " = " + self.get_cast(
                    subtype_lower, IP_PCKT, ctx)
        else:
            exit_NaCl(
                ctx, "Invalid subtype " + subtype +
                ", or pckt name or cpp pckt name not found")
Exemple #22
0
 def validate_dictionary_key(self, key, parent_key, level, value_ctx):
     if level == 1:
         if key not in predefined_lb_keys:
             exit_NaCl(value_ctx, "Invalid Load_balancer member " + key)
     elif level == 2:
         if parent_key == "":
             exit_NaCl(
                 value_ctx, "Internal error: Parent key of " + key +
                 " has not been given")
         if parent_key == LB_KEY_CLIENTS and key not in predefined_lb_clients_keys:
             exit_NaCl(
                 value_ctx, "Invalid Load_balancer member " + key + " in " +
                 self.name + "." + parent_key)
         if parent_key == LB_KEY_SERVERS and key not in predefined_lb_servers_keys:
             exit_NaCl(
                 value_ctx, "Invalid Load_balancer member " + key + " in " +
                 self.name + "." + parent_key)
     else:
         exit_NaCl(value_ctx, "Invalid Load_balancer member " + key)
Exemple #23
0
    def transpile_ip4_cidr(self, ip_cidr_ctx):
        parts = ip_cidr_ctx.ipv4_addr().Number()  # list
        part0 = parts[0].getText()
        part1 = parts[1].getText()
        part2 = parts[2].getText()
        part3 = parts[3].getText()

        if int(part0) > BYTE_LIMIT or int(part1) > BYTE_LIMIT or int(
                part2) > BYTE_LIMIT or int(part3) > BYTE_LIMIT:
            exit_NaCl(
                ip_cidr_ctx, "IPv4 cidr " + ip_cidr_ctx.getText() +
                " contains bytes greater than " + str(BYTE_LIMIT))

        mask = ip_cidr_ctx.cidr_mask().integer().getText()

        if int(mask) > MASK_LIMIT:
            exit_NaCl(
                ip_cidr_ctx, "IPv4 cidr mask in " + ip_cidr_ctx.getText() +
                " is greater than " + str(MASK_LIMIT))

        return INCLUDEOS_IP4_CIDR_CLASS + "{" + part0 + "," + part1 + "," + part2 + "," + part3 + "," + mask + "}"
Exemple #24
0
    def construct_comparison(self, comp_ctx, resolved_lhs, resolved_rhs,
                             comparison_op, op):
        lhs_is_list = True if isinstance(resolved_lhs, list) else False
        rhs_is_list = True if isinstance(resolved_rhs, list) else False

        result = ""

        # If none of these are lists, we have the resolved values
        if not lhs_is_list and not rhs_is_list:
            if INCLUDEOS_IP4_CIDR_CLASS in str(resolved_rhs):
                if comparison_op.lower() != IN:
                    exit_NaCl(comp_ctx.comparison_operator(), "Invalid operator (" + comparison_op + "). Only the 'in' " + \
                     "operator is valid when comparing a property to a range, cidr, list or object")

                result = str(resolved_rhs) + ".contains(" + str(
                    resolved_lhs) + ")"
            else:
                if comparison_op.lower() == IN:
                    exit_NaCl(comp_ctx.comparison_operator(), "The 'in' operator can only be used when comparing a property to " + \
                     "a range, cidr, list or object")

                result = str(resolved_lhs) + " " + comparison_op + " " + str(
                    resolved_rhs)

            if op != "":
                result = "(" + result + ") " + op + " "

            return result

        # If any of the resolved sides is a list, the 'in' operator should have been used
        # (rng, ip4_cidr, list_t, obj)
        if comparison_op != IN:
            exit_NaCl(comp_ctx.comparison_operator(), "Invalid operator (" + comparison_op + \
             "). Only the 'in' operator is valid when comparing a value to a range, cidr, list or object")

        # If the 'in' operator has been used, only the resolved_rhs should be a list, not
        # the resolved_lhs
        if lhs_is_list:
            exit_NaCl(comp_ctx.lhs().value(), "The left hand side of a comparison can not resolve to a set " + \
             "of values, e.g. a range, cidr, list or object")

        if rhs_is_list:
            result = self.construct_comparisons_from_list(
                resolved_rhs, resolved_lhs)

        if op != "":
            return "(" + result + ") " + op + " "

        return result
Exemple #25
0
    def transpile_conditional(self, type_t, subtype, cond):
        content = ""
        bodies = cond.body()
        num_bodies = len(bodies)

        if hasattr(cond, 'If') and cond.If() is not None:
            if num_bodies < 1:
                exit_NaCl(cond, "Invalid syntax")

            # If-body is always first (index 0)
            content += cond.If().getText() + " " + self.transpile_bool_expr(type_t, subtype, cond) + \
             " {\n" + self.transpile_body_elements(type_t, subtype, bodies[0].body_element()) + "}\n"

        if hasattr(cond, 'Else') and cond.Else() is not None:
            if num_bodies < 2:
                exit_NaCl(cond, "Invalid syntax")

            # Else-body is always second/last (index 1)
            content += cond.Else().getText() + " {\n" + \
             self.transpile_body_elements(type_t, subtype, bodies[1].body_element()) + "}\n"

        return content
Exemple #26
0
	def process_members(self):
		# Loop through self.members and transpile the values
		for key, member in self.members.iteritems():
			if key != IFACE_KEY_CONFIG and key != IFACE_KEY_MASQUERADE:
				self.members[key] = self.nacl_state.transpile_value(member)

				# Validate that an Iface with this Iface's index has not already been defined
				if key == IFACE_KEY_INDEX:
					for key, el in self.nacl_state.elements.iteritems():
						if isinstance(el, Iface) and key != self.name:
							el_idx = el.members.get(IFACE_KEY_INDEX)
							el_vlan = el.members.get(IFACE_KEY_VLAN)
							# If another Iface has been defined with the same index and neither this nor that Iface is a vlan
							# (has a vlan member), display an error
							if el_idx is not None and el_idx == self.members.get(IFACE_KEY_INDEX) and el_vlan is None and self.members.get(IFACE_KEY_VLAN) is None:
								exit_NaCl(member, "Another Iface has been defined with index " + el_idx)
			elif key == IFACE_KEY_CONFIG:
				self.members[IFACE_KEY_CONFIG] = member.value_name().getText().lower()
			else:
				masq_val = self.nacl_state.transpile_value(member)

				if not isinstance(masq_val, basestring) or (masq_val.lower() != TRUE and masq_val.lower() != FALSE):
					exit_NaCl(member, "Invalid masquerade value. Must be set to true or false")

				if masq_val == TRUE:
					self.nacl_state.append_to_pystache_data_list(TEMPLATE_KEY_MASQUERADES, {
						TEMPLATE_KEY_IFACE: self.name
					})

		# Update config members
		config = self.members.get(IFACE_KEY_CONFIG)
		if config == DHCP_CONFIG:
			self.config_is_dhcp = True
		elif config == DHCP_FALLBACK_CONFIG:
			self.config_is_dhcp_fallback = True
		else:
			self.config_is_static = True
Exemple #27
0
    def get_pystache_route_obj(self, name, route_ctx):
        route_obj = {"ctx": route_ctx}
        pairs = route_ctx.key_value_list().key_value_pair()

        for pair in pairs:
            orig_key = pair.key().getText()
            key = orig_key.lower()

            if route_obj.get(key) is not None:
                exit_NaCl(
                    pair.key(), "Member " + key +
                    " has already been set for route " + name)

            if key not in PREDEFINED_GATEWAY_ROUTE_KEYS:
                exit_NaCl(pair.key(), orig_key + " is not a valid Gateway route member. " + \
                    "Valid members are: " + ", ".join(PREDEFINED_GATEWAY_ROUTE_KEYS))

            if key != GATEWAY_KEY_IFACE:
                route_obj[key] = self.nacl_state.transpile_value(pair.value())
            else:
                # Then the Iface element's name is to be added to the route_obj,
                # not the transpiled Iface
                iface_name = pair.value().getText()

                if pair.value().value_name() is None:
                    exit_NaCl(
                        pair.value(),
                        "Gateway route member iface contains an invalid value ("
                        + iface_name + ")")

                element = self.nacl_state.elements.get(iface_name)
                if element is None or (hasattr(element, 'type_t') and
                                       element.type_t.lower() != TYPE_IFACE):
                    exit_NaCl(
                        pair.value(),
                        "No Iface with the name " + iface_name + " exists")

                route_obj[key] = iface_name

        return route_obj
Exemple #28
0
    def get_cout_convert_to_type(self, val_ctx):
        if val_ctx.value_name() is None:
            exit_NaCl(val_ctx, "This value can not be printed")

        name_parts = val_ctx.value_name().getText().split(DOT)
        name = name_parts[0]

        if len(name_parts) == 1:
            exit_NaCl(val_ctx, "This value can not be printed")

        if name.lower() not in proto_objects:
            exit_NaCl(val_ctx, name + " is not a valid protocol")

        name_parts.pop(0)
        properties = name_parts
        if len(properties) > 1:
            exit_NaCl(
                val_ctx, "Undefined protocol object properties: " +
                val_ctx.value_name().getText())

        return proto_objects[name.lower()].get_cout_convert_to_type_cpp(
            properties[0].lower(), val_ctx)
Exemple #29
0
    def validate_members(self):
        if self.members.get(IFACE_KEY_INDEX) is None:
            exit_NaCl(self.ctx.value(),
                      "An index needs to be specified for all Ifaces")

        config = self.members.get(IFACE_KEY_CONFIG)
        if config is not None and (config.value_name() is None
                                   or config.value_name().getText().lower()
                                   not in PREDEFINED_CONFIG_TYPES):
            exit_NaCl(config, "Invalid config value " + config.getText())

        if (config is None or config.value_name().getText().lower() != DHCP_CONFIG) and \
         (self.members.get(IFACE_KEY_ADDRESS) is None or \
          self.members.get(IFACE_KEY_NETMASK) is None):
            exit_NaCl(self.ctx.value(), "The members " + IFACE_KEY_ADDRESS + " and " + IFACE_KEY_NETMASK + \
             " must be set for every Iface if the Iface configuration hasn't been set to " + DHCP_CONFIG)
        elif config is not None and config.value_name().getText().lower() == DHCP_CONFIG and \
         (self.members.get(IFACE_KEY_ADDRESS) is not None or \
          self.members.get(IFACE_KEY_NETMASK) is not None or \
          self.members.get(IFACE_KEY_GATEWAY) is not None or \
          self.members.get(IFACE_KEY_DNS) is not None):
            exit_NaCl(config.value_name(), "An Iface with config set to dhcp should not specify " + IFACE_KEY_ADDRESS + \
             ", " + IFACE_KEY_NETMASK + ", " + IFACE_KEY_GATEWAY + " or " + IFACE_KEY_DNS)
Exemple #30
0
    def validate_members(self):
        vlan_index = self.members.get(VLAN_KEY_INDEX)
        vlan_address = self.members.get(VLAN_KEY_ADDRESS)
        vlan_netmask = self.members.get(VLAN_KEY_NETMASK)

        if vlan_index is None or vlan_address is None or vlan_netmask is None:
            exit_NaCl(
                self.ctx,
                "The members index, address and netmask must be set for every Vlan"
            )

        if vlan_index.obj() is not None or vlan_index.list_t() is not None:
            exit_NaCl(
                vlan_index,
                "The Vlan member " + VLAN_KEY_INDEX + " can not be an object")
        if vlan_address.obj() is not None or vlan_address.list_t() is not None:
            exit_NaCl(
                vlan_address, "The Vlan member " + VLAN_KEY_ADDRESS +
                " can not be an object")
        if vlan_netmask.obj() is not None or vlan_netmask.list_t() is not None:
            exit_NaCl(
                vlan_netmask, "The Vlan member " + VLAN_KEY_NETMASK +
                " can not be an object")