示例#1
0
    def perform_secure_deletion_of_files(self):
        # Delete files that are marked for secure deletion
        files_to_delete = yield self.get_files_to_secure_delete()
        for file_to_delete in files_to_delete:
            overwrite_and_remove(file_to_delete)

        if files_to_delete:
            yield self.commit_files_deletion(files_to_delete)

        # Delete the outdated AES files older than 1 day
        files_to_remove = [
            f for f in os.listdir(self.state.settings.tmp_path)
            if fnmatch.fnmatch(f, '*.aes')
        ]
        for f in files_to_remove:
            path = os.path.join(self.state.settings.tmp_path, f)
            timestamp = datetime.datetime.fromtimestamp(os.path.getmtime(path))
            if is_expired(timestamp, days=1):
                os.remove(path)

        # Delete the backups older than 15 days
        for f in os.listdir(self.state.settings.backups_path):
            path = os.path.join(self.state.settings.backups_path, f)
            timestamp = datetime.datetime.fromtimestamp(os.path.getmtime(path))
            if is_expired(timestamp, days=15):
                os.remove(path)
示例#2
0
    def operation(self):
        """
        This function, checks all the InternalTips and their expiration date.
        if expired InternalTips are found, it removes that along with
        all the related DB entries comment and tip related.
        """

        # Reset the exception tracking variable of GLSetting
        GLSetting.exceptions = {}

        tip_list = yield get_tip_timings()
        log.debug("Tip(s) subject to the timings check: %d" % len(tip_list))

        for tip in tip_list:

            if is_expired(ISO8601_to_datetime(tip['expiration_date'])):
                log.info("Deleting an expired Tip (creation date: %s, expiration %s) files %d comments %d" %
                         (tip['creation_date'], tip['expiration_date'], tip['files'], tip['comments']))

                yield itip_cleaning(tip['id'])
                continue

            # check if the tip is gonna to expire in 48 hours (hard-coded value above)
            if is_expired(ISO8601_to_datetime(tip['upcoming_expiration_date'])):
                log.debug("Spotted a Tip matching the upcoming expiration date and "
                          "triggering email notifications")

                expiring_tips_events = ExpiringTipEvent()
                yield expiring_tips_events.notify(tip['id'])
                yield save_events_on_db(expiring_tips_events.events)
示例#3
0
    def operation():
        """
        Goal of this function is to check all the submission not
        finalized, and, if the expiration time sets in the context has
        been reached, then clean the submission_gus along with the fields,
        and, if present, the uploaded folder/files.

        Second goal of this function, is to check all the InternalTip(s)
        and their expiration date, if match, remove that, all the folder,
        comment and tip related.
        """
        try:
            submissions = yield get_tiptime_by_marker(InternalTip._marker[0])  # Submission
            log.debug("(Cleaning routines) %d unfinished Submission are check if expired" % len(submissions))
            for submission in submissions:
                if is_expired(iso2dateobj(submission["creation_date"]), seconds=submission["submission_life_seconds"]):
                    log.info(
                        "Deleting an unfinalized Submission (creation date: %s) files %d"
                        % (submission["creation_date"], submission["files"])
                    )
                    yield itip_cleaning(submission["id"])

            tips = yield get_tiptime_by_marker(InternalTip._marker[2])  # First
            log.debug("(Cleaning routines) %d Tips stored are check if expired" % len(tips))
            for tip in tips:
                if is_expired(iso2dateobj(tip["creation_date"]), seconds=tip["tip_life_seconds"]):
                    log.info(
                        "Deleting an expired Tip (creation date: %s) files %d comments %d"
                        % (tip["creation_date"], tip["files"], tip["comments"])
                    )
                    yield itip_cleaning(tip["id"])

        except Exception as excep:
            log.err("Exception failure in submission/tip cleaning routine (%s)" % excep.message)
            sys.excepthook(*sys.exc_info())
示例#4
0
    def operation(self):
        """
        Goal of this function is to check all the submission not
        finalized, and, if the expiration time sets in the context has
        been reached, then clean the submission_id along with the fields,
        and, if present, the uploaded folder/files.

        Second goal of this function, is to check all the InternalTip(s)
        and their expiration date, if match, remove that, all the folder,
        comment and tip related.

        Third goal of this function is to reset the exception counter that
        acts as limit for mail storm
        """
        try:
            # First Goal
            submissions = yield get_tiptime_by_marker(
                InternalTip._marker[0])  # Submission
            log.debug(
                "(Cleaning routines) %d unfinished Submission are check if expired"
                % len(submissions))
            for submission in submissions:
                if is_expired(ISO8601_to_datetime(submission['creation_date']),
                              GLSetting.defaults.submission_seconds_of_life):
                    log.info(
                        "Deleting an unfinalized Submission (creation %s expiration %s) files %d"
                        % (submission['creation_date'],
                           submission['expiration_date'], submission['files']))
                    yield itip_cleaning(submission['id'])

            # Second Goal
            tips = yield get_tiptime_by_marker(InternalTip._marker[2])  # First
            log.debug(
                "(Cleaning routines) %d Tips stored are check if expired" %
                len(tips))
            for tip in tips:
                if is_expired(ISO8601_to_datetime(tip['expiration_date'])):
                    log.info(
                        "Deleting an expired Tip (creation date: %s, expiration %s) files %d comments %d"
                        % (tip['creation_date'], tip['expiration_date'],
                           tip['files'], tip['comments']))
                    yield itip_cleaning(tip['id'])

            # Third Goal: Reset of GLSetting.exceptions
            GLSetting.exceptions = {}

        except Exception as excep:
            log.err(
                "Exception failure in submission/tip cleaning routine (%s)" %
                excep.message)
            sys.excepthook(*sys.exc_info())
示例#5
0
    def generate_admin_alert_mail(self, event_matrix):
        """
        This function put a mail in queue for the Admin, if the
        Admin notification is disable or if another Anomaly has been
        raised in the last 15 minutes, email is not send.
        """
        do_not_stress_admin_with_more_than_an_email_every_minutes = 120

        if not (self.stress_levels['activity']
                or self.stress_levels['disk_space']):
            # we are lucky! no stress activities detected, no mail needed
            return

        if GLSettings.memory_copy.notif.disable_admin_notification_emails:
            return

        if not is_expired(
                self.last_alarm_email,
                minutes=
                do_not_stress_admin_with_more_than_an_email_every_minutes):
            return

        alert = {
            'stress_levels':
            copy.deepcopy(self.stress_levels),
            'latest_measured_freespace':
            copy.deepcopy(self.latest_measured_freespace),
            'latest_measured_totalspace':
            copy.deepcopy(self.latest_measured_totalspace),
            'event_matrix':
            copy.deepcopy(event_matrix)
        }

        self.last_alarm_email = datetime_now()
        return generate_admin_alert_mail(alert)
示例#6
0
 def perform_secure_deletion_of_temporary_files(self):
     # Delete the outdated temp files if older than 1 day
     for f in os.listdir(self.state.settings.tmp_path):
         path = os.path.join(self.state.settings.tmp_path, f)
         timestamp = datetime.fromtimestamp(os.path.getmtime(path))
         if is_expired(timestamp, days=1):
             overwrite_and_remove(path)
    def operation(self):
        """
        This scheduler is responsible of:
            - Removal of expired sessions
            - Reset of failed login attempts counters
        """

        # Removal of expired sessions
        try:
            # this list is needed because we can't do "del"
            # on a list during a loop on it without breaking the loop.
            sid_to_remove = []

            for session_id in GLSetting.sessions:
                checkd_session = GLSetting.sessions[session_id]

                if is_expired(checkd_session.refreshdate,
                              seconds=GLSetting.defaults.lifetimes[checkd_session.role]):
                    sid_to_remove.append(session_id)

            for expired_sid in sid_to_remove:
                del GLSetting.sessions[expired_sid]

            if len(sid_to_remove):
                log.debug("Expired %d sessions" % len(sid_to_remove))

        except Exception as excep:
            log.err("Exception failure in session cleaning routine (%s)" % excep.message)
            sys.excepthook(*sys.exc_info())

        # Reset of failed login attempts counters
        GLSetting.failed_login_attempts = 0
