Пример #1
0
 def protocol():
     proto = CredReceiver()
     proto.portal = Portal(
         self.loginSystem,
         [self.loginSystem,
          OneTimePadChecker(self._oneTimePads)])
     return proto
Пример #2
0
 def protocol():
     proto = CredReceiver()
     proto.portal = Portal(
         self.loginSystem,
         [self.loginSystem,
          OneTimePadChecker(self._oneTimePads)])
     return proto
Пример #3
0
 def setUp(self):
     """
     Create a L{CredReceiver} hooked up to a fake L{IBoxSender} which
     records boxes sent through it.
     """
     self.username = '******'
     self.password = '******'
     self.checker = InMemoryUsernamePasswordDatabaseDontUse()
     self.checker.addUser(self.username, self.password)
     self.avatar = StubAvatar()
     self.realm = StubRealm(self.avatar)
     self.portal = Portal(self.realm, [self.checker])
     self.server = CredReceiver()
     self.server.portal = self.portal
     self.client = AMP()
     self.finished = loopbackAsync(self.server, self.client)
Пример #4
0
 def setUp(self):
     """
     Create a L{CredReceiver} hooked up to a fake L{IBoxSender} which
     records boxes sent through it.
     """
     self.username = '******'
     self.password = '******'
     self.checker = InMemoryUsernamePasswordDatabaseDontUse()
     self.checker.addUser(self.username, self.password)
     self.avatar = StubAvatar()
     self.realm = StubRealm(self.avatar)
     self.portal = Portal(self.realm, [self.checker])
     self.server = CredReceiver()
     self.server.portal = self.portal
     self.client = AMP()
     self.finished = loopbackAsync(self.server, self.client)
