Beispiel #1
0
def get_config():
    """
    Get the CRIPTs configuration.

    :returns: :class:`cripts.config.config.CRIPTsConfig`
    """

    cripts_config = CRIPTsConfig.objects().first()
    if not cripts_config:
        cripts_config = CRIPTsConfig()
        cripts_config.save()
    return cripts_config
Beispiel #2
0
def get_config():
    """
    Get the CRIPTs configuration.

    :returns: :class:`cripts.config.config.CRIPTsConfig`
    """

    cripts_config = CRIPTsConfig.objects().first()
    if not cripts_config:
        cripts_config = CRIPTsConfig()
        cripts_config.save()
    return cripts_config
Beispiel #3
0
def clean_db():
    """
    Clean up the DB after testing.
    """

    src = SourceAccess.objects(name=TSRC).first()
    if src:
        src.delete()
    user = CRIPTsUser.objects(username=TUSER_NAME).first()
    if user:
        user.delete()
    TestObject.drop_collection()
    TestSourceObject.drop_collection()
    CRIPTsConfig.drop_collection()
Beispiel #4
0
def clean_db():
    """
    Clean up the DB after testing.
    """

    src = SourceAccess.objects(name=TSRC).first()
    if src:
        src.delete()
    user = CRIPTsUser.objects(username=TUSER_NAME).first()
    if user:
        user.delete()
    TestObject.drop_collection()
    TestSourceObject.drop_collection()
    CRIPTsConfig.drop_collection()
Beispiel #5
0
    def __init__(self, username=None, email=None):
        """
        Set the default subject, body, from address, and other bits.
        """

        # set the user and email address to send to
        self.username = username
        self.email = email

        # grab the CRIPTs url to use for links
        cripts_config = CRIPTsConfig.objects().first()
        self.instance_url = cripts_config.instance_url
        if self.instance_url.endswith("/"):
            self.instance_url = self.instance_url[:-1]

        # set the email address to send this email from
        self.from_address = cripts_config.cripts_email

        # setup the email subject
        if cripts_config.cripts_email_end_tag:
            self.subject = "CRIPTs: Subscriptions and Notifications" + cripts_config.cripts_email_subject_tag
        else:
            self.subject = cripts_config.cripts_email_subject_tag + "CRIPTs: Subscriptions and Notifications"

        # start the body of the email
        comments_url = self.instance_url + reverse('cripts.comments.views.activity')
        self.body = "Here's info on the latest comments and updates to CRIPTs that you are subscribed to!\n\n"
        self.body += "For more info, check out the Activity page: %s\n\n" % comments_url
Beispiel #6
0
def upgrade(lv, options):
    """
    Perform the upgrade.

    :param lv: The CRIPTs version we are running.
    :type lv: str
    :param options: The options passed in for what to upgrade.
    :type options: dict
    """

    # eventually we will do something to check to see what the current version
    # of the CRIPTs DB is so we can upgrade through several versions at once.
    # this is important if prep scripts need to be run for certain upgrades
    # to work properly.
    mall = options.get('mall')
    events = options.get('events')
    skip = options.get('skip')

    # run prep migrations
    if not skip:
        prep_database()

    # run full migrations
    if mall or events:
        migrate_collection(Event, sort_ids)

    # Always bump the version to the latest in settings.py
    config = CRIPTsConfig.objects()
    if len(config) > 1:
        print "You have more than one config object. This is really bad."
    else:
        config = config[0]
        config.cripts_version = settings.CRIPTS_VERSION
        config.save()
Beispiel #7
0
    def reset_password(self, rcode, new_p, new_p_c, analyst):
        """
        Reset the user's password. Validate the reset code, ensure the two
        passwords are identical, and then set.

        :param rcode: Reset Code to validate.
        :type rcode: str
        :param new_p: New password.
        :type new_p: str
        :param new_p_c: New password confirmation.
        :type new_p_c: str
        :param analyst: The user.
        :type analyst: str
        :returns: dict with keys "success" (boolean) and "message" (str).
        """

        if self.validate_reset_code(rcode, analyst)['success']:
            if new_p == new_p_c:
                self.password_reset.reset_code = ""
                if self.set_password(new_p):
                    return {'success': True, 'message': 'Password reset.'}
                else:
                    cripts_config = CRIPTsConfig.objects().first()
                    if cripts_config:
                        pw_desc = cripts_config.password_complexity_desc
                    else:
                        pw_desc = settings.PASSWORD_COMPLEXITY_DESC
                    message = 'Password not complex enough: %s' % pw_desc
                    return {'success': False, 'message': message}
            else:
                return {'success': False, 'message': 'Passwords do not match.'}
        else:
            self.password_reset.reset_code = ""
            self.save(username=analyst)
            return {'success': False, 'message': 'Reset Code Expired.'}
Beispiel #8
0
    def __init__(self, username=None, email=None):
        """
        Set the default subject, body, from address, and other bits.
        """

        # set the user and email address to send to
        self.username = username
        self.email = email

        # grab the CRIPTs url to use for links
        cripts_config = CRIPTsConfig.objects().first()
        self.instance_url = cripts_config.instance_url
        if self.instance_url.endswith("/"):
            self.instance_url = self.instance_url[:-1]

        # set the email address to send this email from
        self.from_address = cripts_config.cripts_email

        # setup the email subject
        if cripts_config.cripts_email_end_tag:
            self.subject = "CRIPTs: Subscriptions and Notifications" + cripts_config.cripts_email_subject_tag
        else:
            self.subject = cripts_config.cripts_email_subject_tag + "CRIPTs: Subscriptions and Notifications"

        # start the body of the email
        comments_url = self.instance_url + reverse(
            'cripts.comments.views.activity')
        self.body = "Here's info on the latest comments and updates to CRIPTs that you are subscribed to!\n\n"
        self.body += "For more info, check out the Activity page: %s\n\n" % comments_url
Beispiel #9
0
    def reset_password(self, rcode, new_p, new_p_c, analyst):
        """
        Reset the user's password. Validate the reset code, ensure the two
        passwords are identical, and then set.

        :param rcode: Reset Code to validate.
        :type rcode: str
        :param new_p: New password.
        :type new_p: str
        :param new_p_c: New password confirmation.
        :type new_p_c: str
        :param analyst: The user.
        :type analyst: str
        :returns: dict with keys "success" (boolean) and "message" (str).
        """

        if self.validate_reset_code(rcode, analyst)['success']:
            if new_p == new_p_c:
                self.password_reset.reset_code = ""
                if self.set_password(new_p):
                    return {'success': True, 'message': 'Password reset.'}
                else:
                    cripts_config = CRIPTsConfig.objects().first()
                    if cripts_config:
                        pw_desc = cripts_config.password_complexity_desc
                    else:
                        pw_desc = settings.PASSWORD_COMPLEXITY_DESC
                    message = 'Password not complex enough: %s' % pw_desc
                    return {'success': False, 'message': message}
            else:
                return {'success': False, 'message': 'Passwords do not match.'}
        else:
            self.password_reset.reset_code = ""
            self.save(username=analyst)
            return {'success': False, 'message': 'Reset Code Expired.'}
