Add SASL support to core.

This commit is contained in:
nyuszika7h 2011-09-13 11:07:52 +02:00
parent f273687c5e
commit dcaefbdcf5
2 changed files with 36 additions and 1 deletions

View File

@ -258,7 +258,7 @@ class SpaceSeparatedSetOfChannels(registry.SpaceSeparatedListOf):
else: else:
return ircmsgs.join(channel) return ircmsgs.join(channel)
def registerNetwork(name, password='', ssl=False): def registerNetwork(name, username='', password='', ssl=False):
network = registerGroup(supybot.networks, name) network = registerGroup(supybot.networks, name)
registerGlobalValue(network, 'password', registry.String(password, registerGlobalValue(network, 'password', registry.String(password,
_("""Determines what password will be used on %s. Yes, we know that _("""Determines what password will be used on %s. Yes, we know that
@ -277,6 +277,15 @@ def registerNetwork(name, password='', ssl=False):
registerChannelValue(network.channels, 'key', registry.String('', registerChannelValue(network.channels, 'key', registry.String('',
_("""Determines what key (if any) will be used to join the _("""Determines what key (if any) will be used to join the
channel."""))) channel.""")))
sasl = registerGroup(network, 'sasl')
registerGlobalValue(sasl, 'username', registry.String(username,
_("""Determines what SASL username will be used on %s. This should
be the bot's account name. Due to the way SASL works, you can't use
any grouped nick.""") % name, private=False))
registerGlobalValue(sasl, 'password', registry.String(password,
_("""Determines what SASL password will be used on %s. Yes, we know
that technically passwords are server-specific and not network-specific,
but this is the best we can do right now.""") % name, private=True))
return network return network
# Let's fill our networks. # Let's fill our networks.

View File

@ -31,6 +31,7 @@ import re
import copy import copy
import time import time
import random import random
import base64
import supybot.log as log import supybot.log as log
import supybot.conf as conf import supybot.conf as conf
@ -862,6 +863,8 @@ class Irc(IrcCommandDispatcher):
self.ident = conf.supybot.ident() self.ident = conf.supybot.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.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
@ -875,6 +878,18 @@ class Irc(IrcCommandDispatcher):
self.driver.die() self.driver.die()
self._reallyDie() self._reallyDie()
else: else:
if self.sasl_password:
if not self.sasl_username:
log.error('SASL username is not set, unable to identify.')
else:
auth_string = base64.b64encode('%s\x00%s\x00%s' % (self.sasl_username,
self.sasl_username, self.sasl_password))
log.debug('Sending CAP REQ command, requesting capability \'sasl\'.')
self.queueMsg(ircmsgs.IrcMsg(command="CAP", args=('REQ', 'sasl')))
log.debug('Sending AUTHENTICATE command, using mechanism PLAIN.')
self.queueMsg(ircmsgs.IrcMsg(command="AUTHENTICATE", args=('PLAIN',)))
log.info('Sending AUTHENTICATE command, not logging the password.')
self.queueMsg(ircmsgs.IrcMsg(command="AUTHENTICATE", args=(auth_string,)))
if self.password: if self.password:
log.info('Sending PASS command, not logging the password.') log.info('Sending PASS command, not logging the password.')
self.queueMsg(ircmsgs.password(self.password)) self.queueMsg(ircmsgs.password(self.password))
@ -884,6 +899,17 @@ class Irc(IrcCommandDispatcher):
self.ident, self.user) self.ident, self.user)
self.queueMsg(ircmsgs.user(self.ident, self.user)) self.queueMsg(ircmsgs.user(self.ident, self.user))
def do903(self, msg):
log.info('SASL authentication successful')
log.debug('Sending CAP END command.')
self.queueMsg(ircmsgs.IrcMsg(command="CAP", args=('END',)))
def do904(self, msg):
log.warning('SASL authentication failed')
log.debug('Aborting authentication.')
log.debug('Sending CAP END command.')
self.queueMsg(ircmsgs.IrcMsg(command="CAP", args=('END',)))
def _getNextNick(self): def _getNextNick(self):
if self.alternateNicks: if self.alternateNicks:
nick = self.alternateNicks.pop(0) nick = self.alternateNicks.pop(0)