def schedule_exception_email(exception_text, *args): try: from globaleaks.transactions import schedule_email if not hasattr(GLSettings.memory_copy, 'notif'): log.err( "Error: Cannot send mail exception before complete initialization." ) return if GLSettings.exceptions_email_count >= GLSettings.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 GLSettings.exceptions: GLSettings.exceptions[sha256_hash] = 1 else: GLSettings.exceptions[sha256_hash] += 1 if GLSettings.exceptions[sha256_hash] > 5: log.err( "Exception mail suppressed for (%s) [reason: threshold exceeded]", sha256_hash) return GLSettings.exceptions_email_count += 1 mail_subject = "GlobaLeaks Exception" delivery_list = GLSettings.memory_copy.notif.exception_delivery_list if GLSettings.devel_mode: mail_subject += " [%s]" % GLSettings.developer_name delivery_list = [("*****@*****.**", '')] exception_text = bytes("Platform: %s (%s)\nVersion: %s\n\n%s" \ % (GLSettings.memory_copy.hostname, GLSettings.memory_copy.onionservice, __version__, exception_text)) for mail_address, pub_key in delivery_list: mail_body = exception_text # 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 pub_key: mail_body = encrypt_message(pub_key, mail_body) # avoid waiting for the notification to send and instead rely on threads to handle it schedule_email(mail_address, mail_subject, mail_body) except Exception as excep: # Avoid raising exception inside email logic to avoid chaining errors log.err("Unexpected exception in send_exception_mail: %s", excep)
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 schedule_exception_email(exception_text): from globaleaks.transactions import schedule_email if not hasattr(GLSettings.memory_copy, 'notif'): log.err( "Error: Cannot send mail exception before complete initialization." ) return if GLSettings.exceptions_email_count >= GLSettings.exceptions_email_hourly_limit: return mail_subject = "GlobaLeaks Exception" delivery_list = GLSettings.memory_copy.notif.exception_delivery_list if GLSettings.devel_mode: mail_subject += " [%s]" % GLSettings.developer_name delivery_list = [("*****@*****.**", '') ] exception_text = bytes("Platform: %s (%s)\nVersion: %s\n\n%s" \ % (GLSettings.memory_copy.hostname, GLSettings.memory_copy.onionservice, __version__, exception_text)) sha256_hash = sha256(exception_text) if sha256_hash in GLSettings.exceptions: GLSettings.exceptions[sha256_hash] += 1 if GLSettings.exceptions[sha256_hash] > 5: # if the threshold has been exceeded log.err( "exception mail suppressed for exception (%s) [reason: threshold exceeded]" % sha256_hash) return else: GLSettings.exceptions[sha256_hash] = 1 GLSettings.exceptions_email_count += 1 try: for mail_address, pub_key in delivery_list: mail_body = exception_text # 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 len(pub_key): gpob = GLBPGP() try: r = gpob.load_key(pub_key) mail_body = gpob.encrypt_message(r['fingerprint'], mail_body) gpob.destroy_environment() except Exception as excep: # If this exception email is configured to be subject to encryption # and the encryption step throws, log the error and move on. log.err("Error while encrypting exception email: %s" % str(excep)) gpob.destroy_environment() continue # avoid waiting for the notification to send and instead rely on threads to handle it schedule_email(mail_address, mail_subject, mail_body) except Exception as excep: # Avoid raising exception inside email logic to avoid chaining errors log.err("Unexpected exception in send_exception_mail: %s" % excep)