示例#8
0
def update_session(user):
    """
    Returns True if the session is still valid, False instead.
    Timed out sessions are destroyed.
    """
    session_info = GLSetting.sessions[user.id]
    
    if utility.is_expired(session_info.refreshdate,
                          seconds=GLSetting.defaults.lifetimes[user.role]):

        log.debug("Authentication Expired (%s) %s seconds" % (
                  user.role,
                  GLSetting.defaults.lifetimes[user.role] ))

        del GLSetting.sessions[user.id]
        
        return False

    else:

        # update the access time to the latest
        GLSetting.sessions[user.id].refreshdate = utility.datetime_now()
        GLSetting.sessions[user.id].expirydate = utility.get_future_epoch(
            seconds=GLSetting.defaults.lifetimes[user.role])

        return True
    def operation(self):
        """
        This scheduler is responsible of:
            - Removal of expired sessions
            - Reset of failed login attempts counters
        """

        # Removal of expired sessions
        try:
            # this list is needed because we can't do "del"
            # on a list during a loop on it without breaking the loop.
            sid_to_remove = []

            for session_id in GLSetting.sessions:
                checkd_session = GLSetting.sessions[session_id]

                if is_expired(checkd_session.refreshdate,
                              seconds=GLSetting.defaults.lifetimes[
                                  checkd_session.role]):
                    sid_to_remove.append(session_id)

            for expired_sid in sid_to_remove:
                del GLSetting.sessions[expired_sid]

            if len(sid_to_remove):
                log.debug("Expired %d sessions" % len(sid_to_remove))

        except Exception as excep:
            log.err("Exception failure in session cleaning routine (%s)" %
                    excep.message)
            sys.excepthook(*sys.exc_info())

        # Reset of failed login attempts counters
        GLSetting.failed_login_attempts = 0
示例#10
0
    def check_tenant_anomalies(self, tid):
        """
        This function update the Alarm level.

        """
        self.number_of_anomalies = 0

        self.event_matrix.clear()

        for event in State.tenant_state[tid].RecentEventQ:
            self.event_matrix.setdefault(event.event_type, 0)
            self.event_matrix[event.event_type] += 1

        for event_name, threshold in ANOMALY_MAP.items():
            if event_name in self.event_matrix:
                if self.event_matrix[event_name] > threshold:
                    self.number_of_anomalies += 1

        previous_activity_sl = self.alarm_levels['activity']

        log_function = log.debug
        self.alarm_levels['activity'] = 0

        if self.number_of_anomalies == 1:
            log_function = log.info
            self.alarm_levels['activity'] = 1
        elif self.number_of_anomalies > 1:
            log_function = log.info
            self.alarm_levels['activity'] = 2

        # if there are some anomaly or we're nearby, record it.
        if self.number_of_anomalies >= 1 or self.alarm_levels['activity'] >= 1:
            State.tenant_state[tid].AnomaliesQ.append([datetime_now(), self.event_matrix, self.alarm_levels['activity']])

        if previous_activity_sl != self.alarm_levels['activity']:
            log_function("Alarm level changed from %d => %d" %
                         (previous_activity_sl,
                         self.alarm_levels['activity']))

        if State.tenant_cache[1].notification.disable_admin_notification_emails:
            return

        if not (self.alarm_levels['activity'] or self.alarm_levels['disk_space']):
            return

        if not is_expired(self.last_alarm_email, minutes=120):
            return

        self.last_alarm_email = datetime_now()

        alert = {
            'alarm_levels': self.alarm_levels,
            'measured_freespace': self.measured_freespace,
            'measured_totalspace': self.measured_totalspace,
            'event_matrix': self.event_matrix
        }

        yield generate_admin_alert_mail(tid, alert)
示例#11
0
    def check_tenant_anomalies(self, tid):
        """
        This function update the Alarm level.

        """
        self.number_of_anomalies = 0

        self.event_matrix.clear()

        for event in State.tenant_state[tid].RecentEventQ:
            self.event_matrix.setdefault(event.event_type, 0)
            self.event_matrix[event.event_type] += 1

        for event_name, threshold in ANOMALY_MAP.items():
            if event_name in self.event_matrix:
                if self.event_matrix[event_name] > threshold:
                    self.number_of_anomalies += 1

        previous_activity_sl = self.alarm_levels['activity']

        log_function = log.debug
        self.alarm_levels['activity'] = 0

        if self.number_of_anomalies == 1:
            log_function = log.info
            self.alarm_levels['activity'] = 1
        elif self.number_of_anomalies > 1:
            log_function = log.info
            self.alarm_levels['activity'] = 2

        # if there are some anomaly or we're nearby, record it.
        if self.number_of_anomalies >= 1 or self.alarm_levels['activity'] >= 1:
            State.tenant_state[tid].AnomaliesQ.append([datetime_now(), self.event_matrix, self.alarm_levels['activity']])

        if previous_activity_sl != self.alarm_levels['activity']:
            log_function("Alarm level changed from %d => %d" %
                         (previous_activity_sl,
                         self.alarm_levels['activity']))

        if State.tenant_cache[1].notification.disable_admin_notification_emails:
            return

        if not (self.alarm_levels['activity'] or self.alarm_levels['disk_space']):
            return

        if not is_expired(self.last_alarm_email, minutes=120):
            return

        self.last_alarm_email = datetime_now()

        alert = {
            'alarm_levels': self.alarm_levels,
            'measured_freespace': self.measured_freespace,
            'measured_totalspace': self.measured_totalspace,
            'event_matrix': self.event_matrix
        }

        yield generate_admin_alert_mail(tid, alert)
示例#12
0
    def perform_secure_deletion_of_attachments(self, valid_files):
        # Delete the attachment files not associated to the database
        for f in os.listdir(self.state.settings.attachments_path):
            if f in valid_files:
                continue

            path = os.path.join(self.state.settings.attachments_path, f)
            timestamp = datetime.fromtimestamp(os.path.getmtime(path))
            if is_expired(timestamp, days=1):
                overwrite_and_remove(path)
示例#13
0
    def generate_admin_alert_mail(self, event_matrix):
        """
        This function put a mail in queue for the Admin, if the
        Admin notification is disable or if another Anomaly has been
        raised in the last 15 minutes, email is not send.
        """
        do_not_stress_admin_with_more_than_an_email_every_minutes = 120

        if not (self.stress_levels['activity']
                or self.stress_levels['disk_space']):
            # we are lucky! no stress activities detected, no mail needed
            return

        if GLSettings.memory_copy.notif.disable_admin_notification_emails:
            return

        if self.last_alarm_email and not is_expired(
                self.last_alarm_email,
                minutes=
                do_not_stress_admin_with_more_than_an_email_every_minutes):
            return

        alert = {
            'stress_levels':
            copy.deepcopy(self.stress_levels),
            'latest_measured_freespace':
            copy.deepcopy(self.latest_measured_freespace),
            'latest_measured_totalspace':
            copy.deepcopy(self.latest_measured_totalspace),
            'event_matrix':
            copy.deepcopy(event_matrix)
        }

        @transact
        def _generate_admin_alert_mail(store, alert):
            for user_desc in db_get_admin_users(store):
                user_language = user_desc['language']

                data = {
                    'type': u'admin_anomaly',
                    'node': db_admin_serialize_node(store, user_language),
                    'notification': db_get_notification(store, user_language),
                    'alert': alert
                }

                subject, body = Templating().get_mail_subject_and_body(data)

                db_schedule_email(store, user_desc['mail_address'], subject,
                                  body)

        self.last_alarm_email = datetime_now()
        yield _generate_admin_alert_mail(alert)
