Santiago.verify_sender works; commented out old test stubs.

This commit is contained in:
Nick Daly 2012-05-10 07:23:47 -05:00
parent 3ffbe02cb6
commit 5cc01cc92d
2 changed files with 491 additions and 391 deletions

View File

@ -364,16 +364,18 @@ class Santiago(object):
allowed to send us messages.
"""
if not request.gpg.valid:
gpg_data = request.next()
if not gpg_data:
raise InvalidSignatureError()
if not self.get_host_locations(request.gpg.fingerprint, "santiago"):
if not self.get_host_locations(gpg_data.fingerprint, "santiago"):
raise UnwillingHostError(
"{0} is not a Santiago client.".format(request.gpg.fingerprint))
"{0} is not a Santiago client.".format(gpg_data.fingerprint))
return request_body
return request
def verify_client(self, request_body, proxied_request):
def verify_client(self, request):
"""Verify the signature of the message's source.
This is part (B) in the message diagram.
@ -387,16 +389,19 @@ class Santiago(object):
somebody else.
"""
self.verify_client(request_body)
self.verify_sender(request)
if not request_body:
adict = None
try:
adict = dict(request.message)
except:
return
if not self.i_am(request_body["to"]):
self.proxy(proxied_request)
if not self.i_am(adict["to"]):
self.proxy(adict["request"])
return
return request_body
return request
def decrypt_client(self, request_body):
"""Decrypt the message and validates the encrypted signature.

View File