Beispiel #10
0
    def authenticate(self,
                     username,
                     password=None,
                     user_agent=None,
                     remote_addr=None,
                     accept_language=None,
                     totp_enabled='Disabled'):
        """
        Perform the authentication of the user.

        :param username: The user to authenticate.
        :type username: str
        :param password: The password provided to authenticate with.
        :type password: str
        :param user_agent: The user-agent in the request.
        :type user_agent: str
        :param remote_addr: The hostname/ip in the request.
        :type remote_addr: str
        :param accept_language: The Accept Language in the request.
        :type accept_language: str
        :param totp_enabled: If TOTP is enabled and should be checked as well.
        :type totp_enabled: str
        :returns: :class:`cripts.core.user.CRIPTsUser`, None
        """

        e = EmbeddedLoginAttempt()
        e.user_agent = user_agent
        e.remote_addr = remote_addr
        e.accept_language = accept_language
        if not username:
            logger.warn("No username passed to CRIPTsRemoteUserBackend (auth)")
            return None
        config = CRIPTsConfig.objects().first()
        user = None
        username = self.clean_username(username)
        user = CRIPTsUser.objects(username=username).first()
        if user and user.is_active:
            if self._exceeded_login_threshold(user):
                return None

            # Log in user
            self._successful_settings(user, e, totp_enabled)
            if config.ldap_update_on_login:
                user.update_from_ldap("Auto LDAP update", config)
            return user
        elif not user and config.create_unknown_user:
            # Create the user
            user = CRIPTsUser.create_user(username=username, password=None)
            user.sources.append(config.company_name)
            # Attempt to update info from LDAP
            user.update_from_ldap("Auto LDAP update", config)
            user = self._successful_settings(user, e, totp_enabled)
            return user
        else:
            logger.warn("Unknown user and not creating accounts.")
            return None
Beispiel #11
0
def create_config_if_not_exist():
    """
    If the CRIPTsConfig already exists then the CRIPTsConfig is returned,
    otherwise a new CRIPTsConfig will be created, saved, and returned.

    Returns:
        Returns the CRIPTsConfig if it already exists, otherwise a
        default CRIPTsConfig is returned.
    """

    cripts_config = CRIPTsConfig.objects().first()
    if not cripts_config:
        print "Creating a new CRIPTs configuration."
        cripts_config = CRIPTsConfig()
        cripts_config.save()
    else:
        print "A CRPTs configuration already exists. Skipping default creation."

    return cripts_config
Beispiel #12
0
    def email_user(self, subject, message, from_email=None):
        """
        Sends an e-mail to this User.
        """

        from django.core.mail import send_mail
        if not from_email:
            cripts_config = CRIPTsConfig.objects().first()
            if cripts_config:
                from_email = cripts_config.cripts_email
        send_mail(subject, message, from_email, [self.email])
Beispiel #13
0
    def email_user(self, subject, message, from_email=None):
        """
        Sends an e-mail to this User.
        """

        from django.core.mail import send_mail
        if not from_email:
            cripts_config = CRIPTsConfig.objects().first()
            if cripts_config:
                from_email = cripts_config.cripts_email
        send_mail(subject, message, from_email, [self.email])
Beispiel #14
0
    def authenticate(self, username, password=None, user_agent=None,
                     remote_addr=None, accept_language=None,
                     totp_enabled='Disabled'):
        """
        Perform the authentication of the user.

        :param username: The user to authenticate.
        :type username: str
        :param password: The password provided to authenticate with.
        :type password: str
        :param user_agent: The user-agent in the request.
        :type user_agent: str
        :param remote_addr: The hostname/ip in the request.
        :type remote_addr: str
        :param accept_language: The Accept Language in the request.
        :type accept_language: str
        :param totp_enabled: If TOTP is enabled and should be checked as well.
        :type totp_enabled: str
        :returns: :class:`cripts.core.user.CRIPTsUser`, None
        """

        e = EmbeddedLoginAttempt()
        e.user_agent = user_agent
        e.remote_addr = remote_addr
        e.accept_language = accept_language
        if not username:
            logger.warn("No username passed to CRIPTsRemoteUserBackend (auth)")
            return None
        config = CRIPTsConfig.objects().first()
        user = None
        username = self.clean_username(username)
        user = CRIPTsUser.objects(username=username).first()
        if user and user.is_active:
            if self._exceeded_login_threshold(user):
                return None

            # Log in user
            self._successful_settings(user, e, totp_enabled)
            if config.ldap_update_on_login:
                user.update_from_ldap("Auto LDAP update", config)
            return user
        elif not user and config.create_unknown_user:
            # Create the user
            user = CRIPTsUser.create_user(username=username, password=None)
            user.sources.append(config.company_name)
            # Attempt to update info from LDAP
            user.update_from_ldap("Auto LDAP update", config)
            user = self._successful_settings(user, e, totp_enabled)
            return user
        else:
            logger.warn("Unknown user and not creating accounts.")
            return None
Beispiel #15
0
def prep_db():
    """
    Prep the DB for testing.
    """

    clean_db()
    # Create a new default config
    cripts_config = CRIPTsConfig()
    cripts_config.save()
    # Add Source
    handlers.add_new_source(TSRC, TRANDUSER)
    # Add User
    user = CRIPTsUser.create_user(
        username=TUSER_NAME,
        password=TUSER_PASS,
        email=TUSER_EMAIL,
    )
    user.first_name = TUSER_FNAME
    user.last_name = TUSER_LNAME
    user.save()
    # Add test source object
    obj = TestSourceObject()
    obj.name = TOBJS_NAME
    obj.value = TOBJS_VALUE
    obj.add_source(source=TSRC, analyst=TUSER_NAME)
    obj.save()
    # Add another with Different source
    obj = TestSourceObject()
    obj.name = TOBJS_NAME
    obj.value = TOBJS_VALUE
    obj.add_source(source=TUNKSRC, analyst=TRANDUSER)
    obj.save()
    # Add test non-source object
    obj = TestObject()
    obj.name = TOBJ_NAME
    obj.value = TOBJ_VALUE
    obj.save()
Beispiel #16
0
def prep_db():
    """
    Prep the DB for testing.
    """

    clean_db()
    # Create a new default config
    cripts_config = CRIPTsConfig()
    cripts_config.save()
    # Add Source
    handlers.add_new_source(TSRC, TRANDUSER)
    # Add User
    user = CRIPTsUser.create_user(username=TUSER_NAME,
                                 password=TUSER_PASS,
                                 email=TUSER_EMAIL,
                                 )
    user.first_name = TUSER_FNAME
    user.last_name = TUSER_LNAME
    user.save()
    # Add test source object
    obj = TestSourceObject()
    obj.name = TOBJS_NAME
    obj.value = TOBJS_VALUE
    obj.add_source(source=TSRC, analyst=TUSER_NAME)
    obj.save()
    # Add another with Different source
    obj = TestSourceObject()
    obj.name = TOBJS_NAME
    obj.value = TOBJS_VALUE
    obj.add_source(source=TUNKSRC, analyst=TRANDUSER)
    obj.save()
    # Add test non-source object
    obj = TestObject()
    obj.name = TOBJ_NAME
    obj.value = TOBJ_VALUE
    obj.save()
