예제 #1
0
 def testPlainLarge(self):
     """Test the client splits large AUTHENTICATE messages whose payload
     is not a multiple of 400.
     <http://ircv3.net/specs/extensions/sasl-3.1.html#the-authenticate-command>
     """
     # TODO: authzid is optional
     auth = authentication.Authentication(
         mechanisms=[authentication.Mechanisms.plain],
         username="******",
         password="******" * 200,
     )
     authstring = base64.b64encode(b"\x00".join(
         [b"foo", b"foo", b"bar" * 200])).decode()
     m = self.negotiateCapabilities(["sasl"], auth=auth)
     self.assertEqual(m, Message({}, None, "AUTHENTICATE", ["PLAIN"]))
     self.sendLine("AUTHENTICATE +")
     m = self.getMessage()
     self.assertEqual(
         m, Message({}, None, "AUTHENTICATE", [authstring[0:400]]), m)
     m = self.getMessage()
     self.assertEqual(
         m, Message({}, None, "AUTHENTICATE", [authstring[400:800]]))
     m = self.getMessage()
     self.assertEqual(m,
                      Message({}, None, "AUTHENTICATE", [authstring[800:]]))
     self.sendLine("900 * * {} :You are now logged in.".format("foo"))
     self.sendLine("903 * :SASL authentication successful")
     m = self.negotiateCapabilities(["sasl"], False)
     self.assertEqual(m, Message({}, None, "CAP", ["END"]))
예제 #2
0
    def testPlainNotAvailable(self):
        """`sasl=EXTERNAL` is advertized, whereas the client is configured
        to use PLAIN.

        A client implementing sasl-3.2 can give up authentication immediately.
        A client not implementing it will try authenticating, and will get
        a 904.
        """
        auth = authentication.Authentication(
            mechanisms=[authentication.Mechanisms.plain],
            username="******",
            password="******",
        )
        m = self.negotiateCapabilities(["sasl=EXTERNAL"], auth=auth)
        self.assertEqual(self.acked_capabilities, {"sasl"})
        if m == Message({}, None, "CAP", ["END"]):
            # IRCv3.2-style, for clients that skip authentication
            # when unavailable (eg. Limnoria)
            return
        elif m.command == "QUIT":
            # IRCv3.2-style, for clients that quit when unavailable
            # (eg. Sopel)
            return
        self.assertEqual(m, Message({}, None, "AUTHENTICATE", ["PLAIN"]))
        self.sendLine("904 {} :SASL auth failed".format(self.nick))
        m = self.getMessage()
        self.assertMessageMatch(m, command="CAP")
예제 #3
0
    def testScramBadPassword(self):
        """Test SCRAM-SHA-256 authentication with a bad password."""
        auth = authentication.Authentication(
            mechanisms=[authentication.Mechanisms.scram_sha_256],
            username="******",
            password="******",
        )

        class PasswdDb:
            def get_password(self, *args):
                return ("notsesame", "plain")

        authenticator = scram.SCRAMServerAuthenticator(
            "SHA-256", channel_binding=False, password_database=PasswdDb())

        m = self.negotiateCapabilities(["sasl"], auth=auth)
        self.assertEqual(m, Message({}, None, "AUTHENTICATE",
                                    ["SCRAM-SHA-256"]))
        self.sendLine("AUTHENTICATE +")

        m = self.getMessage()
        self.assertEqual(m.command, "AUTHENTICATE", m)
        client_first = base64.b64decode(m.params[0])
        response = authenticator.start(properties={},
                                       initial_response=client_first)
        assert isinstance(response, bytes), response
        self.sendLine("AUTHENTICATE :" + base64.b64encode(response).decode())

        m = self.getMessage()
        self.assertEqual(m.command, "AUTHENTICATE", m)
        msg = base64.b64decode(m.params[0])
        with self.assertRaises(scram.NotAuthorizedException):
            authenticator.response(msg)
예제 #4
0
 def testEcdsa(self):
     """Test ECDSA authentication."""
     auth = authentication.Authentication(
         mechanisms=[authentication.Mechanisms.ecdsa_nist256p_challenge],
         username="******",
         ecdsa_key=ECDSA_KEY,
     )
     m = self.negotiateCapabilities(["sasl"], auth=auth)
     self.assertEqual(
         m, Message({}, None, "AUTHENTICATE", ["ECDSA-NIST256P-CHALLENGE"]))
     self.sendLine("AUTHENTICATE +")
     m = self.getMessage()
     self.assertEqual(m, Message({}, None, "AUTHENTICATE",
                                 ["amlsbGVz"]))  # jilles
     self.sendLine("AUTHENTICATE {}".format(
         base64.b64encode(CHALLENGE).decode("ascii")))
     m = self.getMessage()
     self.assertMessageMatch(m, command="AUTHENTICATE")
     sk = ecdsa.SigningKey.from_pem(ECDSA_KEY)
     vk = sk.get_verifying_key()
     signature = base64.b64decode(m.params[0])
     try:
         vk.verify(signature,
                   CHALLENGE,
                   hashfunc=IdentityHash,
                   sigdecode=sigdecode_der)
     except ecdsa.BadSignatureError:
         raise AssertionError("Bad signature")
     self.sendLine("900 * * foo :You are now logged in.")
     self.sendLine("903 * :SASL authentication successful")
     m = self.negotiateCapabilities(["sasl"], False)
     self.assertEqual(m, Message({}, None, "CAP", ["END"]))
예제 #5
0
    def testPlainNotAvailable(self):
        """Test the client does not try to authenticate using a mechanism the
        server does not advertise.
        Actually, this is optional."""
        auth = authentication.Authentication(
            mechanisms=[authentication.Mechanisms.plain],
            username="******",
            password="******",
        )
        m = self.negotiateCapabilities(["sasl=EXTERNAL"], auth=auth)
        self.assertEqual(self.acked_capabilities, {"sasl"})

        if m.command == "QUIT":
            # Some clients quit when it can't authenticate (eg. Sopel)
            pass
        else:
            # Others will just skip authentication (eg. Limnoria)
            self.assertEqual(m, Message({}, None, "CAP", ["END"]))
예제 #6
0
 def testPlain(self):
     """Test PLAIN authentication with correct username/password."""
     auth = authentication.Authentication(
         mechanisms=[authentication.Mechanisms.plain],
         username="******",
         password="******",
     )
     m = self.negotiateCapabilities(["sasl"], auth=auth)
     self.assertEqual(m, Message({}, None, "AUTHENTICATE", ["PLAIN"]))
     self.sendLine("AUTHENTICATE +")
     m = self.getMessage()
     self.assertEqual(
         m,
         Message({}, None, "AUTHENTICATE",
                 ["amlsbGVzAGppbGxlcwBzZXNhbWU="]))
     self.sendLine("900 * * jilles :You are now logged in.")
     self.sendLine("903 * :SASL authentication successful")
     m = self.negotiateCapabilities(["sasl"], False)
     self.assertEqual(m, Message({}, None, "CAP", ["END"]))