@ -40,418 +40,512 @@ If I produce a listener that just echoes the parameters, I can validate the resp
"""
import unittest
import ConfigParser as configparser
import os
import sys
import unittest
from pprint import pprint
import gnupg
import simplesantiago
class SantiagoTest(unittest.TestCase):
"""The base class for tests."""
def setUp(self):
super(TestServing, self).setUp()
port_a = "localhost:9000"
port_b = "localhost:8000"
listeners_a = [santiago.SantiagoListener(port_a)]
senders_a = [santiago.SantiagoSender()]
listeners_b = [santiago.SantiagoListener(port_b)]
senders_b = [santiago.SantiagoSender()]
hosting_a = { "b": { "santiago": [ port_a ]}}
consuming_a = { "santiagao": { "b": [ port_b ]}}
hosting_b = { "a": { "santiago": [ port_b ],
"wiki": [ "localhost:8001" ]}}
consuming_b = { "santiagao": { "a": [ port_a ]}}
self.santiago_a = Santiago(listeners_a, senders_a, hosting_a, consuming_a)
self.santiago_b = Santiago(listeners_b, senders_b, hosting_b, consuming_b)
def serveOnPort(self, port):
"""Start listening for connections on a named port.
Used in testing as a mock listener for responses from a Santiago server.
"""
class RequestReceiver(object):
"""A very basic listener.
It merely records the calling arguments.
"""
@cherrypy.expose
def index(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
self.socket_port = port
self.receiver = RequestReceiver()
cherrypy.quickstart(self.receiver)
if sys.version_info < (2, 7):
"""Add a poor man's forward compatibility."""
class ContainsError(AssertionError):
pass
def assertIn(self, a, b):
if not a in b:
raise self.ContainsError("%s not in %s" % (a, b))
class TestClientInitialRequest(SantiagoTest):
"""Does the client send a correctly formed request?
In these tests, we're sending requests to a mock listener which merely
records that the requests were well-formed.
"""
def setUp(self):
super(SantiagoTest, self).setUp()
self.serveOnPort(8000)
def test_request(self):
"""Verify that A queues a properly formatted initial request."""
self.santiago_a.request(from_="a", to="b",
client="a", host="b",
service="wiki", reply_to="localhost:9001")
self.assertEqual(self.santiago_a.outgoing_messages,
[{ "from": "a", "to": "b",
"client": "a", "host": "b",
"service": "wiki", "reply-to": "localhost:9001"}])
def test_request(self):
"""Verify that A sends out a properly formatted initial request."""
self.santiago_a.request(from_="a", to="b",
client="a", host="b",
service="wiki", reply_to="localhost:9001")
self.santiago_a.process()
self.assertEqual(self.receiver.kwargs,
[{ "from": "a", "to": "b",
"client": "a", "host": "b",
"service": "wiki", "reply-to": "localhost:9001"}])
class TestServerInitialRequest(SantiagoTest):
"""Test how the Santiago server replies to initial service requests.
TODO: Add a mock listener to represent A.
TODO: Transform the data structure tests into the mock-response tests.
TODO tests: (normal serving + proxying) * (learning santiagi + not learning)
Proxying
~~~~~~~~
A host/listener (B) trusts proxied requests according to the minimum trust
in the request. If the request comes from an untrusted proxy or is for an
untrusted client, B ignores it.
"""
def setUp(self):
super(SantiagoTest, self).setUp()
self.serveOnPort(9000)
def test_acknowledgement(self):
"""If B receives an authorized request, then it replies with a location.
An "authorized request" in this case is for a service from a client that
B is willing to host that service for.
In this case, B will answer with the wiki's location.
"""
self.santiago_b.receive(from_="a", to="b",
client="a", host="b",
service="wiki", reply_to=None)
self.assertEqual(self.santiago_b.outgoing_messages,
[{"from": "b",
"to": "a",
"client": "a",
"host": "b",
"service": "wiki",
"locations": ["192.168.0.13"],
"reply-to": "localhost:8000"}])
def test_reject_bad_service(self):
"""Does B reject requests for unsupported services?
In this case, B should reply with an empty list of locations.
"""
self.santiago_b.receive(from_="a", to="b",
client="a", host="b",
service="wiki", reply_to=None)
self.assertEqual(self.santiago_b.outgoing_messages,
[{"from": "b",
"to": "a",
"client": "a",
"host": "b",
"service": "wiki",
"locations": [],
"reply-to": "localhost:8000"}])
def test_reject_bad_key(self):
"""If B receives a request from an unauthorized key, it does not reply.
An "unauthorized request" in this case is for a service from a client
that B does not trust. This is different than clients B hosts no
services for.
In this case, B will never answer the request.
"""
self.santiago_b.receive(from_="a", to="b",
client="z", host="b",
service="wiki", reply_to=None)
self.assertEqual(self.santiago_b.outgoing_messages, [])
def test_reject_good_source_bad_client(self):
"""B is silent when a trusted key proxies anything for an untrusted key.
B doesn't know who the client is and should consider it an
untrusted key connection attempt.
"""
self.santiago_b.receive(from_="a", to="b",
client="z", host="b",
service="wiki", reply_to=None)
self.assertEqual(self.santiago_b.outgoing_messages, [])
def test_reject_bad_source_good_client(self):
"""B is silent when an untrusted key proxies anything for a trusted key.
B doesn't know who the proxy is and should consider it an
untrusted key connection attempt.
"""
self.santiago_b.receive(from_="z", to="b",
client="a", host="b",
service="wiki", reply_to=None)
self.assertEqual(self.santiago_b.outgoing_messages, [])
def test_reject_bad_source_bad_client(self):
"""B is silent when untrusted keys proxy anything for untrusted keys.
B doesn't know who anybody is and considers this an untrusted
connection attempt.
"""
self.santiago_b.receive(from_="y", to="b",
client="z", host="b",
service="wiki", reply_to=None)
self.assertEqual(self.santiago_b.outgoing_messages, [])
def test_learn_santaigo(self):
"""Does B learn new Santiago locations from trusted requests?
If A sends B a request with a new Santiago location, B should learn it.
"""
self.santiago_b.receive(from_="a", to="b",
client="a", host="b",
service="wiki", reply_to="localhost:9001")
self.assertEqual(self.santiago_b.consuming["santiago"]["a"],
["localhost:9000", "localhost:9001"])
def test_handle_requests_once(self):
"""Verify that we reply to each request only once."""
self.santiago_b.receive(from_="a", to="b",
client="a", host="b",
service="wiki", reply_to=None)
self.santiago_b.process()
self.assertEqual(self.santiago_b.outgoing_messages, [])
class TestServerInitialResponse(SantiagoTest):
pass
class TestClientInitialResponse(SantiagoTest):
pass
class TestForwardedRequest(SantiagoTest):
pass
class TestForwardedResponse(SantiagoTest):
pass
class TestSimpleSantiago(unittest.TestCase):
def setUp(self):
port_a = "localhost:9000"
port_b = "localhost:8000"
listeners_a = {"http": {"port": port_a}}
senders_a = ({ "protocol": "http", "proxy": tor_proxy_port },)
listeners_b = {"http": {"port": port_b}}
senders_b = ({ "protocol": "http", "proxy": tor_proxy_port },)
hosting_a = { "b": { "santiago": set( ["aDifferentHexNumber.onion"])}}
consuming_a = { "santiagao": {"b": set(["iAmAHexadecimalNumber.onion"])}}
hosting_b = { "a": { "santiago": set( ["iAmAHexadecimalNumber.onion"])}}
consuming_b = { "santiagao": { "a": set( ["aDifferentHexNumber.onion"])}}
self.santiago_a = SimpleSantiago(listeners_a, senders_a,
hosting_a, consuming_a, "a")
self.santiago_b = SimpleSantiago(listeners_b, senders_b,
hosting_b, consuming_b, "b")
cherrypy.Application(self.santiago_a, "/")
cherrypy.Application(self.santiago_b, "/")
cherrypy.engine.start()
def testRequest(self):
self.santiago_a.request(from_="a", to="b",
client="a", host="b",
service="wiki", reply_to="localhost:9000")
class Unwrapping(unittest.TestCase):
def testVerifySigner(self):
pass
def testVerifyClient(self):
pass
def testDecryptClient(self):
pass
class IncomingProxyRequest(unittest.TestCase):
"""Do we correctly handle valid, incoming, proxied messages?
These tests are for the first wrapped layer of the message, that which is
signed by the sender. The sender is not necessarily the original requester
who's asking us to do something with the message.
import logging
from errors import InvalidSignatureError, UnwillingHostError
import simplesantiago as santiago
import test_pgpprocessor
import pgpprocessor
# class SantiagoTest(unittest.TestCase):
# """The base class for tests."""
#
# def setUp(self):
# super(TestServing, self).setUp()
#
# port_a = "localhost:9000"
# port_b = "localhost:8000"
#
# listeners_a = [santiago.SantiagoListener(port_a)]
# senders_a = [santiago.SantiagoSender()]
# listeners_b = [santiago.SantiagoListener(port_b)]
# senders_b = [santiago.SantiagoSender()]
#
# hosting_a = { "b": { "santiago": [ port_a ]}}
# consuming_a = { "santiagao": { "b": [ port_b ]}}
#
# hosting_b = { "a": { "santiago": [ port_b ],
# "wiki": [ "localhost:8001" ]}}
# consuming_b = { "santiagao": { "a": [ port_a ]}}
#
# self.santiago_a = Santiago(listeners_a, senders_a, hosting_a, consuming_a)
# self.santiago_b = Santiago(listeners_b, senders_b, hosting_b, consuming_b)
#
# def serveOnPort(self, port):
# """Start listening for connections on a named port.
#
# Used in testing as a mock listener for responses from a Santiago server.
#
# """
# class RequestReceiver(object):
# """A very basic listener.
#
# It merely records the calling arguments.
#
# """
# @cherrypy.expose
# def index(self, *args, **kwargs):
# self.args = args
# self.kwargs = kwargs
#
# self.socket_port = port
#
# self.receiver = RequestReceiver()
#
# cherrypy.quickstart(self.receiver)
#
# if sys.version_info < (2, 7):
# """Add a poor man's forward compatibility."""
#
# class ContainsError(AssertionError):
# pass
#
# def assertIn(self, a, b):
# if not a in b:
# raise self.ContainsError("%s not in %s" % (a, b))
#
# class TestClientInitialRequest(SantiagoTest):
# """Does the client send a correctly formed request?
#
# In these tests, we're sending requests to a mock listener which merely
# records that the requests were well-formed.
#
# """
# def setUp(self):
# super(SantiagoTest, self).setUp()
#
# self.serveOnPort(8000)
#
# def test_request(self):
# """Verify that A queues a properly formatted initial request."""
#
# self.santiago_a.request(from_="a", to="b",
# client="a", host="b",
# service="wiki", reply_to="localhost:9001")
#
# self.assertEqual(self.santiago_a.outgoing_messages,
# [{ "from": "a", "to": "b",
# "client": "a", "host": "b",
# "service": "wiki", "reply-to": "localhost:9001"}])
#
# def test_request(self):
# """Verify that A sends out a properly formatted initial request."""
#
# self.santiago_a.request(from_="a", to="b",
# client="a", host="b",
# service="wiki", reply_to="localhost:9001")
#
# self.santiago_a.process()
#
# self.assertEqual(self.receiver.kwargs,
# [{ "from": "a", "to": "b",
# "client": "a", "host": "b",
# "service": "wiki", "reply-to": "localhost:9001"}])
#
# class TestServerInitialRequest(SantiagoTest):
# """Test how the Santiago server replies to initial service requests.
#
# TODO: Add a mock listener to represent A.
# TODO: Transform the data structure tests into the mock-response tests.
# TODO tests: (normal serving + proxying) * (learning santiagi + not learning)
#
# Proxying
# ~~~~~~~~
#
# A host/listener (B) trusts proxied requests according to the minimum trust
# in the request. If the request comes from an untrusted proxy or is for an
# untrusted client, B ignores it.
#
# """
# def setUp(self):
# super(SantiagoTest, self).setUp()
#
# self.serveOnPort(9000)
#
# def test_acknowledgement(self):
# """If B receives an authorized request, then it replies with a location.
#
# An "authorized request" in this case is for a service from a client that
# B is willing to host that service for.
#
# In this case, B will answer with the wiki's location.
#
# """
# self.santiago_b.receive(from_="a", to="b",
# client="a", host="b",
# service="wiki", reply_to=None)
#
# self.assertEqual(self.santiago_b.outgoing_messages,
# [{"from": "b",
# "to": "a",
# "client": "a",
# "host": "b",
# "service": "wiki",
# "locations": ["192.168.0.13"],
# "reply-to": "localhost:8000"}])
#
# def test_reject_bad_service(self):
# """Does B reject requests for unsupported services?
#
# In this case, B should reply with an empty list of locations.
#
# """
# self.santiago_b.receive(from_="a", to="b",
# client="a", host="b",
# service="wiki", reply_to=None)
#
# self.assertEqual(self.santiago_b.outgoing_messages,
# [{"from": "b",
# "to": "a",
# "client": "a",
# "host": "b",
# "service": "wiki",
# "locations": [],
# "reply-to": "localhost:8000"}])
#
# def test_reject_bad_key(self):
# """If B receives a request from an unauthorized key, it does not reply.
#
# An "unauthorized request" in this case is for a service from a client
# that B does not trust. This is different than clients B hosts no
# services for.
#
# In this case, B will never answer the request.
#
# """
# self.santiago_b.receive(from_="a", to="b",
# client="z", host="b",
# service="wiki", reply_to=None)
#
# self.assertEqual(self.santiago_b.outgoing_messages, [])
#
# def test_reject_good_source_bad_client(self):
# """B is silent when a trusted key proxies anything for an untrusted key.
#
# B doesn't know who the client is and should consider it an
# untrusted key connection attempt.
#
# """
# self.santiago_b.receive(from_="a", to="b",
# client="z", host="b",
# service="wiki", reply_to=None)
#
# self.assertEqual(self.santiago_b.outgoing_messages, [])
#
# def test_reject_bad_source_good_client(self):
# """B is silent when an untrusted key proxies anything for a trusted key.
#
# B doesn't know who the proxy is and should consider it an
# untrusted key connection attempt.
#
# """
# self.santiago_b.receive(from_="z", to="b",
# client="a", host="b",
# service="wiki", reply_to=None)
#
# self.assertEqual(self.santiago_b.outgoing_messages, [])
#
# def test_reject_bad_source_bad_client(self):
# """B is silent when untrusted keys proxy anything for untrusted keys.
#
# B doesn't know who anybody is and considers this an untrusted
# connection attempt.
#
# """
# self.santiago_b.receive(from_="y", to="b",
# client="z", host="b",
# service="wiki", reply_to=None)
#
# self.assertEqual(self.santiago_b.outgoing_messages, [])
#
# def test_learn_santaigo(self):
# """Does B learn new Santiago locations from trusted requests?
#
# If A sends B a request with a new Santiago location, B should learn it.
#
# """
# self.santiago_b.receive(from_="a", to="b",
# client="a", host="b",
# service="wiki", reply_to="localhost:9001")
#
# self.assertEqual(self.santiago_b.consuming["santiago"]["a"],
# ["localhost:9000", "localhost:9001"])
#
# def test_handle_requests_once(self):
# """Verify that we reply to each request only once."""
#
# self.santiago_b.receive(from_="a", to="b",
# client="a", host="b",
# service="wiki", reply_to=None)
# self.santiago_b.process()
#
# self.assertEqual(self.santiago_b.outgoing_messages, [])
#
# class TestServerInitialResponse(SantiagoTest):
# pass
#
# class TestClientInitialResponse(SantiagoTest):
# pass
#
# class TestForwardedRequest(SantiagoTest):
# pass
#
# class TestForwardedResponse(SantiagoTest):
# pass
#
# class TestSimpleSantiago(unittest.TestCase):
# def setUp(self):
#
# port_a = "localhost:9000"
# port_b = "localhost:8000"
#
# listeners_a = {"http": {"port": port_a}}
# senders_a = ({ "protocol": "http", "proxy": tor_proxy_port },)
#
# listeners_b = {"http": {"port": port_b}}
# senders_b = ({ "protocol": "http", "proxy": tor_proxy_port },)
#
# hosting_a = { "b": { "santiago": set( ["aDifferentHexNumber.onion"])}}
# consuming_a = { "santiagao": {"b": set(["iAmAHexadecimalNumber.onion"])}}
#
# hosting_b = { "a": { "santiago": set( ["iAmAHexadecimalNumber.onion"])}}
# consuming_b = { "santiagao": { "a": set( ["aDifferentHexNumber.onion"])}}
#
# self.santiago_a = santiago.Santiago(listeners_a, senders_a,
# hosting_a, consuming_a, "a")
# self.santiago_b = santiago.Santiago(listeners_b, senders_b,
# hosting_b, consuming_b, "b")
#
# cherrypy.Application(self.santiago_a, "/")
# cherrypy.Application(self.santiago_b, "/")
#
# cherrypy.engine.start()
#
# def testRequest(self):
# self.santiago_a.request(from_="a", to="b",
# client="a", host="b",
# service="wiki", reply_to="localhost:9000")
#
#
# class Unwrapping(unittest.TestCase):
#
# def testVerifySigner(self):
# pass
#
# def testVerifyClient(self):
# pass
#
# def testDecryptClient(self):
# pass
#
# class IncomingProxyRequest(unittest.TestCase):
#
# """Do we correctly handle valid, incoming, proxied messages?
#
# These tests are for the first wrapped layer of the message, that which is
# signed by the sender. The sender is not necessarily the original requester
# who's asking us to do something with the message.
#
# """
#
# def setUp(self):
# pass
#
# def testPassingMessage(self):
# """Does a valid proxied message pass?"""
#
# pass
#
# def testInvalidSig(self):
# """Does an invalid signature raise an error?"""
#
# pass
#
# def testUnknownClient(self):
# """Does an unknown client raise an error?"""
#
# pass
#
# class IncomingSignedRequest(IncomingProxyRequest):
#
# """Do we correctly handle valid, incoming, messages?
#
# These tests focus on the second layer of the message which is signed by the
# host/client and lists a destination.
#
# """
# def testProxyOtherHosts(self):
# """Messages to others are sent to them directly or proxied."""
#
# pass
#
# def testHandleMyHosting(self):
# """Messages to me are not proxied and handled normally."""
#
# pass
#
# def testNoDestination(self):
# """Messages without destinations are ignored."""
#
# pass
#
# class IncomingRequestBody(IncomingSignedRequest):
#
# """Do we correctly handle the body of a request?
#
# This is the last layer of the message which is encrypted by the original
# sender. This validation also depends on the previous layer's data, making
# it a bit more complicated.
#
# """
# def testHandleGoodMessage(self):
# """Sanity check: no errors are thrown for a valid message."""
#
# pass
#
# def testCantDecryptMessage(self):
# """This message isn't for me. I can't decrypt it."""
#
# pass
#
# def testImNotHost(self):
# """Bail out if someone else is the host, yet I am the "to"."""
#
# pass
#
# def testImNotClient(self):
# """Bail out if someone else is the client, yet I am the "to"."""
#
# pass
#
# def testHostAndClient(self):
# """Bail out if the message includes a host and a client.
#
# A circular response?
#
# """
# pass
#
# def testImNotTo(self):
# """This message isn't for me.
#
# The "To" has been repeated from the signed message, but I'm not the
# recipient in the encrypted message.
#
# """
# pass
#
# def testNoDestinations(self):
# """No host, client, or to."""
#
# pass
#
# def testSignersDiffer(self):
# """The signed message and encrypted message have different signers."""
#
# pass
#
# def testSignerAndClientDiffer(self):
# """The encrypted message is signed by someone other than the cilent."""
#
# pass
class VerifySender(test_pgpprocessor.MessageWrapper):
"""Santiago.verify_sender performs as expected.
It must unwrap the message and return the message's (decrypted) body. If
stuff is weird about the message, raise errors:
- Raise an InvalidSignature error when the signature is incorrect.
- Raise an UnwillingHost error when the signer is not a client authorized to
send us Santiago messages.
"""
def setUp(self):
pass
super(VerifySender, self).setUp()
def testPassingMessage(self):
"""Does a valid proxied message pass?"""
self.santiago = santiago.Santiago(
hosting = { self.keyid: {"santiago": ["1"] }},
me = self.keyid)
self.method = "verify_sender"
pass
self.unwrapper = pgpprocessor.Unwrapper(str(self.messages[2]))
def testInvalidSig(self):
"""Does an invalid signature raise an error?"""
def test_valid_message(self):
"""A valid message (correctly signed and from a trusted host) passes."""
pass
gpg_data = getattr(self.santiago, self.method)(self.unwrapper)
def testUnknownClient(self):
"""Does an unknown client raise an error?"""
self.assertEqual(self.messages[1], gpg_data.message)
pass
def test_fail_invalid_signature(self):
"""A message with an invalid signature fails
class IncomingSignedRequest(IncomingProxyRequest):
"""Do we correctly handle valid, incoming, messages?
These tests focus on the second layer of the message which is signed by the
host/client and lists a destination.
"""
def testProxyOtherHosts(self):
"""Messages to others are sent to them directly or proxied."""
pass
def testHandleMyHosting(self):
"""Messages to me are not proxied and handled normally."""
pass
def testNoDestination(self):
"""Messages without destinations are ignored."""
pass
class IncomingRequestBody(IncomingSignedRequest):
"""Do we correctly handle the body of a request?
This is the last layer of the message which is encrypted by the original
sender. This validation also depends on the previous layer's data, making
it a bit more complicated.
"""
def testHandleGoodMessage(self):
"""Sanity check: no errors are thrown for a valid message."""
pass
def testCantDecryptMessage(self):
"""This message isn't for me. I can't decrypt it."""
pass
def testImNotHost(self):
"""Bail out if someone else is the host, yet I am the "to"."""
pass
def testImNotClient(self):
"""Bail out if someone else is the client, yet I am the "to"."""
pass
def testHostAndClient(self):
"""Bail out if the message includes a host and a client.
A circular response?
It raises an InvalidSignature error.
"""
pass
message = self.unwrapper.message.splitlines(True)
message[7] += "q"
self.unwrapper.message = "".join(message)
def testImNotTo(self):
"""This message isn't for me.
self.assertRaises(InvalidSignatureError,
getattr(self.santiago, self.method), self.unwrapper)
The "To" has been repeated from the signed message, but I'm not the
recipient in the encrypted message.
def test_fail_invalid_signer(self):
"""A message with a valid signature from an untrusted signer fails.
It raises an UntrustedClient error.
"""
pass
self.santiago.hosting = { 1: { "santiago": ["1"] }}
def testNoDestinations(self):
"""No host, client, or to."""
self.assertRaises(UnwillingHostError,
getattr(self.santiago, self.method), self.unwrapper)
class VerifyClient(VerifySender):
"""Santiago.verify_client performs as expected.
It must unwrap the message and return the message's (decrypted) body. If
stuff is weird about the message, raise errors:
- Raise an InvalidSignature error when the signature is incorrect.
- Raise an UnwillingHost error when the signer is not a client authorized to
send us Santiago messages.
Is this just unnecessarily fucking complicating all of this? Yes. Screw
proxying, just get it out the door by sending the encrypted bits directly.
"""
def setUp(self):
super(VerifyClient, self).__init__()
self.method = "verify_client"
def test_proxy_request(self):
"""When the message is for somebody else, it gets proxied."""
pass
def testSignersDiffer(self):
"""The signed message and encrypted message have different signers."""
def test_return_only_valid_message(self):
"""Invalid messages (without "to" and "request" keys) return nothing."""
pass
def testSignerAndClientDiffer(self):
"""The encrypted message is signed by someone other than the cilent."""
def test_dont_verify_source(self):
"""If the message is being proxied, we don't care who sent the message.
"""
pass
def show(name, item, iterations=1):
@ -465,4 +559,5 @@ def show(name, item, iterations=1):
pprint(item)
if __name__ == "__main__":
logging.disable(logging.CRITICAL)
unittest.main()