예제 #1
0
    def get(self, request, app_id, login=""):
        try:
            app = Application.objects(
                id=ObjectId(app_id)).no_dereference().only(
                    'name', 'auth_backend', 'sso_profile').first()
            if not app:
                raise Application.DoesNotExist()
        except (Application.DoesNotExist, InvalidId) as e:
            logger.error(
                "SSOProfiles::GET: Application with id '{}' not found".format(
                    app_id))
            return JsonResponse({
                'status':
                False,
                'error':
                "Application with id '{}' not found.".format(app_id)
            })

        insecure = str(request.GET.get('insecure', False)).lower() == "true"

        try:
            if login:
                sso_profiles = app.get_sso_profiles(login, insecure=insecure)
            else:
                sso_profiles = app.get_all_sso_profiles(insecure=insecure)

            return JsonResponse({'status': True, 'sso_profiles': sso_profiles})

        except Exception as e:
            logger.critical(e, exc_info=1)

            return JsonResponse({'status': False, 'error': str(e)})
def get_all(request, fields=None):
    """ return a list of dumps of all applications.
    Fields can be given to filter out the result """
    try:
        fields = fields.split("|")
    except Exception:
        pass

    try:
        to_return = []

        for app in Application.objects():
            to_return.append(app.dump(fields))

        return JsonResponse(to_return,
                            content_type='application/json',
                            safe=False)

    except Exception as error:
        logger.exception(error)

        return JsonResponse({
            'status': False,
            'error': str(error)
        },
                            content_type='application/json')
def get_by_regex(request, regex, fields=None):
    """ return one or several dump(s) according to the regex given.
    Fields can be given to filter out the result """
    try:
        fields = fields.split("|")
    except Exception:
        pass

    try:
        app_list = Application.get_apps_by_regex(regex)

        to_return = []

        for app in app_list:
            to_return.append(app.dump(fields))

        return JsonResponse(to_return,
                            content_type='application/json',
                            safe=False)

    except Exception as error:
        logger.exception(error)

        return JsonResponse({
            'status': False,
            'error': str(error)
        },
                            content_type='application/json')
예제 #4
0
 def get(self, request, object_id):
     obj_inst = self.obj.objects.with_id(ObjectId(object_id))
     if not obj_inst:
         return HttpResponseForbidden("Injection detected.")
     if Application.objects(log_custom=obj_inst):
         self.template_name = 'generic_delete_forbidden.html'
     return super(DeleteModLog, self).get(request, object_id)
예제 #5
0
def report_pf(request):
    apps = []
    for app in Application.objects():
        if app.log_custom.repository_type == 'data':
            apps.append(app)
    apps.sort(key=lambda x: x.name)

    cluster = Cluster.objects.get()
    node = cluster.get_current_node()

    packet_filter = []
    for node in cluster.members:
        try:
            if node.system_settings.pf_settings.repository_type == 'data':
                packet_filter.append({
                    'id':
                    node.id,
                    'name':
                    node.name,
                    'repo':
                    node.system_settings.pf_settings.repository.type_uri
                })
        except:
            pass

    if not request.is_ajax():
        return render_to_response('report_pf.html', {
            'apps': apps,
            'packet_filter': packet_filter
        },
                                  context_instance=RequestContext(request))
예제 #6
0
def report_security(request):
    apps = []
    for app in Application.objects():
        if app.log_custom.repository_type == 'data':
            apps.append(app)
    apps.sort(key=lambda x: x.name)

    if not request.is_ajax():
        return render_to_response('report_security.html', {'apps': apps},
                                  context_instance=RequestContext(request))
def generate(request, is_reload=False):
    """ generate a new application with a given description """
    try:
        is_reload = (is_reload == "reload")
    except Exception:
        pass

    try:
        Application.generate(json.loads(request.body), is_reload)

        return JsonResponse({'status': True}, content_type='application/json')

    except Exception as error:
        logger.exception(error)

        return JsonResponse({
            'status': False,
            'error': str(error)
        },
                            content_type='application/json')
예제 #8
0
    def is_deletable(self):
        """ Method used to know if template object is used by an Application.
        If object is used, user can't delete PortalTemplate

        :return: True if object is not used, False otherwise
        """
        from gui.models.application_settings import Application
        used = Application.objects(template=self)
        if used:
            return False
        return True
예제 #9
0
    def is_deletable(self):
        """ Method used to know if Modlog object is used by an Application.
        If object is used, user can't delete Modlog

        :return: True if object is not used, False otherwise
        """
        from gui.models.application_settings import Application
        used = Application.objects(log_custom=self)
        if used:
            return False
        return True
예제 #10
0
    def delete(self, request, app_id, login=""):
        if not login:
            return JsonResponse({'status': False, 'error': "Login missing."})
        try:
            app = Application.objects(
                id=ObjectId(app_id)).no_dereference().only(
                    'name', 'auth_backend', 'sso_profile').first()
            if not app:
                raise Application.DoesNotExist()
        except (Application.DoesNotExist, InvalidId) as e:
            logger.error(
                "SSOProfiles::GET: Application with id '{}' not found".format(
                    app_id))
            return JsonResponse({
                'status':
                False,
                'error':
                "Application with id '{}' not found.".format(app_id)
            })

        try:
            # Check is an sso_profile does exists
            if SSOProfile.objects.filter(app_id=str(app.id),
                                         repo_id=str(app.getAuthBackend().id),
                                         login=login).count() == 0:
                return JsonResponse({
                    'status':
                    False,
                    'error':
                    "No SSOProfile found with application '{}', repository '{}' "
                    "and login '{}'".format(app.name,
                                            app.getAuthBackend().repo_name,
                                            login)
                })
            app.delete_sso_profile(login)

            return JsonResponse({'status': True})
        except Exception as e:
            logger.exception(e)

            return JsonResponse({'status': False, 'error': str(e)}, status=500)
예제 #11
0
 def post(self, request, object_id):
     confirm = request.POST.get('confirm')
     if confirm == 'yes':
         obj_inst = self.obj.objects.with_id(ObjectId(object_id))
         if not obj_inst:
             return HttpResponseForbidden("Injection detected.")
         # Check if ModLog Object is not used by an Application
         if not Application.objects(log_custom=obj_inst):
             obj_inst.delete()
         else:
             pass
         return HttpResponseRedirect(self.redirect_url)
예제 #12
0
    def post(self, request, object_id):
        confirm = request.POST.get('confirm')

        if confirm == 'yes':
            obj_inst = self.obj.objects.with_id(ObjectId(object_id))
            if not obj_inst:
                return HttpResponseForbidden("Injection detected.")
            app_list = Application.objects(modsec_policy=obj_inst)

            if not len(app_list):
                obj_inst.delete()

            return HttpResponseRedirect(self.redirect_url)
예제 #13
0
def policy_list(request):
    """ Page dedicated to show mod_security profiles list
    """
    try:
        modsec_list = ModSec.objects()
        policy_list = [{
            "modsec": item,
            "is_delible": False
        } if len(Application.objects(
            modsec_policy=item).values_list("name")) else {
                "modsec": item,
                "is_delible": True
            } for item in modsec_list]
    except:
        policy_list = None

    return render_to_response('modsec.html', {'policy_list': policy_list},
                              context_instance=RequestContext(request))
예제 #14
0
def worker_list(request):
    """ Page dedicated to show worker list
    """
    try:
        workers = Worker.objects()
    except Worker.DoesNotExist:
        workers = None

    worker_list = list()
    for worker in workers:
        worker.applist = list()
        for app in Application.objects():
            if app.worker == worker:
                worker.applist.append(app)
        worker_list.append(worker)
    workers = worker_list

    return render_to_response('worker.html', {'workers': workers},
                              context_instance=RequestContext(request))
예제 #15
0
    def perform_action(self):
        # Retrieve all the hkeys in redis matching "backend_(app_id) = (backend_id)"
        # with portal_cookie
        backends_apps = self.redis_portal_session.get_auth_backends()

        backends = list()
        apps = list()
        for key, item in backends_apps.items():
            # Extract the id of the application in "backend_(id)"
            app = key[8:]
            if app not in apps:
                apps.append(app)
            # The item is the backend
            if item not in backends:
                backends.append(item)

        logger.debug(
            "User successfully authenticated on following apps : '{}'".format(
                apps))
        logger.debug(
            "User successfully authenticated on following backends : '{}'".
            format(backends))

        # Retrieve all the apps which need auth AND which the backend or backend_fallback is in common with the backend the user is logged on
        # And retrieve all the apps that does not need authentication
        Query = (Q(need_auth=True) &
                 (Q(auth_backend__in=backends) |
                  Q(auth_backend_fallbacks__in=backends))) | Q(need_auth=False)
        auth_apps = Application.objects(Query).only('name', 'public_name',
                                                    'public_dir', 'id', 'type',
                                                    'listeners', 'need_auth')

        final_apps = list()
        for app in auth_apps:
            final_apps.append({
                'name': app.name,
                'url': str(app.get_redirect_uri()),
                'status': app.need_auth and str(app.id) in apps
            })

        return final_apps
def get_by_name(request, app_name, fields=None):
    """ return a dump of an application according to the name given.
    Fields can be given to filter out the result """
    try:
        fields = fields.split("|")
    except Exception:
        pass

    try:
        app = Application.get_app_by_name(app_name)

        return JsonResponse(app.dump(fields), content_type='application/json')

    except Exception as error:
        logger.exception(error)

        return JsonResponse({
            'status': False,
            'error': str(error)
        },
                            content_type='application/json')
예제 #17
0
def application_list(request):
    """ Page dedicated to show application list
    """

    l_list = dict()
    new_list = {}

    #FIXME: We should display ListenAddress instead of Listeners
    """ Build the list of listeners
        Reminder:   A listener is associated to an APP and refers to a ListenAddress
                    There may have many listeners for a given ListenAddress
                    Here, the listener list is used to display the PLAY / PAUSE / RELOAD buttons
                    We build a dictionary indexed on IP:PORT
                        => We need to be carefull and display listeners that needs to be reloaded

    """
    listeners = ListenAddress.objects()
    for l in listeners:
        lst = str(l.address) + ': ' + str(l.port)
        node_name = l.get_related_node().name

        if node_name not in new_list.keys():
            new_list[node_name] = []
        """ Need to be reloaded => add it ! """
        if l.is_up2date is False:
            l_list[lst] = l
            new_list[node_name].append(l)
        else:
            if not l_list.get(lst):
                new_list[node_name].append(l)
                l_list[lst] = l

    return render_to_response('application.html', {
        'listeners': l_list,
        'apps': Application.objects(),
        'new_listeners': new_list
    },
                              context_instance=RequestContext(request))
