Пример #1
0
def show_fingerprint(request, email, fingerprint, verified, active, page_title):
    ''' Show the fingerprint. '''

    log_message('showing {} fingerprint verified: {}'.format(email, verified))
    log_message('require verification {}'.format(options.require_key_verified()))

    template = 'mail/show_fingerprint.html'
    data = {'page_title': page_title,
            'fingerprint': format_fingerprint(fingerprint),
            'verified': verified,
            'active': active,
            'requires': options.require_key_verified()}
    return render_to_response(template, data, context_instance=RequestContext(request))
Пример #2
0
    def _encrypt_message_with_all(self, encryption_names):
        '''
            Encrypt the message with each encryption program.
        '''
        encrypted = fatal_error = False
        error_message = ''
        encrypted_with = []
        encrypted_classnames = []
        to_user = self.crypto_message.smtp_recipient()
        original_payload = self.crypto_message.get_email_message().get_message().get_payload()

        self._log_message("encrypting using {} with {}'s key".format(encryption_names, to_user))
        for encryption_name in encryption_names:
            encryption_classname = get_key_classname(encryption_name)
            if encryption_classname not in encrypted_classnames:
                try:
                    if options.require_key_verified():
                        __, key_ok, __ = contacts.get_fingerprint(to_user, encryption_name)
                        self._log_message("{} {} key verified: {}".format(to_user, encryption_name, key_ok))
                    else:
                        key_ok = True

                    if key_ok:
                        if self._encrypt_message(encryption_name):
                            encrypted_classnames.append(encryption_classname)
                            encrypted_with.append(encryption_name)
                    else:
                        error_message += i18n('You need to verify the {encryption} key for {email} before you can use it.'.format(
                            encryption=encryption_name, email=to_user))
                        self._log_message(error_message)
                except MessageException as message_exception:
                    fatal_error = True
                    error_message += message_exception.value
                    self._log_exception(error_message)
                    break

        # if the user has encryption software defined, then the message
        # must be encrypted or bounced to the sender
        if len(encrypted_classnames) > 0:
            encrypted = True
        else:
            MSG_NOT_SET = i18n('Message not sent to {email} because there was a problem encrypting.'.format(
                email=to_user))
            fatal_error = True
            if error_message is None or len(error_message) <= 0:
                error_message = '{} {}\n{}'.format(MSG_NOT_SET,
                    i18n("It's possible the recipient's key is missing."),
                    self.POSSIBLE_ENCRYPT_SOLUTION)
            else:
                error_message = '{} {}'.format(MSG_NOT_SET, error_message)

            # restore the payload
            self.crypto_message.get_email_message().get_message().set_payload(original_payload)

        if fatal_error:
            self._log_message('raising message exception in _encrypt_message_with_all')
            self._log_message(error_message)
            raise MessageException(value=error_message)

        return encrypted_with
Пример #3
0
def show_metadata_domains(request):
    '''Show domains that have metadata keys.'''

    if not request.user.is_authenticated():
        context = {}
        context.update(csrf(request))
        response = redirect('/login/?next={}'.format(request.path), context)
    else:
        try:
            metadata_list = contacts.get_metadata_domains()
            if len(metadata_list) > 0:
                error_message = None
            else:
                error_message = i18n("There aren't any domains ready to protect metadata, yet.")

            template = 'mail/metadata_domains.html'
            params = {'metadata_list': metadata_list,
                      'encrypt_metadata': options.encrypt_metadata(),
                      'require_key_verified': options.require_key_verified(),
                      'error_message': error_message}
            response = render_to_response(
                template, params, context_instance=RequestContext(request))
        except Exception:
            record_exception()
            log_message('EXCEPTION - see syr.exception.log for details')
            response = HttpResponseRedirect('/mail/show_metadata_domains/')

    return response
Пример #4
0
def notify_new_key_arrived(to_user, id_fingerprint_pairs):
    '''
        Notify user a new key arrived.

        >>> notify_new_key_arrived(None, None)
    '''

    if to_user is None or id_fingerprint_pairs is None or len(id_fingerprint_pairs) < 1:
        pass
    else:
        # use the first email address from the imported key
        try:
            email, __ = id_fingerprint_pairs[0]
        except:
            email = get_admin_email()

        header = i18n("To be safe, verify their key now by following these instructions:")
        tip = i18n("https://goodcrypto.com/qna/knowledge-base/user-verify-key")
        regular_notice = True
        if require_key_verified():
            regular_notice = False
            if is_metadata_address(email):
                domain = parse_domain(email)
                subject = i18n('Mail to {domain} cannot be sent until you verify the metadata key'.format(domain=domain))
                body = i18n("You received a public key for the email address(es) below. No one can send mail to users with this domain until you verify the key and update the database if it's okay. Otherwise, any mail sent to {domain} will be returned to the sender.".format(domain)),
            else:
                subject = i18n('Mail to {email} cannot be sent until you verify their key'.format(email=email))
                body = i18n("You received a public key for the email address(es) below. You cannot send mail until you check with the sender to verify the key and update the database if it's okay. Otherwise, any mail you send to this user will be returned to you."),
        else:
            if is_metadata_address(email):
                domain = parse_domain(email)
                subject = 'Metadata protection to {domain} is now ready'.format(domain=domain)
                body = 'Unless you disable metadata protection, all mail to {domain} will now have both metadata and content encrypted.'.format(
                        domain=domain)
            else:
                subject = i18n('Mail to {email} is now private'.format(email=email))
                body = i18n(
                  "The content of all messages to {email} will be protected.  ".format(email=email))
        body_text = "{}\n\n{} {}\n".format(
            body,
            header,
            tip)

        for (user_id, fingerprint) in id_fingerprint_pairs:
            body_text += "    {}: {}".format(user_id, format_fingerprint(fingerprint))

        if regular_notice:
            prefix = TAG_PREFIX
        else:
            prefix = TAG_WARNING

        notify_user(to_user, '{} - {}'.format(prefix, str(subject)), body_text)
