Example #1
0
    def test_dkim_signed_but_from_unverified_address(self):
        """Sent from trusted dkim address, but only the From address is known.

        The sender is a known, but unverified address.

        See https://bugs.launchpad.net/launchpad/+bug/925597
        """
        from_address = "*****@*****.**"
        sender_address = "*****@*****.**"
        person = self.factory.makePerson(
            email=from_address,
            name='dkimtest',
            displayname='DKIM Test')
        self.factory.makeEmail(sender_address, person, EmailAddressStatus.NEW)
        self.preload_dns_response()
        tweaked_message = self.makeMessageText(
            sender=sender_address,
            from_address="DKIM Test <*****@*****.**>")
        signed_message = self.fake_signing(tweaked_message)
        principal = authenticateEmail(
            signed_message_from_string(signed_message))
        self.assertEqual(principal.person.preferredemail.email,
            from_address)
        self.assertWeaklyAuthenticated(principal, signed_message)
        self.assertDkimLogContains(
            'valid dkim signature, but not from an active email address')
Example #2
0
 def test_clearsigned_message(self):
     # The test keys belong to Sample Person.
     sender = getUtility(IPersonSet).getByEmail('*****@*****.**')
     msg = self._get_clearsigned_for_person(sender)
     principle = authenticateEmail(msg)
     self.assertIsNot(None, msg.signature)
     self.assertEqual(sender, principle.person)
     self.assertFalse(IWeaklyAuthenticatedPrincipal.providedBy(principle))
Example #3
0
 def test_dkim_valid(self):
     signed_message = self.fake_signing(self.makeMessageText())
     self.preload_dns_response()
     principal = authenticateEmail(
         signed_message_from_string(signed_message))
     self.assertStronglyAuthenticated(principal, signed_message)
     self.assertEqual(principal.person.preferredemail.email,
         '*****@*****.**')
Example #4
0
 def test_detached_signature_message(self):
     # Test a detached correct signature.
     sender = getUtility(IPersonSet).getByEmail('*****@*****.**')
     msg = self._get_detached_message_for_person(sender)
     principle = authenticateEmail(msg)
     self.assertIsNot(None, msg.signature)
     self.assertEqual(sender, principle.person)
     self.assertFalse(IWeaklyAuthenticatedPrincipal.providedBy(principle))
 def test_require_strong_email_authentication_and_signed(self):
     sender = getUtility(IPersonSet).getByEmail('*****@*****.**')
     sender.require_strong_email_authentication = True
     msg = self._get_clearsigned_for_person(sender)
     principal = authenticateEmail(msg)
     self.assertIsNot(None, msg.signature)
     self.assertEqual(sender, principal.person)
     self.assertFalse(IWeaklyAuthenticatedPrincipal.providedBy(principal))
 def test_clearsigned_message(self):
     # The test keys belong to Sample Person.
     sender = getUtility(IPersonSet).getByEmail('*****@*****.**')
     msg = self._get_clearsigned_for_person(sender)
     principle = authenticateEmail(msg)
     self.assertIsNot(None, msg.signature)
     self.assertEqual(sender, principle.person)
     self.assertFalse(
         IWeaklyAuthenticatedPrincipal.providedBy(principle))
Example #7
0
 def test_dkim_garbage_pubkey(self):
     signed_message = self.fake_signing(self.makeMessageText())
     self.preload_dns_response('garbage')
     principal = authenticateEmail(
         signed_message_from_string(signed_message))
     self.assertWeaklyAuthenticated(principal, signed_message)
     self.assertEqual(principal.person.preferredemail.email,
         '*****@*****.**')
     self.assertDkimLogContains('invalid format in _domainkey txt record')
Example #8
0
 def test_dkim_nxdomain(self):
     # If there's no DNS entry for the pubkey it should be handled
     # decently.
     signed_message = self.fake_signing(self.makeMessageText())
     principal = authenticateEmail(
         signed_message_from_string(signed_message))
     self.assertWeaklyAuthenticated(principal, signed_message)
     self.assertEqual(principal.person.preferredemail.email,
         '*****@*****.**')
Example #9
0
 def test_dkim_message_unsigned(self):
     # This is a degenerate case: a message with no signature is
     # treated as weakly authenticated.
     # The library doesn't log anything if there's no header at all.
     principal = authenticateEmail(
         signed_message_from_string(self.makeMessageText()))
     self.assertWeaklyAuthenticated(principal, self.makeMessageText())
     self.assertEqual(principal.person.preferredemail.email,
         '*****@*****.**')
