Exemple #1
0
    def process_mail_creation(self, session, tid, data):
        user_id = data['user']['id']
        language = data['user']['language']

        # Do not spool emails if the receiver has disabled notifications
        if not data['user']['notification'] or ('tip' in data and not data['tip']['enable_notifications']):
            log.debug("Discarding emails for %s due to receiver's preference.", user_id)
            return

        data['node'] = self.serialize_config(session, 'node', tid, language)

        data['submission_statuses'] = db_get_submission_statuses(session, tid, language)

        if data['node']['mode'] == 'default':
            data['notification'] = self.serialize_config(session, 'notification', tid, language)
        else:
            data['notification'] = self.serialize_config(session, 'notification', 1, language)

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

        # If the receiver has encryption enabled encrypt the mail body
        if data['user']['pgp_key_public']:
            pgpctx = PGPContext(self.state.settings.tmp_path)
            fingerprint = pgpctx.load_key(data['user']['pgp_key_public'])['fingerprint']
            body = pgpctx.encrypt_message(fingerprint, body)

        session.add(models.Mail({
            'address': data['user']['mail_address'],
            'subject': subject,
            'body': body,
            'tid': tid,
        }))
Exemple #2
0
    def process_mail_creation(self, session, tid, data):
        user_id = data['user']['id']

        # Do not spool emails if the receiver has opted out of ntfns for this tip.
        if not data['tip']['enable_notifications']:
            log.debug("Discarding emails for %s due to receiver's preference.",
                      user_id)
            return

        # https://github.com/globaleaks/GlobaLeaks/issues/798
        # TODO: the current solution is global and configurable only by the admin
        sent_emails = self.state.get_mail_counter(user_id)
        if sent_emails >= self.state.tenant_cache[
                tid].notification.notification_threshold_per_hour:
            log.debug(
                "Discarding emails for receiver %s due to threshold already exceeded for the current hour",
                user_id)
            return

        self.state.increment_mail_counter(user_id)
        if sent_emails >= self.state.tenant_cache[
                tid].notification.notification_threshold_per_hour:
            log.info(
                "Reached threshold of %d emails with limit of %d for receiver %s",
                sent_emails,
                self.state.tenant_cache[tid].notification.
                notification_threshold_per_hour,
                user_id,
                tid=tid)

            # simply changing the type of the notification causes
            # to send the notification_limit_reached
            data['type'] = u'receiver_notification_limit_reached'

        data['node'] = self.serialize_config(session, 'node', tid,
                                             data['user']['language'])

        if data['node']['mode'] != u'whistleblowing.it':
            data['notification'] = self.serialize_config(
                session, 'notification', tid, data['user']['language'])
        else:
            data['notification'] = self.serialize_config(
                session, 'notification', 1, data['user']['language'])

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

        # If the receiver has encryption enabled encrypt the mail body
        if data['user']['pgp_key_public']:
            pgpctx = PGPContext(self.state.settings.tmp_path)
            fingerprint = pgpctx.load_key(
                data['user']['pgp_key_public'])['fingerprint']
            body = pgpctx.encrypt_message(fingerprint, body)

        session.add(
            models.Mail({
                'address': data['user']['mail_address'],
                'subject': subject,
                'body': body,
                'tid': tid,
            }))
Exemple #3
0
    def format_and_send_mail(self, session, tid, user_desc, template_vars):
        subject, body = Templating().get_mail_subject_and_body(template_vars)

        if user_desc.get('pgp_key_public', ''):
            pgpctx = PGPContext(self.settings.tmp_path)
            fingerprint = pgpctx.load_key(user_desc['pgp_key_public'])['fingerprint']
            body = pgpctx.encrypt_message(fingerprint, body)

        db_schedule_email(session, tid, user_desc['mail_address'], subject, body)
Exemple #4
0
    def format_and_send_mail(self, session, tid, user_desc, template_vars):
        subject, body = Templating().get_mail_subject_and_body(template_vars)

        if user_desc.get('pgp_key_public', ''):
            pgpctx = PGPContext(self.settings.tmp_path)
            fingerprint = pgpctx.load_key(user_desc['pgp_key_public'])['fingerprint']
            body = pgpctx.encrypt_message(fingerprint, body)

        db_schedule_email(session, tid, user_desc['mail_address'], subject, body)
Exemple #5
0
    def schedule_exception_email(self, exception_text, *args):
        from globaleaks.transactions import schedule_email

        if not hasattr(self.tenant_cache[1], 'notification'):
            log.err(
                "Error: Cannot send mail exception before complete initialization."
            )
            return

        if self.exceptions_email_count >= self.settings.exceptions_email_hourly_limit:
            return

        exception_text = (exception_text % args) if args else exception_text

        sha256_hash = sha256(bytes(exception_text))

        if sha256_hash not in self.exceptions:
            self.exceptions[sha256_hash] = 0

        self.exceptions[sha256_hash] += 1
        if self.exceptions[sha256_hash] > 5:
            log.err(
                "Exception mail suppressed for (%s) [reason: threshold exceeded]",
                sha256_hash)
            return

        self.exceptions_email_count += 1

        mail_subject = "GlobaLeaks Exception"
        delivery_list = self.tenant_cache[
            1].notification.exception_delivery_list

        if self.settings.devel_mode:
            mail_subject += " [%s]" % self.settings.developer_name
            delivery_list = [("*****@*****.**",
                              '')]

        mail_body = bytes("Platform: %s (%s)\nVersion: %s\n\n%s" \
                          % (self.tenant_cache[1].hostname,
                             self.tenant_cache[1].onionservice,
                             __version__,
                             exception_text))

        for mail_address, pgp_key_public in delivery_list:
            # Opportunisticly encrypt the mail body. NOTE that mails will go out
            # unencrypted if one address in the list does not have a public key set.
            if pgp_key_public:
                pgpctx = PGPContext(self.settings.tmp_path)
                fingerprint = pgpctx.load_key(pgp_key_public)['fingerprint']
                mail_body = pgpctx.encrypt_message(fingerprint, mail_body)

            # avoid waiting for the notification to send and instead rely on threads to handle it
            schedule_email(1, mail_address, mail_subject, mail_body)
    def format_and_send_mail(self, session, tid, user_desc, template_vars):
        subject, body = Templating().get_mail_subject_and_body(template_vars)

        if user_desc.get('pgp_key_public', ''):
            pgpctx = PGPContext(self.settings.tmp_path)
            fingerprint = pgpctx.load_key(user_desc['pgp_key_public'])['fingerprint']
            body = pgpctx.encrypt_message(fingerprint, body)

        session.add(models.Mail({
            'address': user_desc['mail_address'],
            'subject': subject,
            'body': body,
            'tid': tid,
        }))
