mirror of
https://github.com/progval/Limnoria.git
synced 2025-04-26 04:51:06 -05: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.ident = get_value('ident')
|
||||||
self.alternateNicks = conf.supybot.nick.alternates()[:]
|
self.alternateNicks = conf.supybot.nick.alternates()[:]
|
||||||
self.password = conf.supybot.networks.get(self.network).password()
|
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')
|
self.prefix = '%s!%s@%s' % (self.nick, self.ident, 'unset.domain')
|
||||||
# The rest.
|
# The rest.
|
||||||
self.lastTake = 0
|
self.lastTake = 0
|
||||||
@ -981,8 +974,14 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
|
|||||||
self.startedAt = time.time()
|
self.startedAt = time.time()
|
||||||
self.lastping = time.time()
|
self.lastping = time.time()
|
||||||
self.outstandingPing = False
|
self.outstandingPing = False
|
||||||
|
self.resetSasl()
|
||||||
|
|
||||||
|
def resetSasl(self):
|
||||||
network_config = conf.supybot.networks.get(self.network)
|
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_next_mechanisms = []
|
||||||
self.sasl_current_mechanism = None
|
self.sasl_current_mechanism = None
|
||||||
|
|
||||||
@ -1049,6 +1048,11 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
|
|||||||
self.sasl_current_mechanism = None
|
self.sasl_current_mechanism = None
|
||||||
self.sendMsg(ircmsgs.IrcMsg(command='CAP', args=('END',)))
|
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):
|
def doAuthenticate(self, msg):
|
||||||
if not self.authenticate_decoder:
|
if not self.authenticate_decoder:
|
||||||
self.authenticate_decoder = ircutils.AuthenticateDecoder()
|
self.authenticate_decoder = ircutils.AuthenticateDecoder()
|
||||||
@ -1107,7 +1111,7 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
|
|||||||
def do908(self, msg):
|
def do908(self, msg):
|
||||||
log.info('%s: Supported SASL mechanisms: %s',
|
log.info('%s: Supported SASL mechanisms: %s',
|
||||||
self.network, msg.args[1])
|
self.network, msg.args[1])
|
||||||
# TODO: filter self.sasl_next_mechanisms
|
self.filterSaslMechanisms(set(msg.args[1].split(',')))
|
||||||
|
|
||||||
def doCap(self, msg):
|
def doCap(self, msg):
|
||||||
subcommand = msg.args[1]
|
subcommand = msg.args[1]
|
||||||
@ -1153,7 +1157,6 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
|
|||||||
else:
|
else:
|
||||||
self.state.capabilities_ls[item] = None
|
self.state.capabilities_ls[item] = None
|
||||||
def doCapLs(self, msg):
|
def doCapLs(self, msg):
|
||||||
# TODO: filter self.sasl_next_mechanisms
|
|
||||||
if len(msg.args) == 4:
|
if len(msg.args) == 4:
|
||||||
# Multi-line LS
|
# Multi-line LS
|
||||||
if msg.args[2] != '*':
|
if msg.args[2] != '*':
|
||||||
@ -1164,6 +1167,10 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
|
|||||||
self._addCapabilities(msg.args[2])
|
self._addCapabilities(msg.args[2])
|
||||||
common_supported_capabilities = set(self.state.capabilities_ls) & \
|
common_supported_capabilities = set(self.state.capabilities_ls) & \
|
||||||
self.REQUEST_CAPABILITIES
|
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
|
# NOTE: Capabilities are requested in alphabetic order, because
|
||||||
# sets are unordered, and their "order" is nondeterministic.
|
# sets are unordered, and their "order" is nondeterministic.
|
||||||
# This is needed for the tests.
|
# This is needed for the tests.
|
||||||
|
@ -531,7 +531,7 @@ class SaslTestCase(SupyTestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def startCapNegociation(self):
|
def startCapNegociation(self, sasl_attributes=None):
|
||||||
m = self.irc.takeMsg()
|
m = self.irc.takeMsg()
|
||||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||||
self.failUnless(m.args == ('LS', '302'), 'Expected CAP LS 302, 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()
|
m = self.irc.takeMsg()
|
||||||
self.failUnless(m.command == 'USER', 'Expected USER, got %r.' % m)
|
self.failUnless(m.command == 'USER', 'Expected USER, got %r.' % m)
|
||||||
# TODO
|
|
||||||
self.irc.feedMsg(ircmsgs.IrcMsg(command='CAP',
|
if sasl_attributes:
|
||||||
args=('*', 'LS', 'sasl')))
|
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()
|
m = self.irc.takeMsg()
|
||||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||||
@ -624,6 +628,37 @@ class SaslTestCase(SupyTestCase):
|
|||||||
|
|
||||||
self.endCapNegociation()
|
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):
|
class IrcCallbackTestCase(SupyTestCase):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user