Example #10
0
 def test_clearsigned_message_wrong_sender(self):
     # If the message is signed, but the key doesn't belong to the sender,
     # the principle is set to the sender, but weakly authenticated.
     sender = self.factory.makePerson()
     msg = self._get_clearsigned_for_person(sender)
     principle = authenticateEmail(msg)
     self.assertIsNot(None, msg.signature)
     self.assertEqual(sender, principle.person)
     self.assertTrue(IWeaklyAuthenticatedPrincipal.providedBy(principle))
 def test_detached_signature_message(self):
     # Test a detached correct signature.
     sender = getUtility(IPersonSet).getByEmail('*****@*****.**')
     msg = self._get_detached_message_for_person(sender)
     principle = authenticateEmail(msg)
     self.assertIsNot(None, msg.signature)
     self.assertEqual(sender, principle.person)
     self.assertFalse(
         IWeaklyAuthenticatedPrincipal.providedBy(principle))
 def test_clearsigned_message_wrong_sender(self):
     # If the message is signed, but the key doesn't belong to the sender,
     # the principle is set to the sender, but weakly authenticated.
     sender = self.factory.makePerson()
     msg = self._get_clearsigned_for_person(sender)
     principle = authenticateEmail(msg)
     self.assertIsNot(None, msg.signature)
     self.assertEqual(sender, principle.person)
     self.assertTrue(
         IWeaklyAuthenticatedPrincipal.providedBy(principle))
Example #13
0
 def test_unsigned_message(self):
     # An unsigned message will not have a signature nor signed content,
     # and generates a weakly authenticated principle.
     sender = self.factory.makePerson()
     email_message = self.factory.makeEmailMessage(sender=sender)
     msg = signed_message_from_string(email_message.as_string())
     self.assertIs(None, msg.signedContent)
     self.assertIs(None, msg.signature)
     principle = authenticateEmail(msg)
     self.assertEqual(sender, principle.person)
     self.assertTrue(IWeaklyAuthenticatedPrincipal.providedBy(principle))
     self.assertIs(None, msg.signature)
Example #14
0
 def test_trailing_whitespace(self):
     # Trailing whitespace should be ignored when verifying a message's
     # signature.
     sender = getUtility(IPersonSet).getByEmail('*****@*****.**')
     body = ('A message with trailing spaces.   \n'
             'And tabs\t\t\n'
             'Also mixed. \t ')
     msg = self._get_clearsigned_for_person(sender, body)
     principle = authenticateEmail(msg)
     self.assertIsNot(None, msg.signature)
     self.assertEqual(sender, principle.person)
     self.assertFalse(IWeaklyAuthenticatedPrincipal.providedBy(principle))
Example #15
0
 def test_dkim_body_mismatch(self):
     # The message has a syntactically valid DKIM signature that
     # doesn't actually correspond to what was signed.  We log
     # something about this but we don't want to drop the message.
     signed_message = self.fake_signing(self.makeMessageText())
     signed_message += 'blah blah'
     self.preload_dns_response()
     principal = authenticateEmail(
         signed_message_from_string(signed_message))
     self.assertWeaklyAuthenticated(principal, signed_message)
     self.assertEqual(principal.person.preferredemail.email,
         '*****@*****.**')
     self.assertDkimLogContains('body hash mismatch')
Example #16
0
 def test_dkim_changed_from_realname(self):
     # If the real name part of the message has changed, it's detected.
     signed_message = self.fake_signing(self.makeMessageText())
     self.preload_dns_response()
     fiddled_message = signed_message.replace(
         'From: Foo Bar <*****@*****.**>',
         'From: Evil Foo <*****@*****.**>')
     principal = authenticateEmail(
         signed_message_from_string(fiddled_message))
     # We don't care about the real name for determining the principal.
     self.assertWeaklyAuthenticated(principal, fiddled_message)
     self.assertEqual(principal.person.preferredemail.email,
         '*****@*****.**')
 def test_unsigned_message(self):
     # An unsigned message will not have a signature nor signed content,
     # and generates a weakly authenticated principle.
     sender = self.factory.makePerson()
     email_message = self.factory.makeEmailMessage(sender=sender)
     msg = signed_message_from_string(email_message.as_string())
     self.assertIs(None, msg.signedContent)
     self.assertIs(None, msg.signature)
     principle = authenticateEmail(msg)
     self.assertEqual(sender, principle.person)
     self.assertTrue(
         IWeaklyAuthenticatedPrincipal.providedBy(principle))
     self.assertIs(None, msg.signature)
 def test_trailing_whitespace(self):
     # Trailing whitespace should be ignored when verifying a message's
     # signature.
     sender = getUtility(IPersonSet).getByEmail('*****@*****.**')
     body = (
         'A message with trailing spaces.   \n'
         'And tabs\t\t\n'
         'Also mixed. \t ')
     msg = self._get_clearsigned_for_person(sender, body)
     principle = authenticateEmail(msg)
     self.assertIsNot(None, msg.signature)
     self.assertEqual(sender, principle.person)
     self.assertFalse(
         IWeaklyAuthenticatedPrincipal.providedBy(principle))
