Example #1
0
    def get_format(self):
        """ Force static format for mongoDB and elasticsearch repositories """
        if self.repository_type == 'data':
            repo = BaseAbstractRepository.search_repository(
                self.data_repository)
            if isinstance(repo, MongoDBRepository):
                return "@cee:{\\\"app_name\\\":\\\"%{app_name}e\\\",\\\"src_ip\\\":\\\"%a\\\",\\\"user\\\":\\\"%u\\\",\\\"time\\\":\\\"%{%Y-%m-%dT%H:%M:%S:%Z}t\\\",\\\"http_method\\\":\\\"%m\\\",\\\"requested_uri\\\":\\\"%U%q\\\",\\\"http_code\\\":%>s,\\\"incoming_protocol\\\":\\\"%H\\\",\\\"referer\\\":\\\"%{Referer}i\\\",\\\"user_agent\\\":\\\"%{User-agent}i\\\",\\\"size\\\":%B,\\\"bytes_received\\\":%I,\\\"bytes_sent\\\":%O,\\\"time_elapsed\\\":%D,\\\"country\\\":\\\"%{COUNTRY_CODE}e\\\",\\\"city\\\":\\\"%{CITY}e\\\",\\\"lat\\\":\\\"%{LATITUDE}e\\\",\\\"lon\\\":\\\"%{LONGITUDE}e\\\",\\\"reputation\\\":\\\"%{REPUTATION0}e,%{REPUTATION1}e,%{REPUTATION2}e,%{REPUTATION3}e,%{REPUTATION4}e\\\",\\\"owasp_top10\\\":\\\"%{owasp_top10}e\\\",\\\"reasons\\\":\\\"%{reasons}e\\\",\\\"threshold\\\":\\\"%{threshold}e\\\",\\\"score\\\":\\\"%{score}e\\\"}"
            elif isinstance(repo, ElasticSearchRepository):
                return "@cee:{\\\"app_name\\\":\\\"%{app_name}e\\\",\\\"src_ip\\\":\\\"%a\\\",\\\"user\\\":\\\"%u\\\",\\\"time\\\":\\\"%{%Y-%m-%dT%H:%M:%S%z}t\\\",\\\"http_method\\\":\\\"%m\\\",\\\"requested_uri\\\":\\\"%U%q\\\",\\\"http_code\\\":%>s,\\\"incoming_protocol\\\":\\\"%H\\\",\\\"referer\\\":\\\"%{Referer}i\\\",\\\"user_agent\\\":\\\"%{User-agent}i\\\",\\\"size\\\":%B,\\\"bytes_received\\\":%I,\\\"bytes_sent\\\":%O,\\\"time_elapsed\\\":%D,\\\"country\\\":\\\"%{COUNTRY_CODE}e\\\",\\\"city\\\":\\\"%{CITY}e\\\",\\\"lat\\\":\\\"%{LATITUDE}e\\\",\\\"lon\\\":\\\"%{LONGITUDE}e\\\",\\\"reputation\\\":\\\"%{REPUTATION0}e,%{REPUTATION1}e,%{REPUTATION2}e,%{REPUTATION3}e,%{REPUTATION4}e\\\",\\\"owasp_top10\\\":\\\"%{owasp_top10}e\\\",\\\"reasons\\\":\\\"%{reasons}e\\\",\\\"threshold\\\":\\\"%{threshold}e\\\",\\\"score\\\":\\\"%{score}e\\\"}"

        separators = {
            'space': ' ',
            'tab': '\t',
            'comma': ',',
            'semicolon': ';',
            'underscore': '_',
            'minus': '-'
        }
        sep = separators.get(self.separator, ' ')

        ret = ""
        for s in self.format.split(','):
            s = s.replace('%r', '\\"%r\\"')
            s = s.replace('%{Referer}i', '\\"%{Referer}i\\"')
            s = s.replace('%{User-agent}i', '\\"%{User-agent}i\\"')
            s = s.replace('%{app_name}e', '\\"%{app_name}e\\"')
            ret = ret + s + sep
        return ret[:-1]
    def delete(self, request, repo_id, login=""):
        try:
            assert login, "Login missing."
            repo = BaseAbstractRepository.search_repository(repo_id)
            assert repo, "Authentication repository not found with id '{}'".format(repo_id)
            assert repo.repo_type == "auth", "Repository with id '{}' type is not authentication".format(repo_id)
            backend = repo.get_backend()
        except AssertionError as e:
            logger.error("RepositoriesAPI::POST: {}".format(e))
            return JsonResponse({'status': False,
                                 'error': str(e)})

        try:
            # First check if that user is in repository
            if not self.check_user_exists(backend, login):
                return JsonResponse({'status': False, 'error': "User '{}' does not exists in repository "
                                                               "'{}'".format(login, repo.repo_name)})
            request_data = request.POST or request.JSON
            if not request_data.get('confirm'):
                return JsonResponse({'status': False, 'error': "Please send confirm=true to delete "
                                                               "user {}.".format(login)})

            backend.delete_user(login)

            return JsonResponse({
                'status': True
            })

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

            return JsonResponse({
                'status': False,
                'error': str(e)
            })
 def setAutologonPassword(self, app_id, app_name, backend_id, username,
                          old_password, new_password):
     result = None
     # SECURITY : Verify if the old password is correct !
     if self.getAutologonPassword(app_id, backend_id,
                                  username) == old_password:
         # Update password
         pwd = SSOProfile()
         p = pwd.set_data(
             str(app_id), app_name, str(backend_id),
             BaseAbstractRepository.search_repository(backend_id).repo_name,
             username, 'vlt_autologon_password', new_password)
         if p:
             self.keys['password_' + str(backend_id)] = p
             result = self.handler.hset(self.key,
                                        'password_' + str(backend_id), p)
         else:
             logger.info(
                 "REDISPortalSession::setAutologonPassword: Unable to encrypt password "
             )
     else:
         logger.info(
             "REDISPortalSession::setAutologonPassword: Wrong old_password : cannot set the new one"
         )
     return result
    def get(self, request, repo_id, login=""):
        """ Retrieve authentication repository with its id, and return informations from asked user """
        try:
            assert login, "Login missing."
            repo = BaseAbstractRepository.search_repository(repo_id)
            assert repo, "Authentication repository not found with id '{}'".format(repo_id)
            assert repo.repo_type == "auth", "Repository with id '{}' type is not authentication".format(repo_id)
        except AssertionError as e:
            logger.error("RepositoriesAPI::GET: {}".format(e))
            return JsonResponse({'status': False,
                                 'error': str(e)})
        try:
            user_infos = repo.get_backend().get_user_infos(login)

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

        except NotImplementedError:
            return JsonResponse({'status': False,
                                 'error': "Get user informations on this type of repository is not supported yet."})

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

            return JsonResponse({
                'status': False,
                'error': str(e)
            })