示例#14
0
    def operation(self):
        """
        This function, checks all the InternalTips and their expiration date.
        if expired InternalTips are found, it removes that along with
        all the related DB entries comment and tip related.
        """

        # Reset the exception trackiging variable of GLSetting
        GLSetting.exceptions = {}

        # Check1: check for expired InternalTips (new tips)
        new_tips = yield get_tip_timings(True)
        log.debug("[Tip timings routines / new / expiration ] #%d Tips" % len(new_tips))
        for tip in new_tips:
            if is_expired(ISO8601_to_datetime(tip['expiration_date'])):
                log.info("Deleting an expired Tip (creation date: %s, expiration %s) files %d comments %d" %
                         (tip['creation_date'], tip['expiration_date'], tip['files'], tip['comments']))

                yield itip_cleaning(tip['id'])

        # Check2: check for expired InternalTips (old tips)
        old_tips = yield get_tip_timings(False)
        log.debug("[Tip timings routines / old / expiration upcoming / expire ] #%d Tips" % len(old_tips))
        for tip in old_tips:
            # Check2.1: check if the tip is expired
            if is_expired(ISO8601_to_datetime(tip['expiration_date'])):
                log.info("Deleting an expired Tip (creation date: %s, expiration %s) files %d comments %d" %
                         (tip['creation_date'], tip['expiration_date'], tip['files'], tip['comments']))

                yield itip_cleaning(tip['id'])

            # Check2.2: check if the tip is expiring
            elif is_expired(ISO8601_to_datetime(tip['upcoming_expiration_date'])):
                log.debug("Spotted a Tip matching the upcoming expiration date and "
                          "triggering email notifications")

                expiring_tips_events = ExpiringTipEvent()
                yield expiring_tips_events.notify(tip['id'])
                yield save_events_on_db(expiring_tips_events.events)
示例#15
0
    def operation(self):
        """
        Goal of this function is to check all the submission not
        finalized, and, if the expiration time sets in the context has
        been reached, then clean the submission_id along with the fields,
        and, if present, the uploaded folder/files.

        Second goal of this function, is to check all the InternalTip(s)
        and their expiration date, if match, remove that, all the folder,
        comment and tip related.

        Third goal of this function is to reset the exception counter that
        acts as limit for mail storm
        """
        try:
            # First Goal
            submissions = yield get_tiptime_by_marker(InternalTip._marker[0]) # Submission
            log.debug("(Cleaning routines) %d unfinished Submission are check if expired" % len(submissions))
            for submission in submissions:
                if is_expired(ISO8601_to_datetime(submission['creation_date']), GLSetting.defaults.submission_seconds_of_life):
                    log.info("Deleting an unfinalized Submission (creation %s expiration %s) files %d" %
                             (submission['creation_date'], submission['expiration_date'], submission['files']) )
                    yield itip_cleaning(submission['id'])

            # Second Goal
            tips = yield get_tiptime_by_marker(InternalTip._marker[2]) # First
            log.debug("(Cleaning routines) %d Tips stored are check if expired" % len(tips))
            for tip in tips:
                if is_expired(ISO8601_to_datetime(tip['expiration_date'])):
                    log.info("Deleting an expired Tip (creation date: %s, expiration %s) files %d comments %d" %
                             (tip['creation_date'], tip['expiration_date'], tip['files'], tip['comments']) )
                    yield itip_cleaning(tip['id'])

            # Third Goal: Reset of GLSetting.exceptions
            GLSetting.exceptions = {}

        except Exception as excep:
            log.err("Exception failure in submission/tip cleaning routine (%s)" % excep.message)
            sys.excepthook(*sys.exc_info())
    def submission_not_expired(self):
        """
        Submission is intended the non-finalized Tip, with a shorter life than completed Tips, and
        not yet delivered to anyone. (marker 0)
        """
        sub_list = yield cleaning_sched.get_tiptime_by_marker(models.InternalTip._marker[0])

        self.assertEqual(len(sub_list), 1)

        self.assertFalse(
            is_expired(
                cleaning_sched.iso2dateobj(sub_list[0]['creation_date']),
                sub_list[0]['submission_life_seconds'])
        )
    def tip_not_expired(self):
        """
        Tip is intended InternalTip notified and delivered (marker 2, 'first' layer of deliverance)
        and their life depends by context policies
        """
        tip_list = yield cleaning_sched.get_tiptime_by_marker(models.InternalTip._marker[2])

        self.assertEqual(len(tip_list), 1)

        self.assertFalse(
            is_expired(
                cleaning_sched.iso2dateobj(tip_list[0]['creation_date']),
                tip_list[0]['tip_life_seconds'])
        )
示例#18
0
    def perform_secure_deletion_of_files(self):
        # Delete files that are marked for secure deletion
        files_to_delete = yield self.get_files_to_secure_delete()
        for file_to_delete in files_to_delete:
            overwrite_and_remove(file_to_delete)

        if files_to_delete:
            yield self.commit_files_deletion(files_to_delete)

        # Delete the outdated AES files older than 1 day
        files_to_remove = [f for f in os.listdir(self.state.settings.tmp_path) if fnmatch.fnmatch(f, '*.aes')]
        for f in files_to_remove:
            path = os.path.join(self.state.settings.tmp_path, f)
            timestamp = datetime.fromtimestamp(os.path.getmtime(path))
            if is_expired(timestamp, days=1):
                overwrite_and_remove(path)
    def force_submission_expire(self):
        sub_list = yield cleaning_sched.get_tiptime_by_marker(models.InternalTip._marker[0])
        self.assertEqual(len(sub_list), 1)

        sub_desc = sub_list[0]
        sub_desc['submission_life_seconds'] = 0

        self.assertTrue(
            is_expired(
                cleaning_sched.iso2dateobj(sub_desc['creation_date']),
                sub_desc['submission_life_seconds'])
        )

        # and then, delete the expired submission
        yield cleaning_sched.itip_cleaning(sub_desc['id'])

        new_list = yield cleaning_sched.get_tiptime_by_marker(models.InternalTip._marker[0])
        self.assertEqual(len(new_list), 0)
示例#20
0
    def generate_admin_alert_mail(self, event_matrix):
        """
        This function put a mail in queue for the Admin, if the
        Admin notification is disable or if another Anomaly has been
        raised in the last 15 minutes, email is not send.
        """
        do_not_stress_admin_with_more_than_an_email_every_minutes = 120

        if not (self.stress_levels['activity'] or self.stress_levels['disk_space']):
            # we are lucky! no stress activities detected, no mail needed
            return

        if GLSettings.memory_copy.disable_admin_notification_emails:
            return

        if self.last_alarm_email and not is_expired(self.last_alarm_email,
                                                     minutes=do_not_stress_admin_with_more_than_an_email_every_minutes):
            return

        alert = {
            'stress_levels': copy.deepcopy(self.stress_levels),
            'latest_measured_freespace': copy.deepcopy(self.latest_measured_freespace),
            'latest_measured_totalspace': copy.deepcopy(self.latest_measured_totalspace),
            'event_matrix': copy.deepcopy(event_matrix)
        }

        @transact
        def _generate_admin_alert_mail(store, alert):
            for user_desc in db_get_admin_users(store):
                user_language = user_desc['language']

                data = {
                    'address': user_desc['mail_address'],
                    'type': u'admin_anomaly',
                    'node': db_admin_serialize_node(store, user_language),
                    'notification': db_get_notification(store, user_language),
                    'alert': alert
                }

                Templating().db_prepare_mail(store, data)


        self.last_alarm_email = datetime_now()
        yield _generate_admin_alert_mail(alert)