예제 #18
0
def import_application(conn, headerid, modlog_dict, modssl_dict):
    """
    import all applications from sqlite3
    :param conn: sqlite3 connector
    :param headerid: dict to retrieve sqlite3 id of header generated in previous method
    :param modlog_dict: dict to retrieve sqlite3 id of modlog generated in previous method
    :param modssl_dict: dict to retrieve sqlite3 id of ssl profile generated in previous method
    """
    appid_application = dict()
    app_log = dict()
    appid_logid = dict()
    appid_headerid = dict()
    appid_intfid = dict()
    listenertolistenaddress = dict()
    appid_interfaceid = dict()

    cluster = Cluster.objects.get()
    node = cluster.get_current_node()
    # select the first interface which is em0
    # FIXME: ask user on which interface to bind all the listeners
    # FIXME : Obsolet method
    em = node.get_interfaces()[0].id
    
    # generate list for every table in sqlite database
    
    intf = conn.cursor()
    intf.execute("SELECT * FROM intf")
    intf_sql = intf.fetchall()

    app = conn.cursor()
    app.execute("SELECT * FROM app")
    application_sql = app.fetchall()

    app_intf = conn.cursor()
    app_intf.execute("SELECT * FROM app_intf")
    app_intf_sql = app_intf.fetchall()

    log = conn.cursor()
    log.execute("SELECT * FROM log")
    log_sql = log.fetchall()
    
    header = conn.cursor()
    header.execute("SELECT * FROM header")
    header_sql = header.fetchall()

    plugincontent = conn.cursor()
    plugincontent.execute("SELECT * FROM plugincontent")
    plugincontent_sql = plugincontent.fetchall()

    pluginheader = conn.cursor()
    pluginheader.execute("SELECT * FROM pluginheader")
    pluginheader_sql = pluginheader.fetchall()

    logger.info("Importing network interfaces")

    # Retrieve index in database of each name fields of "app_intf" table
    col_name_list_app_intf = [tuple[0] for tuple in app_intf.description]
    app_intf_id = col_name_list_app_intf.index("id")
    app_intf_app_id = col_name_list_app_intf.index("app_id")
    app_intf_intf_id = col_name_list_app_intf.index("intf_id")

    # Retrieve index in database of each name fields of "intf" table
    col_name_list_intf = [tuple[0] for tuple in intf.description]
    intf_id = col_name_list_intf.index("id")
    intf_name = col_name_list_intf.index("name")
    intf_ip = col_name_list_intf.index("ip")
    intf_port = col_name_list_intf.index("port")
    intf_log_id = col_name_list_intf.index("log_id")

    # Retrieve index in database of each name fields of "app" table
    col_name_list_app = [tuple[0] for tuple in app.description]
    app_id = col_name_list_app.index("id")
    app_friendly_name = col_name_list_app.index("friendly_name")
    app_name = col_name_list_app.index("name")
    app_url = col_name_list_app.index("url")
    app_log_id = col_name_list_app.index("log_id")
    app_logon_url = col_name_list_app.index("logon_url")
    app_auth_id = col_name_list_app.index("auth_id")
    app_auth_url = col_name_list_app.index("auth_url")
    app_Balancer_Name = col_name_list_app.index("Balancer_Name")
    app_Balancer_Node = col_name_list_app.index("Balancer_Node")
    app_enable_ssl = col_name_list_app.index("enable_ssl")
    app_ssl_configuration_id = col_name_list_app.index("ssl_configuration_id")

    # Retrieve index in database of each name fields of "log" table
    col_name_list_log = [tuple[0] for tuple in log.description]
    logs_id = col_name_list_log.index("id")
    logs_name = col_name_list_log.index("name")
    logs_level = col_name_list_log.index("level")
    logs_format = col_name_list_log.index("format")

    # Retrieve index in database of each name fields of "header" table
    col_name_list_header = [tuple[0] for tuple in header.description]
    header_id = col_name_list_header.index("id")
    header_name = col_name_list_header.index("name")
    header_type = col_name_list_header.index("type")
    header_value = col_name_list_header.index("value")
    header_app_id = col_name_list_header.index("app_id")

    # Retrieve index in database of each name fields of "pluginheader" table
    col_name_list_plugin_header = [tuple[0] for tuple in pluginheader.description]
    pluginheader_id = col_name_list_plugin_header.index("id")
    pluginheader_app_id = col_name_list_plugin_header.index("app_id")
    pluginheader_pattern = col_name_list_plugin_header.index("pattern")
    pluginheader_type = col_name_list_plugin_header.index("type")
    pluginheader_options = col_name_list_plugin_header.index("options")
    pluginheader_options1= col_name_list_plugin_header.index("options1")

    # Retrieve index in database of each name fields of "plugincontent" table
    col_name_list_plugin_content = [tuple[0] for tuple in plugincontent.description]
    plugincontent_id = col_name_list_plugin_content.index("id")
    plugincontent_app_id = col_name_list_plugin_content.index("app_id")
    plugincontent_pattern = col_name_list_plugin_content.index("pattern")
    plugincontent_type = col_name_list_plugin_content.index("type")
    plugincontent_options = col_name_list_plugin_content.index("options")
    plugincontent_options1 = col_name_list_plugin_content.index("options1")

    for i in app_intf_sql:
        appid_interfaceid[i[app_intf_app_id]] = i[app_intf_intf_id]

    # generate every listener on the current node
    for i in intf_sql:
        logger.info("Listener " + str(i[intf_name]))
        node = cluster.get_current_node()
        listener = Listener()
        listener.alias = str(i[intf_name])
        listener.ip = str(i[intf_ip])
        listener.version = "4"
        listener.prefixlen = "255.255.255.0"
        listener.is_carp = False
        listener.is_physical = False
        listener.is_gui = False
        listener.is_ghost = False
        listener.save()

        # dictionary to link listener to listen address
        listenertolistenaddress[i[intf_id]] = listener

        logger.info("Creating listener " + str(listener.alias))

        selected_intf = Interface.objects.with_id(em)
        selected_intf.inet_addresses.append(listener)  # append the listen address in the interface
        selected_intf.save()
        listener.deploy_inet()
        node.interfaces[intf_id] = selected_intf  # add the interface modified into the node
        node.save()

    appid_listenaddress = dict()
    logger.info("End of network interfaces import process")
    logger.info("Importing applications")
    for app in application_sql:

        application = Application()
        outgoing_headers = []
        content_rules = []
        headers_in = []
        public_dir = ""

        # Retrieve fqdn and public_dir from app[app_friendly_name]
        tmp = app[app_friendly_name].split("/")
        fqdn = tmp[0]
        public_dir = app[app_friendly_name].replace(fqdn, "")
        if not public_dir.endswith('/'):
            public_dir = public_dir + '/'

        # if there's an authentication portal (app[app_logon_url]) then auth = True
        if app[app_logon_url] is None:
            need_auth = False
        else:
            need_auth = True

        # retrieve type of application
        if app[app_url].split(":")[0] == "balancer":  # if the url start with "balancer://" , app_type=balanced
            app_type = "balanced"
            # [app_Balancer_Name] = balancer uri
            application.proxy_balancer = ProxyBalancer.objects.get(name=app[app_Balancer_Name])
        else:
            app_type = app[app_url].split(":")[0]  # otherwise; filetype is before ":" (http,https,ftp...)

        # retrieve log profile linked to this app (we generated the profile earlier, now we find it back)
        for j in log_sql:
            if app[app_log_id] == j[logs_id]:  # if app[app_log_id] =logs_id of the application match => link
                app_log[app[app_friendly_name]] = j[logs_level]  # link appname -> log_level found
                appid_logid[app[app_id]] = j[logs_id]

        # generate a listen_address for this app based on the interface generated earlier
        for j in intf_sql:
            if appid_interfaceid[app[app_id]] == j[intf_id]:  # find link  between interface and app_id
                interface_id = j[intf_id]
                intf.execute("SELECT * FROM intf WHERE id =?", (interface_id,))  # select interface in db with link
                interface = intf.fetchone()
                appid_intfid[app[app_id]] = interface[0]  # appid_interfaceid appid:interfaceid
                listen_address = ListenAddress()
                # apprend address of listener to current listen address
                listen_address.address = listenertolistenaddress[j[intf_id]]
                listen_address.port = str(j[intf_port])
                listen_address.redirect = False
                listen_address.redirect_port = ""
                # if this app uses a specific SSL profile, then load it
                if app[app_enable_ssl] == 1:
                    listen_address.ssl_profile = modssl_dict[app[app_ssl_configuration_id]]
                listen_address.save()
                appid_listenaddress[app[app_id]] = listen_address

        # Retrieve all request headers except SSL headers (not managed in vulture3)
        for j in header_sql:
            if app[app_id] == j[header_app_id]:
                if j[header_name] != "SSL_CLIENT_S_DN_CN" and \
                                j[header_name] != "SSL_CLIENT_S_DN_O" and j[header_name] != "SSL_CLIENT_S_DN_OU":
                    appid_headerid[str(app[app_id])] = j[header_id]
                    headers_in.append(headerid[j[header_id]])

        # Retrieve headers in "pluginheader" table
        for j in pluginheader_sql:
            if j[pluginheader_app_id] == app[app_id]:
                headerin = HeaderIn()
                headerin.name = j[pluginheader_pattern]
                headerin.action = "edit"
                headerin.value = j[pluginheader_options]
                headerin.replacement = j[pluginheader_options1]
                headerin.condition = "always"
                headerin.save()
                headers_in.append(headerin)

        """ generate each type of header out and contentrule. Stored in the same table "plugincontent"
         with non consistent fields."""
        for i in plugincontent_sql:
            if i[plugincontent_type] == "Rewrite Content" and i[plugincontent_app_id] == app[app_id]:
                content_rule = ContentRule()
                content_rule.path_type = "files"
                content_rule.path = ""
                content_rule.types = ""
                content_rule.flags = ""
                content_rule.deflate = True
                content_rule.inflate = False
                content_rule.pattern = i[plugincontent_pattern]
                content_rule.replacement = i[plugincontent_options]
                content_rule.save()
                content_rules.append(content_rule)
            if i[plugincontent_type] == "Rewrite Link" and i[plugincontent_app_id] == app[app_id]:
                headerout = HeaderOut()
                headerout.name = "Link"
                headerout.value = i[plugincontent_options]
                headerout.replacement = i[plugincontent_pattern]
                headerout.action = "edit"
                headerout.condition = "always"
                headerout.save()
                outgoing_headers.append(headerout)
            if i[plugincontent_type] == "Location" and i[plugincontent_app_id] == app[app_id]:
                headerout = HeaderOut()
                headerout.name = i[plugincontent_pattern]
                headerout.value = i[plugincontent_options1]
                headerout.replacement = i[plugincontent_options]
                headerout.action = "edit"
                headerout.condition = "always"
                headerout.save()
                outgoing_headers.append(headerout)

        # retrieve the Vulture Internal Database repository for authentication.
        repo_list = BaseAbstractRepository.get_auth_repositories()
        for repo in repo_list:
            if repo.is_internal and isinstance(repo.get_backend(), MongoEngineBackend):
                auth_backend = repo

        # select the default worker
        worker = Worker.objects.first()
        # auth_backend = ""
        # populate each field of app generated before
        application.name = app[app_friendly_name]
        application.type = app_type
        application.public_name = fqdn
        application.private_uri = app[app_url]
        application.public_dir = public_dir
        application.proxy_add_header = False
        application.access_mode = []
        # retrieve log profile generated that have a link with this app
        for j in log_sql:
            application.log_custom = modlog_dict[appid_logid[app[app_id]]]
            tmp = application.log_custom.format
            tmp = tmp.replace("\\", "")  # remove escaping chars from mongo
            application.log_custom.format = tmp
        application.log_level = app_log[app[app_friendly_name]]
        application.headers_in = headers_in
        application.headers_out = outgoing_headers
        application.content_rules = content_rules
        application.listeners.append(appid_listenaddress[app[app_id]])
        application.force_tls = False
        application.worker = worker
        application.methods = "HEAD,GET,POST"
        application.enable_h2 = False
        application.enable_rpc = False
        application.need_auth = need_auth
        if need_auth:
            application.auth_type = "basic"
            application.auth_backend = str(auth_backend)
            application.auth_backend_fallback = str(auth_backend)
            application.auth_portal = str(application.private_uri + app[app_logon_url])
            application.auth_timeout = "900"
            application.auth_timeout_restart = True
        application.sso_enabled = False
        if application.sso_enabled:
            application.sso_forward = "form"
            application.sso_forward_basic_mode = "autologon"
            application.sso_forward_only_login = False
            application.sso_forward_basic_url = "http=//your_internal_app/action.do?what=login"
            application.sso_forward_follow_redirect = False
            application.sso_forward_return_post = False
            application.sso_forward_content_type = "default"
            application.sso_url = "http://your_internal_app/action.do?what=login"
            application.sso_vulture_agent = False
            application.sso_capture_content_enabled = False
            application.sso_capture_content = ""
            application.sso_replace_content_enabled = False
            application.sso_replace_content = "By previously captured '$1'/"
            application.sso_after_post_request_enabled = False
            application.sso_after_post_request = "http://My_Responsive_App.com/Default.aspx"
            application.sso_after_post_replace_content_enabled = False
            application.sso_after_post_replace_content = ""
        logger.info("Saving application: " + str(application))
        application.save()
        appid_application[app[app_id]] = application.id
    logger.info("End of applications import process")
    return appid_application