def profile_list(request):
    """ Page dedicated to show application list
    """
    # Retrieve unicity of (app_id, repo_id, login)
    profile_list = list(
        SSOProfile.objects.aggregate(
            {
                "$group": {
                    "_id": {
                        "login": "******",
                        "app_id": "$app_id",
                        "repo_id": "$repo_id"
                    }
                }
            }, {
                "$project": {
                    "_id": 0,
                    "login": "******",
                    "app_id": "$_id.app_id",
                    "login": "******",
                    "repo_id": "$_id.repo_id"
                }
            }))
    for profile in profile_list:
        profile['app_name'] = Application.objects.get(
            id=ObjectId(profile['app_id'])).name
        profile['repo_name'] = BaseAbstractRepository.search_repository(
            profile['repo_id']).repo_name

    return render_to_response('sso_profiles.html', {'profiles': profile_list},
                              context_instance=RequestContext(request))
Example #6
0
    def repository(self):
        """ Property used to map repository field to Repository Object

        :return:
        """
        if self.repository_type == 'data':
            return BaseAbstractRepository.search_repository(
                self.data_repository)
        return self.repository_type
Example #7
0
    def repository(self):
        """ Property used to map repository field to Repository Object

        :return:
        """
        if self.repository_type == 'data':
            from gui.models.repository_settings import BaseAbstractRepository
            return BaseAbstractRepository.search_repository(self.data_repository)
        return self.repository_type
    def post(self, request, repo_id, login=""):
        try:
            assert login, "Login missing."
            repo = BaseAbstractRepository.search_repository(repo_id)
            assert repo, "Authentication repository not found with id '{}'".format(repo_id)
            assert repo.repo_type == "auth", "Repository with id '{}' type is not authentication".format(repo_id)
            backend = repo.get_backend()
        except AssertionError as e:
            logger.error("RepositoriesAPI::POST: {}".format(e))
            return JsonResponse({'status': False,
                                 'error': str(e)})

        try:
            # First check if that user is in repository
            if self.check_user_exists(backend, login):
                return JsonResponse({'status': False, 'error': "User '{}' already exists in repository "
                                                               "'{}'".format(login, repo.repo_name)})

            # Check if fields are correctly filled-in
            request_data = request.POST or (request.JSON if hasattr(request, "JSON") else dict())

            password = request_data.get('password')
            if not password:
                return JsonResponse({'status': False, 'error': "Password missing in POST data."})

            login = login
            password = password
            email = request_data.get('email', "")
            phone = request_data.get('phone', "")

            kwargs = {}
            if isinstance(repo, LDAPRepository):
                group = request_data.get('group')
                update_group = request_data.get('update_group')
                if not group:
                    return JsonResponse({'status': False, 'error': "Group is missing for adding user into LDAP repository."})
                else:
                    group = group
                kwargs['group'] = group
                kwargs['update_group'] = update_group

            backend.add_new_user(login, password, email, phone, **kwargs)

            return JsonResponse({
                'status': True
            })

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

            return JsonResponse({
                'status': False,
                'error': str(e)
            })
    def put(self, request, repo_id, login=""):
        try:
            assert login, "Login missing."
            repo = BaseAbstractRepository.search_repository(repo_id)
            assert repo, "Authentication repository not found with id '{}'".format(repo_id)
            assert repo.repo_type == "auth", "Repository with id '{}' type is not authentication".format(repo_id)
            backend = repo.get_backend()
        except AssertionError as e:
            logger.error("RepositoriesAPI::POST: {}".format(e))
            return JsonResponse({'status': False,
                                 'error': str(e)})

        try:
            # First check if that user is in repository
            if not self.check_user_exists(backend, login):
                return JsonResponse({'status': False, 'error': "User '{}' does not exists in repository "
                                                               "'{}'".format(login, repo.repo_name)})

            # Check if fields are correctly filled-in
            request_data = request.POST or request.JSON

            login = login
            email = request_data.get('email')
            phone = request_data.get('phone')
            password = request_data.get('password')
            if not email and not phone and not password:
                return JsonResponse({'status': False, 'error': "Password, Email and Phone missing in POST data. "
                                                               "Nothing to do."})
            if email:
                email = email
            if phone:
                phone = phone
            if email or phone:
                backend.update_user(login, email=email, phone=phone)

            if password:
                password = password
                backend.change_password(login, "", password)

            return JsonResponse({
                'status': True
            })

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

            return JsonResponse({
                'status': False,
                'error': str(e)
            })
    def register_authentication(self, app_id, app_name, backend_id, url,
                                dbauthentication_required, username, password,
                                oauth2_token, app_token, authentication_datas,
                                timeout):
        if dbauthentication_required:
            self.keys[backend_id] = 0
        else:
            self.keys[backend_id] = 1
        self.keys['url_' + app_id] = url
        self.keys['backend_' + app_id] = backend_id
        self.keys['login_' + backend_id] = username
        if oauth2_token:
            self.keys['oauth2_' + backend_id] = oauth2_token
        self.keys['app_id_' + backend_id] = app_id
        """ Make the link with precedent portal session to get the list of application cookies """
        try:
            tmp = literal_eval(self.keys['app_list'])
            tmp.append(app_token)
            self.keys['app_list'] = str(tmp)
        except Exception as e:
            self.keys['app_list'] = str([app_token])

        # WARNING : THE KEYS ARE NOT INITIALIZED ANYMORE !
        # self.keys['otp']        = None
        # self.keys['authy_id']   = None
        # self.keys['user_phone'] = None
        # self.keys['user_mail']  = None
        """ Try to retrieve user phone from authentication_results """
        self.keys['user_phone'] = authentication_datas.get('user_phone', 'N/A')

        self.keys['user_email'] = authentication_datas.get('user_email', 'N/A')

        if password:
            # Encrypt the password with the application id and user login and store it in portal session
            pwd = SSOProfile()
            p = pwd.set_data(
                app_id, app_name, backend_id,
                BaseAbstractRepository.search_repository(backend_id).repo_name,
                username, 'vlt_autologon_password', password)
            self.keys['password_' + backend_id] = p

        if not self.write_in_redis(timeout or self.default_timeout):
            raise REDISWriteError(
                "REDISPortalSession::register_authentication: Unable to write authentication infos in REDIS"
            )

        return self.key