Beispiel #17
0
 def __init__(self, *args, **kwargs):
     cripts_config = CRIPTsConfig.objects().first()
     depth_max = getattr(cripts_config, 'depth_max', settings.DEPTH_MAX)
     total_max = getattr(cripts_config, 'total_max', settings.TOTAL_MAX)
     rel_max = getattr(cripts_config, 'rel_max', settings.REL_MAX)
     super(DownloadFileForm, self).__init__(*args, **kwargs)
     self.fields['objects'].choices = [('Dataset', 'Datasets'),
                                       ('EmailAddress', 'EmailAddresses'),
                                       ('Hash', 'Hashes'),
                                       ('Target', 'Targets'),
                                       ('UserName', 'UserNames')]
     self.fields['total_limit'].initial = total_max
     self.fields['rel_limit'].initial = rel_max
     self.fields['depth_limit'].help_text = self.fields['depth_limit'].help_text % depth_max
     self.fields['total_limit'].help_text = self.fields['total_limit'].help_text % total_max
     self.fields['rel_limit'].help_text = self.fields['rel_limit'].help_text % rel_max
Beispiel #18
0
def force_reset_config():
    """
    Resets the values for the CRIPTsConfig class by dropping the
    database collection and then saving a new default CRIPTsConfig.
    """

    print "Resetting CRIPTs configuration settings."
    CRIPTsConfig.drop_collection();

    cripts_config = CRIPTsConfig();
    cripts_config.save();
Beispiel #19
0
    def is_password_complex(self, password):
        """
        Based on the CRIPTsConfig, is the password provided complex enough to be
        used?

        :param password: The password to check for complexity.
        :type password: str
        :returns: True, False
        """

        cripts_config = CRIPTsConfig.objects().first()
        if cripts_config:
            pw_regex = cripts_config.password_complexity_regex
        else:
            pw_regex = settings.PASSWORD_COMPLEXITY_REGEX
        complex_regex = re.compile(pw_regex)
        if complex_regex.match(password):
            return True
        return False
Beispiel #20
0
    def is_password_complex(self, password):
        """
        Based on the CRIPTsConfig, is the password provided complex enough to be
        used?

        :param password: The password to check for complexity.
        :type password: str
        :returns: True, False
        """

        cripts_config = CRIPTsConfig.objects().first()
        if cripts_config:
            pw_regex = cripts_config.password_complexity_regex
        else:
            pw_regex = settings.PASSWORD_COMPLEXITY_REGEX
        complex_regex = re.compile(pw_regex)
        if complex_regex.match(password):
            return True
        return False
Beispiel #21
0
 def __init__(self, *args, **kwargs):
     cripts_config = CRIPTsConfig.objects().first()
     depth_max = getattr(cripts_config, 'depth_max', settings.DEPTH_MAX)
     total_max = getattr(cripts_config, 'total_max', settings.TOTAL_MAX)
     rel_max = getattr(cripts_config, 'rel_max', settings.REL_MAX)
     super(DownloadFileForm, self).__init__(*args, **kwargs)
     self.fields['objects'].choices = [('Dataset', 'Datasets'),
                                       ('EmailAddress', 'EmailAddresses'),
                                       ('Hash', 'Hashes'),
                                       ('Target', 'Targets'),
                                       ('UserName', 'UserNames')]
     self.fields['total_limit'].initial = total_max
     self.fields['rel_limit'].initial = rel_max
     self.fields['depth_limit'].help_text = self.fields[
         'depth_limit'].help_text % depth_max
     self.fields['total_limit'].help_text = self.fields[
         'total_limit'].help_text % total_max
     self.fields['rel_limit'].help_text = self.fields[
         'rel_limit'].help_text % rel_max
Beispiel #22
0
    def temp_password(self):
        """
        Temporary password must match the password complexity regex.
        If we don't have one in the DB use the one out of settings.
        """

        cripts_config = CRIPTsConfig.objects().first()
        if cripts_config:
            pw_regex = cripts_config.password_complexity_regex
        else:
            pw_regex = settings.PASSWORD_COMPLEXITY_REGEX
        rex = re.compile(pw_regex)
        chars = string.letters + string.digits + string.punctuation
        for i in xrange(20):
            passwd = ''
            while len(passwd) < 50:
                passwd += choice(chars)
                if rex.match(passwd):
                    return passwd
        raise CommandError("Unable to generate complex enough password.")
Beispiel #23
0
    def temp_password(self):
        """
        Temporary password must match the password complexity regex.
        If we don't have one in the DB use the one out of settings.
        """

        cripts_config = CRIPTsConfig.objects().first()
        if cripts_config:
            pw_regex = cripts_config.password_complexity_regex
        else:
            pw_regex = settings.PASSWORD_COMPLEXITY_REGEX
        rex = re.compile(pw_regex)
        chars = string.letters + string.digits + string.punctuation
        for i in xrange(20):
            passwd = ''
            while len(passwd) < 50:
                passwd += choice(chars)
                if rex.match(passwd):
                    return passwd
        raise CommandError("Unable to generate complex enough password.")
Beispiel #24
0
def cripts_config(request):
    """
    Generate the CRIPTs Configuration template.

    :param request: Django request object (Required)
    :type request: :class:`django.http.HttpRequest`
    :returns: :class:`django.http.HttpResponse`
    """

    cripts_config = CRIPTsConfig.objects().first()
    if cripts_config:
        cripts_config = cripts_config.to_dict()
        cripts_config['allowed_hosts'] = ", ".join(
            cripts_config['allowed_hosts'])
        cripts_config['service_dirs'] = ", ".join(
            cripts_config['service_dirs'])
        config_general_form = ConfigGeneralForm(initial=cripts_config)
        config_LDAP_form = ConfigLDAPForm(initial=cripts_config)
        config_security_form = ConfigSecurityForm(initial=cripts_config)
        config_logging_form = ConfigLoggingForm(initial=cripts_config)
        config_services_form = ConfigServicesForm(initial=cripts_config)
        config_download_form = ConfigDownloadForm(initial=cripts_config)
        config_CRIPTs_form = ConfigCriptsForm(initial=cripts_config)
    else:
        config_general_form = ConfigGeneralForm()
        config_LDAP_form = ConfigLDAPForm()
        config_security_form = ConfigSecurityForm()
        config_logging_form = ConfigLoggingForm()
        config_services_form = ConfigServicesForm()
        config_download_form = ConfigDownloadForm()
        config_CRIPTs_form = ConfigCriptsForm()
    return render_to_response(
        'config.html', {
            'config_general_form': config_general_form,
            'config_LDAP_form': config_LDAP_form,
            'config_security_form': config_security_form,
            'config_logging_form': config_logging_form,
            'config_services_form': config_services_form,
            'config_download_form': config_download_form,
            'config_CRIPTs_form': config_CRIPTs_form
        }, RequestContext(request))