Пример #5
0
def get_metadata_user_details(email, encryption_name):
    '''
        Get the metadata address and key for the encryption program.

        >>> get_metadata_user_details(None, None)
        (False, None, None)
    '''

    metadata_address = fingerprint = None
    ok = False

    try:
        metadata_address = get_metadata_address(email=email)
        fingerprint, verified, active = contacts.get_fingerprint(metadata_address, encryption_name)
        if fingerprint is None:
            from goodcrypto.mail.message.utils import sync_fingerprint_via_queue

            ok = False
            log_message('no fingerprint for {}'.format(metadata_address))
            # queue up to get the fingerprint
            sync_fingerprint_via_queue(contacts.get_contacts_crypto(email, encryption_name=encryption_name))
        elif not active:
            ok = False
            log_message('{}  is not active'.format(metadata_address))
        elif options.require_key_verified() and not verified:
            ok = False
            log_message('{}  is not verified and verification required'.format(metadata_address))
        else:
            ok = True
    except:
        ok = False
        record_exception()
        log_message('EXCEPTION - see syr.exception.log for details')

    if not ok:
        metadata_address = None

    return ok, metadata_address, fingerprint
Пример #6
0
def show_protection(request):
    '''Show the protection for messages.'''

    if not request.user.is_authenticated():
        context = {}
        context.update(csrf(request))
        response = redirect('/login/?next={}'.format(request.path), context)
    else:
        is_secure = is_secure_connection(request)
        template = 'mail/protection.html'
        params = {
            'secure': is_secure,
            'encrypt_metadata': options.encrypt_metadata(),
            'bundle_and_pad': options.bundle_and_pad(),
            'require_key_verified': options.require_key_verified(),
            'filter_html': options.filter_html(),
            'require_outbound_encryption': options.require_outbound_encryption(),
            'clear_sign': options.clear_sign_email(),
            'add_dkim_sig': options.add_dkim_sig(),
        }
        response = render_to_response(
            template, params, context_instance=RequestContext(request))

    return response
Пример #7
0
def notify_new_key_arrived(to_user, id_fingerprint_pairs):
    '''
        Notify user a new key arrived.

        >>> notify_new_key_arrived(None, None)
    '''

    if to_user is None or id_fingerprint_pairs is None or len(
            id_fingerprint_pairs) < 1:
        pass
    else:
        # use the first email address from the imported key
        try:
            email, __ = id_fingerprint_pairs[0]
        except:
            email = get_admin_email()

        header = i18n(
            "To be safe, verify their key now by following these instructions:"
        )
        tip = i18n("https://goodcrypto.com/qna/knowledge-base/user-verify-key")
        regular_notice = True
        if require_key_verified():
            regular_notice = False
            if is_metadata_address(email):
                domain = parse_domain(email)
                subject = i18n(
                    'Mail to {domain} cannot be sent until you verify the metadata key'
                    .format(domain=domain))
                body = i18n(
                    "You received a public key for the email address(es) below. No one can send mail to users with this domain until you verify the key and update the database if it's okay. Otherwise, any mail sent to {domain} will be returned to the sender."
                    .format(domain)),
            else:
                subject = i18n(
                    'Mail to {email} cannot be sent until you verify their key'
                    .format(email=email))
                body = i18n(
                    "You received a public key for the email address(es) below. You cannot send mail until you check with the sender to verify the key and update the database if it's okay. Otherwise, any mail you send to this user will be returned to you."
                ),
        else:
            if is_metadata_address(email):
                domain = parse_domain(email)
                subject = 'Metadata protection to {domain} is now ready'.format(
                    domain=domain)
                body = 'Unless you disable metadata protection, all mail to {domain} will now have both metadata and content encrypted.'.format(
                    domain=domain)
            else:
                subject = i18n(
                    'Mail to {email} is now private'.format(email=email))
                body = i18n(
                    "The content of all messages to {email} will be protected.  "
                    .format(email=email))
        body_text = "{}\n\n{} {}\n".format(body, header, tip)

        for (user_id, fingerprint) in id_fingerprint_pairs:
            body_text += "    {}: {}".format(user_id,
                                             format_fingerprint(fingerprint))

        if regular_notice:
            prefix = TAG_PREFIX
        else:
            prefix = TAG_WARNING

        notify_user(to_user, '{} - {}'.format(prefix, str(subject)), body_text)