예제 #19
0
def edit(request, object_id=None):
    """ View dedicated to application management

    :param object_id: MongoDB object_id of application
    :param request: Django request object
    """
    # Retrieving application configuration
    application = Application.objects.with_id(ObjectId(object_id))

    specific_rules_set = []
    incoming_headers = []
    outgoing_headers = []
    content_rules = []
    listeners = []
    listeners_ips = []
    svms = []
    activated_svms = []

    # Application doesn"'t exist ==> We want to create a new one
    # Fix some default values
    if not application and request.method != 'POST':
        application = Application(name="My App",
                                  type="http",
                                  public_name="www.example.com",
                                  public_alias="www.ex_1.fr",
                                  public_dir="/",
                                  private_uri="https://192.168.1.1/owa/")
        # Fix default security rules
        incoming_headers.append(
            HeaderOut(True, 'unset', '^X-Forwarded-', '', '', 'always', ''))
        # outgoing_headers.append(HeaderOut ('set', 'Content-Security-Policy', 'default-src \'self\'', '', 'always', ''))
        outgoing_headers.append(
            HeaderOut(True, 'set', 'X-Frame-Options', 'SAMEORIGIN', '',
                      'always', ''))
        outgoing_headers.append(
            HeaderOut(True, 'set', 'X-Content-Type-Options', 'nosniff', '',
                      'always', ''))
        outgoing_headers.append(
            HeaderOut(True, 'set', 'X-XSS-Protection', '1; mode=block', '',
                      'always', ''))
        application.headers_in = incoming_headers
        application.headers_out = outgoing_headers

    # Check if request are valid - and populate arrays with form values
    if request.method == 'POST':
        dataPosted = request.POST
        dataPostedRaw = str(request.body).split("&")

        has_listener = False
        dataPosted_length = len(dataPostedRaw)

        if application and not "enabled=on" in dataPostedRaw:
            application.delete_listeners()

        for data in dataPostedRaw:
            if data.startswith("address_"):
                # Listener management
                for cpt in range(dataPosted_length):
                    if data.startswith("address_" + str(cpt) + "="):

                        inet = None
                        port = None
                        redirect_port = None

                        try:
                            listener_id = dataPosted['address_' + str(cpt)]
                            inet = Listener.objects.with_id(
                                ObjectId(listener_id))
                        except Exception as e:
                            pass

                        try:
                            port = dataPosted['port_' + str(cpt)]
                        except Exception as e:
                            pass

                        try:
                            redirect_port = dataPosted['redirect_port_' +
                                                       str(cpt)]
                        except Exception as e:
                            pass

                        try:
                            ssl_profile = ModSSL.objects.with_id(
                                ObjectId(dataPosted['ssl_profile_' +
                                                    str(cpt)]))
                        except Exception as e:
                            ssl_profile = None
                            pass

                        if (inet and port):

                            address = ListenAddress(
                                address=inet,
                                port=port,
                                ssl_profile=ssl_profile,
                                redirect_port=redirect_port)
                            """ Add '1' because we don't want to save yet the listener """
                            address.related_node = address.get_related_node(1)
                            listeners.append(address)
                            listeners_ips.append(
                                (address.related_node, inet.ip, port))
                            has_listener = True

                        dataPosted_length -= 4

            if data.startswith("SpecificRS_url_"):
                for cpt in range(dataPosted_length):
                    if data.startswith("SpecificRS_url_" + str(cpt) + "="):

                        # Force default values to prevent injection or any problem
                        specific_rs_url = dataPosted.get(
                            'SpecificRS_url_' + str(cpt), '/login/')
                        try:
                            specific_rs_rs = ModSecRulesSet.objects.with_id(
                                ObjectId(
                                    dataPosted.get(
                                        'modsec_specific_rs_select' + str(cpt),
                                        None)))
                        except:
                            specific_rs_rs = ModSecRulesSet.objects.first()

                        specific_rs = ModSecSpecificRulesSet(
                            url=specific_rs_url, rs=specific_rs_rs)
                        specific_rules_set.append(specific_rs)

                        cpt -= 2

            # Incoming header management
            if data.startswith("header_action_"):
                for cpt in range(dataPosted_length):
                    if data.startswith("header_action_" + str(cpt) + "="):

                        # Force harmless default values to prevent any injection or jQuery problem
                        header_enable = (dataPosted.get(
                            'header_enable_' + str(cpt), 'off') == 'on')
                        header_action = dataPosted.get(
                            'header_action_' + str(cpt), 'add')
                        header_name = dataPosted.get('header_name_' + str(cpt),
                                                     'Vulture')
                        header_value = dataPosted.get(
                            'header_value_' + str(cpt), '')
                        header_replacement = dataPosted.get(
                            'header_replacement_' + str(cpt), '')
                        header_condition = dataPosted.get(
                            'header_condition_' + str(cpt), 'always')
                        header_condition_v = dataPosted.get(
                            'header_condition_v_' + str(cpt), '')

                        # FIXME: Coherence control
                        header = HeaderIn(header_enable, header_action,
                                          header_name, header_value,
                                          header_replacement, header_condition,
                                          header_condition_v)
                        incoming_headers.append(header)

                        dataPosted_length -= 7

            # Outgoing header management
            if data.startswith("header_out_action_"):
                for cpt in range(dataPosted_length):
                    if data.startswith("header_out_action_" + str(cpt) + "="):

                        # Force harmless default values to prevent any injection or jQuery problem
                        header_enable = (dataPosted.get(
                            'header_out_enable_' + str(cpt), 'off') == 'on')
                        header_action = dataPosted.get(
                            'header_out_action_' + str(cpt), 'add')
                        header_name = dataPosted.get(
                            'header_out_name_' + str(cpt), 'Vulture')
                        header_value = dataPosted.get(
                            'header_out_value_' + str(cpt), '')
                        header_replacement = dataPosted.get(
                            'header_out_replacement_' + str(cpt), '')
                        header_condition = dataPosted.get(
                            'header_out_condition_' + str(cpt), 'always')
                        header_condition_v = dataPosted.get(
                            'header_out_condition_v_' + str(cpt), '')

                        # FIXME: Coherence control
                        header = HeaderOut(header_enable, header_action,
                                           header_name, header_value,
                                           header_replacement,
                                           header_condition,
                                           header_condition_v)
                        outgoing_headers.append(header)

                        dataPosted_length -= 7

            # # Content rules management
            if data.startswith("content_types_"):
                for cpt in range(dataPosted_length):
                    if data.startswith("content_types_" + str(cpt) + "="):

                        # Force harmless default values to prevent any injection
                        # or jQuery problem
                        content_enable = True if dataPosted.get(
                            'content_enable_' +
                            str(cpt), 'off') == 'on' else False
                        content_types = dataPosted.get(
                            'content_types_' + str(cpt), 'text/html')
                        content_condition = dataPosted.get(
                            'condition_' + str(cpt), '')
                        content_deflate = True if dataPosted.get(
                            'content_deflate_' +
                            str(cpt), 'off') == 'on' else False
                        content_inflate = True if dataPosted.get(
                            'content_inflate_' +
                            str(cpt), 'off') == 'on' else False
                        content_pattern = dataPosted.get(
                            'content_pattern_' + str(cpt), '')
                        content_replacement = dataPosted.get(
                            'content_replacement_' + str(cpt), '')
                        content_replacement_flags = dataPosted.get(
                            'content_replacement_flags_' + str(cpt), '')

                        # FIXME: Coherence control
                        rule = ContentRule(content_enable, content_types,
                                           content_condition, content_deflate,
                                           content_inflate, content_pattern,
                                           content_replacement,
                                           content_replacement_flags)
                        content_rules.append(rule)

                        dataPosted_length -= 8

            # SVMs management
            if data.startswith("checkbox_chart_uri_analysis_"):
                m = re.match('checkbox_chart_uri_analysis_([0-9|a-f]+)', data)
                if m:
                    dataset_id_ = m.group(1)

                    # Force harmless default values to prevent any injection or jQuery problem
                    svm_enable = False
                    try:
                        svm_enable = True if dataPosted.get(
                            'checkbox_chart_uri_analysis_' +
                            dataset_id_) == 'on' else False
                        if svm_enable:
                            svm = SVM.objects(dataset_used=dataset_id_,
                                              algo_used="Levenstein")[0]
                            activated_svms.append(str(svm.id))
                            logger.debug(
                                "Activated SVM with id '{}' for application saved"
                                .format(str(svm.id)))
                    except KeyError:
                        pass
                    except Exception as e:
                        logger.error(
                            "Unable to retrieve activated SVM - Dataset_id:{}, algo_used:Levenstein - Exception: {}"
                            .format(dataset_id_, str(e)))

            if data.startswith("checkbox_chart_uri_analysis_2_"):
                m = re.match('checkbox_chart_uri_analysis_2_([0-9|a-f]+)',
                             data)
                if m:
                    dataset_id_ = m.group(1)

                    # Force harmless default values to prevent any injection or jQuery problem
                    svm_enable = False
                    try:
                        svm_enable = True if dataPosted.get(
                            'checkbox_chart_uri_analysis_2_' +
                            dataset_id_) == 'on' else False
                        if svm_enable:
                            svm = SVM.objects(dataset_used=dataset_id_,
                                              algo_used="Levenstein2")[0]
                            activated_svms.append(str(svm.id))
                            logger.debug(
                                "Activated SVM with id '{}' for application saved"
                                .format(str(svm.id)))
                    except KeyError:
                        pass
                    except Exception as e:
                        logger.error(
                            "Unable to retrieve activated SVM - Dataset_id:{}, algo_used:Levenstein2 - Exception: {}"
                            .format(dataset_id_, str(e)))

            if data.startswith("checkbox_chart_bytes_received_"):
                m = re.match('checkbox_chart_bytes_received_([0-9|a-f]+)',
                             data)
                if m:
                    dataset_id_ = m.group(1)

                    # Force harmless default values to prevent any injection or jQuery problem
                    svm_enable = False
                    try:
                        svm_enable = True if dataPosted.get(
                            'checkbox_chart_bytes_received_' +
                            dataset_id_) == 'on' else False
                        if svm_enable:
                            svm = SVM.objects(
                                dataset_used=dataset_id_,
                                algo_used="HTTPcode_bytes_received")[0]
                            activated_svms.append(str(svm.id))
                            logger.debug(
                                "Activated SVM with id '{}' for application saved"
                                .format(str(svm.id)))
                    except KeyError:
                        pass
                    except Exception as e:
                        logger.error(
                            "Unable to retrieve activated SVM - Dataset_id:{}, algo_used:HTTPcode_bytes_received - Exception: {}"
                            .format(dataset_id_, str(e)))

            if data.startswith("checkbox_chart_ratio_"):
                m = re.match('checkbox_chart_ratio_([0-9|a-f]+)', data)
                if m:
                    dataset_id_ = m.group(1)

                    # Force harmless default values to prevent any injection or jQuery problem
                    svm_enable = False
                    try:
                        svm_enable = True if dataPosted.get(
                            'checkbox_chart_ratio_' +
                            dataset_id_) == 'on' else False
                        if svm_enable:
                            svm = SVM.objects(dataset_used=dataset_id_,
                                              algo_used="Ratio")[0]
                            activated_svms.append(str(svm.id))
                            logger.debug(
                                "Activated SVM with id '{}' for application saved"
                                .format(str(svm.id)))
                    except KeyError:
                        pass
                    except Exception as e:
                        logger.error(
                            "Unable to retrieve activated SVM - Dataset_id:{}, algo_used:Ratio - Exception: {}"
                            .format(dataset_id_, str(e)))

        form = ApplicationForm(request.POST,
                               instance=application,
                               listeners=listeners)
    else:

        if not object_id:
            try:
                rulesset_vulture = [
                    ModSecRulesSet.objects.get(name="Vulture RS").id
                ]
            except ModSecRulesSet.DoesNotExist:
                rulesset_vulture = []

            form = ApplicationForm(initial={
                "rules_set":
                rulesset_vulture,
                "modsec_policy":
                ModSec.objects.get(name="Default Policy")
            },
                                   instance=application)
        else:
            form = ApplicationForm(
                initial={'rules_set': [x.id for x in application.rules_set]},
                instance=application)

        incoming_headers = application.headers_in
        outgoing_headers = application.headers_out
        content_rules = application.content_rules

        specific_rules_set = list()
        for i in application.specific_rules_set:
            specific_rules_set.append(
                ModSecSpecificRulesSet(url=re.sub('^' + application.public_dir,
                                                  '', i.url),
                                       rs=i.rs))

        # We replace '\' by '\\' in strings because they're interpreted by templates
        for tmp_rule in content_rules:
            tmp_rule.pattern = tmp_rule.pattern.replace("\\", "\\\\")
            tmp_rule.replacement = tmp_rule.replacement.replace("\\", "\\\\")

        listeners = application.listeners

        svms = [
            SVM.objects(id=ObjectId(svm_id)).no_dereference().only(
                'dataset_used', 'algo_used', 'id').first()
            for svm_id in application.activated_svms
        ]

    # Saving information into database and redirect to application list
    if request.method == 'POST' and form.is_valid():

        # Listener is mandatory
        if has_listener:
            old_app = Application.objects.with_id(ObjectId(object_id))

            # 1) Remove old listeners, headers and content rules
            if old_app and old_app.listeners:
                for listener in old_app.listeners:
                    ip = listener.address.ip
                    port = listener.port
                    n = listener.related_node
                    """ Stop the listener if there is only this app running on it """
                    if (n, ip, port) not in listeners_ips:
                        logger.info("Stopping listener {}:{}".format(ip, port))
                        listener.stop()

                    listener.delete()

            if old_app and old_app.headers_in:
                for header in old_app.headers_in:
                    header.delete()

            if old_app and old_app.headers_out:
                for header in old_app.headers_out:
                    header.delete()

            if old_app and old_app.content_rules:
                for rule in old_app.content_rules:
                    rule.delete()

            if old_app and old_app.specific_rules_set:
                for ruleset in old_app.specific_rules_set:
                    ruleset.delete()

            old_cookie_encryption = False
            old_cookie_cipher = None
            if old_app:
                application.wl_bl_rules = old_app.wl_bl_rules

                old_cookie_encryption = old_app.cookie_encryption
                old_cookie_cipher = old_app.cookie_cipher
                old_cookie_cipher_key = old_app.cookie_cipher_key
                old_cookie_cipher_iv = old_app.cookie_cipher_iv

            # 2) Create new listeners, headers and content rules
            for listener in listeners:
                listener.save()
            for header in incoming_headers:
                header.save()
            for header in outgoing_headers:
                header.save()
            for rule in content_rules:
                rule.save()

            # 3) Assign listeners, headers and content rules
            auth_backend = form.cleaned_data.get('auth_backend')
            auth_backend_fallbacks = form.cleaned_data.get(
                'auth_backend_fallbacks')
            application = form.save(commit=False)

            if auth_backend:
                application.auth_backend = auth_backend
            else:
                application.auth_backend = None
            if auth_backend_fallbacks:
                application.auth_backend_fallbacks = auth_backend_fallbacks
            else:
                application.auth_backend_fallbacks = None

            application.listeners = listeners
            application.headers_in = incoming_headers
            application.headers_out = outgoing_headers
            application.specific_rules_set = specific_rules_set
            application.content_rules = content_rules
            application.activated_svms = activated_svms

            if application.cookie_encryption:
                if not old_cookie_encryption or not old_cookie_cipher or application.cookie_cipher != old_cookie_cipher:
                    application.cookie_cipher_key = get_random_string(
                        32
                    ) if application.cookie_cipher == 'aes256' else get_random_string(
                        16)
                    application.cookie_cipher_iv = get_random_string(
                        32
                    ) if application.cookie_cipher == 'aes256' else get_random_string(
                        16)

                else:
                    application.cookie_cipher_key = old_cookie_cipher_key
                    application.cookie_cipher_iv = old_cookie_cipher_iv

            # 4) Save application
            if not application.public_dir.endswith('/'):
                application.public_dir += '/'
            if application.auth_portal and not application.auth_portal.endswith(
                    '/'):
                application.auth_portal += '/'
            if application.private_uri and not application.private_uri.endswith(
                    '/'):
                application.private_uri += '/'

            for ruleset in specific_rules_set:
                ruleset.url = os.path.normpath(
                    str(application.public_dir) + '/' + str(ruleset.url))
                ruleset.save()

            if not object_id:
                # Create BlackList/WhiteList ModSecRuleSet
                modsec_wl_bl = ModSecRulesSet(
                    name="{} whitelist/blacklist".format(application.name),
                    type_rule="wlbl")
                modsec_wl_bl.save()
                modsec_wl_bl.conf = modsec_wl_bl.get_conf()
                modsec_wl_bl.save()

                application.wl_bl_rules = modsec_wl_bl

            else:
                # If the application is modified, modify the name of the RS references
                application.wl_bl_rules.name = "{} whitelist/blacklist".format(
                    form.cleaned_data.get('name'))
                application.wl_bl_rules.save()
                for modsec_ruleset in ModSecRulesSet.objects.filter(
                        name="Learning {} WL"):
                    modsec_ruleset.name = form.cleaned_data.get('name')
                    modsec_ruleset.save()

            if application.type == "balanced":
                application.private_uri = "{}://{}".format(
                    application.proxy_balancer.members[0].uri_type,
                    application.proxy_balancer.members[0].uri)

            # Check if api_call to reload rsyslogd is needed
            if old_app:
                if application.log_custom != old_app.log_custom or application.log_level != old_app.log_level or application.learning != old_app.learning:
                    application.save()
                else:
                    application.save(no_apicall=True)
            else:
                application.save()

            return HttpResponseRedirect('/application/')

    inets = Listener.objects()
    address_list = list()
    vhid_list = list()
    # List and categorize inet (carp or not) to render them in template
    for inet in inets:
        listener = dict()
        if inet.is_carp:
            listener['inet'] = inet
            listener['id'] = getattr(inet, 'id')
            vhid_list.append(inet.carp_vhid)

        elif inet.carp_vhid in vhid_list:
            continue

        else:
            listener['inet'] = inet
            listener['id'] = getattr(inet, 'id')

        address_list.append(listener)

    ssl_profile_list = ModSSL.objects()

    rules_set_list = ModSecRulesSet.objects.filter(
        type_rule__in=['crs', 'trustwave', 'vulture', 'custom'])

    return render_to_response('application_edit.html', {
        'form': form,
        'object_id': object_id,
        'headers_in': incoming_headers,
        'headers_out': outgoing_headers,
        'content_rules': content_rules,
        'listeners': listeners,
        'address_list': address_list,
        'ssl_profile_list': ssl_profile_list,
        'application': application,
        'svms': svms,
        'rules_set_list': rules_set_list,
        'specific_rules_set': specific_rules_set
    },
                              context_instance=RequestContext(request))