示例#21
0
    def admin_alarm_notification(event_matrix):
        """
        This function put a mail in queue for the Admin, if the
        Admin notification is disable or if another Anomaly has been
        raised in the last 15 minutes, email is not send.
        """
        # import here in order to avoid circular import error
        from globaleaks.handlers.admin.notification import get_notification

        do_not_stress_admin_with_more_than_an_email_after_minutes = 15

        @transact_ro
        def _get_node_admin_email(store):
            node = store.find(models.Node).one()
            return node.email

        @transact_ro
        def _get_admin_user_language(store):
            admin_user = store.find(models.User, models.User.username == u'admin').one()
            return admin_user.language

        @transact_ro
        def _get_message_template(store):
            admin_user = store.find(models.User, models.User.username == u'admin').one()
            notif = store.find(models.Notification).one()
            template = notif.admin_anomaly_template
            if admin_user.language in template:
                return template[admin_user.language]
            elif GLSetting.memory_copy.language in template:
                return template[GLSetting.memory_copy.language]
            else:
                raise Exception("Cannot find any language for admin notification")

        def _activity_alarm_level():
            return "%s" % Alarm.stress_levels['activity']

        def _activity_dump():
            retstr = ""
            for event, amount in event_matrix.iteritems():
                retstr = "%s: %d\n%s" % (event, amount, retstr)
            return retstr

        def _disk_alarm_level():
            return "%s" % Alarm.stress_levels['disk_space']

        def _disk_dump():
            return "%s" % bytes_to_pretty_str(Alarm.latest_measured_freespace)

        def _disk_status_message():
            if Alarm.stress_levels['disk_message']:
                return unicode(Alarm.stress_levels['disk_message'])
            else:
                return "Disk space OK"

        @transact_ro
        def _node_name(store):
            node = store.find(models.Node).one()
            return unicode(node.name)

        KeyWordTemplate = {
            "%ActivityAlarmLevel%": _activity_alarm_level,
            "%ActivityDump%": _activity_dump,
            "%DiskAlarmLevel%": _disk_alarm_level,
            "%DiskDump%": _disk_dump,
            "%DiskErrorMessage%": _disk_status_message,
            "%NodeName%": _node_name
        }
        # ------------------------------------------------------------------

        # Here start the Anomaly Notification code, before checking if we have to send email
        if not (Alarm.stress_levels['activity'] or Alarm.stress_levels['disk_space']):
            # lucky, no stress activities recorded: no mail needed
            defer.returnValue(None)

        if not GLSetting.memory_copy.admin_notif_enable:
            # event_matrix is {} if we are here only for disk
            log.debug("Anomaly to be reported %s, but Admin has Notification disabled" %
                      "[%s]" % event_matrix if event_matrix else "")
            defer.returnValue(None)

        if Alarm.last_alarm_email:
            if not is_expired(Alarm.last_alarm_email,
                              minutes=do_not_stress_admin_with_more_than_an_email_after_minutes):
                log.debug("Alert email want be send, but the threshold of %d minutes is not yet reached since %s" % (
                    do_not_stress_admin_with_more_than_an_email_after_minutes,
                    datetime_to_ISO8601(Alarm.last_alarm_email)))
                defer.returnValue(None)

        # and now, processing the template
        message = yield _get_message_template()
        for keyword, templ_funct in KeyWordTemplate.iteritems():

            where = message.find(keyword)

            if where == -1:
                continue

            # based on the type of templ_funct, we've to use 'yield' or not
            # cause some returns a deferred.
            if isinstance(templ_funct, type(sendmail)):
                content = templ_funct()
            else:
                content = yield templ_funct()

            message = "%s%s%s" % (
                message[:where],
                content,
                message[where + len(keyword):])

        admin_email = yield _get_node_admin_email()

        admin_language = yield _get_admin_user_language()

        notification_settings = yield get_notification(admin_language)

        message = MIME_mail_build(GLSetting.memory_copy.notif_source_email,
                                  GLSetting.memory_copy.notif_source_email,
                                  admin_email,
                                  admin_email,
                                  notification_settings['admin_anomaly_mail_title'],
                                  message)

        log.debug('Alarm Email for admin (%s): connecting to [%s:%d], '
                  'the next mail should be in %d minutes' %
                  (event_matrix,
                   GLSetting.memory_copy.notif_server,
                   GLSetting.memory_copy.notif_port,
                   do_not_stress_admin_with_more_than_an_email_after_minutes))

        Alarm.last_alarm_email = datetime_now()
示例#22
0
 def force_tip_expire(self, store):
     tips = store.find(models.InternalTip)
     for tip in tips:
         tip.expiration_date = datetime_null()
         self.assertTrue(is_expired(tip.expiration_date))
示例#23
0
 def check_tip_not_expired(self, store):
     tips = store.find(models.InternalTip)
     for tip in tips:
         self.assertFalse(is_expired(tip.expiration_date))
示例#24
0
    def admin_alarm_generate_mail(event_matrix):
        """
        This function put a mail in queue for the Admin, if the
        Admin notification is disable or if another Anomaly has been
        raised in the last 15 minutes, email is not send.
        """
        do_not_stress_admin_with_more_than_an_email_every_minutes = 120
        # if emergency is set to True, the previous time check is ignored.
        emergency_notification = False

        @transact_ro
        def _get_node_admin_email(store):
            node = store.find(models.Node).one()
            return node.email

        @transact_ro
        def _get_admin_user_language(store):
            admin_user = store.find(models.User, models.User.username == u'admin').one()
            return admin_user.language

        # THE THREE FUNCTIONS BELOW ARE POORLY SUBOPTIMAL,
        # AND THIS IS BAD: REFACTOR TO BE DONE ON THIS SUBJECT
        @transact_ro
        def _get_message_template(store):
            admin_user = store.find(models.User, models.User.username == u'admin').one()
            notif = store.find(models.Notification).one()
            template = notif.admin_anomaly_mail_template
            if admin_user.language in template:
                localized_template = template[admin_user.language]
            elif GLSettings.memory_copy.default_language in template:
                localized_template = template[GLSettings.memory_copy.default_language]
            else:
                raise Exception("Cannot find any language for admin notification")
            return localized_template

        @transact_ro
        def _disk_anomaly_detail(store):
            # This happen all the time anomalies are present but disk is ok
            if Alarm.stress_levels['disk_space'] == 0:
                return u''
            admin_user = store.find(models.User, models.User.username == u'admin').one()
            notif = store.find(models.Notification).one()
            if Alarm.stress_levels['disk_space'] == 1:
                template = notif.admin_anomaly_disk_low
            elif Alarm.stress_levels['disk_space'] == 2:
                template = notif.admin_anomaly_disk_medium
            elif Alarm.stress_levels['disk_space'] == 3:
                template = notif.admin_anomaly_disk_high
            else:
                raise Exception("Invalid disk stess level %d" %
                                Alarm.stress_levels['disk_space'])
            if admin_user.language in template:
                localized_template = template[admin_user.language]
            elif GLSettings.memory_copy.default_language in template:
                localized_template = template[GLSettings.memory_copy.default_language]
            else:
                raise Exception("Cannot find any language for Admin disk alarm (level %d)" %
                                Alarm.stress_levels['disk_space'])
            return localized_template

        @transact_ro
        def _activities_anomaly_detail(store):
            # This happen all the time there is not anomalous traffic
            if Alarm.stress_levels['activity'] == 0:
                return u''
            admin_user = store.find(models.User, models.User.username == u'admin').one()
            notif = store.find(models.Notification).one()
            template = notif.admin_anomaly_activities
            if admin_user.language in template:
                localized_template = template[admin_user.language]
            elif GLSettings.memory_copy.default_language in template:
                localized_template = template[GLSettings.memory_copy.default_language]
            else:
                raise Exception("Cannot find any language for admin notification")
            return localized_template

        # END OF THE SUB-OPTIMAL SECTION OF CODE THAT HAS TO BE RESTRUCTURED

        def _activity_alarm_level():
            return "%s" % Alarm.stress_levels['activity']

        def _activity_dump():
            retstr = ""
            for event, amount in event_matrix.iteritems():
                if not amount:
                    continue
                retstr = "%s%s%d\n%s" % \
                         (event, (25 - len(event)) * " ",
                          amount, retstr)
            return retstr

        @transact_ro
        def _node_name(store):
            node = store.find(models.Node).one()
            return unicode(node.name)

        def _free_disk_space():
            return "%s" % bytes_to_pretty_str(Alarm.latest_measured_freespace)

        def _total_disk_space():
            return "%s" % bytes_to_pretty_str(Alarm.latest_measured_totalspace)

        def _notification_suppressed():
            if Alarm.stress_levels['notification'] == []:
                return u''
            emergency_notification = True
            return "** %s **" % Alarm.stress_levels['notification']


        KeyWordTemplate = {
            "%AnomalyDetailDisk%": _disk_anomaly_detail,
            "%AnomalyDetailActivities%": _activities_anomaly_detail,
            "%ActivityAlarmLevel%": _activity_alarm_level,
            "%ActivityDump%": _activity_dump,
            "%NotificationSuppressed%": _notification_suppressed,
            "%NodeName%": _node_name,
            "%FreeMemory%": _free_disk_space,
            "%TotalMemory%": _total_disk_space,
        }
        # ------------------------------------------------------------------

        # Independently from the event_matrix, the status of the stress level can
        # be in non-0 value.
        # Here start the Anomaly Notification code, before checking if we have to send email
        if not (Alarm.stress_levels['activity'] or
                    Alarm.stress_levels['disk_space'] or
                    Alarm.stress_levels['notification']):
            # lucky, no stress activities recorded: no mail needed
            defer.returnValue(None)

        if GLSettings.memory_copy.disable_admin_notification_emails:
            # event_matrix is {} if we are here only for disk
            log.debug("Anomaly to be reported %s, but Admin has Notification disabled" %
                      "[%s]" % event_matrix if event_matrix else "")
            defer.returnValue(None)

        if Alarm.last_alarm_email and not emergency_notification:
            if not is_expired(Alarm.last_alarm_email,
                              minutes=do_not_stress_admin_with_more_than_an_email_every_minutes):
                defer.returnValue(None)
                # This is skipped then:
                log.debug("Alert [%s] want be sent, but the threshold of %d minutes still unexpired %s" % (
                    Alarm.stress_levels,
                    do_not_stress_admin_with_more_than_an_email_every_minutes,
                    datetime_to_ISO8601(Alarm.last_alarm_email)))

        admin_email = yield _get_node_admin_email()
        admin_language = yield _get_admin_user_language()
        notification_settings = yield get_notification(admin_language)

        # and now, processing the template
        message = yield _get_message_template()
        message_title = notification_settings['admin_anomaly_mail_title']
        recursion_time = 2

        # since the ActivityDetails, we've to manage recursion
        while recursion_time:
            recursion_time -= 1

            for keyword, templ_funct in KeyWordTemplate.iteritems():

                where = message.find(keyword)
                if where == -1:
                    continue

                # based on the type of templ_funct, we've to use 'yield' or not
                # cause some returns a deferred.
                if isinstance(templ_funct, type(sendmail)):
                    content = templ_funct()
                else:
                    content = yield templ_funct()

                message = "%s%s%s" % (
                    message[:where],
                    content,
                    message[where + len(keyword):])

        # message title, we can't put the loop together at the moment
        for keyword, templ_funct in KeyWordTemplate.iteritems():

            where = message_title.find(keyword)
            if where == -1:
                continue

            if isinstance(templ_funct, type(sendmail)):
                content = templ_funct()
            else:
                content = yield templ_funct()

            message_title = "%s%s%s" % (
                message_title[:where],
                content,
                message_title[where + len(keyword):])

        message = MIME_mail_build(GLSettings.memory_copy.notif_source_name,
                                  GLSettings.memory_copy.notif_source_email,
                                  admin_email,
                                  admin_email,
                                  message_title,
                                  message)

        log.debug('Alarm Email generated for Admin (%s): connecting to [%s:%d], '
                  'the next mail should be in %d minutes' %
                  (event_matrix,
                   GLSettings.memory_copy.notif_server,
                   GLSettings.memory_copy.notif_port,
                   do_not_stress_admin_with_more_than_an_email_every_minutes))

        defer.returnValue({
            'admin_email': admin_email,
            'message': message,
        })