Beispiel #25
0
def change_user_password(username, current_p, new_p, new_p_c):
    """
    Change the password for a user.

    :param username: The user to query for.
    :type username: str
    :param current_p: The user's current password.
    :type current_p: str
    :param new_p: The new password.
    :type new_p: str
    :param new_p_c: New password confirmation.
    :type new_p_c: str
    :returns: dict with keys "success" (boolean) and "message" (str) if failed.
    """

    if new_p != new_p_c:
        return {
            'success': False,
            'message': 'New password confirmation does not match.'
        }
    from cripts.core.user import CRIPTsUser
    username = str(username)
    user = CRIPTsUser.objects(username=username).first()
    if not user:
        return {'success': False, 'message': 'Unknown user.'}
    if not user.check_password(current_p):
        return {'success': False, 'message': 'Current password invalid.'}
    if user.set_password(new_p, username):
        return {'success': True, 'message': 'Password Change Successful.'}
    else:
        from cripts.config.config import CRIPTsConfig
        cripts_config = CRIPTsConfig.objects().first()
        if cripts_config:
            regex_desc = cripts_config.password_complexity_desc
        else:
            regex_desc = settings.PASSWORD_COMPLEXITY_DESC
        return {
            'success': False,
            'message': 'Password not complex enough: %s' % regex_desc
        }
Beispiel #26
0
def cripts_config(request):
    """
    Generate the CRIPTs Configuration template.

    :param request: Django request object (Required)
    :type request: :class:`django.http.HttpRequest`
    :returns: :class:`django.http.HttpResponse`
    """

    cripts_config = CRIPTsConfig.objects().first()
    if cripts_config:
        cripts_config = cripts_config.to_dict()
        cripts_config['allowed_hosts'] = ", ".join(cripts_config['allowed_hosts'])
        cripts_config['service_dirs'] = ", ".join(cripts_config['service_dirs'])
        config_general_form = ConfigGeneralForm(initial=cripts_config)
        config_LDAP_form = ConfigLDAPForm(initial=cripts_config)
        config_security_form = ConfigSecurityForm(initial=cripts_config)
        config_logging_form = ConfigLoggingForm(initial=cripts_config)
        config_services_form = ConfigServicesForm(initial=cripts_config)
        config_download_form = ConfigDownloadForm(initial=cripts_config)
        config_CRIPTs_form = ConfigCriptsForm(initial=cripts_config)
    else:
        config_general_form = ConfigGeneralForm()
        config_LDAP_form = ConfigLDAPForm()
        config_security_form = ConfigSecurityForm()
        config_logging_form = ConfigLoggingForm()
        config_services_form = ConfigServicesForm()
        config_download_form = ConfigDownloadForm()
        config_CRIPTs_form = ConfigCriptsForm()
    return render_to_response('config.html',
                              {'config_general_form': config_general_form,
                               'config_LDAP_form': config_LDAP_form,
                               'config_security_form': config_security_form,
                               'config_logging_form': config_logging_form,
                               'config_services_form': config_services_form,
                               'config_download_form': config_download_form,
                               'config_CRIPTs_form': config_CRIPTs_form},
                              RequestContext(request))
Beispiel #27
0
def modify_configuration(forms, analyst):
    """
    Modify the configuration with the submitted changes.

    :param config_form: The form data.
    :type config_form: dict
    :param analyst: The user making the modifications.
    :type analyst: str
    :returns: dict with key "message"
    """

    config = CRIPTsConfig.objects().first()
    if not config:
        config = CRIPTsConfig()

    data = None
    for form in forms:
        if not data:
            data = form.cleaned_data
        else:
            data.update(form.cleaned_data)

# data = config_form.cleaned_data
    allowed_hosts_list = data['allowed_hosts'].split(',')
    allowed_hosts = ()
    for allowed_host in allowed_hosts_list:
        allowed_hosts = allowed_hosts + (allowed_host.strip(), )
    data['allowed_hosts'] = allowed_hosts
    service_dirs_list = data['service_dirs'].split(',')
    service_dirs = ()
    for service_dir in service_dirs_list:
        service_dirs = service_dirs + (service_dir.strip(), )
    data['service_dirs'] = service_dirs
    config.merge(data, overwrite=True)
    try:
        config.save(username=analyst)
        return {'message': "Success!"}
    except Exception, e:
        return {'message': "Failure: %s" % e}
Beispiel #28
0
def change_user_password(username, current_p, new_p, new_p_c):
    """
    Change the password for a user.

    :param username: The user to query for.
    :type username: str
    :param current_p: The user's current password.
    :type current_p: str
    :param new_p: The new password.
    :type new_p: str
    :param new_p_c: New password confirmation.
    :type new_p_c: str
    :returns: dict with keys "success" (boolean) and "message" (str) if failed.
    """

    if new_p != new_p_c:
        return {"success": False, "message": "New password confirmation does not match."}
    from cripts.core.user import CRIPTsUser

    username = str(username)
    user = CRIPTsUser.objects(username=username).first()
    if not user:
        return {"success": False, "message": "Unknown user."}
    if not user.check_password(current_p):
        return {"success": False, "message": "Current password invalid."}
    if user.set_password(new_p, username):
        return {"success": True, "message": "Password Change Successful."}
    else:
        from cripts.config.config import CRIPTsConfig

        cripts_config = CRIPTsConfig.objects().first()
        if cripts_config:
            regex_desc = cripts_config.password_complexity_desc
        else:
            regex_desc = settings.PASSWORD_COMPLEXITY_DESC
        return {"success": False, "message": "Password not complex enough: %s" % regex_desc}
Beispiel #29
0
def update_database_version():

    c = CRIPTsConfig.objects().first()
    c.cripts_version = "0.1.0"
    c.save()
Beispiel #30
0
def create_zip(files, pw_protect=True):
    """
    Create a zip file. Creates a temporary directory to write files to on disk
    using :class:`tempfile`. Uses /usr/bin/zip as the zipping mechanism
    currently. Will password protect the zip file as a default. The password for
    the zip file defaults to "infected", but it can be changed in the config
    under zip7_password.

    :param files: The files to add to the zip file.
    :type files: list of files which are in the format of a list or tuple of
                 (<filename>, <data>).
    :param pw_protect: To password protect the zip file or not.
    :type pw_protect: boolean
    :returns: :class:`cripts.core.exceptions.ZipFileError`, str
    """

    dumpdir = ""
    try:
        # Zip can take data from stdin to compress, but
        # you can't define the filenames within the archive,
        # they show up as "-".  Therefore, we need to write
        # out the file, compress it and return the zip.
        # Save the sample as a file in a temp directory
        # NOTE: the following line was causing a "permission denied" exception.
        # Removed dir arg.
        from cripts.config.config import CRIPTsConfig
        cripts_config = CRIPTsConfig.objects().first()
        if cripts_config:
            zip7_password = cripts_config.zip7_password or 'hashed'
        else:
            zip7_password = settings.ZIP7_PASSWORD or 'hashed'
        dumpdir = tempfile.mkdtemp()  #dir=temproot
        #write out binary files
        for f in files:
            filename = f[0]
            file_data = f[1]

            # make sure our desired path doesn't already exist (some files may
            # have the same name but different data)
            path = dumpdir + "/" + filename.encode("utf-8")
            i = 1
            tmp = path
            while os.path.exists(tmp):
                tmp = path + "(" + str(i) + ")"
                i += 1

            with open(tmp, "wb") as fh:
                fh.write(file_data)

        # Build the command line for zip
        # NOTE: forking subprocess instead of using Python's ZipFile library
        # because ZipFile does not allow us to create password-protected zip
        # archives, only read them.
        # -j don't include original filepath
        zipname = "zip.zip"  #The name we give it doesn't really matter
        args = ["/usr/bin/zip", "-r", "-j", dumpdir + "/" + zipname, dumpdir]
        if pw_protect:
            args += ["-P", zip7_password]
        args += [dumpdir + "/" + zipname, dumpdir]

        proc = subprocess.Popen(args,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT)
        # Give the process 30 seconds to complete, otherwise kill it
        waitSeconds = 30
        while (proc.poll() is None and waitSeconds):
            time.sleep(1)
            waitSeconds -= 1

        zipdata = ""
        if proc.returncode:  # zip spit out an error
            errmsg = "Error while creating archive\n" + proc.stdout.read()
            raise ZipFileError, errmsg
        elif not waitSeconds:  # Process timed out
            proc.terminate()
            raise ZipFileError, "Error:\nProcess failed to terminate"
        else:
            with open(dumpdir + "/" + zipname, "rb") as fh:
                zipdata = fh.read()
        if not len(zipdata):
            raise ZipFileError, "Error:\nThe zip archive contains no data"
        return zipdata

    except ZipFileError:
        raise
    except Exception, ex:
        errmsg = ""
        for err in ex.args:
            errmsg = errmsg + " " + unicode(err)
        raise ZipFileError, errmsg