예제 #20
0
    def perform_action(self, request, old_password):
        new_passwd = request.POST['password_1']
        new_passwd_cfrm = request.POST['password_2']

        rdm = (request.GET.get("rdm", None) or request.POST.get('rdm', None))

        # If not rdm : Verify password
        if not rdm:
            saved_app_id = self.redis_portal_session.keys['app_id_' +
                                                          str(self.backend.id)]
            saved_app = Application.objects(id=ObjectId(saved_app_id)).only(
                'id', 'name', 'pw_min_len', 'pw_min_upper', 'pw_min_lower',
                'pw_min_number', 'pw_min_symbol').first()
            if not self.redis_portal_session.getAutologonPassword(
                    str(saved_app.id), str(self.backend.id), self.username):
                raise AuthenticationError("Wrong old password")
        else:
            saved_app = self.application

        #Check if password meets required complexity
        upper_case = 0
        lower_case = 0
        number = 0
        symbol = 0

        min_len = int(saved_app.pw_min_len)
        min_upper = int(saved_app.pw_min_upper)
        min_lower = int(saved_app.pw_min_lower)
        min_number = int(saved_app.pw_min_number)
        min_symbol = int(saved_app.pw_min_symbol)

        for i in new_passwd:
            if i.isupper():
                upper_case += 1
            elif i.islower():
                lower_case += 1
            elif i.isdigit():
                number += 1
            else:
                symbol += 1

        if not (len(new_passwd) >= min_len and upper_case >= min_upper
                and lower_case >= min_lower and number >= min_number
                and symbol >= min_symbol):
            logger.info("SELF::change_password: Password is too weak")
            raise AuthenticationError(
                "Password do not meet complexity requirements")

        if issubclass(self.backend.__class__, Backend):
            self.backend.change_password(
                self.username,
                old_password,
                new_passwd,
                krb5_service=self.application.app_krb_service)
        elif isinstance(self.backend.get_backend(), MongoEngineBackend):
            user = User.objects.get(username=str(self.username))
            new_password_hash = make_password(new_passwd)
            user.password = new_password_hash
            user.save()
        else:
            self.backend.get_backend().change_password(
                self.username,
                old_password,
                new_passwd,
                krb5_service=self.application.app_krb_service)
        logger.info(
            "SELF::change_password: Password successfully changed in backend")

        # If not rdm : set new password in Redis portal session
        if not rdm:
            if self.redis_portal_session.setAutologonPassword(
                    str(saved_app.id), str(saved_app.name), str(
                        self.backend.id), self.username, old_password,
                    new_passwd) is None:
                # If setAutologonPasswd return None : the old_password was incorrect
                raise AuthenticationError("Wrong old password")
            logger.info(
                "SELF::change_password: Password successfully changed in Redis"
            )

        return "Password successfully changed"
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Vulture 3.  If not, see http://www.gnu.org/licenses/.
"""
__author__ = "Olivier de Régis"
__credits__ = []
__license__ = "GPLv3"
__version__ = "3.0.0"
__maintainer__ = "Vulture Project"
__email__ = "*****@*****.**"
__doc__ = """This migration script update the auth_backend_fallback to a list"""

import os
import sys

sys.path.append('/home/vlt-gui/vulture')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", 'vulture.settings')

import django
django.setup()

from gui.models.application_settings import Application

if __name__ == '__main__':

    applications = Application.objects()
    for app in applications:
        app.auth_backend_fallbacks = [app.auth_backend_fallback]
        app.save()
예제 #22
0
    def clean(self):
        super(ApplicationForm, self).clean()

        if self.cleaned_data.get('type') == 'balanced' \
                and not self.cleaned_data.get('proxy_balancer'):
            self.add_error('proxy_balancer', 'Please choose a proxy balancer')

        if self.cleaned_data.get('need_auth') and self.cleaned_data.get(
                'auth_type'
        ) == "form" and not self.cleaned_data.get('template'):
            self.add_error(
                'template',
                'Please choose a template for authentication forms')

        if self.cleaned_data.get(
                'public_name') and '/' in self.cleaned_data.get('public_name'):
            self.add_error('public_name', 'Public FQDN cannot contain "/"')

        if self.cleaned_data.get(
                'public_alias') and '/' in self.cleaned_data.get(
                    'public_alias'):
            self.add_error('public_alias', 'Public FQDN cannot contain "/"')

        if ' ' in self.cleaned_data.get('public_dir'):
            self.add_error('public_dir', 'Public dir must not contain space')

        if self.cleaned_data.get('auth_type') != 'form':
            self.cleaned_data['otp_repository'] = None

        # It is not possible to set auth_type AND sso_type to 'kerberos'
        if self.cleaned_data.get(
                'auth_type') == 'kerberos' and self.cleaned_data.get(
                    'sso_forward') == 'kerberos':
            self.add_error(
                'auth_type',
                " You cannot set authentication type AND sso forward type to 'kerberos'"
            )
            self.add_error(
                'sso_forward',
                " You cannot set authentication type AND sso forward type to 'kerberos'"
            )

        loadbalancers = [
            "{}:{}".format(lb.incoming_listener.ip, lb.incoming_port)
            for lb in Loadbalancer.objects.all()
        ]
        for listener in self.listeners:
            if "{}:{}".format(listener.address.ip,
                              listener.port) in loadbalancers:
                self.add_error(
                    'Network',
                    " An haproxy configuration is currently using this port with this Listener"
                )

        # If sso_forward == "kerberos" -> verify if auth_backend(fallback) is a KerberosRepository
        error = True
        if self.cleaned_data.get('sso_forward') == 'kerberos':
            for repo in BaseAbstractRepository.get_auth_repositories():
                if str(self.cleaned_data.get('auth_backend')) == str(
                        repo.id) and isinstance(repo.get_backend(),
                                                KerberosBackend):
                    error = False
                    break
                elif str(
                        self.cleaned_data.get('auth_backend_fallback')) == str(
                            repo.id) and isinstance(repo.get_backend(),
                                                    KerberosBackend):
                    error = False
                    break
            if error:
                self.add_error(
                    'sso_forward',
                    "If sso_forward = 'Kerberos', you must have a kerberos backend"
                )

        auth_type = [x[0] for x in Application().AUTH_TYPE]
        if self.cleaned_data.get('sso_enabled') and self.cleaned_data.get(
                'auth_type') not in auth_type:
            self.add_error(
                'auth_type',
                "Please select a forward type for the SSO Forward configuration"
            )

        # If there is a modsec rulesSet selected
        if self.cleaned_data.get('rules_set', None):
            # And a ModSecPolicy with 'body_inspection' if Off
            modsec_policy = self.cleaned_data.get('modsec_policy', None)
            if not hasattr(modsec_policy, 'seccontentinjection'
                           ) or not modsec_policy.seccontentinjection:
                self.add_error(
                    'rules_set',
                    'The ModSec Policy must have "Content injection" to On to activate ModSec RulesSet'
                )

        self.cleaned_data["custom_location"] = self.cleaned_data.get(
            'custom_location', "").replace("\r", "")
        self.cleaned_data["custom_vhost"] = self.cleaned_data.get(
            'custom_vhost', "").replace("\r", "")
        self.cleaned_data["custom_proxy"] = self.cleaned_data.get(
            'custom_proxy', "").replace("\r", "")

        return self.cleaned_data
예제 #23
0
def log_in(request, token_name=None, token=None, proxy_app_id=None):
    """ Handle authentication in Vulture Portal
    :param request: Django request object
    :returns: Home page if user auth succeed. Logon page if auth failed
    """

    default_authentication_type = None

    cluster = Cluster.objects.get()
    """ Check if URI arguments are valid """
    if token_name and token_name != cluster.getTokenName():
        logger.info("PORTAL::Authentication: Invalid token in URI " +
                    str(token_name) + '/' + str(token))
        return HttpResponseForbidden()

    authentication_classes = {
        'form': POSTAuthentication,
        'basic': BASICAuthentication,
        'kerberos': KERBEROSAuthentication
    }
    """ Retrieve token and cookies to instantiate Redis wrapper objects """
    # Retrieve cookies required for authentication
    portal_cookie_name = cluster.getPortalCookie()
    portal_cookie = request.COOKIES.get(portal_cookie_name, None)
    app_cookie = request.COOKIES.get(cluster.getAppCookie(), None)
    try:
        # Instantiate authentication object to retrieve application auth_type
        authentication = Authentication(token_name, token, app_cookie,
                                        portal_cookie)
        # And then instantiate the right authentication class with auth_type ('form','basic','kerberos')
        authentication = authentication_classes[
            authentication.application.auth_type](token_name, token,
                                                  app_cookie, portal_cookie)
        logger.debug("PORTAL::log_in: Authentication successfully created")

    # Application does not need authentication
    except RedirectionNeededError as e:
        logger.error("PORTAL::log_in: {}".format(str(e)))
        return HttpResponseRedirect(e.redirect_url)

    # Redis connection error
    except RedisConnectionError as e:
        logger.error(
            "PORTAL::log_in: Unable to connect to Redis server : {}".format(
                str(e)))
        return response_failure(HttpResponseServerError(), "authentication")

    # Token not found while instantiating RedisSession or RedisAppSession
    except TokenNotFoundError as e:
        logger.error("PORTAL::log_in: {}".format(str(e)))
        try:
            # Retrieve application object to redirect to application default uri
            application = Application.objects(id=ObjectId(proxy_app_id)).only(
                'listeners', 'public_name', 'public_dir').first()
            return HttpResponseRedirect(application.get_redirect_uri())

        # If "proxy_app_id" not found : FORBIDDEN
        except (Application.DoesNotExist, InvalidId, ValidationError) as e:
            logger.error(
                "PORTAL::log_in: Application with id '{}' not found : {}".
                format(proxy_app_id, str(e)))
            return response_failure(HttpResponseForbidden(), "authentication")

    # If redis_session.keys['application_id'] does not exists : FORBIDDEN
    except (Application.DoesNotExist, ValidationError, InvalidId) as e:
        logger.error(
            "PORTAL::log_in: Application with id '{}' not found".format(
                authentication.redis_session.keys['application_id']))
        return response_failure(HttpResponseForbidden(), "authentication")

    # If assertionError : Ask credentials by portal
    except AssertionError as e:
        logger.error(
            "PORTAL::log_in: AssertionError while trying to create Authentication : "
            .format(e))
        return authentication.ask_credentials_response(request=request)
    """ If user is not authenticated : try to retrieve credentials and authenticate him on backend/fallback-backends """
    # If the user is not authenticated and application need authentication
    if not authentication.is_authenticated():
        default_authentication_type = "authentication"
        try:
            backend_id = authentication.authenticate_on_backend()
            if not backend_id:
                # Retrieve credentials
                authentication.retrieve_credentials(request)
                logger.debug(
                    "PORTAL::log_in: Credentials successfully retrieved")

                # Authenticate user with credentials retrieven
                authentication_results = authentication.authenticate(request)
                logger.debug(
                    "PORTAL::log_in: Authentication succeed on backend {}".
                    format(authentication.backend_id))

                # Register authentication results in Redis
                app_cookie, portal_cookie, oauth2_token = authentication.register_user(
                    authentication_results)
                logger.debug(
                    "PORTAL::log_in: User {} successfully registered in Redis".
                    format(authentication.credentials[0]))

                if authentication_results['data'].get('password_expired',
                                                      None):
                    logger.info(
                        "PORTAL::log_in: User '{}' must change its password, redirect to self-service portal"
                        .format(authentication.credentials[0]))
                    app_url = authentication.get_url_portal()
                    return response_success(
                        response_redirect_with_portal_cookie(
                            app_url + str(token_name) + '/self/change',
                            portal_cookie_name, portal_cookie,
                            app_url.startswith('https'), None),
                        "authentication")
            # If the user is already authenticated (retrieven with RedisPortalSession ) => SSO
            else:
                app_cookie, portal_cookie, oauth2_token = authentication.register_sso(
                    backend_id)
                logger.info(
                    "PORTAL::log_in: User {} successfully SSO-powered !".
                    format(authentication.credentials[0]))

        except AssertionError as e:
            logger.error(
                "PORTAL::log_in: Bad captcha taped for username '{}' : {}".
                format(authentication.credentials[0], e))
            return response_failure(
                authentication.ask_credentials_response(request=request,
                                                        error="Bad captcha"),
                "authentication")

        except AccountLocked as e:
            logger.error(
                "PORTAL::log_in: Error while trying to authenticate user '{}' : {}"
                .format(authentication.credentials[0], e))
            return response_failure(
                authentication.ask_credentials_response(
                    request=request, error="Bad credentials"),
                "authentication")

        except AuthenticationError as e:
            logger.error(
                "PORTAL::log_in: AuthenticationError while trying to authenticate user '{}' : {}"
                .format(authentication.credentials[0], e))
            return response_failure(
                authentication.ask_credentials_response(
                    request=request, error="Bad credentials"),
                "authentication")

        except ACLError as e:
            logger.error(
                "PORTAL::log_in: ACLError while trying to authenticate user '{}' : {}"
                .format(authentication.credentials[0], e))
            return response_failure(
                authentication.ask_credentials_response(
                    request=request, error="Bad credentials"),
                "authentication")

        except (DBAPIError, PyMongoError, LDAPError) as e:
            logger.error(
                "PORTAL::log_in: Repository driver Error while trying to authentication user '{}' : {}"
                .format(authentication.credentials[0], e))
            return response_failure(
                authentication.ask_credentials_response(
                    request=request, error="Bad credentials"),
                "authentication")

        except (MultiValueDictKeyError, AttributeError, KeyError) as e:
            #vltprtlsrnm is always empty during the initial redirection. Don't log that
            logger.debug(
                "PORTAL::log_in: Error while trying to authentication user '{}' : {}"
                .format(authentication.credentials[0], e))
            return authentication.ask_credentials_response(request=request)

        except REDISWriteError as e:
            logger.error(
                "PORTAL::log_in: RedisWriteError while trying to register user '{}' informations : {}"
                .format(authentication.credentials[0], e))
            return response_failure(HttpResponseServerError(),
                                    "authentication")

        except Exception as e:
            logger.exception(e)
            return response_failure(HttpResponseServerError(),
                                    "authentication")
    """ If user is not double-authenticated and double-authentication needed : try to retrieve credentials and authenticate him on otp-backend """
    # If the user is authenticated but not double-authenticated and double-authentication required
    if authentication.double_authentication_required():
        default_authentication_type = "otp"
        logger.info(
            "PORTAL::log_in: Double authentication required for user '{}'".
            format(authentication.credentials[0]))
        try:
            # Instantiate DOUBLEAuthentication object
            db_authentication = DOUBLEAuthentication(cluster.getTokenName(),
                                                     token, app_cookie,
                                                     portal_cookie)
            logger.debug(
                "PORTAL::log_in: DoubleAuthentication successfully created")
            # And try to retrieve credentials
            db_authentication.retrieve_credentials(request)
            logger.debug(
                "PORTAL::log_in: DoubleAuthentication credentials successfully retrieven"
            )
            # And use them to authenticate user
            db_authentication.authenticate(request)
            logger.info(
                "PORTAL::log_in: User '{}' successfully double authenticated".
                format(authentication.credentials[0]))

        except AssertionError as e:
            """ If redis_portal_session does not exists or can't retrieve otp key in redis """
            logger.error(
                "PORTAL::log_in: DoubleAuthentication failure for username '{}' : {}"
                .format(authentication.credentials[0], str(e)))
            return response_failure(
                authentication.ask_credentials_response(
                    request=request,
                    portal_cookie_name=portal_cookie_name,
                    error="Portal cookie expired"), "otp")

        except (Application.DoesNotExist, ValidationError, InvalidId) as e:
            """ Invalid POST 'vulture_two_factors_authentication' value """
            logger.error(
                "PORTAL::log_in: Double-authentication failure for username {} : {}"
                .format(authentication.credentials[0], str(e)))
            return response_failure(
                HttpResponseForbidden("Intrusion attempt blocked"), "otp")

        except REDISWriteError as e:
            """ Cannot register double-authentication in Redis : internal server error """
            logger.error(
                "PORTAL::log_in: Failed to write double-authentication results in Redis for username '{}' : {}"
                .format(db_authentication.credentials[0], str(e)))
            return response_failure(HttpResponseServerError(), "otp")

        # If authentication failed : create double-authentication key and ask-it
        except CredentialsError as e:
            """ CredentialsError: no OTP credentials provided : ask-them """
            logger.error(
                "PORTAL::log_in: Double-authentication failure for username {} : {}"
                .format(authentication.credentials[0], str(e)))
            try:
                db_authentication.create_authentication()
                # If we get here, authentication has succeed
                return response_success(
                    db_authentication.ask_credentials_response(
                        request=request,
                        portal_cookie_name=portal_cookie_name),
                    "authentication")

            except (OTPError, REDISWriteError, RedisConnectionError) as e:
                """ Error while sending/registering in Redis the OTP informations : display portal"""
                logger.error(
                    "PORTAL::log_in: Failed to create/send double-authentication key : {}"
                    .format(str(e)))
                db_authentication.deauthenticate_user()
                logger.info(
                    "PORTAL::log_in: User '{}' successfully deauthenticated due to db-authentication error"
                    .format(authentication.credentials[0]))
                return response_failure(
                    authentication.ask_credentials_response(
                        request=request,
                        error="<b> Error sending OTP Key </b> </br> " +
                        str(e)), "otp")

        except AuthenticationError as e:
            """ Bad OTP key """
            logger.error(
                "PORTAL::log_in: DoubleAuthentication failure for username {} : {}"
                .format(authentication.credentials[0], str(e)))
            try:
                db_authentication.create_authentication()
                db_authentication.authentication_failure()
                logger.debug(
                    "PORTAL:log_in: DoubleAuthentication failure successfully registered in Redis"
                )
                return response_failure(
                    db_authentication.ask_credentials_response(
                        request=request,
                        portal_cookie_name=portal_cookie_name,
                        error="<b> Bad OTP key </b>"), "otp")

            except TwoManyOTPAuthFailure as e:
                logger.error(
                    "PORTAL::log_in: Two many OTP authentication failures for username'{}', redirecting to portal"
                    .format(authentication.credentials[0]))
                db_authentication.deauthenticate_user()
                logger.info(
                    "PORTAL::log_in: User '{}' successfully deauthenticated due to db-authentication error"
                    .format(authentication.credentials[0]))
                return response_failure(
                    authentication.ask_credentials_response(request=request,
                                                            error=e.args[0]),
                    "otp")

            except (OTPError, REDISWriteError, RedisConnectionError) as e:
                logger.error(
                    "PORTAL::log_in: Error while preparing double-authentication : {}"
                    .format(str(e)))
                return response_failure(
                    db_authentication.ask_credentials_response(
                        request=request,
                        portal_cookie_name=portal_cookie_name,
                        error="<b> Error sending OTP Key </b> </br> " +
                        str(e)), "otp")

        except OTPError as e:
            """ OTP Error while authenticating given token """
            logger.error(
                "PORTAL::log_in: Double-authentication failure for username {} : {}"
                .format(authentication.credentials[0], str(e)))
            return response_failure(
                db_authentication.ask_credentials_response(
                    request=request,
                    portal_cookie_name=portal_cookie_name,
                    error="<b> OTP Error </b> {}".format(str(e))), "otp")

        except TwoManyOTPAuthFailure as e:
            logger.error(
                "PORTAL::log_in: Two many OTP authentication failures for username'{}', redirecting to portal"
                .format(authentication.credentials[0]))
            db_authentication.deauthenticate_user()
            logger.info(
                "PORTAL::log_in: User '{}' successfully deauthenticated due to db-authentication error"
                .format(authentication.credentials[0]))
            return response_failure(
                authentication.ask_credentials_response(request=request,
                                                        error=e.args[0]),
                "otp")

    # If we arrive here : the user is authenticated
    #  and double-authenticated if double-authentication needed
    sso_methods = {
        'form': SSOForwardPOST,
        'basic': SSOForwardBASIC,
        'kerberos': SSOForwardKERBEROS
    }
    """ If SSOForward enabled : perform-it """
    if authentication.application.sso_enabled:
        # Try to retrieve credentials from authentication object
        try:
            if not authentication.credentials[
                    0] or not authentication.credentials[1]:
                authentication.get_credentials(request)
            # If we cannot retrieve them, ask credentials
            if not authentication.credentials[
                    0]:  # or not authentication.credentials[1]:
                # If we get here, otp or auth has succeed
                return response_success(
                    authentication.ask_credentials_response(
                        request=request,
                        portal_cookie_name=portal_cookie_name,
                        error="Credentials not found"),
                    default_authentication_type)
            logger.info(
                "PORTAL::log_in: Credentials successfuly retrieven for SSO performing"
            )

        except Exception as e:
            logger.error(
                "PORTAL::log_in: Error while retrieving credentials for SSO : "
            )
            logger.exception(e)
            return response_success(
                authentication.ask_credentials_response(
                    request=request,
                    portal_cookie_name=portal_cookie_name,
                    error="Credentials not found"),
                default_authentication_type)

        try:
            # Instantiate SSOForward object with sso_forward type
            sso_forward = sso_methods[authentication.application.sso_forward](
                request, authentication.application, authentication)
            logger.info("PORTAL::log_in: SSOForward successfully created")
            # Get credentials needed for sso forward : AutoLogon or Learning
            sso_data, profiles_to_stock, url = sso_forward.retrieve_credentials(
                request)
            logger.info(
                "PORTAL::log_in: SSOForward credentials successfully retrieven"
            )
            # If credentials retrieven needs to be stocked
            for profile_name, profile_value in profiles_to_stock.items():
                sso_forward.stock_sso_field(authentication.credentials[0],
                                            profile_name, profile_value)

            # Use 'sso_data' and 'url' to authenticate user on application
            response = sso_forward.authenticate(
                sso_data,
                post_url=url,
                redis_session=authentication.redis_session)
            logger.info("PORTAL::log_in: SSOForward performing success")
            # Generate response depending on application.sso_forward options
            final_response = sso_forward.generate_response(
                request, response, authentication.get_redirect_url())
            logger.info(
                "PORTAL::log_in: SSOForward response successfuly generated")

            # If the user has not yet a portal cookie : give-it
            if not request.COOKIES.get(
                    portal_cookie_name,
                    None) or not authentication.redis_base.hgetall(
                        request.COOKIES.get(portal_cookie_name, None)):
                final_response = set_portal_cookie(
                    final_response, portal_cookie_name, portal_cookie,
                    authentication.get_redirect_url())
            return response_success(final_response,
                                    default_authentication_type)

        # If learning credentials cannot be retrieven : ask them
        except CredentialsMissingError as e:
            logger.error(
                "PORTAL::log_in: Learning credentials missing : asking-them")
            return response_success(
                authentication.ask_learning_credentials(
                    request=request,
                    portal_cookie_name=None if request.POST.get(
                        portal_cookie_name, None) else portal_cookie_name,
                    fields=e.fields_missing), default_authentication_type)

        # If KerberosBackend object cannot be retrieven from mongo with the backend_id that the user is authenticated on
        except InvalidId:
            logger.error(
                "PORTAL::log_in: The user is authenticated on a not Kerberos backend, cannot do SSOForward"
            )

        except (RequestsConnectionError, OpenSSLError) as e:
            logger.error(
                "PORTAL::log_in: ConnectionError while trying to SSO to backend : "
            )
            logger.exception(e)

        except Exception as e:
            logger.error(
                "PORTAL::log_in: Unexpected error while trying to perform SSO Forward :"
            )
            logger.exception(e)
    """ If no response has been returned yet : redirect to the asked-uri/default-uri with portal_cookie """
    redirection_url = authentication.get_redirect_url()
    logger.info(
        "PORTAL::log_in: Redirecting user to '{}'".format(redirection_url))
    try:
        kerberos_token_resp = authentication_results['data']['token_resp']
    except:
        kerberos_token_resp = None
    return response_success(
        response_redirect_with_portal_cookie(
            redirection_url, portal_cookie_name, portal_cookie,
            redirection_url.startswith('https'), kerberos_token_resp),
        default_authentication_type)