Example #19
0
    def test_dkim_broken_pubkey(self):
        """Handle a subtly-broken pubkey like qq.com, see bug 881237.

        The message is not trusted but inbound message processing does not
        abort either.
        """
        signed_message = self.fake_signing(self.makeMessageText())
        self.preload_dns_response('broken')
        principal = authenticateEmail(
            signed_message_from_string(signed_message))
        self.assertWeaklyAuthenticated(principal, signed_message)
        self.assertEqual(principal.person.preferredemail.email,
            '*****@*****.**')
        self.assertDkimLogContains('unexpected error in DKIM verification')
Example #20
0
 def test_dkim_signing_irrelevant(self):
     # It's totally valid for a message to be signed by a domain other than
     # that of the From-sender, if that domain is relaying the message.
     # However, we shouldn't then trust the purported sender, because they
     # might have just made it up rather than relayed it.
     tweaked_message = self.makeMessageText(
         from_address='*****@*****.**')
     signed_message = self.fake_signing(tweaked_message)
     self.preload_dns_response()
     principal = authenticateEmail(
         signed_message_from_string(signed_message))
     self.assertWeaklyAuthenticated(principal, signed_message)
     # should come from From, not the dkim signature
     self.assertEqual(principal.person.preferredemail.email,
         '*****@*****.**')
Example #21
0
 def test_dkim_changed_from_address(self):
     # If the address part of the message has changed, it's detected.
     #  We still treat this as weakly authenticated by the purported
     # From-header sender, though perhaps in future we would prefer
     # to reject these messages.
     signed_message = self.fake_signing(self.makeMessageText())
     self.preload_dns_response()
     fiddled_message = signed_message.replace(
         'From: Foo Bar <*****@*****.**>',
         'From: Carlos <*****@*****.**>')
     principal = authenticateEmail(
         signed_message_from_string(fiddled_message))
     self.assertWeaklyAuthenticated(principal, fiddled_message)
     # should come from From, not the dkim signature
     self.assertEqual(principal.person.preferredemail.email,
         '*****@*****.**')
Example #22
0
    def test_dkim_untrusted_signer(self):
        # Valid signature from an untrusted domain -> untrusted
        signed_message = self.fake_signing(self.makeMessageText())
        self.preload_dns_response()
        saved_domains = incoming._trusted_dkim_domains[:]

        def restore():
            incoming._trusted_dkim_domains = saved_domains

        self.addCleanup(restore)
        incoming._trusted_dkim_domains = []
        principal = authenticateEmail(
            signed_message_from_string(signed_message))
        self.assertWeaklyAuthenticated(principal, signed_message)
        self.assertEqual(principal.person.preferredemail.email,
            '*****@*****.**')
Example #23
0
 def test_dkim_signed_by_other_address(self):
     # If the message is From one of a person's addresses, and the Sender
     # corresponds to another, and there is a DKIM signature for the Sender
     # domain, this is valid - see bug 643223.  For this to be a worthwhile
     # test  we need the two addresses to be in different domains.   It
     # will be signed by canonical.com, so make that the sender.
     person = self.factory.makePerson(
         email='*****@*****.**',
         name='dkimtest',
         displayname='DKIM Test')
     self.factory.makeEmail(
         person=person,
         address='*****@*****.**')
     self.preload_dns_response()
     tweaked_message = self.makeMessageText(
         sender="*****@*****.**",
         from_address="DKIM Test <*****@*****.**>")
     signed_message = self.fake_signing(tweaked_message)
     principal = authenticateEmail(
         signed_message_from_string(signed_message))
     self.assertStronglyAuthenticated(principal, signed_message)
Example #24
0
 def test_unknown_email(self):
     # An unknown email address returns no principal.
     unknown = "*****@*****.**"
     mail = self.factory.makeSignedMessage(email_address=unknown)
     self.assertThat(authenticateEmail(mail), Is(None))
Example #25
0
 def test_badly_formed_email(self):
     # A badly formed email address returns no principal.
     bad = "\[email protected]"
     mail = self.factory.makeSignedMessage(email_address=bad)
     self.assertThat(authenticateEmail(mail), Is(None))
 def test_unknown_email(self):
     # An unknown email address returns no principal.
     unknown = '*****@*****.**'
     mail = self.factory.makeSignedMessage(email_address=unknown)
     self.assertThat(authenticateEmail(mail), Is(None))
 def test_badly_formed_email(self):
     # A badly formed email address returns no principal.
     bad = '\[email protected]'
     mail = self.factory.makeSignedMessage(email_address=bad)
     self.assertThat(authenticateEmail(mail), Is(None))