Пример #8
0
def get_decrypt_signature_tag(crypto_message, from_user, signed_by, crypto_name):
    ''' Get the tag when the encrypted message was signed. '''

    tag = None
    if len(crypto_message.get_metadata_crypted_with()) > 0:
        log_message('metadata crypted with: {}'.format(crypto_message.get_metadata_crypted_with()))
        received_privately = RECEIVED_FULL_MESSAGE_PRIVATELY
    else:
        received_privately = RECEIVED_CONTENT_PRIVATELY

    if signed_by is None:
        tag = '{}, {}'.format(received_privately, SENDER_UNSIGNED_SUFFIX)
    else:
        from_user_addr = get_email(from_user)
        signed_by_addr = get_email(signed_by)
        log_message("message encrypted and signed by {}".format(signed_by_addr))

        # if the signer's not a match with the sender, see if the key is used for multiple
        # email addresses and one of those addresses is the sender's address
        if from_user_addr != signed_by_addr:
            log_message("checking if key is for multiple email addresses")
            from_fingerprint, __, __ = get_fingerprint(from_user_addr, crypto_name)
            if from_fingerprint is not None:
                signer_fingerprint, __, __ = get_fingerprint(signed_by_addr, crypto_name)
                if from_fingerprint == signer_fingerprint:
                    signed_by_addr = from_user_addr
                    log_message("signer key is for multiple addresses, including sender")

        # remember that the message was signed
        crypto_message.set_private_signed(True)

        if from_user_addr == signed_by_addr:
            # assume the key is ok unless it's required to be verified before we use it
            key_ok = not options.require_key_verified()
            if not key_ok:
                __, key_ok, __ = get_fingerprint(signed_by_addr, crypto_name)

            if key_ok:
                tag = '{}.'.format(received_privately)
                crypto_message.add_private_signer({
                   constants.SIGNER: signed_by_addr, constants.SIGNER_VERIFIED: True})
                log_message('signed by: {}'.format(crypto_message.private_signers_list()))
            else:
                tag = '{}, {}'.format(
                  received_privately, KEY_UNVERIFIED_SUFFIX.format(email=signed_by_addr))

                crypto_message.add_private_signer({
                  constants.SIGNER: signed_by_addr, constants.SIGNER_VERIFIED: False})
                log_message('signed by: {}'.format(crypto_message.private_signers_list()))
        else:
            tag = '{}, {}'.format(
              received_privately,
              SIGNED_BY_NOT_BY_SUFFIX.format(signer=signed_by_addr, sender=from_user_addr))

            crypto_message.add_private_signer({
              constants.SIGNER: signed_by_addr, constants.SIGNER_VERIFIED: False})
            log_message('signed by: {}'.format(crypto_message.private_signers_list()))

    log_message('verified sig tag: {}'.format(tag))

    return tag
Пример #9
0
def view_fingerprint(request):
    '''View the fingerprint for a user.'''

    if options.login_to_view_fingerprints() and not request.user.is_authenticated():
        context = {}
        context.update(csrf(request))
        response = redirect('/login/?next={}'.format(request.path), context)
    else:
        response = None
        form = forms.GetFingerprintForm()
        if request.method == 'POST':

            email = None
            encryption_software = None

            form = forms.GetFingerprintForm(request.POST)
            if form.is_valid():
                try:
                    email = form.cleaned_data['email']
                    encryption_software = form.cleaned_data['encryption_software']

                    page_title = i18n('{encryption_software} fingerprint for {email}'.format(
                        encryption_software=encryption_software, email=email))

                    fingerprint, verified, active = contacts.get_fingerprint(email, encryption_software.name)
                    if fingerprint is None:
                        fingerprint = i18n('No fingerprint defined')
                        checked = None
                    elif request.user.is_authenticated():
                        if verified:
                            checked = 'checked'
                        else:
                            checked = None
                        form_template = 'mail/verify_fingerprint.html'
                        response = render_to_response(
                            form_template, {'form': form,
                                            'page_title': page_title,
                                            'email': email,
                                            'encryption_name': encryption_software.name,
                                            'fingerprint': format_fingerprint(fingerprint),
                                            'checked': checked,
                                            'active': active,
                                            'requires': options.require_key_verified()},
                                            context_instance=RequestContext(request))

                    if response is None:
                        response = show_fingerprint(request, email, fingerprint, verified, active, page_title)
                except Exception:
                    record_exception()
                    log_message('EXCEPTION - see syr.exception.log for details')

            if response is None:
                log_message('view fingerprint post: {}'.format(request.POST))

        if response is None:
            form_template = 'mail/get_fingerprint.html'
            form = forms.GetFingerprintForm()
            response = render_to_response(
                form_template, {'form': form}, context_instance=RequestContext(request))

    return response