def p_addr_set_line_3(p): '''addr_set_line : SET START_IP IP_ADDR''' if p_info['range_ip']: object_dict[p_info['current_object']].append({'address': Operator('RANGE', Ip(p[3]), p_info['range_ip'])}) p_info['range_ip'] = None else: p_info['range_ip'] = Ip(p[3])
def get_all_simple_path(self, source, dest): """Get all simple path from a point to an other. Return ------ Return a networkX list of path """ source_node = None dest_node = None if source: for i in self.subnet_list: if Ip.ListContains([i], source): source_node = i break if dest: for i in self.subnet_list: if Ip.ListContains([i], dest): dest_node = i break if not source or not dest: for node in self.graph.nodes(data=True): if node[1]['object'].marker_type == 'from': source_node = node[0] if node[1]['object'].marker_type == 'to': dest_node = node[0] if not source_node or not self.multidigraph.has_node(source_node)\ or not dest_node or not self.multidigraph.has_node(dest_node): raise return nx.all_simple_paths(self.multidigraph, source_node, dest_node)
def ip_operator_compare(self, operator_1, operator_2): """ take two ip_operator in input return true if the second one is contain or is equal to the first """ check = False # 4294967295 value for 255.255.255.255 if operator_1.v1.mask != 4294967295: tmp_val = 4294967295 ip_min_check = operator_1.v1.ip & operator_1.v1.mask tmp_val = tmp_val ^ operator_1.v1.mask ip_max_check = operator_1.v1.ip | tmp_val operator_1 = Operator("RANGE", Ip(ip_min_check), Ip(ip_max_check)) if operator_2.v1.mask != 4294967295: tmp_val = 4294967295 ip_min_check = operator_2.v1.ip & operator_2.v1.mask tmp_val = tmp_val ^ operator_2.v1.mask ip_max_check = operator_2.v1.ip | tmp_val operator_2 = Operator("RANGE", Ip(ip_min_check), Ip(ip_max_check)) if operator_1.operator == "RANGE" and operator_2.operator == "RANGE": if operator_1.v1.ip <= operator_2.v1.ip <= operator_1.v2.ip: if operator_1.v1.ip <= operator_2.v2.ip <= operator_1.v2.ip: check = True elif operator_1.operator == "RANGE" and operator_2.operator != "RANGE": if operator_1.v1.ip <= operator_2.v1.ip <= operator_1.v2.ip: check = True elif operator_1.operator != "RANGE" and operator_2.operator == "RANGE": if operator_1.v1.ip == operator_2.v1.ip and operator_1.v1.ip == operator_2.v2.ip: check = True elif operator_1.operator != "RANGE" and operator_2.operator != "RANGE": if operator_1.v1.ip == operator_2.v1.ip: check = True return check
def p_address_line_3(p): '''address_line : SET ADDRESS WORD object_name IP_ADDR opt_slash NUMBER | SET ADDRESS WORD object_name IP_ADDR opt_slash NUMBER words''' object_dict[p[4]] = [{ 'address': Operator('EQ', Ip(p[5], Ip.CidrToMask(int(p[7])))) }]
def get_acl_list(self, src=None, dst=None, firewall=None): """Get all acl filtered by optional parameters Parameters ---------- src : Ip / Firewall (optional). The source of the acl any if src is not defined dst : Ip / Firewall (optional). The destination of the acl any if dst is not defined firewall : Firewall (optional). Filter acl belonging to this firewall any if firewall is not defined """ acl_list = [] if src and isinstance(src, Ip) and not self.multidigraph.has_node(src): src = Ip.ListContains(self.digraph_subnet_list, src) if dst and isinstance(dst, Ip) and not self.multidigraph.has_node(dst): dst = Ip.ListContains(self.digraph_subnet_list, dst) if src and not self.multidigraph.has_node(src): return acl_list for elem in self.multidigraph.edges(src, data=True): if dst and elem[1] != dst: continue if firewall and elem[2]['firewall'] != firewall: continue acl_list.append(elem[2]['acl']) return acl_list
def p_nat_rule_static(p): '''nat_rule_line : STATIC LPAREN WORD COMA WORD RPAREN IP_ADDR IP_ADDR NETMASK IP_ADDR''' in_iface = p_info['firewall'].get_interface_by_name(p[3]) out_iface = p_info['firewall'].get_interface_by_name(p[5]) rule = Nat_Rule(None, None, [], [Ip(p[7], p[10])], [],[] , [], [Ip(p[8], p[10])], [], 'static', [out_iface], [in_iface]) p_info['firewall'].nat_rule_list.append(rule)
def fill_obj_dict_netobj(obj): if nd.has_key(obj['name']): nd[obj['name']].append( {obj['name']: Operator('EQ', Ip(obj['ipaddr']))}) else: nd[obj['name']] = list() nd[obj['name']].append( {obj['name']: Operator('EQ', Ip(obj['ipaddr']))})
def to_ip_list(string): ip_list = [] sub_list = string.split(',') for sub in sub_list: sub.split('/') mask = Ip.CidrToMask(sub[1]) if len(sub) > 1 else '255.255.255.255' ip_list.append(Ip(sub[0], mask)) return ip_list
def merge_ip_range(self, ip_min, ip_max, ip_to_compare_min, ip_to_compare_max): """ The function merge 2 range or 1 range and one ip If the merge is possible return the new operator otherwise return nothing ip_min/ip_max are the ip for the first range ip_to_compare_min/ip_to_compare_max is the second range to compare to an ip just send a non value for ip_to_compare_max """ ip1 = None ip2 = None operator = None if (not ip_to_compare_max) and (ip_min <= ip_to_compare_min <= ip_max): ip1 = Ip(ip_min.ip) ip2 = Ip(ip_max.ip) elif ip_to_compare_max: if ip_min.ip <= ip_to_compare_min.ip <= ip_max.ip: ip1 = Ip(ip_min.ip) ip2 = Ip( ip_max.ip) if ip_max.ip > ip_to_compare_max.ip else Ip( ip_to_compare_max.ip) elif ip_min.ip <= ip_to_compare_max.ip <= ip_max.ip: ip1 = Ip(ip_to_compare_min.ip) ip2 = Ip(ip_max.ip) elif ip_to_compare_min.ip < ip_min.ip and ip_to_compare_max.ip > ip_max.ip: ip1 = Ip(ip_to_compare_min.ip) ip2 = Ip(ip_to_compare_max.ip) if ip1 and ip2: operator = Operator("RANGE", ip1, ip2) return operator
def get_all_flows(self): for flow in self.liststore: current_rule = Rule(None, None, [], [], [], [], [], Action(False)) try: if isinstance(flow[0], str) and len(flow[0]) != 0: current_rule.identifier = int(flow[0]) if isinstance(flow[1], str) and len(flow[1]) != 0: protocols = flow[1].split(',') for protocol in protocols: current_rule.protocol.append( Operator('EQ', Protocol(protocol))) if isinstance(flow[2], str) and len(flow[2]) != 0: ips = flow[2].split(',') for ip in ips: if '/' in ip: mask = ip[ip.index('/') + 1:] ip = ip[:ip.index('/')] current_rule.ip_source.append( Operator( 'EQ', Ip(ip, self.fromDec2Dotted(int(mask))))) else: current_rule.ip_source.append( Operator('EQ', Ip(ip, '255.255.255.255'))) if isinstance(flow[3], str) and len(flow[3]) != 0: ports = flow[3].split(',') for port in ports: current_rule.port_source.append( Operator('EQ', Port(int(port)))) if isinstance(flow[4], str) and len(flow[4]) != 0: ips = flow[4].split(',') for ip in ips: if '/' in ip: mask = ip[ip.index('/') + 1:] ip = ip[:ip.index('/')] current_rule.ip_dest.append( Operator( 'EQ', Ip(ip, self.fromDec2Dotted(int(mask))))) else: current_rule.ip_dest.append( Operator('EQ', Ip(ip, '255.255.255.255'))) if isinstance(flow[5], str) and len(flow[5]) != 0: ports = flow[5].split(',') for port in ports: current_rule.port_dest.append( Operator('EQ', Port(int(port)))) if flow[6] == 'deny': current_rule.action = Action(False) elif flow[6] == 'accept': current_rule.action = Action(True) except KeyError: print 'error' # self.flows.append(current_rule)
def p_route_line(p): '''route_line : ROUTE item IP_ADDR IP_ADDR IP_ADDR NUMBER''' #for i in p : print i iface = p_info['firewall'].get_interface_by_name(str(p[2])) route = Route(p_info['index_route'], iface, Ip(p[3]), Ip(p[4]), Ip(p[5]), int(p[6])) p_info['route_list'].append(route) p_info['index_route'] += 1 print route.to_string() print('okk') print 'pb instanticiation de la route'
def p_route_line(p) : '''route_line : ROUTE WORD IP_ADDR IP_ADDR IP_ADDR NUMBER''' iface = p_info['firewall'].get_interface_by_name(str(p[2])) if not isinstance(iface, Interface) : for i in p_info['firewall'].interfaces : iface = i.get_subif_by_name(str(p[7])) if isinstance(iface, Interface) : break route = Route(p_info['index_route'], iface, Ip(p[3]), Ip(p[4]), Ip(p[5]), int(p[6])) p_info['route_list'].append(route) p_info['index_route'] += 1
def get_rule_from_iptable_line(self, rule_line): """ get one iptable line and return a corresponding rule This function need some improvement in order to manage every case """ action = Action(True) if rule_line[0] != "DROP" else Action(False) if rule_line[3] == "anywhere": ip_source = [] else: if "/" not in rule_line[3]: ip_source = [Operator("EQ", Ip(rule_line[3]))] else: ip_source = [ Operator( 'EQ', Ip(rule_line[3].split('/')[0], fromDec2Dotted(int(rule_line[3].split('/')[1])))) ] if rule_line[4] == "anywhere": ip_dest = [] else: if "/" not in rule_line[4]: ip_dest = [Operator("EQ", Ip(rule_line[4]))] else: ip_dest = [ Operator( 'EQ', Ip(rule_line[4].split('/')[0], fromDec2Dotted(int(rule_line[4].split('/')[1])))) ] port_source = [] port_dest = [] protocol = [] if rule_line[1] == "all" else [ Operator("EQ", Protocol(rule_line[1])) ] if len(rule_line) >= 7: if "spt" in rule_line[6]: port_source.append(Operator("EQ", Port(rule_line[6][4:-1]))) elif "dpt" in rule_line[6]: port_dest.append(Operator("EQ", Port(rule_line[6][4:-1]))) elif "multiport" in rule_line: tmp_idx = rule_line.index("multiport") if rule_line[tmp_idx + 1] == "dports": ports_dest_list = rule_line[tmp_idx + 2].split(",") for tmp_port_dest in ports_dest_list: port_dest.append(Operator("EQ", Port(tmp_port_dest))) else: tmp_line = "" for tmp_elem in rule_line: tmp_line += " " + tmp_elem print tmp_line return Rule(0, "", protocol, ip_source, port_source, ip_dest, port_dest, action)
def p_nat_rule_inside(p): '''nat_rule_line : NAT LPAREN WORD RPAREN NUMBER IP_ADDR IP_ADDR''' global nats, globs if p[5] not in nats.keys(): nats[p[5]] = {} nats[p[5]]['iface'] = [] iface = p_info['firewall'].get_interface_by_name(p[3]) nats[p[5]]['iface'].append(iface) nats[p[5]]['src'] = [] nats[p[5]]['src'].append(Ip(p[6], p[7])) else: iface = p_info['firewall'].get_interface_by_name(p[3]) nats[p[5]]['iface'].append(iface) nats[p[5]]['src'].append(Ip(p[6], p[7]))
def p_nat_rule_outside(p): '''nat_rule_line : GLOBAL LPAREN WORD RPAREN NUMBER IP_ADDR''' global nats, globs if p[5] not in globs.keys(): globs[p[5]] = {} globs[p[5]]['iface'] = [] iface = p_info['firewall'].get_interface_by_nameif(p[3]) globs[p[5]]['iface'].append(iface) globs[p[5]]['dst'] = [] globs[p[5]]['dst'].append(Ip(p[6])) else: iface = p_info['firewall'].get_interface_by_nameif(p[3]) globs[p[5]]['iface'].append(iface) globs[p[5]]['dst'].append(Ip(p[6]))
def p_route_line2(p): '''route_line : IP_ADDR SLASH NUMBER VIA IP_ADDR DEV WORD''' print[p[i] for i in range(len(p))] iface = p_info['firewall'].get_interface_by_name(str(p[5])) if not isinstance(iface, Interface): for i in p_info['firewall'].interfaces: iface = i.get_subif_by_name(str(p[5])) if isinstance(iface, Interface): break route = Route(p_info['index_route'], iface, Ip(p[1]), Ip(fromDec2Dotted(int(p[3]))), Ip(p[5])) print route.to_string() p_info['route_list'].append(route) p_info['index_route'] += 1
def p_default_route_line(p): '''route_line : DEFAULT VIA IP_ADDR DEV WORD''' print[p[i] for i in range(len(p))] iface = p_info['firewall'].get_interface_by_name(str(p[5])) if not isinstance(iface, Interface): for i in p_info['firewall'].interfaces: iface = i.get_subif_by_name(str(p[5])) if isinstance(iface, Interface): break route = Route(p_info['index_route'], iface, Ip('0.0.0.0'), Ip('0.0.0.0'), Ip(p[3])) print route.to_string() p_info['route_list'].append(route) p_info['index_route'] += 1
def finish_dst(s): tmpObj = resolve(s) if tmpObj['type'] in {'host', 'gateway', 'gateway_cluster'}: p_info['current_rule'].ip_dest.append( Operator('EQ', Ip(tmpObj['ipaddr']))) elif tmpObj['type'] == 'network': p_info['current_rule'].ip_dest.append( Operator('EQ', Ip(tmpObj['ipaddr'], tmpObj['netmask']))) elif tmpObj['type'] == 'machines_range': p_info['current_rule'].ip_dest.append( Operator('RANGE', Ip(tmpObj['start_range']), Ip(tmpObj['stop_range']))) elif tmpObj['type'] in {'group', 'Group'}: for member in tmpObj['members']: subTmpOBj = resolve(member) if subTmpOBj['type'] in {'host', 'gateway', 'gateway_cluster'}: p_info['current_rule'].ip_dest.append( Operator('EQ', Ip(subTmpOBj['ipaddr']))) elif subTmpOBj['type'] == 'network': p_info['current_rule'].ip_dest.append( Operator('EQ', Ip(subTmpOBj['ipaddr'], subTmpOBj['netmask']))) elif subTmpOBj['type'] == 'machines_range': p_info['current_rule'].ip_dest.append( Operator('RANGE', Ip(subTmpOBj['start_range']), Ip(subTmpOBj['stop_range'])))
def toBDD(self, index): """Construct the ROBDD Parameters ---------- index : int. Used for variable index in ROBDD. Return ------ Return the computed ROBDD """ if self.operator == 'LT': if isinstance(self.v1, Protocol): return Protocol.range2bdd(0, self.v1.get_value(), index) elif isinstance(self.v1, Ip): return Ip.range2bdd(0, self.v1.ip | ~self.v1.mask & 0xFFFFFFFF, index) elif isinstance(self.v1, Port): return Port.range2bdd(0, self.v1.get_value(), index) else: return self.v1.toBDD(index) elif self.operator == 'GT': if isinstance(self.v1, Protocol): return Protocol.range2bdd(self.v1.get_value(), 2**8 - 1, index) elif isinstance(self.v1, Ip): return Ip.range2bdd(self.v1.ip & self.v1.mask, 2**32 - 1, index) elif isinstance(self.v1, Port): return Port.range2bdd(self.v1.get_value(), 2**16 - 1, index) else: return self.v1.toBDD(index) elif self.operator == 'EQ': return self.v1.toBDD(index) elif self.operator == 'NEQ': return negate_bdd(self.v1.toBDD(index)) elif self.operator == 'RANGE': if isinstance(self.v1, Protocol): return Protocol.range2bdd(self.v1.get_value(), self.v2.get_value(), index) elif isinstance(self.v1, Ip): return Ip.range2bdd(self.v1.ip & self.v1.mask, self.v2.ip | ~self.v2.mask & 0xFFFFFFFF, index) elif isinstance(self.v1, Port): return Port.range2bdd(self.v1.get_value(), self.v2.get_value(), index) else: return self.v1.toBDD(index) else: return self.v1.toBDD(index)
def merge_ip(self, ips_list): """ return a list with all common element present in each list of ip """ len_ips_list = len(ips_list) for idx, ports in enumerate(ips_list): if idx + 1 <= len_ips_list - 1: tmp_list = None if len(ips_list[idx]) == 0: continue elif len(ips_list[idx + 1]) == 0: ips_list[idx + 1] = ips_list[idx] continue for ip1 in ips_list[idx]: for ip2 in ips_list[idx + 1]: # 4294967295 value for 255.255.255.255 if ip1.v1.mask != 4294967295: tmp_val = 4294967295 ip_min_check = ip1.v1.ip & ip1.v1.mask tmp_val = tmp_val ^ ip1.v1.mask ip_max_check = ip1.v1.ip | tmp_val ip1 = Operator("RANGE", Ip(ip_min_check), Ip(ip_max_check)) if ip2.v1.mask != 4294967295: tmp_val = 4294967295 ip_min_check = ip2.v1.ip & ip2.v1.mask tmp_val = tmp_val ^ ip2.v1.mask ip_max_check = ip2.v1.ip | tmp_val ip2 = Operator("RANGE", Ip(ip_min_check), Ip(ip_max_check)) if ip1.operator == "EQ" and ip2.operator == "EQ": if ip1.v1.ip == ip2.v1.ip: tmp_list = tmp_list.append( ip1) if tmp_list is not None else [ip1] break elif ip1.operator == "RANGE" and ip2.operator == "EQ": if ip1.v1.ip < ip2.v1.ip < ip1.v2.ip: tmp_list.append(ip2) elif ip1.operator == "EQ" and ip2.operator == "RANGE": if ip2.v1.ip < ip1.v1.ip < ip2.v2.i: tmp_list.append(ip1) elif ip1.operator == "RANGE" and ip2.operator == "RANGE": if ip1.v1.ip < ip2.v1.ip < ip1.v2.ip and ip1.v1.ip < ip2.v2.ip < ip1.v2.ip: tmp_list.append(ip1) elif ip1.v1.ip < ip2.v1.ip < ip1.v2.ip and ip1.v2.ip < ip2.v2.ip: tmp_list.append( Operator("RANGE", Ip(ip2.v1.ip), Ip(ip1.v2.ip))) elif ip2.v1.ip < ip1.v1.ip and ip1.v1.ip < ip2.v2.ip < ip1.v2.ip: tmp_list.append( Operator("RANGE", Ip(ip1.v1.ip), Ip(ip2.v2.ip))) elif ip2.v1.ip < ip1.v1.ip < ip2.v2.ip and ip2.v1.ip < ip1.v2.ip < ip2.v2.ip: tmp_list.append(ip2) ips_list[idx + 1] = tmp_list if tmp_list == None: ips_list[len(ips_list) - 1] = None break return ips_list[len(ips_list) - 1]
def p_address_line_1(p): '''address_line : SET ADDRESS WORD object_name WORD | SET ADDRESS WORD object_name WORD words''' object_dict[p[4]] = [{ 'address': Operator('EQ', Ip(socket.gethostbyname(p[5]))) }]
def p_address_line(p): '''address_line : ADDRESS WORD IP_ADDR SLASH NUMBER SEMI_COLON''' global parsing_level1, parsing_level2, parsing_level3, networks if parsing_level1 == 'security' and parsing_level2 == 'networks' and parsing_level3 == 'address': networks.append({ 'name': p[2], 'ip_addr': Ip(p[3], fromDec2Dotted(int(p[5]))) })
def p_ipsec_peer(p): '''map_attr_line : CRYPTO MAP WORD NUMBER SET PEER IP_ADDR ''' maps = p_info['firewall'].ipsec_maps if p[3] in maps.keys(): if p[4] in maps[p[3]].keys(): maps[p[3]][p[4]]['peer_dst'] = Ip(p[7]) else: maps[p[3]][p[4]] = {} maps[p[3]][p[4]]['peer_dst'] = Ip(p[7]) else: maps[p[3]] = {} if p[4] in maps[p[3]].keys(): maps[p[3]][p[4]]['peer_dst'] = Ip(p[7]) else: maps[p[3]][p[4]] = {} maps[p[3]][p[4]]['peer_dst'] = Ip(p[7])
def iptable_route_from_data(self, data): if data[0] == "default": ip_route = Ip("0.0.0.0") mask_route = Ip("0.0.0.0", "0.0.0.0") interface_name = data[4] id = len(self.routes) gw = Ip(data[2]) tmp = Route(id, interface_name, ip_route, mask_route, gw) self.routes.append(tmp) else: print data[0] if '/' in data[0]: ip_route = Ip(data[0].split('/')[0]) mask_route = Ip( "0.0.0.0", self.fromDec2Dotted(int(data[0].split('/')[1]))) else: ip_route = Ip(data[0]) mask_route = Ip("0.0.0.0") interface_name = data[2] iface = None for interface in self.fw.interfaces: if interface.nameif == interface_name: iface = interface break if iface is not None: id = len(self.routes) tmp = Route(id, iface, ip_route, mask_route, iface.network) self.routes.append(tmp) return self.routes
def p_policy_context_line_2(p): '''policy_context_line : SET DST_ADDRESS NEGATE''' if not p_info['context_policy'].ip_dest: p_info['context_policy'].ip_dest.append(Operator('EQ', Ip(0))) else: res = [] for op in p_info['context_policy'].ip_dest: res += op.toggle() p_info['context_policy'].ip_dest = res
def p_policy_context_line_4(p): '''policy_context_line : SET SRC_ADDRESS NEGATE''' if not p_info['context_policy'].ip_source: p_info['context_policy'].ip_source.append(Operator('EQ', Ip(0))) else: res = [] for op in p_info['context_policy'].ip_source: res += op.toggle() p_info['context_policy'].ip_source = res
def p_ip_src_line_1(p): '''ip_src_line : IP_SRC COLON words''' for src_ip in p[3].split(','): p_info['current_rule'].ip_source.append( Operator( 'EQ', Ip( src_ip.split('/')[0], fromDec2Dotted(int(src_ip.split('/')[1])))))
def p_ip_dst_line_1(p): '''ip_dst_line : IP_DST COLON words''' for dst_ip in p[3].split(','): p_info['current_rule'].ip_dest.append( Operator( 'EQ', Ip( dst_ip.split('/')[0], fromDec2Dotted(int(dst_ip.split('/')[1])))))
def p_route_line(p): '''route_line : SET ROUTE IP_ADDR SLASH NUMBER INTERFACE WORD GATEWAY IP_ADDR | SET ROUTE IP_ADDR SLASH NUMBER INTERFACE WORD GATEWAY IP_ADDR PREFERENCE NUMBER''' iface = p_info['firewall'].get_interface_by_nameif(str(p[7])) if not isinstance(iface, Interface): for i in p_info['firewall'].interfaces: iface = i.get_subif_by_nameif(str(p[7])) if isinstance(iface, Interface): break print iface.name route = Route(p_info['index_route'], iface, Ip(p[3]), Ip(str(calcDottedMask(int(p[5])))), Ip(p[9])) print 'ok' p_info['route_list'].append(route) p_info['index_route'] += 1 print route.to_string() print('okk') print 'pb instanticiation de la route'
def p_nat_rule_static1(p): '''nat_rule_line : STATIC LPAREN WORD COMA WORD RPAREN TCP IP_ADDR NUMBER IP_ADDR NUMBER NETMASK IP_ADDR | STATIC LPAREN WORD COMA WORD RPAREN UDP IP_ADDR NUMBER IP_ADDR NUMBER NETMASK IP_ADDR | STATIC LPAREN WORD COMA WORD RPAREN WORD IP_ADDR NUMBER IP_ADDR NUMBER NETMASK IP_ADDR ''' in_iface = p_info['firewall'].get_interface_by_name(p[3]) out_iface = p_info['firewall'].get_interface_by_name(p[5]) rule = Nat_Rule(None, None, [Protocol(p[7])], [Ip(p[8], p[13])], [], [], [Port(int(p[9]))], [Ip(p[10], p[13])], [Port(int(p[11]))], 'static', [out_iface], [in_iface]) p_info['firewall'].nat_rule_list.append(rule)
def p_network_line_3(p): '''network_line : OP_RANGE IP_ADDR IP_ADDR''' for i in range(Ip.toInteger(p[2]), Ip.toInteger(p[3]) + 1): object_dict[p_info['object_name']].append({'network': Operator('EQ', Ip(i, '255.255.255.255'))})