Beispiel #31
0
def update_database_version():

    c = CRIPTsConfig.objects().first()
    c.cripts_version = "0.1.0"
    c.save()
Beispiel #32
0
class Command(BaseCommand):
    """
    Script Class.
    """

    option_list = BaseCommand.option_list + (
        make_option('--adduser',
                    '-a',
                    dest='adduser',
                    action='store_true',
                    default=False,
                    help='Add a new user to CRIPTs.'),
        make_option('--administrator',
                    '-A',
                    dest='admin',
                    action='store_true',
                    default=False,
                    help='Make this user an administrator.'),
        make_option('--clearsecret',
                    '-c',
                    dest='clearsecret',
                    action='store_true',
                    default=False,
                    help="Clear a user's secret."),
        make_option('--deactivateuser',
                    '-d',
                    dest='deactivate',
                    action='store_true',
                    default=False,
                    help='Deactivate a user account.'),
        make_option('--email',
                    '-e',
                    dest='email',
                    default=None,
                    help='Email address of new user.'),
        make_option('--sendemail',
                    '-E',
                    dest='sendemail',
                    action='store_true',
                    default=False,
                    help='Email new user their temporary password.'),
        make_option('--firstname',
                    '-f',
                    dest='firstname',
                    default='',
                    help='First name of new user.'),
        make_option('--invalidreset',
                    '-i',
                    dest='invalidreset',
                    action='store_true',
                    default=False,
                    help="Reset a user's invalid login attempts to 0."),
        make_option('--lastname',
                    '-l',
                    dest='lastname',
                    default='',
                    help='Last name of new user.'),
        make_option('--organization',
                    '-o',
                    dest='organization',
                    default='',
                    help='Assign user to an organization/source.'),
        make_option('--reset',
                    '-r',
                    dest='reset',
                    action='store_true',
                    default=False,
                    help='Assign a new temporary password to a user.'),
        make_option('--setactive',
                    '-s',
                    dest='setactive',
                    action='store_true',
                    default=False,
                    help='Set a user account to active.'),
        make_option('--enabletotp',
                    '-t',
                    dest='enabletotp',
                    action='store_true',
                    default=False,
                    help='Enable TOTP for a user.'),
        make_option('--disabletotp',
                    '-T',
                    dest='disabletotp',
                    action='store_true',
                    default=False,
                    help='Disable TOTP for a user.'),
        make_option('--username',
                    '-u',
                    dest='username',
                    default=None,
                    help='Username for new user.'),
    )
    help = 'Add and edit a CRIPTs user. If "-a" is not used, we will try to edit.'

    def handle(self, *args, **options):
        """
        Script execution.
        """

        adduser = options.get('adduser')
        admin = options.get('admin')
        clearsecret = options.get('clearsecret')
        deactivate = options.get('deactivate')
        disabletotp = options.get('disabletotp')
        email = options.get('email')
        enabletotp = options.get('enabletotp')
        firstname = options.get('firstname')
        invalidreset = options.get('invalidreset')
        lastname = options.get('lastname')
        sendemail = options.get('sendemail')
        organization = options.get('organization')
        password = self.temp_password()
        reset = options.get('reset')
        setactive = options.get('setactive')
        username = options.get('username')

        # We always need a username
        if not username:
            raise CommandError("Must provide a username.")
        user = CRIPTsUser.objects(username=username).first()

        # If we've found a user with that username and we aren't trying to add a
        # new user...
        if user and not adduser:
            if admin:
                user.role = "Administrator"
            if clearsecret:
                user.secret = ""
            if deactivate and not setactive:
                user.is_active = False
            if disabletotp and not enabletotp:
                user.totp = False
            if email:
                user.email = email
            if enabletotp and not disabletotp:
                user.totp = True
            if firstname:
                user.first_name = firstname
            if lastname:
                user.last_name = lastname
            if invalidreset:
                user.invalid_login_attempts = 0
            if organization:
                user.organization = organization
            if reset:
                user.set_password(password)
            if setactive and not deactivate:
                user.is_active = True
            try:
                user.save()
                if reset:
                    print "New temporary password for %s: %s" % (username,
                                                                 password)
                print "User %s has been updated!" % username
            except Exception, e:
                raise CommandError("Error saving changes: %s" % str(e))
            if adduser:
                raise CommandError("User '%s' exists in CRIPTs!" % username)
        elif adduser:
            if not email:
                raise CommandError("Must provide an email address!")
            user = CRIPTsUser.create_user(username, password, email)
            user.first_name = firstname
            user.last_name = lastname
            user.is_staff = True
            user.save()
            user.organization = organization
            if admin:
                user.role = "Administrator"
            user.save()

            if sendemail:
                cripts_config = CRIPTsConfig.objects().first()
                if cripts_config.cripts_email_end_tag:
                    subject = "New CRIPTs User Account" + cripts_config.cripts_email_subject_tag
                else:
                    subject = cripts_config.cripts_email_subject_tag + "New CRIPTs User Account"
                body = """You are receiving this email because someone has created a
CRIPTs account for you. If you feel like you have received this in
error, please ignore this email. Your account information is below:\n\n
"""
                body += "Username:\t%s\n" % username
                body += "Password:\t%s\n\n\n" % password
                body += """You should log in immediately and reset your password.\n
Thank you!
"""
                user.email_user(subject, body)

            self.stdout.write("User '%s' created successfully!" % username)
            self.stdout.write("\nTemp password: \t%s" % password)
            self.stdout.write("\n")