Example #11
0
    def authenticate(self, user_id, key, **kwargs):
        totp = TOTP(user_id)
        if not totp.verify(key):
            raise AuthenticationError("TOTP taped token is not valid.")

        logger.info(
            "TOTP Token for user {} successfully verified.".format(user_id))

        # If the SSOProfile is not yet in MongoDB, set-it
        app_id = kwargs['app']
        app_name = kwargs['app_name']
        backend_id = kwargs['backend']
        login = kwargs['login']

        try:
            aes = AESCipher("{}{}{}{}{}".format(SECRET_KEY, app_id, backend_id,
                                                login, "totp"))
            encrypted_field = aes.key.hex()
            sso_profile = SSOProfile.objects.filter(
                encrypted_name=encrypted_field, login=login).first()
            if sso_profile:
                decrypted_value = sso_profile.get_data(
                    sso_profile.encrypted_value, app_id, backend_id, login,
                    "totp")
                if decrypted_value:
                    logger.debug(
                        "TOTP token for user '{}' retrieven from database.".
                        format(login))
                    return True

            # SSOProfile not found -> Create it
            sso_profile = SSOProfile()
            sso_profile.set_data(
                app_id, app_name, backend_id,
                BaseAbstractRepository.search_repository(
                    ObjectId(backend_id)).repo_name, login, "totp", user_id)
            logger.info(
                "TOTP token for user {} stored in database.".format(login))
            # Save in Mongo
            sso_profile.store()
        except Exception as e:
            logger.exception(e)
            raise e

        return True
