def logical_to_physical(user, handle_id): """ :param user: Django user :param handle_id: unique id :return: NodeHandle, norduniclient model """ nh, logical_node = get_nh_node(handle_id) # Make the node physical meta_type = 'Physical' physical_node = logical_node.change_meta_type(meta_type) nh.node_meta_type = meta_type nh.save() # Convert Uses relationships to Owns. relations = physical_node.get_relations() for item in relations.get('Uses', []): relationship = nc.get_relationship_model(nc.graphdb.manager, item.get('relationship_id')) set_owner(user, physical_node, relationship.start) activitylog.delete_relationship(user, relationship) relationship.delete() # Remove Depends_on relationships logical = physical_node.get_dependencies() for item in logical.get('Depends_on', []): relationship = nc.get_relationship_model(nc.graphdb.manager, item.get('relationship_id')) activitylog.delete_relationship(user, relationship) relationship.delete() return nh, physical_node
def obj_get(self, request=None, **kwargs): pk = int(kwargs['pk']) try: return self._new_obj( nc.get_relationship_model(nc.graphdb.manager, pk)) except KeyError: raise NotFound("Object not found")
def remove_locations(user, node): # Remove Located_in relationships location = node.get_location() for item in location.get('Located_in', []): relationship = nc.get_relationship_model(nc.graphdb.manager, item.get('relationship_id')) activitylog.delete_relationship(user, relationship) relationship.delete()
def remove_peer_conf(user, data_age): peerq = """ MATCH (peer_group:Node:Peering_Group) MATCH (peer_group)<-[r:Uses]-(peering_partner:Peering_Partner) WHERE (peer_group.noclook_auto_manage = true) OR (r.noclook_auto_manage = true) RETURN collect(distinct peer_group.handle_id) as peer_groups, collect(id(r)) as uses_relationships """ peer_result = nc.query_to_dict(nc.graphdb.manager, peerq) for relationship_id in peer_result.get('uses_relationships', []): relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) if relationship: last_seen, expired = helpers.neo4j_data_age( relationship.data, data_age) if expired: rel_info = helpers.relationship_to_str(relationship) helpers.delete_relationship(user, relationship.id) logger.warning('Deleted relationship {rel_info}'.format( rel_info=rel_info)) for handle_id in peer_result.get('peer_groups', []): peer_group = nc.get_node_model(nc.graphdb.manager, handle_id) if peer_group: last_seen, expired = helpers.neo4j_data_age( peer_group.data, data_age) if expired: helpers.delete_node(user, peer_group.handle_id) logger.warning('Deleted node {name} ({handle_id}).'.format( name=peer_group.data.get('name'), handle_id=handle_id))
def insert_external_bgp_peering(peering, peering_group): """ Creates/updates the relationship and nodes needed to express the external peerings. """ user = utils.get_user() # Get or create the peering partner, unique per AS peer_node = get_peering_partner(peering) if peer_node is None: # We are done. This is a broken peering. return # Get all relationships with this ip address, should never be more than one remote_address = peering.get('remote_address', None).lower() if remote_address: # DEBUG try: result = peer_node.get_peering_group(peering_group.handle_id, remote_address) except AttributeError: print(peer_node) sys.exit(1) if not result.get('Uses'): result = peer_node.set_peering_group(peering_group.handle_id, remote_address) relationship_id = result.get('Uses')[0]['relationship_id'] relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) helpers.set_noclook_auto_manage(relationship, True) if result.get('Uses')[0].get('created', False): activitylog.create_relationship(user, relationship) # Match the remote address against a local network dependency_node, local_address = match_remote_ip_address( ipaddress.ip_address(remote_address)) if dependency_node and local_address: result = peering_group.get_group_dependency( dependency_node.handle_id, local_address) if not result.get('Depends_on'): result = peering_group.set_group_dependency( dependency_node.handle_id, local_address) relationship_id = result.get('Depends_on')[0]['relationship_id'] relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) helpers.set_noclook_auto_manage(relationship, True) if result.get('Depends_on')[0].get('created', False): activitylog.create_relationship(user, relationship) logger.info( 'Peering Partner {name} done.'.format(name=peer_node.data['name']))
def obj_update(self, bundle, **kwargs): helpers.dict_update_relationship(nc.graphdb.manager, kwargs['pk'], bundle.data['properties'], bundle.data['properties'].keys()) updated_rel = nc.get_relationship_model(nc.graphdb.manager, kwargs['pk']) bundle.obj = self._new_obj(updated_rel) return bundle
def obj_create(self, bundle, **kwargs): start_pk = resource_uri2id(bundle.data['start']) end_pk = resource_uri2id(bundle.data['end']) rel_id = nc.create_relationship(nc.graphdb.manager, start_pk, end_pk, bundle.data['type']) rel = nc.get_relationship_model(nc.graphdb.manager, rel_id) props = bundle.data.get('properties') if props: nc.set_relationship_properties(nc.graphdb.manager, rel.id, props) bundle.obj = self._new_obj(rel) return bundle
def test_relationship_to_str_with_model(self): nh1 = self.create_node('Router1', 'router') router1 = nh1.get_node() nh2 = self.create_node('Port1', 'port') result = router1.set_has(nh2.handle_id) relationship_id = result['Has'][0]['relationship_id'] rel = nc.get_relationship_model(nc.graphdb.manager, relationship_id) out = helpers.relationship_to_str(rel) expected = '(Router1 ({a_id}))-[{r_id}:Has]->(Port1 ({b_id}))'.format(a_id=nh1.handle_id, r_id=relationship_id, b_id=nh2.handle_id) self.assertEqual(expected, out)
def set_responsible_for(user, node, responsible_for_id): """ :param user: Django user :param node: norduniclient model :param responsible_for_id: unique id :return: norduniclient model, boolean """ result = node.set_responsible_for(responsible_for_id) relationship_id = result.get('Responsible_for')[0].get('relationship_id') relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) created = result.get('Responsible_for')[0].get('created') if created: activitylog.create_relationship(user, relationship) return relationship, created
def set_connected_to(user, node, has_id): """ :param user: Django user :param node: norduniclient model :param has_id: unique id :return: norduniclient model, boolean """ result = node.set_connected_to(has_id) relationship_id = result.get('Connected_to')[0].get('relationship_id') relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) created = result.get('Connected_to')[0].get('created') if created: activitylog.create_relationship(user, relationship) return relationship, created
def set_parent_of(user, node, parent_org_id): """ :param user: Django user :param node: norduniclient model :param child_org_id: unique id :return: norduniclient model, boolean """ result = node.set_parent(parent_org_id, overwrite=True) relationship_id = result.get('Parent_of')[0].get('relationship_id') relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) created = result.get('Parent_of')[0].get('created') if created: activitylog.create_relationship(user, relationship) return relationship, created
def set_uses_a(user, node, procedure_id): """ :param user: Django user :param node: norduniclient model :param procedure_id: unique id :return: norduniclient model, boolean """ result = node.add_procedure(procedure_id) relationship_id = result.get('Uses_a')[0].get('relationship_id') relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) created = result.get('Uses_a')[0].get('created') if created: activitylog.create_relationship(user, relationship) return relationship, created
def dict_update_relationship(user, relationship_id, properties, keys=None): relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) if not keys: keys = properties.keys() for key in keys: pre_value = relationship.data.get(key, '') if properties.get(key, None) or properties.get(key, None) == 0: if pre_value != properties[key]: relationship.data[key] = properties[key] activitylog.update_relationship_property(user, relationship, key, pre_value, properties[key]) elif properties.get(key, None) == '' and key in relationship.data.keys(): del relationship.data[key] activitylog.update_relationship_property(user, relationship, key, pre_value, properties[key]) nc.set_relationship_properties(nc.graphdb.manager, relationship_id, relationship.data) return True
def set_member_of(user, node, group_id): """ :param user: Django user :param node: norduniclient model :param group_id: unique id :return: norduniclient model, boolean """ result = node.add_group(group_id) relationship_id = result.get('Member_of')[0].get('relationship_id') relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) created = result.get('Member_of')[0].get('created') if created: activitylog.create_relationship(user, relationship) return relationship, created
def set_has_address(user, site, has_id): """ :param user: Django user :param site: norduniclient Site model :param has_address_id: unique id for an Address node :return: norduniclient model, boolean """ result = site.set_has_address(has_id) relationship_id = result.get('Has_address')[0].get('relationship_id') relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) created = result.get('Has_address')[0].get('created') if created: activitylog.create_relationship(user, relationship) return relationship, created
def set_user(user, node, user_id): """ :param user: Django user :param node: norduniclient model :param user_id: unique id :return: norduniclient model, boolean """ if not isinstance(user_id, int): user_id = user_id['handle_id'] result = node.set_user(user_id) relationship_id = result.get('Uses')[0].get('relationship_id') relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) created = result.get('Uses')[0].get('created') if created: activitylog.create_relationship(user, relationship) return relationship, created
def set_supports(user, node, group_id): """ :param user: Django user :param node: norduniclient model :param group_id: unique id :return: norduniclient model, boolean """ group = NodeHandle.objects.get(handle_id=group_id) group_node = group.get_node() result = group_node.set_supports(node.handle_id) relationship_id = result.get('Supports')[0].get('relationship_id') relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) created = result.get('Supports')[0].get('created') if created: activitylog.create_relationship(user, relationship) return relationship, created
def delete_relationship(request, slug, handle_id, rel_id): """ Removes the relationship if the node has a relationship matching the supplied id. """ success = False if request.method == 'POST': nh, node = helpers.get_nh_node(handle_id) try: relationship = nc.get_relationship_model(nc.graphdb.manager, rel_id) if node.handle_id == relationship.start['handle_id'] or node.handle_id == relationship.end['handle_id']: activitylog.delete_relationship(request.user, relationship) relationship.delete() success = True except nc.exceptions.RelationshipNotFound: success = True return JsonResponse({'success': success, 'relationship_id': '{}'.format(rel_id)})
def set_depends_on(user, node, dependency_id): """ :param user: Django user :param node: norduniclient model :param dependency_id: unique id :return: norduniclient model, boolean """ # Check that the node is physical, else convert it if node.meta_type == 'Physical': nh, node = physical_to_logical(user, node.handle_id) result = node.set_dependency(dependency_id) relationship_id = result.get('Depends_on')[0].get('relationship_id') relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) created = result.get('Depends_on')[0].get('created') if created: activitylog.create_relationship(user, relationship) return relationship, created
def relationship_to_str(relationship): """ Takes a relationship and returns a string representation of the relationship: ("":Router)<-[:Has]-("":Port) """ if isinstance(relationship, int): rel = nc.get_relationship_model(nc.graphdb.manager, relationship) else: rel = relationship return '({a_name} ({a_handle_id}))-[{rel_id}:{rel_type}]->({b_name} ({b_handle_id}))'.format( a_name=rel.start['name'], a_handle_id=rel.start['handle_id'], rel_id=rel.id, rel_type=rel.type, b_name=rel.end['name'], b_handle_id=rel.end['handle_id'], )
def get_object_list(self, request, **kwargs): results = [] if kwargs.get('parent_obj', None): rel_type = kwargs.get('rel_type', None) nh = NodeHandle.objects.get(pk=kwargs['parent_obj']) relationships = nh.get_node().relationships if rel_type: keys = [rel_type] else: keys = relationships.keys() for key in keys: for item in relationships.get(key, []): relationship = nc.get_relationship_model( nc.graphdb.manager, item['relationship_id']) results.append(self._new_obj(relationship)) return results else: raise ImmediateHttpResponse(HttpResponseNotAllowed(['POST']))
def add_address_organization(user, address, organization_id): """ :param user: Django user :param address: norduniclient model (address) :param organization_id: organization id to associate to the address instance :return: norduniclient model, boolean """ organization = NodeHandle.objects.get(handle_id=organization_id) result = organization.get_node().add_address(address.handle_id) relationship_id = result.get('Has_address')[0].get('relationship_id') relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) created = result.get('Has_address')[0].get('created') if created: activitylog.create_relationship(user, relationship) return relationship, created
def add_email_contact(user, email, contact_id): """ :param user: Django user :param email: norduniclient model (email) :param contact_id: contact id to associate to the email instance :return: norduniclient model, boolean """ contact = NodeHandle.objects.get(handle_id=contact_id) result = contact.get_node().add_email(email.handle_id) relationship_id = result.get('Has_email')[0].get('relationship_id') relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) created = result.get('Has_email')[0].get('created') if created: activitylog.create_relationship(user, relationship) return relationship, created
def update_relationship(request, slug, handle_id, rel_id): """ Removes the relationship if the node has a relationship matching the supplied id. """ success = False properties = {} if request.POST: nh, node = helpers.get_nh_node(handle_id) try: for key, value in request.POST.items(): properties[key] = json.loads(value) relationship = nc.get_relationship_model(nc.graphdb.manager, int(rel_id)) if node.handle_id == relationship.start['handle_id'] or node.handle_id == relationship.end['handle_id']: success = helpers.dict_update_relationship(request.user, relationship.id, properties) except nc.exceptions.RelationshipNotFound: # If the relationship does not exist, then we cannot update success = False except ValueError: pass return JsonResponse({'success': success, 'relationship_id': '{}'.format(rel_id), 'data': properties})
def set_noclook_auto_manage(item, auto_manage): """ Sets the node or relationship noclook_auto_manage flag to True or False. Also sets the noclook_last_seen flag to now. :param item: norduclient model :param auto_manage: boolean :return: None """ auto_manage_data = { 'noclook_auto_manage': auto_manage, 'noclook_last_seen': datetime.now().isoformat() } if isinstance(item, nc.models.BaseNodeModel): node = nc.get_node_model(nc.graphdb.manager, item.handle_id) node.data.update(auto_manage_data) nc.set_node_properties(nc.graphdb.manager, node.handle_id, node.data) elif isinstance(item, nc.models.BaseRelationshipModel): relationship = nc.get_relationship_model(nc.graphdb.manager, item.id) relationship.data.update(auto_manage_data) nc.set_relationship_properties(nc.graphdb.manager, relationship.id, relationship.data)
def update_noclook_auto_manage(item): """ Updates the noclook_auto_manage and noclook_last_seen properties. If noclook_auto_manage is not set, it is set to True. :param item: norduclient model :return: None """ auto_manage_data = {} auto_manage = item.data.get('noclook_auto_manage', None) if auto_manage or auto_manage is None: auto_manage_data['noclook_auto_manage'] = True auto_manage_data['noclook_last_seen'] = datetime.now().isoformat() if isinstance(item, nc.models.BaseNodeModel): node = nc.get_node_model(nc.graphdb.manager, item.handle_id) node.data.update(auto_manage_data) nc.set_node_properties(nc.graphdb.manager, node.handle_id, node.data) elif isinstance(item, nc.models.BaseRelationshipModel): relationship = nc.get_relationship_model(nc.graphdb.manager, item.id) relationship.data.update(auto_manage_data) nc.set_relationship_properties(nc.graphdb.manager, relationship.id, relationship.data)
def physical_to_logical(user, handle_id): """ :param user: Django user :param handle_id: unique id :return: NodeHandle, norduniclient model """ nh, physical_node = get_nh_node(handle_id) # Remove Located_in relationships remove_locations(user, physical_node) # Make the node logical meta_type = 'Logical' logical_node = physical_node.change_meta_type(meta_type) nh.node_meta_type = meta_type nh.save() # Convert Owns relationships to Uses. relations = logical_node.get_relations() for item in relations.get('Owns', []): relationship = nc.get_relationship_model(nc.graphdb.manager, item.get('relationship_id')) set_user(user, logical_node, relationship.start) activitylog.delete_relationship(user, relationship) relationship.delete() return nh, logical_node
def delete_relationship(user, relationship_id): relationship = nc.get_relationship_model(nc.graphdb.manager, relationship_id) activitylog.delete_relationship(user, relationship) relationship.delete() return True
def insert_services(service_dict, host_node, external_check=False): """ Takes a dictionary of services and a node id for a host. Gets or creates a service and makes a Depends_on relationship between the service and host. Example service_dict: {"127.0.0.1": { "tcp": { "80": { "conf": "10", "extrainfo": "", "name": "http", "product": "VMware ESXi Server httpd", "reason": "syn-ack", "state": "open", "version": "" }, "8443": { "conf": "10", "extrainfo": "", "name": "ssl", "product": "TLS", "reason": "syn-ack", "state": "open", "version": "1.0" } } } """ user = nt.get_user() node_type = "Host Service" meta_type = 'Logical' services_locked = host_node.data.get('services_locked', False) # Expected service data from nmap property_keys = [ 'ip_address', 'protocol', 'port', 'conf', 'extrainfo', 'name', 'product', 'reason', 'state', 'version' ] if external_check: property_keys.extend(['public', 'noclook_last_external_check']) external_dict = { 'public': True, 'noclook_last_external_check': datetime.now().isoformat() } set_not_public(host_node) for address in service_dict.keys(): for protocol in service_dict[address].keys(): for port in service_dict[address][protocol].keys(): service = service_dict[address][protocol][port] if service['state'] != 'closed': service_name = service['name'] if not service_name: # Blank service_name = 'unknown' service_node_handle = nt.get_unique_node_handle( service_name, node_type, meta_type) service_node = service_node_handle.get_node() helpers.update_noclook_auto_manage(service_node) relationship_properties = { 'ip_address': address, 'protocol': protocol, 'port': port } result = host_node.get_host_service( service_node.handle_id, **relationship_properties) if not result.get('Depends_on'): result = host_node.set_host_service( service_node.handle_id, **relationship_properties) relationship_id = result.get('Depends_on')[0].get( 'relationship_id') relationship = nc.get_relationship_model( nc.graphdb.manager, relationship_id) created = result.get('Depends_on')[0].get('created') # Set or update relationship properties relationship_properties.update(service) if external_check: relationship_properties.update(external_dict) if created: activitylog.create_relationship(user, relationship) if services_locked: logger.warn( 'New open port found for host {name}.'.format( name=host_node.data['name'])) property_keys.append('rogue_port') relationship_properties['rogue_port'] = True logger.info( 'Host Service {host_service_name} using port {port}/{protocol} created.' .format( host_service_name=service_node.data['name'], port=relationship.data['port'], protocol=relationship.data['protocol'])) if not created: logger.info( 'Host Service {host_service_name} using port {port}/{protocol} found.' .format( host_service_name=service_node.data['name'], port=relationship.data['port'], protocol=relationship.data['protocol'])) helpers.update_noclook_auto_manage(relationship) helpers.dict_update_relationship(user, relationship.id, relationship_properties, property_keys) logger.info( '{name} {ip_address} {port}/{protocol} processed...'. format(name=host_node.data['name'], ip_address=address, protocol=protocol, port=port))
def get_relationship_model(relationship_id): return nc.get_relationship_model(nc.graphdb.manager, relationship_id)