Beispiel #33
0
    def authenticate(self, username=None, password=None, user_agent=None,
                     remote_addr=None, accept_language=None,
                     totp_enabled='Disabled'):
        """
        Perform the authentication of the user.

        :param username: The user to authenticate.
        :type username: str
        :param password: The password provided to authenticate with.
        :type password: str
        :param user_agent: The user-agent in the request.
        :type user_agent: str
        :param remote_addr: The hostname/ip in the request.
        :type remote_addr: str
        :param accept_language: The Accept Language in the request.
        :type accept_language: str
        :param totp_enabled: If TOTP is enabled and should be checked as well.
        :type totp_enabled: str
        :returns: :class:`cripts.core.user.CRIPTsUser`, None
        """

        # Need username and password for logins, checkem both
        if not all([username, password]):
            return None

        e = EmbeddedLoginAttempt()
        e.user_agent = user_agent
        e.remote_addr = remote_addr
        e.accept_language = accept_language
        fusername = username
        if '\\' in username:
            username = username.split("\\")[1]
        user = CRIPTsUser.objects(username=username).first()
        if user:
            # If the user needs TOTP and it is not disabled system-wide, and
            # the user has exceeded the login threshold for this time period
            # don't go any further. Track the invalid login and return.
            if (((user.totp and totp_enabled == 'Optional') or
                    totp_enabled == 'Required') and
                    self._exceeded_login_threshold(user)):
                e.success = False
                self.track_login_attempt(user, e)
                user.reload()
                return None
            config = CRIPTsConfig.objects().first()
            if not config:
                return None
            if config.ldap_auth:
                import ldap, ldapurl
                try:
                    # If you are using Oracle's server that's based on
                    # Netscape's code, and your users can't login after
                    # password expiration warning kicks in, you need:
                    # python-ldap 2.4.15 installed and
                    # import ldap.controls.pwdpolicy to fix it
                    #
                    import ldap.controls.pwdpolicy
                except ImportError:
                    logger.info("ldap.controls.pwdpolicy not present.")
                try:
                    # don't parse the port if there is one
                    ldap_server = config.ldap_server.split(':')
                    scheme = "ldap"
                    if config.ldap_tls:
                        scheme = "ldaps"
                    url = ldapurl.LDAPUrl('%s://%s' % (scheme, ldap_server[0]))
                    if len(ldap_server) == 2:
                        l = ldap.initialize('%s:%s' % (url.unparse(),
                                                       ldap_server[1]))
                    else:
                        l = ldap.initialize(url.unparse())
                    l.protocol_version = 3
                    l.set_option(ldap.OPT_REFERRALS, 0)
                    l.set_option(ldap.OPT_TIMEOUT, 10)
                    # two-step ldap binding
                    if len(config.ldap_bind_dn) > 0:
                    	try:
                    		logger.info("binding with bind_dn: %s" % config.ldap_bind_dn)
                    		l.simple_bind_s(config.ldap_bind_dn, config.ldap_bind_password)
                    		filter = '(|(cn='+fusername+')(uid='+fusername+')(mail='+fusername+'))'
                    		# use the retrieved dn for the second bind
                        	un = l.search_s(config.ldap_userdn,ldap.SCOPE_SUBTREE,filter,['dn'])[0][0]
                        except Exception as err:
            			#logger.error("Error binding to LDAP for: %s" % config.ldap_bind_dn)
            			logger.error("authenticate ERR: %s" % err)
                        l.unbind()
                        if len(ldap_server) == 2:
                            l = ldap.initialize('%s:%s' % (url.unparse(),
                                                           ldap_server[1]))
                        else:
                            l = ldap.initialize(url.unparse())
                        l.protocol_version = 3
                        l.set_option(ldap.OPT_REFERRALS, 0)
                        l.set_option(ldap.OPT_TIMEOUT, 10)
                    else:
                        un = fusername
                    # setup auth for custom cn's
                    if len(config.ldap_usercn) > 0:
                        un = "%s%s,%s" % (config.ldap_usercn,
                                          fusername,
                                          config.ldap_userdn)
                    elif "@" in config.ldap_userdn:
                        un = "%s%s" % (fusername, config.ldap_userdn)
                    logger.info("Logging in user: %s" % un)
                    l.simple_bind_s(un, password)
                    user = self._successful_settings(user, e, totp_enabled)
                    if config.ldap_update_on_login:
                        user.update_from_ldap("Auto LDAP update", config, password)
                    l.unbind()
                    return user
                except ldap.INVALID_CREDENTIALS:
                    l.unbind()
                    logger.info("Invalid LDAP credentials for: %s" % un)
                except Exception as err:
                    logger.info("LDAP Auth error: %s" % err)
            # If LDAP auth fails, attempt normal CRIPTs auth.
            # This will help with being able to use local admin accounts when
            # you have LDAP auth enabled.
            if password and user.check_password(password):
                self._successful_settings(user, e, totp_enabled)
                if config.ldap_update_on_login:
                    user.update_from_ldap("Auto LDAP update", config)
                return user
            else:
                e.success = False
                user.invalid_login_attempts += 1

            if user.is_active and user.invalid_login_attempts > settings.INVALID_LOGIN_ATTEMPTS:
                user.is_active = False
                logger.info("Account disabled due to too many invalid login attempts: %s" %
                            user.username)

                if config.cripts_email_end_tag:
                    subject = "CRIPTs Account Lockout" + config.cripts_email_subject_tag
                else:
                    subject = config.cripts_email_subject_tag + "CRIPTs Account Lockout"
                body = """

You are receiving this email because your CRIPTs account has been locked out due to
too many invalid login attempts.  If you did not perform this action,
someone may be attempting to access your account.

Please contact a site administrator to resolve.

"""
                try:
                    user.email_user(subject, body)
                except Exception, err:
                    logger.warning("Error sending email: %s" % str(err))
            self.track_login_attempt(user, e)
            user.reload()