Пример #5
0
class CredReceiverTests(TestCase):
    """
    Tests for L{CredReceiver}, an L{IBoxReceiver} which integrates with
    L{twisted.cred} to provide authentication and authorization of AMP
    connections.
    """
    def setUp(self):
        """
        Create a L{CredReceiver} hooked up to a fake L{IBoxSender} which
        records boxes sent through it.
        """
        self.username = '******'
        self.password = '******'
        self.checker = InMemoryUsernamePasswordDatabaseDontUse()
        self.checker.addUser(self.username, self.password)
        self.avatar = StubAvatar()
        self.realm = StubRealm(self.avatar)
        self.portal = Portal(self.realm, [self.checker])
        self.server = CredReceiver()
        self.server.portal = self.portal
        self.client = AMP()
        self.finished = loopbackAsync(self.server, self.client)


    def test_otpLogin(self):
        """
        L{CredReceiver.otpLogin} returns without error if the pad is valid.
        """
        PAD = 'test_otpLogin'
        self.portal.registerChecker(OneTimePadChecker({PAD: 'user'}))
        d = self.server.otpLogin(PAD)
        def cbLoggedIn(result):
            self.assertEqual(result, {})
        d.addCallback(cbLoggedIn)
        return d


    def test_otpLoginUnauthorized(self):
        """
        L{CredReceiver.otpLogin} should fail with L{UnauthorizedLogin} if an
        invalid pad is received.
        """
        self.portal.registerChecker(OneTimePadChecker({}))
        return self.assertFailure(
            self.server.otpLogin('test_otpLoginUnauthorized'),
            UnauthorizedLogin)


    def test_otpLoginNotImplemented(self):
        """
        L{CredReceiver.otpLogin} should fail with L{NotImplementedError} if
        the realm raises L{NotImplementedError} when asked for the avatar.
        """
        def noAvatar(avatarId, mind, *interfaces):
            raise NotImplementedError()
        self.realm.requestAvatar = noAvatar

        PAD = 'test_otpLoginNotImplemented'
        self.portal.registerChecker(OneTimePadChecker({PAD: 'user'}))
        return self.assertFailure(
            self.server.otpLogin(PAD), NotImplementedError)


    def test_otpLoginResponder(self):
        """
        L{CredReceiver} responds to the L{OTPLogin} command.
        """
        PAD = 'test_otpLoginResponder'
        self.portal.registerChecker(OneTimePadChecker({PAD: 'user'}))
        d = self.client.callRemote(OTPLogin, pad=PAD)
        def cbLoggedIn(result):
            self.assertEqual(result, {})
        d.addCallback(cbLoggedIn)
        return d


    def test_passwordLoginDifferentChallenges(self):
        """
        L{CredReceiver.passwordLogin} returns a new challenge each time it is
        called.
        """
        first = self.server.passwordLogin(self.username)
        second = self.server.passwordLogin(self.username)
        self.assertNotEqual(first['challenge'], second['challenge'])


    def test_passwordLoginResponder(self):
        """
        L{CredReceiver} responds to the L{PasswordLogin} L{Command} with a
        challenge.
        """
        d = self.client.callRemote(PasswordLogin, username=self.username)
        def cbLogin(result):
            self.assertIn('challenge', result)
        d.addCallback(cbLogin)
        return d


    def test_determineFromDifferentNonces(self):
        """
        Each time L{PasswordChallengeResponse.determineFrom} is used, it
        generates a different C{cnonce} value.
        """
        first = PasswordChallengeResponse.determineFrom('a', 'b')
        second = PasswordChallengeResponse.determineFrom('a', 'b')
        self.assertNotEqual(first['cnonce'], second['cnonce'])


    def test_passwordChallengeResponse(self):
        """
        L{CredReceiver.passwordChallengeResponse} returns without error if the
        response is valid.
        """
        challenge = self.server.passwordLogin(self.username)['challenge']
        cnonce = '123abc'
        cleartext = '%s %s %s' % (challenge, cnonce, self.password)
        response = sha1(cleartext).digest()
        d = self.server.passwordChallengeResponse(cnonce, response)
        def cbLoggedIn(result):
            self.assertEqual(result, {})
        d.addCallback(cbLoggedIn)
        return d


    def test_passwordChallengeResponseResponder(self):
        """
        L{CredReceiver} responds to the L{PasswordChallengeResponse} L{Command}
        with an empty box if the response supplied is valid.
        """
        challenge = self.server.passwordLogin(self.username)['challenge']
        d = self.client.callRemote(
            PasswordChallengeResponse, **PasswordChallengeResponse.determineFrom(
                challenge, self.password))
        def cbResponded(result):
            self.assertEqual(result, {})
        d.addCallback(cbResponded)
        return d


    def test_response(self):
        """
        L{PasswordChallengeResponse.determineFrom} generates the correct
        response to a challenge issued by L{CredReceiver.passwordLogin}.
        """
        challenge = self.server.passwordLogin(self.username)['challenge']
        result = PasswordChallengeResponse.determineFrom(
            challenge, self.password)
        d = self.server.passwordChallengeResponse(**result)
        def cbLoggedIn(ignored):
            [(avatarId, mind, interfaces)] = self.realm.requests
            self.assertEqual(avatarId, self.username)
            self.assertEqual(interfaces, (IBoxReceiver,))

            # The avatar is now the protocol's box receiver.
            self.assertIdentical(self.server.boxReceiver, self.avatar)

            # And the avatar has been started up with the protocol's
            # IBoxSender.
            self.assertIdentical(self.avatar.boxSender, self.server.boxSender)

            # After the connection is lost, the logout function should be
            # called.
            self.assertEqual(self.realm.loggedOut, 0)
            self.server.connectionLost(
                Failure(ConnectionDone("test connection lost")))
            self.assertEqual(self.realm.loggedOut, 1)

        d.addCallback(cbLoggedIn)
        return d


    def test_invalidResponse(self):
        """
        L{CredReceiver.passwordChallengeResponse} returns a L{Deferred} which
        fails with L{UnauthorizedLogin} if it is passed a response which is not
        valid.
        """
        challenge = self.server.passwordLogin(self.username)['challenge']
        return self.assertFailure(
            self.server.passwordChallengeResponse(cnonce='bar', response='baz'),
            UnauthorizedLogin)


    def test_connectionLostWithoutAvatar(self):
        """
        L{CredReceiver.connectionLost} does not raise an exception if no login
        has occurred when it is called.
        """
        self.server.connectionLost(
            Failure(ConnectionDone("test connection lost")))


    def test_unrecognizedCredentialsLogin(self):
        """
        L{login} raises L{UnhandledCredentials} if passed a credentials object
        which provides no interface explicitly supported by that function,
        currently L{IUsernamePassword}.
        """
        self.assertRaises(UnhandledCredentials, login, None, None)


    def test_passwordChallengeLogin(self):
        """
        L{login} issues the commands necessary to authenticate against
        L{CredReceiver} when given an L{IUsernamePassword} provider with its
        C{username} and C{password} attributes set to valid credentials.
        """
        loginDeferred = login(
            self.client, UsernamePassword(self.username, self.password))

        def cbLoggedIn(clientAgain):
            self.assertIdentical(self.client, clientAgain)
            self.assertIdentical(self.server.boxReceiver, self.avatar)
        loginDeferred.addCallback(cbLoggedIn)
        return loginDeferred


    def test_passwordChallengeInvalid(self):
        """
        L{login} returns a L{Deferred} which fires with L{UnauthorizedLogin} if
        the L{UsernamePassword} credentials object given does not contain valid
        authentication information.
        """
        boxReceiver = self.server.boxReceiver
        loginDeferred = login(
            self.client, UsernamePassword(self.username + 'x', self.password))
        self.assertFailure(loginDeferred, UnauthorizedLogin)
        def cbFailed(ignored):
            self.assertIdentical(self.server.boxReceiver, boxReceiver)
        loginDeferred.addCallback(cbFailed)
        return loginDeferred


    def test_noAvatar(self):
        """
        L{login} returns a L{Deferred} which fires with L{NotImplementedError}
        if the realm raises L{NotImplementedError} when asked for the avatar.
        """
        def noAvatar(avatarId, mind, *interfaces):
            raise NotImplementedError()
        self.realm.requestAvatar = noAvatar

        loginDeferred = login(
            self.client, UsernamePassword(self.username, self.password))
        return self.assertFailure(loginDeferred, NotImplementedError)