示例#25
0
    def admin_alarm_generate_mail(event_matrix):
        """
        This function put a mail in queue for the Admin, if the
        Admin notification is disable or if another Anomaly has been
        raised in the last 15 minutes, email is not send.
        """
        ret = []

        do_not_stress_admin_with_more_than_an_email_every_minutes = 120

        def replace_keywords(text):
            iterations = 3
            stop = False
            while (stop == False and iterations > 0):
                iterations -= 1
                count = 0
                for keyword, function in KeywordTemplate.iteritems():
                    where = text.find(keyword)
                    if where == -1:
                        continue

                    count += 1

                    text = "%s%s%s" % (text[:where],
                                       function(notification_dict),
                                       text[where + len(keyword):])

                    if count == 0:
                        # finally!
                        stop = True
                        break

            return text

        def _disk_anomaly_detail(notification_dict):
            # This happens all the time anomalies are present but disk is ok
            if Alarm.stress_levels['disk_space'] == 0:
                return u''

            if Alarm.stress_levels['disk_space'] == 1:
                return notification_dict['admin_anomaly_disk_low']
            elif Alarm.stress_levels['disk_space'] == 2:
                return notification_dict['admin_anomaly_disk_medium']
            else:
                return notification_dict['admin_anomaly_disk_high']

        def _activities_anomaly_detail(notification_dict):
            # This happens all the time there is not anomalous traffic
            if Alarm.stress_levels['activity'] == 0:
                return u''

            return notification_dict['admin_anomaly_activities']

        def _activity_alarm_level(notification_dict):
            return "%s" % Alarm.stress_levels['activity']

        def _activity_dump(notification_dict):
            retstr = ""

            for event, amount in event_matrix.iteritems():
                if not amount:
                    continue
                retstr = "%s%s%d\n%s" % \
                         (event, (25 - len(event)) * " ", amount, retstr)

            return retstr

        def _node_name(notification_dict):
            return unicode(GLSettings.memory_copy.nodename)

        def _free_disk_space(notification_dict):
            return "%s" % bytes_to_pretty_str(Alarm.latest_measured_freespace)

        def _total_disk_space(notification_dict):
            return "%s" % bytes_to_pretty_str(Alarm.latest_measured_totalspace)

        def _notifications_suppressed(notification_dict):
            if Alarm.stress_levels['notification'] == []:
                return u''
            return "** %s **" % Alarm.stress_levels['notification']

        KeywordTemplate = {
            "%AnomalyDetailDisk%": _disk_anomaly_detail,
            "%AnomalyDetailActivities%": _activities_anomaly_detail,
            "%ActivityAlarmLevel%": _activity_alarm_level,
            "%ActivityDump%": _activity_dump,
            "%NotificationsSuppressed%": _notifications_suppressed,
            "%NodeName%": _node_name,
            "%FreeMemory%": _free_disk_space,
            "%TotalMemory%": _total_disk_space,
        }
        # ------------------------------------------------------------------

        if not (Alarm.stress_levels['activity'] or
                    Alarm.stress_levels['disk_space'] or
                    Alarm.stress_levels['notification']):
            # we are lucky! no stress activities detected, no mail needed
            defer.returnValue([])

        if GLSettings.memory_copy.disable_admin_notification_emails:
            defer.returnValue([])

        if Alarm.last_alarm_email:
            if not is_expired(Alarm.last_alarm_email,
                              minutes=do_not_stress_admin_with_more_than_an_email_every_minutes):
                defer.returnValue([])

        admin_users = yield get_admin_users()
        for u in admin_users:
            notification_dict = yield get_notification(u['language'])

            subject = notification_dict['admin_anomaly_mail_title']
            body = notification_dict['admin_anomaly_mail_template']

            subject = replace_keywords(subject)
            body = replace_keywords(body)

            ret.append({
                'mail_address': u['mail_address'],
                'subject': subject,
                'body': body
            })

        defer.returnValue(ret)