Beispiel #34
0
    def info_from_ldap(self, config=None, password=''):
        """
        Get information about this user from LDAP.
        """

        import ldap, ldapurl
        resp = {"result": "ERROR"}
        if not config:
            config = CRIPTsConfig.objects().first()
        # Make sure we have the rquired settings, else return failure
        if not config.ldap_server or not config.ldap_userdn:
            return resp
        ldap_server = config.ldap_server.split(':')
        scheme = "ldap"
        if config.ldap_tls:
            scheme = "ldaps"
        url = ldapurl.LDAPUrl('%s://%s' % (scheme, ldap_server[0]))
        if len(ldap_server) == 2:
            l = ldap.initialize('%s:%s' % (url.unparse(),
                                           ldap_server[1]))
        else:
            l = ldap.initialize(url.unparse())
        l.protocol_version = 3
        l.set_option(ldap.OPT_REFERRALS, 0)
        l.set_option(ldap.OPT_TIMEOUT, 10)
        # setup auth for custom cn's
        cn = "cn="
        if config.ldap_usercn:
            cn = config.ldap_usercn
        # two-step ldap binding
        if len(config.ldap_bind_dn) > 0:
            try:
            	logger.info("binding with bind_dn: %s" % config.ldap_bind_dn)
            	l.simple_bind_s(config.ldap_bind_dn, config.ldap_bind_password)
            	filter = '(|(cn='+self.username+')(uid='+self.username+')(mail='+self.username+'))'
            	# use the retrieved dn for the second bind
            	un = l.search_s(config.ldap_userdn,ldap.SCOPE_SUBTREE,filter,['dn'])[0][0]
            except Exception as err:
            	#logger.error("Error binding to LDAP for: %s" % config.ldap_bind_dn)
            	logger.error("Error in info_from_ldap: %s" % err)
            l.unbind()
            if len(ldap_server) == 2:
                l = ldap.initialize('%s:%s' % (url.unparse(),
                                               ldap_server[1]))
            else:
                l = ldap.initialize(url.unparse())
            l.protocol_version = 3
            l.set_option(ldap.OPT_REFERRALS, 0)
            l.set_option(ldap.OPT_TIMEOUT, 10)
        else:
            un = self.username
        # setup auth for custom cn's
        if len(config.ldap_usercn) > 0:
            un = "%s%s,%s" % (config.ldap_usercn,
                              self.username,
                              config.ldap_userdn)
        elif "@" in config.ldap_userdn:
            un = "%s%s" % (self.username, config.ldap_userdn)
	try:
            # Try auth bind first
            l.simple_bind_s(un, password)
            logger.info("Bound to LDAP for: %s" % un)
        except Exception as e:
            #logger.error("Error binding to LDAP for: %s" % self.username)
            logger.error("info_from_ldap:ERR: %s" % e)
        try:
            uatr = None
            uatr = l.search_s(config.ldap_userdn,
                              ldap.SCOPE_SUBTREE,
                              '(|(cn='+self.username+')(uid='+self.username+'))'
                              )[0][1]
            resp['first_name'] = uatr['givenName'][0]
            resp['last_name'] = uatr['sn'][0]
            resp['email'] = uatr['mail'][0]
            resp['result'] = "OK"
            logger.info("Retrieved LDAP info for: %s" % self.username)
        except Exception as e:
            #logger.error("Error retrieving LDAP info for: %s" % self.username)
            logger.error("info_from_ldap ERR: %s" % e)
        l.unbind()
        return resp
Beispiel #35
0
    def info_from_ldap(self, config=None, password=''):
        """
        Get information about this user from LDAP.
        """

        import ldap, ldapurl
        resp = {"result": "ERROR"}
        if not config:
            config = CRIPTsConfig.objects().first()
        # Make sure we have the rquired settings, else return failure
        if not config.ldap_server or not config.ldap_userdn:
            return resp
        ldap_server = config.ldap_server.split(':')
        scheme = "ldap"
        if config.ldap_tls:
            scheme = "ldaps"
        url = ldapurl.LDAPUrl('%s://%s' % (scheme, ldap_server[0]))
        if len(ldap_server) == 2:
            l = ldap.initialize('%s:%s' % (url.unparse(), ldap_server[1]))
        else:
            l = ldap.initialize(url.unparse())
        l.protocol_version = 3
        l.set_option(ldap.OPT_REFERRALS, 0)
        l.set_option(ldap.OPT_TIMEOUT, 10)
        # setup auth for custom cn's
        cn = "cn="
        if config.ldap_usercn:
            cn = config.ldap_usercn
        # two-step ldap binding
        if len(config.ldap_bind_dn) > 0:
            try:
                logger.info("binding with bind_dn: %s" % config.ldap_bind_dn)
                l.simple_bind_s(config.ldap_bind_dn, config.ldap_bind_password)
                filter = '(|(cn=' + self.username + ')(uid=' + self.username + ')(mail=' + self.username + '))'
                # use the retrieved dn for the second bind
                un = l.search_s(config.ldap_userdn, ldap.SCOPE_SUBTREE, filter,
                                ['dn'])[0][0]
            except Exception as err:
                #logger.error("Error binding to LDAP for: %s" % config.ldap_bind_dn)
                logger.error("Error in info_from_ldap: %s" % err)
            l.unbind()
            if len(ldap_server) == 2:
                l = ldap.initialize('%s:%s' % (url.unparse(), ldap_server[1]))
            else:
                l = ldap.initialize(url.unparse())
            l.protocol_version = 3
            l.set_option(ldap.OPT_REFERRALS, 0)
            l.set_option(ldap.OPT_TIMEOUT, 10)
        else:
            un = self.username
        # setup auth for custom cn's
        if len(config.ldap_usercn) > 0:
            un = "%s%s,%s" % (config.ldap_usercn, self.username,
                              config.ldap_userdn)
        elif "@" in config.ldap_userdn:
            un = "%s%s" % (self.username, config.ldap_userdn)
        try:
            # Try auth bind first
            l.simple_bind_s(un, password)
            logger.info("Bound to LDAP for: %s" % un)
        except Exception as e:
            #logger.error("Error binding to LDAP for: %s" % self.username)
            logger.error("info_from_ldap:ERR: %s" % e)
        try:
            uatr = None
            uatr = l.search_s(
                config.ldap_userdn, ldap.SCOPE_SUBTREE, '(|(cn=' +
                self.username + ')(uid=' + self.username + '))')[0][1]
            resp['first_name'] = uatr['givenName'][0]
            resp['last_name'] = uatr['sn'][0]
            resp['email'] = uatr['mail'][0]
            resp['result'] = "OK"
            logger.info("Retrieved LDAP info for: %s" % self.username)
        except Exception as e:
            #logger.error("Error retrieving LDAP info for: %s" % self.username)
            logger.error("info_from_ldap ERR: %s" % e)
        l.unbind()
        return resp
