Add tests for SCRAM.

This commit is contained in:
Valentin Lorentz 2017-01-11 00:07:25 +01:00 committed by Daniel Oaks
parent 754f9ad250
commit 37ea5be753
4 changed files with 75 additions and 1 deletions

View File

@ -8,9 +8,11 @@ class Mechanisms(enum.Enum):
def as_string(cls, mech):
return {cls.plain: 'PLAIN',
cls.ecdsa_nist256p_challenge: 'ECDSA-NIST256P-CHALLENGE',
cls.scram_sha_256: 'SCRAM-SHA-256',
}[mech]
plain = 1
ecdsa_nist256p_challenge = 2
scram_sha_256 = 3
Authentication = collections.namedtuple('Authentication',
'mechanisms username password ecdsa_key')

View File

@ -1,5 +1,7 @@
import ecdsa
import base64
import pyxmpp2_scram as scram
from irctest import cases
from irctest import authentication
from irctest.irc_utils.message_parser import Message
@ -153,6 +155,74 @@ class SaslTestCase(cases.BaseClientTestCase, cases.ClientNegociationHelper,
m = self.negotiateCapabilities(['sasl'], False)
self.assertEqual(m, Message([], None, 'CAP', ['END']))
@cases.OptionalityHelper.skipUnlessHasMechanism('SCRAM-SHA-256')
def testScram(self):
"""Test SCRAM-SHA-256 authentication.
"""
auth = authentication.Authentication(
mechanisms=[authentication.Mechanisms.scram_sha_256],
username='jilles',
password='sesame',
)
class PasswdDb:
def get_password(self, *args):
return ('sesame', '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])
r = authenticator.response(msg)
assert isinstance(r, tuple), r
assert len(r) == 2, r
(properties, response) = r
self.sendLine('AUTHENTICATE :' + base64.b64encode(response).decode())
self.assertEqual(properties, {'authzid': None, 'username': 'jilles'})
@cases.OptionalityHelper.skipUnlessHasMechanism('SCRAM-SHA-256')
def testScramBadPassword(self):
"""Test SCRAM-SHA-256 authentication with a bad password.
"""
auth = authentication.Authentication(
mechanisms=[authentication.Mechanisms.scram_sha_256],
username='jilles',
password='sesame',
)
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)
class Irc302SaslTestCase(cases.BaseClientTestCase, cases.ClientNegociationHelper,
cases.OptionalityHelper):
@cases.OptionalityHelper.skipUnlessHasMechanism('PLAIN')

View File

@ -9,6 +9,7 @@ TEMPLATE_CONFIG = """
supybot.directories.conf: {directory}/conf
supybot.directories.data: {directory}/data
supybot.directories.migrations: {directory}/migrations
supybot.log.level: DEBUG
supybot.log.stdout.level: {loglevel}
supybot.networks: testnet
@ -27,7 +28,7 @@ supybot.networks.testnet.sasl.mechanisms: {mechanisms}
class LimnoriaController(BaseClientController, DirectoryBasedController):
software_name = 'Limnoria'
supported_sasl_mechanisms = {
'PLAIN', 'ECDSA-NIST256P-CHALLENGE', 'EXTERNAL',
'PLAIN', 'ECDSA-NIST256P-CHALLENGE', 'SCRAM-SHA-256', 'EXTERNAL',
}
def create_config(self):
super().create_config()

View File

@ -1,3 +1,4 @@
limnoria > 2012.08.04 # Needs MultipleReplacer, from 1a64f105
psutil >= 3.1.0 # Fixes #640
ecdsa
pyxmpp2_scram