示例#26
0
    def admin_alarm_generate_mail(event_matrix):
        """
        This function put a mail in queue for the Admin, if the
        Admin notification is disable or if another Anomaly has been
        raised in the last 15 minutes, email is not send.
        """
        ret = []

        do_not_stress_admin_with_more_than_an_email_every_minutes = 120

        def replace_keywords(text):
            iterations = 3
            stop = False
            while (stop == False and iterations > 0):
                iterations -= 1
                count = 0
                for keyword, function in KeywordTemplate.iteritems():
                    where = text.find(keyword)
                    if where == -1:
                        continue

                    count += 1

                    text = "%s%s%s" % (text[:where],
                                       function(notification_dict),
                                       text[where + len(keyword):])

                    if count == 0:
                        # finally!
                        stop = True
                        break

        def _disk_anomaly_detail(notification_dict):
            # This happens all the time anomalies are present but disk is ok
            if Alarm.stress_levels['disk_space'] == 0:
                return u''

            if Alarm.stress_levels['disk_space'] == 1:
                return notification_dict['admin_anomaly_disk_low']
            elif Alarm.stress_levels['disk_space'] == 2:
                return notification_dict['admin_anomaly_disk_medium']
            else:
                return notification_dict['admin_anomaly_disk_high']

        def _activities_anomaly_detail(notification_dict):
            # This happens all the time there is not anomalous traffic
            if Alarm.stress_levels['activity'] == 0:
                return u''

            return notification_dict['admin_anomaly_activities']

        def _activity_alarm_level(notification_dict):
            return "%s" % Alarm.stress_levels['activity']

        def _activity_dump(notification_dict):
            retstr = ""

            for event, amount in event_matrix.iteritems():
                if not amount:
                    continue
                retstr = "%s%s%d\n%s" % \
                         (event, (25 - len(event)) * " ", amount, retstr)

            return retstr

        def _node_name(notification_dict):
            return unicode(GLSettings.memory_copy.nodename)

        def _free_disk_space(notification_dict):
            return "%s" % bytes_to_pretty_str(Alarm.latest_measured_freespace)

        def _total_disk_space(notification_dict):
            return "%s" % bytes_to_pretty_str(Alarm.latest_measured_totalspace)

        def _notifications_suppressed(notification_dict):
            if Alarm.stress_levels['notification'] == []:
                return u''
            return "** %s **" % Alarm.stress_levels['notification']

        KeywordTemplate = {
            "%AnomalyDetailDisk%": _disk_anomaly_detail,
            "%AnomalyDetailActivities%": _activities_anomaly_detail,
            "%ActivityAlarmLevel%": _activity_alarm_level,
            "%ActivityDump%": _activity_dump,
            "%NotificationsSuppressed%": _notifications_suppressed,
            "%NodeName%": _node_name,
            "%FreeMemory%": _free_disk_space,
            "%TotalMemory%": _total_disk_space,
        }
        # ------------------------------------------------------------------

        if not (Alarm.stress_levels['activity']
                or Alarm.stress_levels['disk_space']
                or Alarm.stress_levels['notification']):
            # we are lucky! no stress activities detected, no mail needed
            defer.returnValue([])

        if GLSettings.memory_copy.disable_admin_notification_emails:
            defer.returnValue([])

        if Alarm.last_alarm_email:
            if not is_expired(
                    Alarm.last_alarm_email,
                    minutes=
                    do_not_stress_admin_with_more_than_an_email_every_minutes):
                defer.returnValue([])

        admin_users = yield get_admin_users()
        for u in admin_users:
            notification_dict = yield get_notification(u['language'])

            subject = notification_dict['admin_anomaly_mail_title']
            body = notification_dict['admin_anomaly_mail_template']

            replace_keywords(subject)
            replace_keywords(body)

            ret.append({
                'mail_address': u['mail_address'],
                'subject': subject,
                'body': body
            })

        defer.returnValue(ret)
示例#27
0
    def admin_alarm_notification(event_matrix):
        """
        This function put a mail in queue for the Admin, if the
        configured threshold has been reached for Alarm notification.
        TODO put a GLSetting + Admin configuration variable,
        now is hardcoded to notice at >= 1
        """

        @transact_ro
        def _get_admin_email(store):
            node = store.find(models.Node).one()
            return node.email

        @transact_ro
        def _get_message_template(store):
            admin_user = store.find(models.User, models.User.username == u'admin').one()
            notif = store.find(models.Notification).one()
            template = notif.admin_anomaly_template
            if admin_user.language in template:
                return template[admin_user.language]
            elif GLSetting.memory_copy.default_language in template:
                return template[GLSetting.memory_copy.default_language]
            else:
                raise Exception("Cannot find any language for admin notification")

        def _aal():
            return "%s" % Alarm.stress_levels['activity']

        def _ad():

            retstr = ""
            for event, amount in event_matrix.iteritems():
                retstr = "%s: %d\n%s" % (event, amount, retstr)
            return retstr

        def _dal():
            return "%s" % Alarm.stress_levels['disk_space']

        def _dd():
            return "%s Megabytes" % Alarm.latest_measured_freespace

        message_required = False
        if Alarm.stress_levels['activity'] >= 1:
            message_required = True
        if Alarm.stress_levels['disk_space'] >= 1:
            message_required = True

        if not message_required:
            # luckly, no mail needed
            return

        KeyWordTemplate = {
            "%ActivityAlarmLevel%" : _aal,
            "%ActivityDump%" : _ad,
            "%DiskAlarmLevel%" : _dal,
            "%DiskDump%" : _dd,
        }

        message = yield _get_message_template()
        for keyword, function in KeyWordTemplate.iteritems():
            where = message.find(keyword)
            message = "%s%s%s" % (
                message[:where],
                function(),
                message[where + len(keyword):])

        if Alarm.last_alarm_email:
            if not is_expired(Alarm.last_alarm_email, minutes=10):
                log.debug("Alert email want be send, but the threshold of 10 minutes is not yet reached since %s" %
                    datetime_to_ISO8601(Alarm.last_alarm_email))
                return

        to_address = yield _get_admin_email()
        message = MIME_mail_build(GLSetting.memory_copy.notif_source_name,
                                    GLSetting.memory_copy.notif_source_email,
                                    "Tester",
                                    to_address,
                                    "ALERT: Anomaly detection",
                                    message)

        log.debug('Alarm Email for admin: connecting to [%s:%d]' %
                    (GLSetting.memory_copy.notif_server,
                     GLSetting.memory_copy.notif_port) )

        Alarm.last_alarm_email = datetime_now()

        yield sendmail(authentication_username=GLSetting.memory_copy.notif_username,
                       authentication_password=GLSetting.memory_copy.notif_password,
                       from_address=GLSetting.memory_copy.notif_source_email,
                       to_address=to_address,
                       message_file=message,
                       smtp_host=GLSetting.memory_copy.notif_server,
                       smtp_port=GLSetting.memory_copy.notif_port,
                       security=GLSetting.memory_copy.notif_security,
                       event=None)
示例#28
0
 def test_is_expired(self):
     self.assertTrue(utility.is_expired(utility.datetime_null()))
     self.assertTrue(utility.is_expired(utility.datetime_now()))
     self.assertFalse(utility.is_expired(utility.datetime_never()))
