Merge pull request #810 from nyuszika7h/fix-cap

Fix capability negotiation
This commit is contained in:
Valentin Lorentz 2014-08-05 11:27:20 +02:00
commit 6e6ff5774b
2 changed files with 29 additions and 27 deletions

View File

@ -654,7 +654,6 @@ class Irc(IrcCommandDispatcher):
self._setNonResettingVariables() self._setNonResettingVariables()
self._queueConnectMessages() self._queueConnectMessages()
self.startedSync = ircutils.IrcDict() self.startedSync = ircutils.IrcDict()
self.caps = set(['account-notify', 'extended-join'])
def isChannel(self, s): def isChannel(self, s):
"""Helper function to check whether a given string is a channel on """Helper function to check whether a given string is a channel on
@ -939,7 +938,16 @@ class Irc(IrcCommandDispatcher):
return return
self.queueMsg(ircmsgs.IrcMsg(command='CAP', args=('LS',))) sasl = self.sasl_username and self.sasl_password
if sasl:
self.queueMsg(ircmsgs.IrcMsg(command='CAP', args=('REQ', 'sasl')))
self.queueMsg(ircmsgs.IrcMsg(command='CAP', args=('REQ', 'account-notify')))
self.queueMsg(ircmsgs.IrcMsg(command='CAP', args=('REQ', 'extended-join')))
if not sasl:
self.queueMsg(ircmsgs.IrcMsg(command='CAP', args=('END',)))
if self.password: if self.password:
log.info('%s: Queuing PASS command, not logging the password.', log.info('%s: Queuing PASS command, not logging the password.',
@ -958,7 +966,7 @@ class Irc(IrcCommandDispatcher):
self.queueMsg(ircmsgs.user(self.ident, self.user)) self.queueMsg(ircmsgs.user(self.ident, self.user))
def doAuthenticate(self, msg): def doAuthenticate(self, msg):
if msg.args[0] == '+': if len(msg.args) == 1 and msg.args[0] == '+':
log.info('%s: Authenticating using SASL.', self.network) log.info('%s: Authenticating using SASL.', self.network)
authstring = base64.b64encode('\0'.join([ authstring = base64.b64encode('\0'.join([
@ -970,30 +978,18 @@ class Irc(IrcCommandDispatcher):
self.queueMsg(ircmsgs.IrcMsg(command='AUTHENTICATE', args=(authstring,))) self.queueMsg(ircmsgs.IrcMsg(command='AUTHENTICATE', args=(authstring,)))
def doCap(self, msg): def doCap(self, msg):
if self.sasl_password: if len(msg.args) == 3:
if self.sasl_username: for cap in msg.args[2].split(' '):
self.caps.append('sasl') if msg.args[1] == 'ACK':
else: log.info('%s: Server acknowledged capability %r',
log.warning('%s: SASL username is not set, unable to ' self.network, cap)
'identify.', self.network)
for cap in msg.args[2].split(' '): if cap == 'sasl':
if msg.args[1] == 'LS' and cap in self.caps: self.queueMsg(ircmsgs.IrcMsg(command='AUTHENTICATE',
log.debug('%s: Requesting capability %r', self.network, cap) args=('PLAIN',)))
self.queueMsg(ircmsgs.IrcMsg(command='CAP', args=('REQ', cap))) elif msg.args[1] == 'NAK':
elif msg.args[1] == 'ACK': log.warning('%s: Server refused capability %r',
log.info('%s: Server acknowledged capability %r', self.network, cap)
self.network, cap)
if cap == 'sasl':
self.queueMsg(ircmsgs.IrcMsg(command='AUTHENTICATE',
args=('PLAIN',)))
elif msg.args[1] == 'NAK':
log.warning('%s: Server refused capability %r',
self.network, cap)
if cap == 'sasl':
self.queueMsg(ircmsgs.IrcMsg(command='CAP', args=('END',)))
def do903(self, msg): def do903(self, msg):
log.info('%s: SASL authentication successful', self.network) log.info('%s: SASL authentication successful', self.network)

View File

@ -385,6 +385,10 @@ class IrcTestCase(SupyTestCase):
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)
m = self.irc.takeMsg() m = self.irc.takeMsg()
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
m = self.irc.takeMsg()
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
m = self.irc.takeMsg()
self.failUnless(m.command == 'USER', 'Expected USER, got %r.' % m) self.failUnless(m.command == 'USER', 'Expected USER, got %r.' % m)
def testPingResponse(self): def testPingResponse(self):
@ -482,7 +486,9 @@ class IrcCallbackTestCase(SupyTestCase):
user = 'user any user' user = 'user any user'
conf.supybot.user.setValue(user) conf.supybot.user.setValue(user)
expected = [ircmsgs.nick(nick), expected = [ircmsgs.nick(nick),
ircmsgs.IrcMsg(command='CAP', args=('LS',)), ircmsgs.IrcMsg(command='CAP', args=('REQ', 'account-notify')),
ircmsgs.IrcMsg(command='CAP', args=('REQ', 'extended-join')),
ircmsgs.IrcMsg(command='CAP', args=('END',)),
ircmsgs.user('limnoria', user)] ircmsgs.user('limnoria', user)]
irc = irclib.Irc('test') irc = irclib.Irc('test')
msgs = [irc.takeMsg()] msgs = [irc.takeMsg()]