예제 #24
0
    def post(self, request, app_id, login=""):
        if not login:
            return JsonResponse({'status': False, 'error': "Login missing."})
        try:
            app = Application.objects(
                id=ObjectId(app_id)).no_dereference().only(
                    'name', 'auth_backend', 'sso_profile').first()
            if not app:
                raise Application.DoesNotExist()
            assert app.sso_profile, "No wizard SSO configured for the application '{}'".format(
                app.name)
        except (Application.DoesNotExist, InvalidId) as e:
            logger.error(
                "SSOProfiles::GET: Application with id '{}' not found".format(
                    app_id))
            return JsonResponse({
                'status':
                False,
                'error':
                "Application with id '{}' not found.".format(app_id)
            })
        except AssertionError as e:
            return JsonResponse({'status': False, 'error': str(e)})

        try:
            # First check if that user is in repository
            if not self.check_user_exists(app, login):
                return JsonResponse({
                    'status':
                    False,
                    'error':
                    "User '{}' not found "
                    "in repository '{}'".format(login, app.getAuthBackend())
                })
            # Verify if a Profile already exists
            if SSOProfile.objects.filter(app_id=str(app.id),
                                         repo_id=str(app.getAuthBackend().id),
                                         login=login).count() != 0:
                return JsonResponse({
                    'status': False,
                    'error': "SSOProfile already exists."
                })

            # Retrieve the list of application sso_profiles
            sso_profiles_app = json_loads(app.sso_profile)
            # And verify if all fields are provided
            request_data = request.POST or request.JSON
            new_sso_profiles = {}
            unknown_fields = list(request_data.keys())
            for sso_profile_app in sso_profiles_app:
                if sso_profile_app['type'] in ("learn", "learn_secret"):
                    field_name = sso_profile_app['name'].split(';vlt;')[0]
                    # First try to retrieve the friendly name.
                    if sso_profile_app.get('asked_name') and request_data.get(
                            sso_profile_app.get('asked_name')):
                        field_value = request_data.get(
                            sso_profile_app.get('asked_name'))
                        unknown_fields.remove(
                            sso_profile_app.get('asked_name'))
                    else:
                        field_value = request_data.get(field_name)
                        if field_name in unknown_fields:
                            unknown_fields.remove(field_name)
                    assert field_value, "Field named '{}' {} missing.".format(
                        field_name, "friendly name '{}'".format(
                            sso_profile_app.get('asked_name'))
                        if sso_profile_app.get('asked_name') else "")
                    new_sso_profiles[field_name] = field_value
            # Check if a field provided is not in application's sso_profiles
            if unknown_fields:
                # Correctly format fields for error
                if len(unknown_fields) == 1:
                    unknown_fields = unknown_fields.pop()
                else:
                    unknown_fields = ",".join(unknown_fields)
                raise Exception(
                    "Field(s) '{}' not found in Application learning fields.".
                    format(unknown_fields))

            app.set_sso_profiles(login, new_sso_profiles)

            return JsonResponse({'status': True})

        except Exception as e:
            logger.critical(e, exc_info=1)

            return JsonResponse({'status': False, 'error': str(e)})