示例#29
0
def login(session,
          tid,
          username,
          password,
          receiver_second_login,
          receiver_auth_code,
          client_using_tor,
          client_ip,
          token=''):
    """
    login returns a tuple (user_id, state, role, pcn, authCodePrepared)
    """
    if token:
        user = session.query(User).filter(User.auth_token == token, \
                                          User.state != u'disabled', \
                                          User.tid == tid).one_or_none()
    else:
        user = session.query(User).filter(User.username == username, \
                                          User.state != u'disabled', \
                                          User.tid == tid).one_or_none()

    if user is None or (not token and not security.check_password(
            password, user.salt, user.password)):
        log.debug("Login: Invalid credentials")
        Settings.failed_login_attempts += 1
        raise errors.InvalidAuthentication

    if not client_using_tor and not mystate.tenant_cache[tid]['https_' +
                                                              user.role]:
        log.err("Denied login request over Web for role '%s'" % user.role)
        raise errors.TorNetworkRequired

    # Check if we're doing IP address checks today
    if mystate.tenant_cache[tid]['ip_filter_authenticated_enable']:
        ip_networks = parse_csv_ip_ranges_to_ip_networks(
            mystate.tenant_cache[tid]['ip_filter_authenticated'])
        client_ip = text_type(client_ip)
        client_ip_obj = ipaddress.ip_address(client_ip)

        # Safety check, we always allow localhost to log in
        success = False
        if client_ip_obj.is_loopback is True:
            success = True

        for ip_network in ip_networks:
            if client_ip_obj in ip_network:
                success = True

        if success is not True:
            raise errors.AccessLocationInvalid

    # se sono arrivato qui il primo login è andato a buon fine
    # il login (username, password) per un ricevente viene rieseguito anche al secondo passaggio
    # per motivi di sicurezza
    # A QUESTO PUNTO:
    # SE receiver2ndStepLoginState = 'N':
    # 1 - genero il codice
    # 2 - memorizzo record in ReceiverAuthCode
    # 3 - invio mail
    # ELSE:
    # verifico la correttenza del secondo codice
    if user.role == 'receiver':

        receiver = session.query(Receiver).filter(
            Receiver.id == user.id).one_or_none()

        if receiver.two_step_login_enabled and not user.password_change_needed:

            if receiver_second_login == 'first_login_to_complete':

                yyyy = str(datetime_now().year)
                mm = str(datetime_now().month).zfill(2)
                dd = str(datetime_now().day).zfill(2)
                result_query = session.query(ReceiverAuthCode).filter(
                    ReceiverAuthCode.receiver_id == user.id,
                    func.strftime("%Y-%m-%d",
                                  ReceiverAuthCode.creation_date) == yyyy +
                    '-' + mm + '-' + dd).all()

                # genero il codice
                #chiamo la funzione generate_authcode_password che genera la password con l'utilizzo della funzione os.urandom
                #randnum = ''.join(["%s" % SystemRandom().randint(0, 9) for num in range(0, 12)])
                randnum = generate_authcode_password(12)

                #print randnum
                log.debug(randnum[0:4] + ' ' + randnum[4:8] + ' ' +
                          randnum[8:12])

                # inserisco il record nel db
                newAuthCode = models.ReceiverAuthCode()
                newAuthCode.receiver_id = receiver.id

                newAuthCode.salt = security.generateRandomSalt()
                newAuthCode.auth_code = security.hash_password(
                    randnum, newAuthCode.salt)

                session.add(newAuthCode)
                session.flush()

                # invio i tre pezzi del codice alle tre mail specificate nel profilo del ricevente
                email_prg = str(len(result_query) + 1)
                day = dd + '/' + mm + '/' + yyyy
                mystate.sendmail(
                    1, receiver.control_mail_1,
                    "Receiver Auth Code #" + email_prg + " - " + day,
                    randnum[0:4])
                mystate.sendmail(
                    1, receiver.control_mail_2,
                    "Receiver Auth Code #" + email_prg + " - " + day,
                    randnum[4:8])
                mystate.sendmail(
                    1, receiver.control_mail_3,
                    "Receiver Auth Code #" + email_prg + " - " + day,
                    randnum[8:12])

                log.debug("Invio delle mail effettuato con successo")

                receiver_second_login = '******'

            elif receiver_second_login == 'second_login_to_complete':
                auth_code_item = session.query(ReceiverAuthCode).filter(ReceiverAuthCode.receiver_id == user.id) \
                                                                .order_by(ReceiverAuthCode.creation_date.desc()).first()

                # se non sono passati TOT minuti dall'ultimo codice emesso si può controllare la validità del codice
                if auth_code_item is not None and auth_code_item.is_valid and not is_expired(
                        auth_code_item.creation_date, 0,
                        AUTH_CODE_EXPIRATION_IN_MINUTES, 0, 0):

                    # qui devo verificare che il codice inviato dall'utente sia uguale a una delle permutazioni dei tre blocchi
                    # da quattro cifre che si ottengono dal codice salvato sul db
                    firstBlock = receiver_auth_code[0:4]
                    secondBlock = receiver_auth_code[4:8]
                    thirdBlock = receiver_auth_code[8:12]
                    combList = []
                    combList.insert(0, firstBlock + secondBlock + thirdBlock)
                    combList.insert(1, firstBlock + thirdBlock + secondBlock)
                    combList.insert(2, secondBlock + firstBlock + thirdBlock)
                    combList.insert(3, secondBlock + thirdBlock + firstBlock)
                    combList.insert(4, thirdBlock + firstBlock + secondBlock)
                    combList.insert(5, thirdBlock + secondBlock + firstBlock)

                    auth_code_match = False
                    for authCode in combList:
                        if security.check_password(authCode,
                                                   auth_code_item.salt,
                                                   auth_code_item.auth_code):
                            auth_code_match = True

                            # POSSO ANCHE FARE UNA UPDATE del campo is_valid PER IL RECORD UTILIZZATO NELLA VALIDAZIONE
                            auth_code_item.is_valid = False
                            session.add(auth_code_item)
                            session.flush()

                            #objs = session.query(ReceiverAuthCode).filter(ReceiverAuthCode.receiver_id == auth_code_item.receiver_id) \
                            #                                      .order_by(ReceiverAuthCode.creation_date.desc(), ReceiverAuthCode.daily_prg.desc())
                            #for obj in objs:
                            #    session.delete(obj)
                            #    session.flush()
                            #session.delete(auth_code_item)

                            receiver_second_login = '******'
                            break

                    if not auth_code_match:
                        log.debug("Login: Invalid authentication code")
                        Settings.failed_login_attempts += 1
                        raise errors.InvalidAuthentication

                else:
                    log.debug(
                        "Login: authentication code is expired. Please repeat login"
                    )
                    Settings.failed_login_attempts += 1
                    raise errors.InvalidAuthentication

            else:
                log.debug(
                    "receiver_auth_code diverso da first_login_to_complete e second_login_to_complete"
                )
                receiver_second_login = '******'
        else:
            receiver_second_login = '******'  #da tenere sotto controllo

    else:
        receiver_second_login = '******'  # da tenere sotto controllo

    log.debug("Login: Success (%s)" % user.role)

    user.last_login = datetime_now()

    return user.id, user.state, user.role, user.password_change_needed, receiver_second_login