Пример #6
0
class CredReceiverTests(TestCase):
    """
    Tests for L{CredReceiver}, an L{IBoxReceiver} which integrates with
    L{twisted.cred} to provide authentication and authorization of AMP
    connections.
    """
    def setUp(self):
        """
        Create a L{CredReceiver} hooked up to a fake L{IBoxSender} which
        records boxes sent through it.
        """
        self.username = '******'
        self.password = '******'
        self.checker = InMemoryUsernamePasswordDatabaseDontUse()
        self.checker.addUser(self.username, self.password)
        self.avatar = StubAvatar()
        self.realm = StubRealm(self.avatar)
        self.portal = Portal(self.realm, [self.checker])
        self.server = CredReceiver()
        self.server.portal = self.portal
        self.client = AMP()
        self.finished = loopbackAsync(self.server, self.client)

    def test_otpLogin(self):
        """
        L{CredReceiver.otpLogin} returns without error if the pad is valid.
        """
        PAD = 'test_otpLogin'
        self.portal.registerChecker(OneTimePadChecker({PAD: 'user'}))
        d = self.server.otpLogin(PAD)

        def cbLoggedIn(result):
            self.assertEqual(result, {})

        d.addCallback(cbLoggedIn)
        return d

    def test_otpLoginUnauthorized(self):
        """
        L{CredReceiver.otpLogin} should fail with L{UnauthorizedLogin} if an
        invalid pad is received.
        """
        self.portal.registerChecker(OneTimePadChecker({}))
        return self.assertFailure(
            self.server.otpLogin('test_otpLoginUnauthorized'),
            UnauthorizedLogin)

    def test_otpLoginNotImplemented(self):
        """
        L{CredReceiver.otpLogin} should fail with L{NotImplementedError} if
        the realm raises L{NotImplementedError} when asked for the avatar.
        """
        def noAvatar(avatarId, mind, *interfaces):
            raise NotImplementedError()

        self.realm.requestAvatar = noAvatar

        PAD = 'test_otpLoginNotImplemented'
        self.portal.registerChecker(OneTimePadChecker({PAD: 'user'}))
        return self.assertFailure(self.server.otpLogin(PAD),
                                  NotImplementedError)

    def test_otpLoginResponder(self):
        """
        L{CredReceiver} responds to the L{OTPLogin} command.
        """
        PAD = 'test_otpLoginResponder'
        self.portal.registerChecker(OneTimePadChecker({PAD: 'user'}))
        d = self.client.callRemote(OTPLogin, pad=PAD)

        def cbLoggedIn(result):
            self.assertEqual(result, {})

        d.addCallback(cbLoggedIn)
        return d

    def test_passwordLoginDifferentChallenges(self):
        """
        L{CredReceiver.passwordLogin} returns a new challenge each time it is
        called.
        """
        first = self.server.passwordLogin(self.username)
        second = self.server.passwordLogin(self.username)
        self.assertNotEqual(first['challenge'], second['challenge'])

    def test_passwordLoginResponder(self):
        """
        L{CredReceiver} responds to the L{PasswordLogin} L{Command} with a
        challenge.
        """
        d = self.client.callRemote(PasswordLogin, username=self.username)

        def cbLogin(result):
            self.assertIn('challenge', result)

        d.addCallback(cbLogin)
        return d

    def test_determineFromDifferentNonces(self):
        """
        Each time L{PasswordChallengeResponse.determineFrom} is used, it
        generates a different C{cnonce} value.
        """
        first = PasswordChallengeResponse.determineFrom('a', 'b')
        second = PasswordChallengeResponse.determineFrom('a', 'b')
        self.assertNotEqual(first['cnonce'], second['cnonce'])

    def test_passwordChallengeResponse(self):
        """
        L{CredReceiver.passwordChallengeResponse} returns without error if the
        response is valid.
        """
        challenge = self.server.passwordLogin(self.username)['challenge']
        cnonce = '123abc'
        cleartext = '%s %s %s' % (challenge, cnonce, self.password)
        response = sha1(cleartext).digest()
        d = self.server.passwordChallengeResponse(cnonce, response)

        def cbLoggedIn(result):
            self.assertEqual(result, {})

        d.addCallback(cbLoggedIn)
        return d

    def test_passwordChallengeResponseResponder(self):
        """
        L{CredReceiver} responds to the L{PasswordChallengeResponse} L{Command}
        with an empty box if the response supplied is valid.
        """
        challenge = self.server.passwordLogin(self.username)['challenge']
        d = self.client.callRemote(
            PasswordChallengeResponse,
            **PasswordChallengeResponse.determineFrom(challenge,
                                                      self.password))

        def cbResponded(result):
            self.assertEqual(result, {})

        d.addCallback(cbResponded)
        return d

    def test_response(self):
        """
        L{PasswordChallengeResponse.determineFrom} generates the correct
        response to a challenge issued by L{CredReceiver.passwordLogin}.
        """
        challenge = self.server.passwordLogin(self.username)['challenge']
        result = PasswordChallengeResponse.determineFrom(
            challenge, self.password)
        d = self.server.passwordChallengeResponse(**result)

        def cbLoggedIn(ignored):
            [(avatarId, mind, interfaces)] = self.realm.requests
            self.assertEqual(avatarId, self.username)
            self.assertEqual(interfaces, (IBoxReceiver, ))

            # The avatar is now the protocol's box receiver.
            self.assertIdentical(self.server.boxReceiver, self.avatar)

            # And the avatar has been started up with the protocol's
            # IBoxSender.
            self.assertIdentical(self.avatar.boxSender, self.server.boxSender)

            # After the connection is lost, the logout function should be
            # called.
            self.assertEqual(self.realm.loggedOut, 0)
            self.server.connectionLost(
                Failure(ConnectionDone("test connection lost")))
            self.assertEqual(self.realm.loggedOut, 1)

        d.addCallback(cbLoggedIn)
        return d

    def test_invalidResponse(self):
        """
        L{CredReceiver.passwordChallengeResponse} returns a L{Deferred} which
        fails with L{UnauthorizedLogin} if it is passed a response which is not
        valid.
        """
        challenge = self.server.passwordLogin(self.username)['challenge']
        return self.assertFailure(
            self.server.passwordChallengeResponse(cnonce='bar',
                                                  response='baz'),
            UnauthorizedLogin)

    def test_connectionLostWithoutAvatar(self):
        """
        L{CredReceiver.connectionLost} does not raise an exception if no login
        has occurred when it is called.
        """
        self.server.connectionLost(
            Failure(ConnectionDone("test connection lost")))

    def test_unrecognizedCredentialsLogin(self):
        """
        L{login} raises L{UnhandledCredentials} if passed a credentials object
        which provides no interface explicitly supported by that function,
        currently L{IUsernamePassword}.
        """
        self.assertRaises(UnhandledCredentials, login, None, None)

    def test_passwordChallengeLogin(self):
        """
        L{login} issues the commands necessary to authenticate against
        L{CredReceiver} when given an L{IUsernamePassword} provider with its
        C{username} and C{password} attributes set to valid credentials.
        """
        loginDeferred = login(self.client,
                              UsernamePassword(self.username, self.password))

        def cbLoggedIn(clientAgain):
            self.assertIdentical(self.client, clientAgain)
            self.assertIdentical(self.server.boxReceiver, self.avatar)

        loginDeferred.addCallback(cbLoggedIn)
        return loginDeferred

    def test_passwordChallengeInvalid(self):
        """
        L{login} returns a L{Deferred} which fires with L{UnauthorizedLogin} if
        the L{UsernamePassword} credentials object given does not contain valid
        authentication information.
        """
        boxReceiver = self.server.boxReceiver
        loginDeferred = login(
            self.client, UsernamePassword(self.username + 'x', self.password))
        self.assertFailure(loginDeferred, UnauthorizedLogin)

        def cbFailed(ignored):
            self.assertIdentical(self.server.boxReceiver, boxReceiver)

        loginDeferred.addCallback(cbFailed)
        return loginDeferred

    def test_noAvatar(self):
        """
        L{login} returns a L{Deferred} which fires with L{NotImplementedError}
        if the realm raises L{NotImplementedError} when asked for the avatar.
        """
        def noAvatar(avatarId, mind, *interfaces):
            raise NotImplementedError()

        self.realm.requestAvatar = noAvatar

        loginDeferred = login(self.client,
                              UsernamePassword(self.username, self.password))
        return self.assertFailure(loginDeferred, NotImplementedError)