mirror of
https://github.com/Mikaela/Limnoria.git
synced 2025-02-02 15:44:06 +01:00
Filter list of SASL mechanisms when provided (908 or IRCv3.2-style CAP LS).
This commit is contained in:
parent
932345fa48
commit
8aff8170e4
@ -966,13 +966,6 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
|
||||
self.ident = get_value('ident')
|
||||
self.alternateNicks = conf.supybot.nick.alternates()[:]
|
||||
self.password = conf.supybot.networks.get(self.network).password()
|
||||
self.sasl_username = \
|
||||
conf.supybot.networks.get(self.network).sasl.username()
|
||||
self.sasl_password = \
|
||||
conf.supybot.networks.get(self.network).sasl.password()
|
||||
self.sasl_ecdsa_key = \
|
||||
conf.supybot.networks.get(self.network).sasl.ecdsa_key()
|
||||
self.authenticate_decoder = None
|
||||
self.prefix = '%s!%s@%s' % (self.nick, self.ident, 'unset.domain')
|
||||
# The rest.
|
||||
self.lastTake = 0
|
||||
@ -981,8 +974,14 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
|
||||
self.startedAt = time.time()
|
||||
self.lastping = time.time()
|
||||
self.outstandingPing = False
|
||||
self.resetSasl()
|
||||
|
||||
def resetSasl(self):
|
||||
network_config = conf.supybot.networks.get(self.network)
|
||||
self.sasl_username = network_config.sasl.username()
|
||||
self.sasl_password = network_config.sasl.password()
|
||||
self.sasl_ecdsa_key = network_config.sasl.ecdsa_key()
|
||||
self.authenticate_decoder = None
|
||||
self.sasl_next_mechanisms = []
|
||||
self.sasl_current_mechanism = None
|
||||
|
||||
@ -1049,6 +1048,11 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
|
||||
self.sasl_current_mechanism = None
|
||||
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('END',)))
|
||||
|
||||
def filterSaslMechanisms(self, available):
|
||||
self.sasl_next_mechanisms = [
|
||||
x for x in self.sasl_next_mechanisms
|
||||
if x in available]
|
||||
|
||||
def doAuthenticate(self, msg):
|
||||
if not self.authenticate_decoder:
|
||||
self.authenticate_decoder = ircutils.AuthenticateDecoder()
|
||||
@ -1107,7 +1111,7 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
|
||||
def do908(self, msg):
|
||||
log.info('%s: Supported SASL mechanisms: %s',
|
||||
self.network, msg.args[1])
|
||||
# TODO: filter self.sasl_next_mechanisms
|
||||
self.filterSaslMechanisms(set(msg.args[1].split(',')))
|
||||
|
||||
def doCap(self, msg):
|
||||
subcommand = msg.args[1]
|
||||
@ -1153,7 +1157,6 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
|
||||
else:
|
||||
self.state.capabilities_ls[item] = None
|
||||
def doCapLs(self, msg):
|
||||
# TODO: filter self.sasl_next_mechanisms
|
||||
if len(msg.args) == 4:
|
||||
# Multi-line LS
|
||||
if msg.args[2] != '*':
|
||||
@ -1164,6 +1167,10 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
|
||||
self._addCapabilities(msg.args[2])
|
||||
common_supported_capabilities = set(self.state.capabilities_ls) & \
|
||||
self.REQUEST_CAPABILITIES
|
||||
if 'sasl' in self.state.capabilities_ls:
|
||||
s = self.state.capabilities_ls['sasl']
|
||||
if s is not None:
|
||||
self.filterSaslMechanisms(set(s.split(',')))
|
||||
# NOTE: Capabilities are requested in alphabetic order, because
|
||||
# sets are unordered, and their "order" is nondeterministic.
|
||||
# This is needed for the tests.
|
||||
|
@ -531,7 +531,7 @@ class SaslTestCase(SupyTestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def startCapNegociation(self):
|
||||
def startCapNegociation(self, sasl_attributes=None):
|
||||
m = self.irc.takeMsg()
|
||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||
self.failUnless(m.args == ('LS', '302'), 'Expected CAP LS 302, got %r.' % m)
|
||||
@ -541,9 +541,13 @@ class SaslTestCase(SupyTestCase):
|
||||
|
||||
m = self.irc.takeMsg()
|
||||
self.failUnless(m.command == 'USER', 'Expected USER, got %r.' % m)
|
||||
# TODO
|
||||
self.irc.feedMsg(ircmsgs.IrcMsg(command='CAP',
|
||||
args=('*', 'LS', 'sasl')))
|
||||
|
||||
if sasl_attributes:
|
||||
self.irc.feedMsg(ircmsgs.IrcMsg(command='CAP',
|
||||
args=('*', 'LS', 'sasl=%s' % sasl_attributes)))
|
||||
else:
|
||||
self.irc.feedMsg(ircmsgs.IrcMsg(command='CAP',
|
||||
args=('*', 'LS', 'sasl')))
|
||||
|
||||
m = self.irc.takeMsg()
|
||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||
@ -624,6 +628,37 @@ class SaslTestCase(SupyTestCase):
|
||||
|
||||
self.endCapNegociation()
|
||||
|
||||
def testFilter(self):
|
||||
try:
|
||||
conf.supybot.networks.test.sasl.username.setValue('jilles')
|
||||
conf.supybot.networks.test.sasl.password.setValue('sesame')
|
||||
conf.supybot.networks.test.certfile.setValue('foo')
|
||||
self.irc = irclib.Irc('test')
|
||||
finally:
|
||||
conf.supybot.networks.test.sasl.username.setValue('')
|
||||
conf.supybot.networks.test.sasl.password.setValue('')
|
||||
conf.supybot.networks.test.certfile.setValue('')
|
||||
self.assertEqual(self.irc.sasl_current_mechanism, None)
|
||||
self.assertEqual(self.irc.sasl_next_mechanisms,
|
||||
['external', 'plain'])
|
||||
|
||||
self.startCapNegociation(sasl_attributes='foo,plain,bar')
|
||||
|
||||
m = self.irc.takeMsg()
|
||||
self.assertEqual(m, ircmsgs.IrcMsg(command='AUTHENTICATE',
|
||||
args=('PLAIN',)))
|
||||
|
||||
self.irc.feedMsg(ircmsgs.IrcMsg(command='AUTHENTICATE', args=('+',)))
|
||||
|
||||
m = self.irc.takeMsg()
|
||||
self.assertEqual(m, ircmsgs.IrcMsg(command='AUTHENTICATE',
|
||||
args=('amlsbGVzAGppbGxlcwBzZXNhbWU=',)))
|
||||
|
||||
self.irc.feedMsg(ircmsgs.IrcMsg(command='900', args=('jilles',)))
|
||||
self.irc.feedMsg(ircmsgs.IrcMsg(command='903', args=('jilles',)))
|
||||
|
||||
self.endCapNegociation()
|
||||
|
||||
|
||||
|
||||
class IrcCallbackTestCase(SupyTestCase):
|
||||
|
Loading…
Reference in New Issue
Block a user