예제 #25
0
def profile_edit(request, app_id, login):
    try:
        app = Application.objects(id=ObjectId(app_id)).no_dereference().only(
            'name', 'auth_backend', 'sso_profile', 'sso_forward').first()
    except (Application.DoesNotExist, InvalidId) as e:
        logger.error(
            "SSOProfiles::GET: Application with id '{}' not found".format(
                app_id))
        return HttpResponseForbidden(
            "Application with id '{}' not found.".format(app_id))

    # Check if user exists ?
    if app.sso_forward == "basic":
        sso_profiles_app = [{
            'type': "learn",
            'name': "basic_username;vlt;",
            'asked_name': "username"
        }, {
            'type': "learn_secret",
            'name': "basic_password;vlt;",
            'asked_name': "password"
        }]
    elif app.sso_forward == "kerberos":
        sso_profiles_app = [{
            'type': "learn",
            'name': "kerberos_username;vlt;",
            'asked_name': "username"
        }, {
            'type': "learn_secret",
            'name': "kerberos_password;vlt;",
            'asked_name': "password"
        }]
    else:
        # Retrieve the list of application sso_profiles
        try:
            sso_profiles_app = json_loads(app.sso_profile)
        except:
            raise Exception(
                "No SSO wizard configured for this application. Cannot retrieve user profiles."
            )

    errors = []
    profiles = []
    try:
        if request.method == "POST":
            # And verify if all fields are provided
            request_data = request.POST
            user_profiles = {}
            for sso_profile_app in sso_profiles_app:
                if sso_profile_app['type'] in ("learn", "learn_secret"):
                    field_name, field_id = sso_profile_app['name'].split(
                        ';vlt;')
                    field_value = request_data.get(field_name)
                    # If a learning_secret field has not been modified, no need to update it
                    if field_value == "*" * len(field_value):
                        continue
                    elif field_value is None:
                        errors.append(
                            "Field named '{}' missing.".format(field_name))
                    else:
                        user_profiles[field_name] = field_value

            # Check if a field provided is not in application's sso_profiles
            unknown_fields = list(
                set(request_data.keys()).difference(set(user_profiles.keys())))
            if not unknown_fields:
                errors.append(
                    "Field(s) {} not found in Application learning fields".
                    format(",".join(unknown_fields)))

            if not errors:
                app.set_sso_profiles(login, user_profiles)
                return HttpResponseRedirect("/repository/sso_profiles")

        else:
            user_profiles = app.get_sso_profiles(login)

        # Get application sso wizard, in case some field(s) has been added
        for profile in sso_profiles_app:
            if profile['type'] in ("learn", "learn_secret"):
                profile_name = profile['name'].split(";vlt;")[0]
                if profile.get('asked_name'):
                    profile_value = user_profiles.get(
                        profile.get('asked_name'))
                if not profile_value:
                    profile_value = user_profiles.get(profile_name, "")
                profiles.append(
                    (profile_name, profile.get("asked_name", "Not field"),
                     profile_value, profile['type']))

    except Exception as e:
        logger.critical(e, exc_info=1)
        errors = [str(e)]

    return render_to_response("sso_profiles_edit.html", {
        'profiles': profiles,
        'app_name': app.name,
        'repository': app.getAuthBackend().repo_name,
        'login': login,
        'error': errors
    },
                              context_instance=RequestContext(request))