示例#30
0
    def admin_alarm_generate_mail(event_matrix):
        """
        This function put a mail in queue for the Admin, if the
        Admin notification is disable or if another Anomaly has been
        raised in the last 15 minutes, email is not send.
        """
        do_not_stress_admin_with_more_than_an_email_every_minutes = 120
        # if emergency is set to True, the previous time check is ignored.
        emergency_notification = False

        @transact_ro
        def _get_node_admin_email(store):
            node = store.find(models.Node).one()
            return node.email

        @transact_ro
        def _get_admin_user_language(store):
            admin_user = store.find(models.User,
                                    models.User.username == u'admin').one()
            return admin_user.language

        # THE THREE FUNCTIONS BELOW ARE POORLY SUBOPTIMAL,
        # AND THIS IS BAD: REFACTOR TO BE DONE ON THIS SUBJECT
        @transact_ro
        def _get_message_template(store):
            admin_user = store.find(models.User,
                                    models.User.username == u'admin').one()
            notif = store.find(models.Notification).one()
            template = notif.admin_anomaly_mail_template
            if admin_user.language in template:
                localized_template = template[admin_user.language]
            elif GLSettings.memory_copy.default_language in template:
                localized_template = template[
                    GLSettings.memory_copy.default_language]
            else:
                raise Exception(
                    "Cannot find any language for admin notification")
            return localized_template

        @transact_ro
        def _disk_anomaly_detail(store):
            # This happen all the time anomalies are present but disk is ok
            if Alarm.stress_levels['disk_space'] == 0:
                return u''
            admin_user = store.find(models.User,
                                    models.User.username == u'admin').one()
            notif = store.find(models.Notification).one()
            if Alarm.stress_levels['disk_space'] == 1:
                template = notif.admin_anomaly_disk_low
            elif Alarm.stress_levels['disk_space'] == 2:
                template = notif.admin_anomaly_disk_medium
            elif Alarm.stress_levels['disk_space'] == 3:
                template = notif.admin_anomaly_disk_high
            else:
                raise Exception("Invalid disk stess level %d" %
                                Alarm.stress_levels['disk_space'])
            if admin_user.language in template:
                localized_template = template[admin_user.language]
            elif GLSettings.memory_copy.default_language in template:
                localized_template = template[
                    GLSettings.memory_copy.default_language]
            else:
                raise Exception(
                    "Cannot find any language for Admin disk alarm (level %d)"
                    % Alarm.stress_levels['disk_space'])
            return localized_template

        @transact_ro
        def _activities_anomaly_detail(store):
            # This happen all the time there is not anomalous traffic
            if Alarm.stress_levels['activity'] == 0:
                return u''
            admin_user = store.find(models.User,
                                    models.User.username == u'admin').one()
            notif = store.find(models.Notification).one()
            template = notif.admin_anomaly_activities
            if admin_user.language in template:
                localized_template = template[admin_user.language]
            elif GLSettings.memory_copy.default_language in template:
                localized_template = template[
                    GLSettings.memory_copy.default_language]
            else:
                raise Exception(
                    "Cannot find any language for admin notification")
            return localized_template

        # END OF THE SUB-OPTIMAL SECTION OF CODE THAT HAS TO BE RESTRUCTURED

        def _activity_alarm_level():
            return "%s" % Alarm.stress_levels['activity']

        def _activity_dump():
            retstr = ""
            for event, amount in event_matrix.iteritems():
                if not amount:
                    continue
                retstr = "%s%s%d\n%s" % \
                         (event, (25 - len(event)) * " ",
                          amount, retstr)
            return retstr

        @transact_ro
        def _node_name(store):
            node = store.find(models.Node).one()
            return unicode(node.name)

        def _free_disk_space():
            return "%s" % bytes_to_pretty_str(Alarm.latest_measured_freespace)

        def _total_disk_space():
            return "%s" % bytes_to_pretty_str(Alarm.latest_measured_totalspace)

        def _notification_suppressed():
            if Alarm.stress_levels['notification'] == []:
                return u''
            emergency_notification = True
            return "** %s **" % Alarm.stress_levels['notification']

        KeyWordTemplate = {
            "%AnomalyDetailDisk%": _disk_anomaly_detail,
            "%AnomalyDetailActivities%": _activities_anomaly_detail,
            "%ActivityAlarmLevel%": _activity_alarm_level,
            "%ActivityDump%": _activity_dump,
            "%NotificationSuppressed%": _notification_suppressed,
            "%NodeName%": _node_name,
            "%FreeMemory%": _free_disk_space,
            "%TotalMemory%": _total_disk_space,
        }
        # ------------------------------------------------------------------

        # Independently from the event_matrix, the status of the stress level can
        # be in non-0 value.
        # Here start the Anomaly Notification code, before checking if we have to send email
        if not (Alarm.stress_levels['activity']
                or Alarm.stress_levels['disk_space']
                or Alarm.stress_levels['notification']):
            # lucky, no stress activities recorded: no mail needed
            defer.returnValue(None)

        if GLSettings.memory_copy.disable_admin_notification_emails:
            # event_matrix is {} if we are here only for disk
            log.debug(
                "Anomaly to be reported %s, but Admin has Notification disabled"
                % "[%s]" % event_matrix if event_matrix else "")
            defer.returnValue(None)

        if Alarm.last_alarm_email and not emergency_notification:
            if not is_expired(
                    Alarm.last_alarm_email,
                    minutes=
                    do_not_stress_admin_with_more_than_an_email_every_minutes):
                defer.returnValue(None)
                # This is skipped then:
                log.debug(
                    "Alert [%s] want be sent, but the threshold of %d minutes still unexpired %s"
                    %
                    (Alarm.stress_levels,
                     do_not_stress_admin_with_more_than_an_email_every_minutes,
                     datetime_to_ISO8601(Alarm.last_alarm_email)))

        admin_email = yield _get_node_admin_email()
        admin_language = yield _get_admin_user_language()
        notification_settings = yield get_notification(admin_language)

        # and now, processing the template
        message = yield _get_message_template()
        message_title = notification_settings['admin_anomaly_mail_title']
        recursion_time = 2

        # since the ActivityDetails, we've to manage recursion
        while recursion_time:
            recursion_time -= 1

            for keyword, templ_funct in KeyWordTemplate.iteritems():

                where = message.find(keyword)
                if where == -1:
                    continue

                # based on the type of templ_funct, we've to use 'yield' or not
                # cause some returns a deferred.
                if isinstance(templ_funct, type(sendmail)):
                    content = templ_funct()
                else:
                    content = yield templ_funct()

                message = "%s%s%s" % (message[:where], content,
                                      message[where + len(keyword):])

        # message title, we can't put the loop together at the moment
        for keyword, templ_funct in KeyWordTemplate.iteritems():

            where = message_title.find(keyword)
            if where == -1:
                continue

            if isinstance(templ_funct, type(sendmail)):
                content = templ_funct()
            else:
                content = yield templ_funct()

            message_title = "%s%s%s" % (message_title[:where], content,
                                        message_title[where + len(keyword):])

        message = MIME_mail_build(GLSettings.memory_copy.notif_source_name,
                                  GLSettings.memory_copy.notif_source_email,
                                  admin_email, admin_email, message_title,
                                  message)

        log.debug(
            'Alarm Email generated for Admin (%s): connecting to [%s:%d], '
            'the next mail should be in %d minutes' %
            (event_matrix, GLSettings.memory_copy.notif_server,
             GLSettings.memory_copy.notif_port,
             do_not_stress_admin_with_more_than_an_email_every_minutes))

        defer.returnValue({
            'admin_email': admin_email,
            'message': message,
        })
示例#31
0
 def test_is_expired(self):
     self.assertFalse(utility.is_expired(None))
     self.assertTrue(utility.is_expired(utility.datetime_null()))
     self.assertTrue(utility.is_expired(utility.datetime_now()))
     self.assertFalse(utility.is_expired(utility.utc_future_date(seconds=1337)))
示例#32
0
    def admin_alarm_notification(event_matrix):
        """
        This function put a mail in queue for the Admin, if the
        configured threshold has been reached for Alarm notification.
        TODO put a GLSetting + Admin configuration variable,
        now is hardcoded to notice at >= 1
        """
        @transact_ro
        def _get_node_name(store):
            node = store.find(models.Node).one()
            return node.email

        @transact_ro
        def _get_admin_email(store):
            node = store.find(models.Node).one()
            return node.email

        node_name = yield _get_node_name()
        admin_email = yield _get_admin_email()

        @transact_ro
        def _get_message_template(store):
            admin_user = store.find(models.User,
                                    models.User.username == u'admin').one()
            notif = store.find(models.Notification).one()
            template = notif.admin_anomaly_template
            if admin_user.language in template:
                return template[admin_user.language]
            elif GLSetting.memory_copy.language in template:
                return template[GLSetting.memory_copy.language]
            else:
                raise Exception(
                    "Cannot find any language for admin notification")

        def _aal():
            return "%s" % Alarm.stress_levels['activity']

        def _ad():
            retstr = ""
            for event, amount in event_matrix.iteritems():
                retstr = "%s: %d\n%s" % (event, amount, retstr)
            return retstr

        def _dal():
            return "%s" % Alarm.stress_levels['disk_space']

        def _dd():
            return "%s" % bytes_to_pretty_str(Alarm.latest_measured_freespace)

        def _nn():
            return "%s" % node_name

        message_required = False
        if Alarm.stress_levels['activity'] >= 1:
            message_required = True
        if Alarm.stress_levels['disk_space'] >= 1:
            message_required = True

        if not message_required:
            # luckly, no mail needed
            return

        KeyWordTemplate = {
            "%ActivityAlarmLevel%": _aal,
            "%ActivityDump%": _ad,
            "%DiskAlarmLevel%": _dal,
            "%DiskDump%": _dd,
            "%NodeSignature%": _nn
        }

        message = yield _get_message_template()
        for keyword, function in KeyWordTemplate.iteritems():
            where = message.find(keyword)
            message = "%s%s%s" % (message[:where], function(),
                                  message[where + len(keyword):])

        if Alarm.last_alarm_email:
            if not is_expired(Alarm.last_alarm_email, minutes=10):
                log.debug(
                    "Alert email want be send, but the threshold of 10 minutes is not yet reached since %s"
                    % datetime_to_ISO8601(Alarm.last_alarm_email))
                return

        message = MIME_mail_build(GLSetting.memory_copy.notif_source_name,
                                  GLSetting.memory_copy.notif_source_email,
                                  "Admin", admin_email,
                                  "ALERT: Anomaly detection", message)

        log.debug('Alarm Email for admin: connecting to [%s:%d]' %
                  (GLSetting.memory_copy.notif_server,
                   GLSetting.memory_copy.notif_port))

        Alarm.last_alarm_email = datetime_now()

        yield sendmail(
            authentication_username=GLSetting.memory_copy.notif_username,
            authentication_password=GLSetting.memory_copy.notif_password,
            from_address=GLSetting.memory_copy.notif_source_email,
            to_address=admin_email,
            message_file=message,
            smtp_host=GLSetting.memory_copy.notif_server,
            smtp_port=GLSetting.memory_copy.notif_port,
            security=GLSetting.memory_copy.notif_security,
            event=None)
示例#33
0
 def test_is_expired(self):
     self.assertFalse(utility.is_expired(None))
     self.assertTrue(utility.is_expired(utility.datetime_null()))
     self.assertTrue(utility.is_expired(utility.datetime_now()))
     self.assertFalse(utility.is_expired(utility.utc_future_date(seconds=1337)))
示例#34
0
 def test_is_expired(self):
     self.assertTrue(utility.is_expired(utility.datetime_null()))
     self.assertTrue(utility.is_expired(utility.datetime_now()))
     self.assertFalse(utility.is_expired(utility.datetime_never()))