Beispiel #36
0
    def authenticate(self,
                     username=None,
                     password=None,
                     user_agent=None,
                     remote_addr=None,
                     accept_language=None,
                     totp_enabled='Disabled'):
        """
        Perform the authentication of the user.

        :param username: The user to authenticate.
        :type username: str
        :param password: The password provided to authenticate with.
        :type password: str
        :param user_agent: The user-agent in the request.
        :type user_agent: str
        :param remote_addr: The hostname/ip in the request.
        :type remote_addr: str
        :param accept_language: The Accept Language in the request.
        :type accept_language: str
        :param totp_enabled: If TOTP is enabled and should be checked as well.
        :type totp_enabled: str
        :returns: :class:`cripts.core.user.CRIPTsUser`, None
        """

        # Need username and password for logins, checkem both
        if not all([username, password]):
            return None

        e = EmbeddedLoginAttempt()
        e.user_agent = user_agent
        e.remote_addr = remote_addr
        e.accept_language = accept_language
        fusername = username
        if '\\' in username:
            username = username.split("\\")[1]
        user = CRIPTsUser.objects(username=username).first()
        if user:
            # If the user needs TOTP and it is not disabled system-wide, and
            # the user has exceeded the login threshold for this time period
            # don't go any further. Track the invalid login and return.
            if (((user.totp and totp_enabled == 'Optional')
                 or totp_enabled == 'Required')
                    and self._exceeded_login_threshold(user)):
                e.success = False
                self.track_login_attempt(user, e)
                user.reload()
                return None
            config = CRIPTsConfig.objects().first()
            if not config:
                return None
            if config.ldap_auth:
                import ldap, ldapurl
                try:
                    # If you are using Oracle's server that's based on
                    # Netscape's code, and your users can't login after
                    # password expiration warning kicks in, you need:
                    # python-ldap 2.4.15 installed and
                    # import ldap.controls.pwdpolicy to fix it
                    #
                    import ldap.controls.pwdpolicy
                except ImportError:
                    logger.info("ldap.controls.pwdpolicy not present.")
                try:
                    # don't parse the port if there is one
                    ldap_server = config.ldap_server.split(':')
                    scheme = "ldap"
                    if config.ldap_tls:
                        scheme = "ldaps"
                    url = ldapurl.LDAPUrl('%s://%s' % (scheme, ldap_server[0]))
                    if len(ldap_server) == 2:
                        l = ldap.initialize('%s:%s' %
                                            (url.unparse(), ldap_server[1]))
                    else:
                        l = ldap.initialize(url.unparse())
                    l.protocol_version = 3
                    l.set_option(ldap.OPT_REFERRALS, 0)
                    l.set_option(ldap.OPT_TIMEOUT, 10)
                    # two-step ldap binding
                    if len(config.ldap_bind_dn) > 0:
                        try:
                            logger.info("binding with bind_dn: %s" %
                                        config.ldap_bind_dn)
                            l.simple_bind_s(config.ldap_bind_dn,
                                            config.ldap_bind_password)
                            filter = '(|(cn=' + fusername + ')(uid=' + fusername + ')(mail=' + fusername + '))'
                            # use the retrieved dn for the second bind
                            un = l.search_s(config.ldap_userdn,
                                            ldap.SCOPE_SUBTREE, filter,
                                            ['dn'])[0][0]
                        except Exception as err:
                            #logger.error("Error binding to LDAP for: %s" % config.ldap_bind_dn)
                            logger.error("authenticate ERR: %s" % err)
                        l.unbind()
                        if len(ldap_server) == 2:
                            l = ldap.initialize(
                                '%s:%s' % (url.unparse(), ldap_server[1]))
                        else:
                            l = ldap.initialize(url.unparse())
                        l.protocol_version = 3
                        l.set_option(ldap.OPT_REFERRALS, 0)
                        l.set_option(ldap.OPT_TIMEOUT, 10)
                    else:
                        un = fusername
                    # setup auth for custom cn's
                    if len(config.ldap_usercn) > 0:
                        un = "%s%s,%s" % (config.ldap_usercn, fusername,
                                          config.ldap_userdn)
                    elif "@" in config.ldap_userdn:
                        un = "%s%s" % (fusername, config.ldap_userdn)
                    logger.info("Logging in user: %s" % un)
                    l.simple_bind_s(un, password)
                    user = self._successful_settings(user, e, totp_enabled)
                    if config.ldap_update_on_login:
                        user.update_from_ldap("Auto LDAP update", config,
                                              password)
                    l.unbind()
                    return user
                except ldap.INVALID_CREDENTIALS:
                    l.unbind()
                    logger.info("Invalid LDAP credentials for: %s" % un)
                except Exception as err:
                    logger.info("LDAP Auth error: %s" % err)
            # If LDAP auth fails, attempt normal CRIPTs auth.
            # This will help with being able to use local admin accounts when
            # you have LDAP auth enabled.
            if password and user.check_password(password):
                self._successful_settings(user, e, totp_enabled)
                if config.ldap_update_on_login:
                    user.update_from_ldap("Auto LDAP update", config)
                return user
            else:
                e.success = False
                user.invalid_login_attempts += 1

            if user.is_active and user.invalid_login_attempts > settings.INVALID_LOGIN_ATTEMPTS:
                user.is_active = False
                logger.info(
                    "Account disabled due to too many invalid login attempts: %s"
                    % user.username)

                if config.cripts_email_end_tag:
                    subject = "CRIPTs Account Lockout" + config.cripts_email_subject_tag
                else:
                    subject = config.cripts_email_subject_tag + "CRIPTs Account Lockout"
                body = """

You are receiving this email because your CRIPTs account has been locked out due to
too many invalid login attempts.  If you did not perform this action,
someone may be attempting to access your account.

Please contact a site administrator to resolve.

"""
                try:
                    user.email_user(subject, body)
                except Exception, err:
                    logger.warning("Error sending email: %s" % str(err))
            self.track_login_attempt(user, e)
            user.reload()
Beispiel #37
0
def create_zip(files, pw_protect=True):
    """
    Create a zip file. Creates a temporary directory to write files to on disk
    using :class:`tempfile`. Uses /usr/bin/zip as the zipping mechanism
    currently. Will password protect the zip file as a default. The password for
    the zip file defaults to "infected", but it can be changed in the config
    under zip7_password.

    :param files: The files to add to the zip file.
    :type files: list of files which are in the format of a list or tuple of
                 (<filename>, <data>).
    :param pw_protect: To password protect the zip file or not.
    :type pw_protect: boolean
    :returns: :class:`cripts.core.exceptions.ZipFileError`, str
    """

    dumpdir = ""
    try:
        # Zip can take data from stdin to compress, but
        # you can't define the filenames within the archive,
        # they show up as "-".  Therefore, we need to write
        # out the file, compress it and return the zip.
        # Save the sample as a file in a temp directory
        # NOTE: the following line was causing a "permission denied" exception.
        # Removed dir arg.
        from cripts.config.config import CRIPTsConfig
        cripts_config = CRIPTsConfig.objects().first()
        if cripts_config:
            zip7_password = cripts_config.zip7_password or 'hashed'
        else:
            zip7_password = settings.ZIP7_PASSWORD or 'hashed'
        dumpdir = tempfile.mkdtemp() #dir=temproot
        #write out binary files
        for f in files:
            filename = f[0]
            file_data = f[1]

            # make sure our desired path doesn't already exist (some files may
            # have the same name but different data)
            path = dumpdir + "/" + filename.encode("utf-8")
            i = 1
            tmp = path
            while os.path.exists(tmp):
                tmp = path+"("+str(i)+")"
                i += 1

            with open(tmp, "wb") as fh:
                fh.write(file_data)

        # Build the command line for zip
        # NOTE: forking subprocess instead of using Python's ZipFile library
        # because ZipFile does not allow us to create password-protected zip
        # archives, only read them.
        # -j don't include original filepath
        zipname = "zip.zip" #The name we give it doesn't really matter
        args = ["/usr/bin/zip", "-r", "-j", dumpdir+"/"+zipname, dumpdir]
        if pw_protect:
            args += ["-P", zip7_password]
        args += [dumpdir+"/"+zipname, dumpdir]

        proc = subprocess.Popen(args,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT)
        # Give the process 30 seconds to complete, otherwise kill it
        waitSeconds = 30
        while (proc.poll() is None and waitSeconds):
            time.sleep(1)
            waitSeconds -= 1

        zipdata = ""
        if proc.returncode:     # zip spit out an error
            errmsg = "Error while creating archive\n" + proc.stdout.read()
            raise ZipFileError, errmsg
        elif not waitSeconds:   # Process timed out
            proc.terminate()
            raise ZipFileError, "Error:\nProcess failed to terminate"
        else:
            with open(dumpdir + "/" + zipname, "rb") as fh:
                zipdata = fh.read()
        if not len(zipdata):
            raise ZipFileError, "Error:\nThe zip archive contains no data"
        return zipdata

    except ZipFileError:
        raise
    except Exception, ex:
        errmsg = ""
        for err in ex.args:
            errmsg = errmsg + " " + unicode(err)
        raise ZipFileError, errmsg