Example #12
0
    def repository(self):
        """ Property used to map repository field to Repository Object

        :return:
        """
        return BaseAbstractRepository.search_repository(self.logs_repository)
Example #13
0
    def __init__(self, *args, **kwargs):
        try:
            self.listeners = kwargs.pop('listeners')
        except KeyError:
            pass

        super(ApplicationForm, self).__init__(*args, **kwargs)

        self = bootstrap_tooltips(self)
        repo_lst = BaseAbstractRepository.get_auth_repositories()
        auth_repo_lst = list()
        for rep in repo_lst:
            auth_repo_lst.append((
                ObjectId(rep.id),
                rep.repo_name,
            ))

        mod_sec_choices = list()
        for rule in ModSecRulesSet.objects(type_rule__nin=('wlbl', )):
            mod_sec_choices.append((ObjectId(rule.id), rule.name))

        dataset_list = list()
        dataset_list.append(((None), "------------------------------"))
        for dataset in Dataset.objects(svm_built=True).only('name', 'id'):
            dataset_list.append((ObjectId(dataset.id), dataset.name))

        client_certificate = [('', '---------')]
        for cert in SSLCertificate.objects(is_trusted_ca__ne=True).only(
                'id', 'cn'):
            client_certificate.append(("%sSSLProxyCertificateFile-%s.txt" %
                                       (settings.CONF_DIR, cert.id), cert.cn))

        COOCKIE_CIPHER = (
            ('rc4', 'RC4 (128 bits)'),
            ('aes128', 'AES 128 (128 bits)'),
            ('aes256', 'AES 256 (256 bits)'),
        )

        IP_REPUTATION = []
        loganalyser_rules = Cluster.objects.get(
        ).system_settings.loganalyser_settings.loganalyser_rules
        for rule in loganalyser_rules:
            tags = rule.tags.split(',')

            for tag in tags:
                IP_REPUTATION.append((tag, tag.capitalize()))

        GEOIP = []
        for tag in [
                "AF", "AX", "AL", "DZ", "AS", "AD", "AO", "AI", "AQ", "AG",
                "AR", "AM", "AW", "AU", "AT", "AZ", "BS", "BH", "BD", "BB",
                "BY", "BE", "BZ", "BJ", "BM", "BT", "BO", "BQ", "BA", "BW",
                "BV", "BR", "IO", "BN", "BG", "BF", "BI", "KH", "CM", "CA",
                "CV", "KY", "CF", "TD", "CL", "CN", "CX", "CC", "CO", "KM",
                "CG", "CD", "CK", "CR", "CI", "HR", "CU", "CW", "CY", "CZ",
                "DK", "DJ", "DM", "DO", "EC", "EG", "SV", "GQ", "ER", "EE",
                "ET", "FK", "FO", "FJ", "FI", "FR", "GF", "PF", "TF", "GA",
                "GM", "GE", "DE", "GH", "GI", "GR", "GL", "GD", "GP", "GU",
                "GT", "GG", "GN", "GW", "GY", "HT", "HM", "VA", "HN", "HK",
                "HU", "IS", "IN", "ID", "IR", "IQ", "IE", "IM", "IL", "IT",
                "JM", "JP", "JE", "JO", "KZ", "KE", "KI", "KP", "KR", "KW",
                "KG", "LA", "LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU",
                "MO", "MK", "MG", "MW", "MY", "MV", "ML", "MT", "MH", "MQ",
                "MR", "MU", "YT", "MX", "FM", "MD", "MC", "MN", "ME", "MS",
                "MA", "MZ", "MM", "NA", "NR", "NP", "NL", "NC", "NZ", "NI",
                "NE", "NG", "NU", "NF", "MP", "NO", "OM", "PK", "PW", "PS",
                "PA", "PG", "PY", "PE", "PH", "PN", "PL", "PT", "PR", "QA",
                "RE", "RO", "RU", "RW", "BL", "SH", "KN", "LC", "MF", "PM",
                "VC", "WS", "SM", "ST", "SA", "SN", "RS", "SC", "SL", "SG",
                "SX", "SK", "SI", "SB", "SO", "ZA", "GS", "SS", "ES", "LK",
                "SD", "SR", "SJ", "SZ", "SE", "CH", "SY", "TW", "TJ", "TZ",
                "TH", "TL", "TG", "TK", "TO", "TT", "TN", "TR", "TM", "TC",
                "TV", "UG", "UA", "AE", "GB", "US", "UM", "UY", "UZ", "VU",
                "VE", "VN", "VG", "VI", "WF", "EH", "YE", "ZM", "ZW"
        ]:
            GEOIP.append((tag, tag))

        self.fields['block_reputation'] = MultipleChoiceField(
            required=False,
            choices=set(IP_REPUTATION),
            widget=SelectMultiple(attrs={'class': 'form-control select2'}))
        self.fields['block_geoip'] = MultipleChoiceField(
            required=False,
            choices=set(GEOIP),
            widget=SelectMultiple(attrs={'class': 'form-control select2'}))
        self.fields['allow_geoip'] = MultipleChoiceField(
            required=False,
            choices=set(GEOIP),
            widget=SelectMultiple(attrs={'class': 'form-control select2'}))

        self.fields['template'].queryset = portalTemplate.objects.filter()
        self.fields['auth_backend'] = ChoiceField(
            choices=auth_repo_lst,
            required=False,
            widget=Select(attrs={'class': 'form-control'}))
        self.fields['auth_backend_fallbacks'] = MultipleChoiceField(
            choices=auth_repo_lst,
            required=False,
            widget=SelectMultiple(attrs={'class': 'form-control select2'}))
        self.fields['redirect_uri'] = CharField(
            required=False,
            widget=Textarea(attrs={
                'cols': 80,
                'rows': 1,
                'class': 'form-control'
            }))
        self.fields['sso_capture_content'] = CharField(
            required=False,
            widget=Textarea(attrs={
                'cols': 80,
                'rows': 2,
                'class': 'form-control'
            }))
        self.fields['sso_replace_pattern'] = CharField(
            required=False,
            widget=Textarea(attrs={
                'cols': 40,
                'rows': 2,
                'class': 'form-control'
            }))
        self.fields['sso_replace_content'] = CharField(
            required=False,
            widget=Textarea(attrs={
                'cols': 40,
                'rows': 2,
                'class': 'form-control'
            }))
        self.fields['sso_after_post_request'] = CharField(
            required=False,
            widget=Textarea(attrs={
                'cols': 80,
                'rows': 2,
                'class': 'form-control'
            }))
        self.fields['rules_set'] = MultipleChoiceField(
            choices=mod_sec_choices,
            required=False,
            widget=SelectMultiple(attrs={'class': 'form-control'}))
        self.fields['datasets'] = ChoiceField(
            choices=dataset_list,
            required=False,
            widget=Select(attrs={'class': 'form-control'}))
        self.fields['ssl_protocol'] = ChoiceField(
            choices=SSL_PROTOCOLS,
            required=False,
            widget=Select(attrs={'class': 'form-control'}))
        self.fields['ssl_client_certificate'] = ChoiceField(
            choices=client_certificate,
            required=False,
            widget=Select(attrs={'class': 'form-control'}))

        self.fields['custom_vhost'] = CharField(
            required=False,
            widget=Textarea(attrs={
                'cols': 80,
                'rows': 15,
                'class': 'form-control'
            }))
        self.fields['custom_location'] = CharField(
            required=False,
            widget=Textarea(attrs={
                'cols': 80,
                'rows': 15,
                'class': 'form-control'
            }))
        self.fields['custom_proxy'] = CharField(
            required=False,
            widget=Textarea(attrs={
                'cols': 80,
                'rows': 15,
                'class': 'form-control'
            }))

        self.fields['cookie_cipher'] = ChoiceField(
            choices=COOCKIE_CIPHER,
            required=False,
            widget=Select(attrs={'class': 'form-control'}))

        if self.initial.get("auth_backend"):
            repo = BaseAbstractRepository.search_repository(
                self.initial.get('auth_backend'))
            if isinstance(repo, LDAPRepository):
                try:
                    groups = [(x, x)
                              for x in repo.get_backend().enumerate_groups()]
                except:
                    groups = []
                finally:
                    self.fields['group_registration'] = ChoiceField(
                        choices=groups,
                        required=False,
                        widget=Select(attrs={'class': 'form-control'}))
Example #14
0
 def stock_sso_field(self, username, field, value):
     try:
         sso_profile = self.retrieve_sso_profile(username, field)
         if not sso_profile:
             raise Exception("Cannot retrieve sso profile")
     except Exception as e:
         logger.debug("Cannot retrieve sso profile '{}' for user '{}' : {}".format(field, username, e))
         try:
             sso_profile = SSOProfile()
             sso_profile.set_data(str(self.application.id), self.application.name, str(self.backend_id), BaseAbstractRepository.search_repository(self.backend_id).repo_name, str(username), str(field), str(value))
             sso_profile.store()
         except Exception as e:
             logger.error("SSOForward::stock_sso_field: Unable to store SSO Profile (field={},username={}) : {}".format(field, username, str(e)))
             logger.exception(e)