def process_mail_creation(self, store, data): receiver_id = data['receiver']['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." % receiver_id) return # https://github.com/globaleaks/GlobaLeaks/issues/798 # TODO: the current solution is global and configurable only by the admin sent_emails = GLSettings.get_mail_counter(receiver_id) if sent_emails >= GLSettings.memory_copy.notification_threshold_per_hour: log.debug("Discarding emails for receiver %s due to threshold already exceeded for the current hour" % receiver_id) return GLSettings.increment_mail_counter(receiver_id) if sent_emails >= GLSettings.memory_copy.notification_threshold_per_hour: log.info("Reached threshold of %d emails with limit of %d for receiver %s" % ( sent_emails, GLSettings.memory_copy.notification_threshold_per_hour, receiver_id) ) # simply changing the type of the notification causes # to send the notification_limit_reached data['type'] = u'receiver_notification_limit_reached' data['notification'] = db_get_notification(store, data['receiver']['language']) data['node'] = db_admin_serialize_node(store, data['receiver']['language']) if not data['node']['allow_unencrypted'] and data['receiver']['pgp_key_status'] != u'enabled': return subject, body = Templating().get_mail_subject_and_body(data) # If the receiver has encryption enabled encrypt the mail body if data['receiver']['pgp_key_status'] == u'enabled': gpob = GLBPGP() try: gpob.load_key(data['receiver']['pgp_key_public']) body = gpob.encrypt_message(data['receiver']['pgp_key_fingerprint'], body) except Exception as excep: log.err("Error in PGP interface object (for %s: %s)! (notification+encryption)" % (data['receiver']['username'], str(excep))) return finally: # the finally statement is always called also if # except contains a return or a raise gpob.destroy_environment() mail = models.Mail({ 'address': data['receiver']['mail_address'], 'subject': subject, 'body': body }) store.add(mail)
def test_encrypt_file(self): # setup the PGP key before GLSettings.pgproot = PGPROOT tempsource = os.path.join(os.getcwd(), "temp_source.txt") with file(tempsource, 'w+') as f1: f1.write("\n\nDecrypt the Cat!\n\nhttp://tobtu.com/decryptocat.php\n\n") f1.seek(0) fake_receiver_desc = { 'pgp_key_public': unicode(VALID_PGP_KEY1), 'pgp_key_status': u'enabled', 'pgp_key_fingerprint': u"CF4A22020873A76D1DCB68D32B25551568E49345", 'username': u'*****@*****.**', } # these are the same lines used in delivery_sched.py pgpobj = GLBPGP() pgpobj.load_key(VALID_PGP_KEY1) encrypted_file_path, encrypted_file_size = pgpobj.encrypt_file(fake_receiver_desc['pgp_key_fingerprint'], tempsource, f1, "/tmp") pgpobj.destroy_environment() with file(encrypted_file_path, "r") as f2: first_line = f2.readline() self.assertSubstring('-----BEGIN PGP MESSAGE-----', first_line) with file(encrypted_file_path, "r") as f2: whole = f2.read() self.assertEqual(encrypted_file_size, len(whole))
def test_encrypt_file(self): # setup the PGP key before GLSetting.pgproot = PGPROOT tempsource = os.path.join(os.getcwd(), "temp_source.txt") with file(tempsource, 'w+') as f1: f1.write("\n\nDecrypt the Cat!\n\nhttp://tobtu.com/decryptocat.php\n\n") f1.seek(0) fake_receiver_desc = { 'pgp_key_public': unicode(VALID_PGP_KEY1), 'pgp_key_status': u'enabled', 'pgp_key_fingerprint': u"CF4A22020873A76D1DCB68D32B25551568E49345", 'username': u'*****@*****.**', } # these are the same lines used in delivery_sched.py pgpobj = GLBPGP() pgpobj.load_key(VALID_PGP_KEY1) encrypted_file_path, encrypted_file_size = pgpobj.encrypt_file(fake_receiver_desc['pgp_key_fingerprint'], tempsource, f1, "/tmp") pgpobj.destroy_environment() with file(encrypted_file_path, "r") as f2: first_line = f2.readline() self.assertSubstring('-----BEGIN PGP MESSAGE-----', first_line) with file(encrypted_file_path, "r") as f2: whole = f2.read() self.assertEqual(encrypted_file_size, len(whole))
def do_notify(self, event): if event.type == "digest": subject = event.tip_info["body"] body = event.tip_info["title"] else: subject, body = self.get_mail_subject_and_body(event) receiver_mail = event.receiver_info["mail_address"] # If the receiver has encryption enabled (for notification), encrypt the mail body if event.receiver_info["pgp_key_status"] == u"enabled": gpob = GLBPGP() try: gpob.load_key(event.receiver_info["pgp_key_public"]) body = gpob.encrypt_message(event.receiver_info["pgp_key_fingerprint"], body) except Exception as excep: log.err( "Error in PGP interface object (for %s: %s)! (notification+encryption)" % (event.receiver_info["username"], str(excep)) ) # On this condition (PGP enabled but key invalid) the only # thing to do is to return None; # It will be duty of the PGP check schedule will disable the key # and advise the user and the admin about that action. return fail(None) finally: # the finally statement is always called also if # except contains a return or a raise gpob.destroy_environment() return sendmail(receiver_mail, subject, body)
def test_encrypt_file(self): file_src = os.path.join(os.getcwd(), 'test_plaintext_file.txt') file_dst = os.path.join(os.getcwd(), 'test_encrypted_file.txt') fake_receiver_desc = { 'pgp_key_public': helpers.PGPKEYS['VALID_PGP_KEY1_PRV'], 'pgp_key_fingerprint': u'ECAF2235E78E71CD95365843C7B190543CAA7585', 'username': u'*****@*****.**', } # these are the same lines used in delivery_sched.py pgpobj = GLBPGP() pgpobj.load_key(helpers.PGPKEYS['VALID_PGP_KEY1_PRV']) with open(file_src, 'w+') as f: f.write(self.secret_content) f.seek(0) encrypted_object, length = pgpobj.encrypt_file(fake_receiver_desc['pgp_key_fingerprint'], f, file_dst) with open(file_dst, 'r') as f: self.assertEqual(str(pgpobj.gnupg.decrypt_file(f)), self.secret_content) pgpobj.destroy_environment()
def test_encrypt_file(self): file_src = os.path.join(os.getcwd(), 'test_plaintext_file.txt') file_dst = os.path.join(os.getcwd(), 'test_encrypted_file.txt') fake_receiver_desc = { 'pgp_key_public': helpers.PGPKEYS['VALID_PGP_KEY1_PRV'], 'pgp_key_fingerprint': u'ECAF2235E78E71CD95365843C7B190543CAA7585', 'username': u'*****@*****.**', } # these are the same lines used in delivery_sched.py pgpobj = GLBPGP() pgpobj.load_key(helpers.PGPKEYS['VALID_PGP_KEY1_PRV']) with open(file_src, 'w+') as f: f.write(self.secret_content) f.seek(0) encrypted_object, length = pgpobj.encrypt_file( fake_receiver_desc['pgp_key_fingerprint'], f, file_dst) with open(file_dst, 'r') as f: self.assertEqual(str(pgpobj.gnupg.decrypt_file(f)), self.secret_content) pgpobj.destroy_environment()
def test_encrypt_file(self): file_src = os.path.join(os.getcwd(), 'test_plaintext_file.txt') file_dst = os.path.join(os.getcwd(), 'test_encrypted_file.txt') fake_receiver_desc = { 'pgp_key_public': helpers.PGPKEYS['VALID_PGP_KEY1_PRV'], 'pgp_key_fingerprint': u'BFB3C82D1B5F6A94BDAC55C6E70460ABF9A4C8C1', 'username': u'*****@*****.**', } # these are the same lines used in delivery_sched.py pgpobj = GLBPGP() pgpobj.load_key(helpers.PGPKEYS['VALID_PGP_KEY1_PRV']) with open(file_src, 'w+') as f: f.write(self.secret_content) f.seek(0) pgpobj.encrypt_file(fake_receiver_desc['pgp_key_fingerprint'], f, file_dst) with open(file_dst, 'r') as f: self.assertEqual(str(pgpobj.gnupg.decrypt_file(f)), self.secret_content) pgpobj.destroy_environment()
def migrate_Receiver(self): gpgobj = GLBPGP() old_receivers = self.store_old.find(self.model_from['Receiver']) for old_receiver in old_receivers: new_receiver = self.model_to['Receiver']() gpg_key_expiration = datetime_null() if old_receiver.gpg_key_armor: try: gpg_key_expiration = gpgobj.load_key(old_receiver.gpg_key_armor)['expiration'] except Exception: pass for _, v in new_receiver._storm_columns.iteritems(): if v.name == 'gpg_key_status': if old_receiver.gpg_key_status == u'Enabled': new_receiver.gpg_key_status = u'enabled' else: new_receiver.gpg_key_status = u'disabled' continue if v.name == 'gpg_key_expiration': new_receiver.gpg_key_expiration = gpg_key_expiration continue setattr(new_receiver, v.name, getattr(old_receiver, v.name)) self.store_new.add(new_receiver) gpgobj.destroy_environment()
def fsops_pgp_encrypt(fpath, recipient_pgp): """ return path of encrypted file, length of the encrypted file this function is used to encrypt a file for a specific recipient. commonly 'receiver_desc' is expected as second argument; anyhow a simpler dict can be used. required keys are checked on top """ gpoj = GLBPGP() try: gpoj.load_key(recipient_pgp['pgp_key_public']) filepath = os.path.join(GLSettings.submission_path, fpath) with GLSecureFile(filepath) as f: encrypted_file_path = os.path.join(os.path.abspath(GLSettings.submission_path), "pgp_encrypted-%s" % generateRandomKey(16)) _, encrypted_file_size = gpoj.encrypt_file(recipient_pgp['pgp_key_fingerprint'], f, encrypted_file_path) except: raise finally: # the finally statement is always called also if # except contains a return or a raise gpoj.destroy_environment() return encrypted_file_path, encrypted_file_size
def process_mail_creation(self, store, data): # https://github.com/globaleaks/GlobaLeaks/issues/798 # TODO: the current solution is global and configurable only by the admin receiver_id = data['receiver']['id'] sent_emails = GLSettings.get_mail_counter(receiver_id) if sent_emails >= GLSettings.memory_copy.notification_threshold_per_hour: log.debug( "Discarding emails for receiver %s due to threshold already exceeded for the current hour" % receiver_id) return GLSettings.increment_mail_counter(receiver_id) if sent_emails >= GLSettings.memory_copy.notification_threshold_per_hour: log.info( "Reached threshold of %d emails with limit of %d for receiver %s" % (sent_emails, GLSettings.memory_copy.notification_threshold_per_hour, receiver_id)) # simply changing the type of the notification causes # to send the notification_limit_reached data['type'] = u'receiver_notification_limit_reached' data['notification'] = db_get_notification( store, data['receiver']['language']) data['node'] = db_admin_serialize_node(store, data['receiver']['language']) if not data['node']['allow_unencrypted'] and data['receiver'][ 'pgp_key_status'] != u'enabled': return subject, body = Templating().get_mail_subject_and_body(data) # If the receiver has encryption enabled encrypt the mail body if data['receiver']['pgp_key_status'] == u'enabled': gpob = GLBPGP() try: gpob.load_key(data['receiver']['pgp_key_public']) body = gpob.encrypt_message( data['receiver']['pgp_key_fingerprint'], body) except Exception as excep: log.err( "Error in PGP interface object (for %s: %s)! (notification+encryption)" % (data['receiver']['username'], str(excep))) return finally: # the finally statement is always called also if # except contains a return or a raise gpob.destroy_environment() mail = models.Mail({ 'address': data['receiver']['mail_address'], 'subject': subject, 'body': body }) store.add(mail)
def do_notify(self, event): if event.type == 'digest': subject = event.tip_info['body'] body = event.tip_info['title'] else: subject, body = self.get_mail_subject_and_body(event) receiver_mail = event.receiver_info['mail_address'] # If the receiver has encryption enabled (for notification), encrypt the mail body if event.receiver_info['pgp_key_status'] == u'enabled': gpob = GLBPGP() try: gpob.load_key(event.receiver_info['pgp_key_public']) body = gpob.encrypt_message(event.receiver_info['pgp_key_fingerprint'], body) except Exception as excep: log.err("Error in PGP interface object (for %s: %s)! (notification+encryption)" % (event.receiver_info['username'], str(excep))) # On this condition (PGP enabled but key invalid) the only # thing to do is to return None; # It will be duty of the PGP check schedule will disable the key # and advise the user and the admin about that action. return fail(None) finally: # the finally statement is always called also if # except contains a return or a raise gpob.destroy_environment() return sendmail(receiver_mail, subject, body)
def send_exception_email(mail_body, mail_reason="GlobaLeaks Exception"): if GLSettings.exceptions_email_count >= GLSettings.exceptions_email_hourly_limit: return if isinstance(mail_body, str) or isinstance(mail_body, unicode): mail_body = bytes(mail_body) if ( not hasattr(GLSettings.memory_copy, "notif_source_name") or not hasattr(GLSettings.memory_copy, "notif_source_email") or not hasattr(GLSettings.memory_copy, "exception_email_address") ): log.err("Error: Cannot send mail exception before complete initialization.") return sha256_hash = sha256(mail_body) 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: mail_subject = "%s %s" % (mail_reason, __version__) if GLSettings.devel_mode: mail_subject += " [%s]" % GLSettings.developer_name # If the receiver has encryption enabled (for notification), encrypt the mail body if GLSettings.memory_copy.exception_email_pgp_key_status == u"enabled": gpob = GLBPGP() try: gpob.load_key(GLSettings.memory_copy.exception_email_pgp_key_public) mail_body = gpob.encrypt_message(GLSettings.memory_copy.exception_email_pgp_key_fingerprint, mail_body) except Exception as excep: # If exception emails are configured to be subject to encryption an the key # expires the only thing to do is to disable the email. # TODO: evaluate if notificate an alert in plaintext to the exception email # this could be done simply here replacing the email subject and body. log.err("Error while encrypting exception email: %s" % str(excep)) return None finally: # the finally statement is always called also if # except contains a return or a raise gpob.destroy_environment() # avoid to wait for the notification to happen but rely on background completion sendmail(GLSettings.memory_copy.exception_email_address, mail_subject, mail_body) except Exception as excep: # we strongly need to avoid raising exception inside email logic to avoid chained errors log.err("Unexpected exception in process_mail_exception: %s" % excep)
def test_read_expirations(self): pgpobj = GLBPGP() self.assertEqual(pgpobj.load_key(helpers.PGPKEYS['VALID_PGP_KEY1_PRV'])['expiration'], datetime.utcfromtimestamp(0)) self.assertEqual(pgpobj.load_key(helpers.PGPKEYS['EXPIRED_PGP_KEY_PUB'])['expiration'], datetime.utcfromtimestamp(1391012793)) pgpobj.destroy_environment()
def test_pgp_read_expirations(self): pgpobj = GLBPGP() self.assertEqual(pgpobj.load_key(VALID_PGP_KEY1)['expiration'], datetime.utcfromtimestamp(0)) self.assertEqual(pgpobj.load_key(EXPIRED_PGP_KEY)['expiration'], datetime.utcfromtimestamp(1391012793)) pgpobj.destroy_environment()
def test_read_expirations(self): pgpobj = GLBPGP() self.assertEqual( pgpobj.load_key( helpers.PGPKEYS['VALID_PGP_KEY1_PRV'])['expiration'], datetime.utcfromtimestamp(0)) self.assertEqual( pgpobj.load_key( helpers.PGPKEYS['EXPIRED_PGP_KEY_PUB'])['expiration'], datetime.utcfromtimestamp(1391012793)) pgpobj.destroy_environment()
def test_encrypt_message(self): fake_receiver_desc = { 'pgp_key_public': helpers.PGPKEYS['VALID_PGP_KEY1_PUB'], 'pgp_key_fingerprint': u'ECAF2235E78E71CD95365843C7B190543CAA7585', 'username': u'*****@*****.**', } pgpobj = GLBPGP() pgpobj.load_key(helpers.PGPKEYS['VALID_PGP_KEY1_PRV']) encrypted_body = pgpobj.encrypt_message(fake_receiver_desc['pgp_key_fingerprint'], self.secret_content) self.assertEqual(str(pgpobj.gnupg.decrypt(encrypted_body)), self.secret_content) pgpobj.destroy_environment()
def test_encrypt_message(self): fake_receiver_desc = { 'pgp_key_public': helpers.PGPKEYS['VALID_PGP_KEY1_PUB'], 'pgp_key_fingerprint': u'ECAF2235E78E71CD95365843C7B190543CAA7585', 'username': u'*****@*****.**', } pgpobj = GLBPGP() pgpobj.load_key(helpers.PGPKEYS['VALID_PGP_KEY1_PRV']) encrypted_body = pgpobj.encrypt_message( fake_receiver_desc['pgp_key_fingerprint'], self.secret_content) self.assertEqual(str(pgpobj.gnupg.decrypt(encrypted_body)), self.secret_content) pgpobj.destroy_environment()
def parse_pgp_options(notification, request): """ This is called in a @transact, when an users update their preferences or when admins configure keys on their behalf. @param user: the user ORM object @param request: the dictionary containing the pgp infos to be parsed @return: None """ new_pgp_key = request.get('exception_email_pgp_key_public', None) remove_key = request.get('exception_email_pgp_key_remove', False) # the default notification.exception_email_pgp_key_status = u'disabled' if remove_key: # In all the cases below, the key is marked disabled as request notification.exception_email_pgp_key_status = u'disabled' notification.exception_email_pgp_key_info = None notification.exception_email_pgp_key_public = None notification.exception_email_pgp_key_fingerprint = None notification.exception_email_pgp_key_expiration = None elif new_pgp_key: gnob = GLBPGP() try: result = gnob.load_key(new_pgp_key) log.debug("PGP Key imported: %s" % result['fingerprint']) notification.exception_email_pgp_key_status = u'enabled' notification.exception_email_pgp_key_info = result['info'] notification.exception_email_pgp_key_public = new_pgp_key notification.exception_email_pgp_key_fingerprint = result[ 'fingerprint'] notification.exception_email_pgp_key_expiration = result[ 'expiration'] except: raise finally: # the finally statement is always called also if # except contains a return or a raise gnob.destroy_environment()
def test_encrypt_message(self): fake_receiver_desc = { 'pgp_key_public': helpers.PGPKEYS['VALID_PGP_KEY1_PUB'], 'pgp_key_fingerprint': u'BFB3C82D1B5F6A94BDAC55C6E70460ABF9A4C8C1', 'username': u'*****@*****.**', } pgpobj = GLBPGP() pgpobj.load_key(helpers.PGPKEYS['VALID_PGP_KEY1_PRV']) encrypted_body = pgpobj.encrypt_message( fake_receiver_desc['pgp_key_fingerprint'], self.secret_content) self.assertEqual(str(pgpobj.gnupg.decrypt(encrypted_body)), self.secret_content) pgpobj.destroy_environment()
def do_notify(self, event): if event.type == 'digest': body = event.tip_info['body'] title = event.tip_info['title'] else: body, title = self.get_mail_body_and_title(event) if not self.validate_admin_opt(event.notification_settings): log.err('Invalid Mail Settings, no mail can be deliver') return None # If the receiver has encryption enabled (for notification), encrypt the mail body if event.receiver_info['pgp_key_status'] == u'enabled': gpob = GLBPGP() try: gpob.load_key(event.receiver_info['pgp_key_public']) body = gpob.encrypt_message(event.receiver_info['pgp_key_fingerprint'], body) except Exception as excep: log.err("Error in PGP interface object (for %s: %s)! (notification+encryption)" % (event.receiver_info['username'], str(excep))) # On this condition (PGP enabled but key invalid) the only # thing to do is to return None; # It will be duty of the PGP check schedule will disable the key # and advise the user and the admin about that action. return None finally: # the finally statement is always called also if # except contains a return or a raise gpob.destroy_environment() receiver_mail = event.receiver_info['mail_address'] message = MIME_mail_build(GLSettings.memory_copy.notif_source_name, GLSettings.memory_copy.notif_source_email, event.receiver_info['name'], receiver_mail, title, body) return self.mail_flush(event.notification_settings['source_email'], [receiver_mail], message, event)
def parse_pgp_options(notification, request): """ This is called in a @transact, when an users update their preferences or when admins configure keys on their behalf. @param user: the user ORM object @param request: the dictionary containing the pgp infos to be parsed @return: None """ new_pgp_key = request.get('exception_email_pgp_key_public', None) remove_key = request.get('exception_email_pgp_key_remove', False) # the default notification.exception_email_pgp_key_status = u'disabled' if remove_key: # In all the cases below, the key is marked disabled as request notification.exception_email_pgp_key_status = u'disabled' notification.exception_email_pgp_key_info = None notification.exception_email_pgp_key_public = None notification.exception_email_pgp_key_fingerprint = None notification.exception_email_pgp_key_expiration = None elif new_pgp_key: gnob = GLBPGP() try: result = gnob.load_key(new_pgp_key) log.debug("PGP Key imported: %s" % result['fingerprint']) notification.exception_email_pgp_key_status = u'enabled' notification.exception_email_pgp_key_info = result['info'] notification.exception_email_pgp_key_public = new_pgp_key notification.exception_email_pgp_key_fingerprint = result['fingerprint'] notification.exception_email_pgp_key_expiration = result['expiration'] except: raise finally: # the finally statement is always called also if # except contains a return or a raise gnob.destroy_environment()
def parse_pgp_options(user, request): """ Used for parsing PGP key infos and fill related user configurations. @param user: the user orm object @param request: the dictionary containing the pgp infos to be parsed @return: None """ new_pgp_key = request.get('pgp_key_public', None) remove_key = request.get('pgp_key_remove', False) # the default user.pgp_key_status = u'disabled' if remove_key: # In all the cases below, the key is marked disabled as request user.pgp_key_status = u'disabled' user.pgp_key_info = None user.pgp_key_public = None user.pgp_key_fingerprint = None user.pgp_key_expiration = None elif new_pgp_key: gnob = GLBPGP() try: result = gnob.load_key(new_pgp_key) log.debug("PGP Key imported: %s" % result['fingerprint']) user.pgp_key_status = u'enabled' user.pgp_key_info = result['info'] user.pgp_key_public = new_pgp_key user.pgp_key_fingerprint = result['fingerprint'] user.pgp_key_expiration = result['expiration'] except: raise finally: # the finally statement is always called also if # except contains a return or a raise gnob.destroy_environment()
def test_encrypt_message(self): mail_content = "https://www.youtube.com/watch?v=FYdX0W96-os" GLSettings.pgproot = PGPROOT fake_receiver_desc = { 'pgp_key_public': unicode(helpers.VALID_PGP_KEY1), 'pgp_key_fingerprint': u"CF4A22020873A76D1DCB68D32B25551568E49345", 'pgp_key_status': u'enabled', 'username': u'*****@*****.**', } pgpobj = GLBPGP() pgpobj.load_key(helpers.VALID_PGP_KEY1) encrypted_body = pgpobj.encrypt_message(fake_receiver_desc['pgp_key_fingerprint'], mail_content) self.assertSubstring('-----BEGIN PGP MESSAGE-----', encrypted_body) self.assertSubstring('-----END PGP MESSAGE-----', encrypted_body) pgpobj.destroy_environment()
def test_encrypt_message(self): mail_content = "https://www.youtube.com/watch?v=FYdX0W96-os" GLSettings.pgproot = PGPROOT fake_receiver_desc = { 'pgp_key_public': unicode(helpers.VALID_PGP_KEY1), 'pgp_key_fingerprint': u"CF4A22020873A76D1DCB68D32B25551568E49345", 'pgp_key_status': u'enabled', 'username': u'*****@*****.**', } pgpobj = GLBPGP() pgpobj.load_key(helpers.VALID_PGP_KEY1) encrypted_body = pgpobj.encrypt_message( fake_receiver_desc['pgp_key_fingerprint'], mail_content) self.assertSubstring('-----BEGIN PGP MESSAGE-----', encrypted_body) self.assertSubstring('-----END PGP MESSAGE-----', encrypted_body) pgpobj.destroy_environment()
def migrate_Receiver(self): print "%s Receiver migration assistant" % self.std_fancy gpgobj = GLBPGP() old_receivers = self.store_old.find( self.get_right_model("Receiver", 16)) for old_receiver in old_receivers: new_receiver = self.get_right_model("Receiver", 17)() gpg_key_expiration = datetime_null() if old_receiver.gpg_key_armor: try: gpg_key_expiration = gpgobj.load_key( old_receiver.gpg_key_armor)['expiration'] except: pass for _, v in new_receiver._storm_columns.iteritems(): if v.name == 'gpg_key_status': if old_receiver.gpg_key_status == u'Enabled': new_receiver.gpg_key_status = u'enabled' else: new_receiver.gpg_key_status = u'disabled' continue if v.name == 'gpg_key_expiration': new_receiver.gpg_key_expiration = gpg_key_expiration continue setattr(new_receiver, v.name, getattr(old_receiver, v.name)) self.store_new.add(new_receiver) self.store_new.commit() gpgobj.destroy_environment()
def test_encrypt_message(self): dummy_template = "In %EventTime% you've got a crush for Taryn Southern, yay!! \ more info on: https://www.youtube.com/watch?v=C7JZ4F3zJdY \ and know that you're not alone!" mock_event = Event(type=u'encrypted_tip', trigger='Tip', tip_info = { 'creation_date': '2013-05-13T17:49:26.105485', #epoch! 'id': 'useless', 'wb_steps' : self.fill_random_fields(self.dummyContext['id']), }, node_info = MockDict().dummyNode, receiver_info = MockDict().dummyReceiver, context_info = MockDict().dummyContext, steps_info = {}, subevent_info = {}, do_mail=False) mail_content = Templating().format_template(dummy_template, mock_event) # setup the PGP key before GLSetting.pgproot = PGPROOT fake_receiver_desc = { 'pgp_key_public': unicode(VALID_PGP_KEY1), 'pgp_key_fingerprint': u"CF4A22020873A76D1DCB68D32B25551568E49345", 'pgp_key_status': u'enabled', 'username': u'*****@*****.**', } pgpobj = GLBPGP() pgpobj.load_key(VALID_PGP_KEY1) encrypted_body = pgpobj.encrypt_message(fake_receiver_desc['pgp_key_fingerprint'], mail_content) self.assertSubstring('-----BEGIN PGP MESSAGE-----', encrypted_body) pgpobj.destroy_environment()
def test_encrypt_message(self): dummy_template = "In %EventTime% you've got a crush for Taryn Southern, yay!! \ more info on: https://www.youtube.com/watch?v=C7JZ4F3zJdY \ and know that you're not alone!" mock_event = Event(type=u'tip', trigger='Tip', tip_info = { 'creation_date': '2013-05-13T17:49:26.105485', #epoch! 'id': 'useless', 'wb_steps' : self.fill_random_answers(self.dummyContext['id']), }, node_info = MockDict().dummyNode, receiver_info = MockDict().dummyReceiver, context_info = MockDict().dummyContext, subevent_info = {}, do_mail=False) mail_content = Templating().format_template(dummy_template, mock_event) # setup the PGP key before GLSettings.pgproot = PGPROOT fake_receiver_desc = { 'pgp_key_public': unicode(VALID_PGP_KEY1), 'pgp_key_fingerprint': u"CF4A22020873A76D1DCB68D32B25551568E49345", 'pgp_key_status': u'enabled', 'username': u'*****@*****.**', } pgpobj = GLBPGP() pgpobj.load_key(VALID_PGP_KEY1) encrypted_body = pgpobj.encrypt_message(fake_receiver_desc['pgp_key_fingerprint'], mail_content) self.assertSubstring('-----BEGIN PGP MESSAGE-----', encrypted_body) pgpobj.destroy_environment()
def migrate_Receiver(self): print "%s Receiver migration assistant" % self.std_fancy gpgobj = GLBPGP() old_receivers = self.store_old.find(self.get_right_model("Receiver", 16)) for old_receiver in old_receivers: new_receiver = self.get_right_model("Receiver", 17)() gpg_key_expiration = datetime_null() if old_receiver.gpg_key_armor: try: gpg_key_expiration = gpgobj.load_key(old_receiver.gpg_key_armor)['expiration'] except: pass for _, v in new_receiver._storm_columns.iteritems(): if v.name == 'gpg_key_status': if old_receiver.gpg_key_status == u'Enabled': new_receiver.gpg_key_status = u'enabled' else: new_receiver.gpg_key_status = u'disabled' continue if v.name == 'gpg_key_expiration': new_receiver.gpg_key_expiration = gpg_key_expiration continue setattr(new_receiver, v.name, getattr(old_receiver, v.name)) self.store_new.add(new_receiver) self.store_new.commit() gpgobj.destroy_environment()
def send_exception_email(exception_text): if not hasattr(GLSettings.memory_copy.notif, 'exception_delivery_list'): 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("GlobaLeaks version: %s\n\n%s" % (__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 sendmail(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 send_exception_email(mail_body, mail_reason="GlobaLeaks Exception"): if (GLSettings.exceptions_email_count >= GLSettings.exceptions_email_hourly_limit): return if isinstance(mail_body, str) or isinstance(mail_body, unicode): mail_body = bytes(mail_body) if not hasattr(GLSettings.memory_copy, 'notif_source_name') or \ not hasattr(GLSettings.memory_copy, 'notif_source_email') or \ not hasattr(GLSettings.memory_copy, 'exception_email_address'): log.err( "Error: Cannot send mail exception before complete initialization." ) return sha256_hash = sha256(mail_body) 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: mail_subject = "%s %s" % (mail_reason, __version__) if GLSettings.devel_mode: mail_subject += " [%s]" % GLSettings.developer_name # If the receiver has encryption enabled (for notification), encrypt the mail body if GLSettings.memory_copy.exception_email_pgp_key_status == u'enabled': gpob = GLBPGP() try: gpob.load_key( GLSettings.memory_copy.exception_email_pgp_key_public) mail_body = gpob.encrypt_message( GLSettings.memory_copy.exception_email_pgp_key_fingerprint, mail_body) except Exception as excep: # If exception emails are configured to be subject to encryption an the key # expires the only thing to do is to disable the email. # TODO: evaluate if notificate an alert in plaintext to the exception email # this could be done simply here replacing the email subject and body. log.err("Error while encrypting exception email: %s" % str(excep)) return None finally: # the finally statement is always called also if # except contains a return or a raise gpob.destroy_environment() # avoid to wait for the notification to happen but rely on background completion sendmail(GLSettings.memory_copy.exception_email_address, mail_subject, mail_body) except Exception as excep: # we strongly need to avoid raising exception inside email logic to avoid chained errors log.err("Unexpected exception in process_mail_exception: %s" % excep)
def pgp_options_parse(receiver, request): """ This is called in a @transact, when receiver update prefs and when admin configure a new key (at the moment, Admin GUI do not permit to sets preferences, but still the same function is used. @param receiver: the Storm object @param request: the Dict receiver by the Internets @return: None This function is called in create_recever and update_receiver and is used to manage the PGP options forced by the administrator This is needed also because no one of these fields are *enforced* by unicode_keys or bool_keys in models.Receiver PGP management, here are check'd these actions: 1) Proposed a new PGP key, is imported to check validity, and stored in Storm DB if not error raise 2) Removal of the present key Further improvement: update the keys using keyserver """ new_pgp_key = request.get('pgp_key_public', None) remove_key = request.get('pgp_key_remove', False) # the default receiver.pgp_key_status = u'disabled' if remove_key: log.debug("User %s %s request to remove PGP key (%s)" % (receiver.name, receiver.user.username, receiver.pgp_key_fingerprint)) # In all the cases below, the key is marked disabled as request receiver.pgp_key_status = u'disabled' receiver.pgp_key_info = None receiver.pgp_key_public = None receiver.pgp_key_fingerprint = None receiver.pgp_key_expiration = datetime_null() if new_pgp_key: gnob = GLBPGP() try: result = gnob.load_key(new_pgp_key) log.debug("PGP Key imported: %s" % result['fingerprint']) receiver.pgp_key_status = u'enabled' receiver.pgp_key_info = result['info'] receiver.pgp_key_public = new_pgp_key receiver.pgp_key_fingerprint = result['fingerprint'] receiver.pgp_key_expiration = result['expiration'] except: raise finally: # the finally statement is always called also if # except contains a return or a raise gnob.destroy_environment()