예제 #26
0
def traffic(request):
    apps = []
    for app in Application.objects():
        if app.log_custom.repository_type == 'data':
            apps.append(app)

    if not request.is_ajax():
        cluster = Cluster.objects.get()

        loganalyser_settings = cluster.system_settings.loganalyser_settings
        rules = loganalyser_settings.loganalyser_rules

        tags = []
        for rule in rules:
            tags.extend(rule.tags.split(','))        

        return render_to_response('monitor_traffic.html', {'apps': apps, 'tags': set(tags)},
            context_instance=RequestContext(request))



    codes   = json.loads(request.POST['codes'])
    apps_id = json.loads(request.POST['apps_id'])
    tags    = json.loads(request.POST['tags'])
    if apps_id is not None:
        repos = {}
        for app_id in apps_id:
            app = Application.objects.with_id(ObjectId(app_id))
            try:
                repos[app.log_custom.repository].append(app)
            except:
                repos[app.log_custom.repository] = [app]

    else:
        repos = {}
        for app in apps:
            try:
                repos[app.log_custom.repository].append(app)
            except:
                repos[app.log_custom.repository] = [app]

    now    = datetime.datetime.utcnow()
    before = now - datetime.timedelta(minutes=10)

    params = {
        'codes'    : codes,
        'tags'     : tags,
        'startDate': before,
        'endDate'  : now
    }

    results, max_n = {}, 0
    for repo, apps in repos.items():
        params['apps'] = apps

        if repo.type_uri == 'mongodb':
            client = MongoDBClient(repo)

        elif repo.type_uri == 'elasticsearch':
            client = ElasticSearchClient(repo)

        for key, value in client.map(params).items():
            try:
                results[key] += value
            except KeyError:
                results[key] = value
                
            if value > max_n:
                max_n = value

    return JsonResponse({
        'results': results,
        'max'    : max_n
    })