Exemple #7
0
    def test_encrypt_message(self):
        fake_receiver_desc = {
            'pgp_key_public': helpers.PGPKEYS['VALID_PGP_KEY1_PUB'],
            'pgp_key_fingerprint': u'BFB3C82D1B5F6A94BDAC55C6E70460ABF9A4C8C1',
            'username': u'*****@*****.**',
        }

        pgpctx = PGPContext()
        pgpctx.load_key(helpers.PGPKEYS['VALID_PGP_KEY1_PRV'])

        encrypted_body = pgpctx.encrypt_message(fake_receiver_desc['pgp_key_fingerprint'],
                                                self.secret_content)

        self.assertEqual(str(pgpctx.gnupg.decrypt(encrypted_body)), self.secret_content)
Exemple #8
0
    def process_mail_creation(self, session, tid, data):
        user_id = data['user']['id']

        # Do not spool emails if the receiver has opted out of ntfns for this tip.
        if not data['tip']['enable_notifications']:
            log.debug("Discarding emails for %s due to receiver's preference.", user_id)
            return

        # https://github.com/globaleaks/GlobaLeaks/issues/798
        # TODO: the current solution is global and configurable only by the admin
        sent_emails = self.state.get_mail_counter(user_id)
        if sent_emails >= self.state.tenant_cache[tid].notification.notification_threshold_per_hour:
            log.debug("Discarding emails for receiver %s due to threshold already exceeded for the current hour",
                      user_id)
            return

        self.state.increment_mail_counter(user_id)
        if sent_emails >= self.state.tenant_cache[tid].notification.notification_threshold_per_hour:
            log.info("Reached threshold of %d emails with limit of %d for receiver %s",
                     sent_emails,
                     self.state.tenant_cache[tid].notification.notification_threshold_per_hour,
                     user_id,
                     tid=tid)

            # simply changing the type of the notification causes
            # to send the notification_limit_reached
            data['type'] = u'receiver_notification_limit_reached'

        data['node'] = self.serialize_config(session, 'node', tid, data['user']['language'])

        if data['node']['mode'] != u'whistleblowing.it':
            data['notification'] = self.serialize_config(session, 'notification', tid, data['user']['language'])
        else:
            data['notification'] = self.serialize_config(session, 'notification', 1, data['user']['language'])

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

        # If the receiver has encryption enabled encrypt the mail body
        if data['user']['pgp_key_public']:
            pgpctx = PGPContext(self.state.settings.tmp_path)
            fingerprint = pgpctx.load_key(data['user']['pgp_key_public'])['fingerprint']
            body = pgpctx.encrypt_message(fingerprint, body)

        session.add(models.Mail({
            'address': data['user']['mail_address'],
            'subject': subject,
            'body': body,
            'tid': tid,
        }))
Exemple #9
0
    def schedule_exception_email(self, exception_text, *args):
        if not hasattr(self.tenant_cache[1], 'notification'):
            log.err("Error: Cannot send mail exception before complete initialization.")
            return

        if self.exceptions_email_count >= self.settings.exceptions_email_hourly_limit:
            return

        exception_text = (exception_text % args) if args else exception_text

        sha256_hash = sha256(exception_text.encode())

        if sha256_hash not in self.exceptions:
            self.exceptions[sha256_hash] = 0

        self.exceptions[sha256_hash] += 1
        if self.exceptions[sha256_hash] > 5:
            log.err("Exception mail suppressed for (%s) [reason: threshold exceeded]", sha256_hash)
            return

        self.exceptions_email_count += 1

        mail_subject = "GlobaLeaks Exception"
        delivery_list = self.tenant_cache[1].notification.exception_delivery_list

        mail_body = text_type("Platform: %s\nHost: %s (%s)\nVersion: %s\n\n%s"
                          % (self.tenant_cache[1].name,
                             self.tenant_cache[1].hostname,
                             self.tenant_cache[1].onionservice,
                             __version__,
                             exception_text))

        for mail_address, pgp_key_public in delivery_list:
            # Opportunisticly encrypt the mail body. NOTE that mails will go out
            # unencrypted if one address in the list does not have a public key set.
            if pgp_key_public:
                pgpctx = PGPContext(self.settings.tmp_path)
                fingerprint = pgpctx.load_key(pgp_key_public)['fingerprint']
                mail_body = pgpctx.encrypt_message(fingerprint, mail_body)

            # avoid waiting for the notification to send and instead rely on threads to handle it
            tw(db_schedule_email, 1, mail_address, mail_subject, mail_body)