예제 #27
0
def check_config_changes (sender, id, **kwargs):
    """ Receiver of config_modified signal.
    This checks if the Vulture's Apache configuration files needs to be refreshed

    :param sender:
    :param kwargs:
    :return:
    """

    from gui.models.application_settings import Application, ListenAddress
    from gui.models.modssl_settings import ModSSL
    from gui.models.rewrite_settings import Rewrite

    """ According to sender name, find Applications using the sender's Class """
    if sender.__name__ == "ModLog":
        app_list = Application.objects.filter(log_custom=ObjectId(id))

    elif sender.__name__ == "ModAccess":
        app_list = Application.objects.filter(access_mode=ObjectId(id))

    elif sender.__name__ == 'portalTemplate':
        listeners, tmp = [], []
        for app in Application.objects.filter(template=ObjectId(id)):
            for l in app.listeners:
                if "{}:{}".format(l.address.ip, l.port) not in tmp:
                    l.is_up2date = False
                    l.save()
                    tmp.append("{}:{}".format(l.address.ip, l.port))

        return None

    elif sender.__name__ == "SSLCertificate" or sender.__name__ == "ModSSL":
        if sender.__name__ == "SSLCertificate":
            ssl_profile = ModSSL.objects.filter(certificate=ObjectId(id))
            listeners = list()
            for profile in ssl_profile:
                ls = ListenAddress.objects.filter(ssl_profile=profile)
                for l in ls:
                    if l not in listeners:
                        listeners.append(l)
        else:
            listeners = ListenAddress.objects.filter(ssl_profile=ObjectId(id))

        """ Job's done: check listeners """
        done = list()
        for listener in listeners:
            key = listener.address.ip + ':' + listener.port
            if key not in done:
                print("Dealing with listener " + key)
                listener.need_restart()
                done.append(key)

        return None

    elif sender.__name__ == "ModSec":
        app_list = Application.objects.filter(modsec_policy=ObjectId(id))

    elif sender.__name__ == "ModSecRulesSet":
        app_list = Application.objects.filter(Q(rules_set=ObjectId(id)) or Q(wlbl=ObjectId(id)))

    elif sender.__name__ == "ProxyBalancer":
        app_list = Application.objects.filter(proxy_balancer=ObjectId(id))

    elif sender.__name__ == "Rewrite":
        app_list = None
        try:
            app_list = Rewrite.objects.get(id=ObjectId(id)).application
        except:
            pass
        """ This is a rule that apply to all applications """
        if not app_list:
            app_list = Application.objects()

    elif sender.__name__ == "Worker":
        app_list = Application.objects.filter(worker=ObjectId(id))

    elif sender.__name__ == "Cluster":
        app_list = Application.objects.all()

    else:
        print("Signal::check_config_changes(): Sender is unknown: " + str(sender.__name__))
        return None

    done = list()
    for app in app_list:
        for listener in app.listeners:
            key = listener.address.ip+':'+str(listener.port)
            if key not in done:
                print("Dealing with listener " + key)
                listener.need_restart()
                done.append(key)
예제 #28
0
def report_data(request):

    daterange = json.loads(request.POST['daterange'])
    params = {
        'startDate': daterange['startDate'],
        'endDate': daterange['endDate'],
        'reporting_type': request.POST['reporting_type']
    }

    errors = []

    if request.POST['reporting_type'] in ('access', 'security'):
        apps = []
        apps_id = json.loads(request.POST['apps'])
        if apps_id is not None:
            repos = {}
            for app_id in apps_id:
                app = Application.objects.with_id(ObjectId(app_id))
                try:
                    repos[app.log_custom.repository].append(app)
                except:
                    repos[app.log_custom.repository] = [app]
        else:
            for app in Application.objects():
                if app.log_custom.repository_type == 'data':
                    apps.append(app)

            repos = {}
            for app in apps:
                try:
                    repos[app.log_custom.repository].append(app)
                except:
                    repos[app.log_custom.repository] = [app]

        params['type_logs'] = 'access'

        results = {}
        for repo, apps in repos.items():
            params['apps'] = apps
            try:
                if repo.type_uri == 'mongodb':
                    client = MongoDBClient(repo)

                elif repo.type_uri == 'elasticsearch':
                    client = ElasticSearchClient(repo)

                aggregation = client.aggregate(params)
                if results:
                    results = client.merge_aggregations(aggregation, results)
                else:
                    results = aggregation
            except ClientLogException as e:
                errors.append(str(e))

        results = client.fill_data(results)

    elif request.POST['reporting_type'] == 'packet_filter':
        node_id = request.POST['node']
        results = {}

        node = Node.objects.with_id(ObjectId(node_id))
        repo = node.system_settings.pf_settings.repository

        params['type_logs'] = 'packet_filter'
        params['node'] = node.name
        try:
            if repo.type_uri == 'mongodb':
                client = MongoDBClient(repo)
                results = client.aggregate(params)

            elif repo.type_uri == 'elasticsearch':
                client = ElasticSearchClient(repo)
                results = client.aggregate(params)

        except ClientLogException as e:
            errors.append(str(e))

        results = client.fill_data(results)

    return JsonResponse({'results': results, 'errors': errors})