Identify with SASL

Identify through SASL using the convenient ib3 mixins, and
get rid of a bunch of special-case code in the process.

This helps when dealing with channels set to require identified
users, as otherwise channel joins will race NickServ's processing of
the identify message and some channels will end up not serviced by
the bot (an alternative would be to delay joining channels until the
identify success is confirmed, but the implementation for that looks
like it would be at least as complex).

Note this also effectively drops non-SSL IRC support. Given
passwords are sent over this connection, I don't see it as a loss.

Change-Id: I0aa15d81f0158fcf2b74825cdb3968d62356fa1d
Co-Authored-By: Thierry Carrez <thierry@openstack.org>
This commit is contained in:
Jeremy Stanley 2018-08-31 18:13:42 +00:00
parent 7b3a04a575
commit bfe0a11ad7
2 changed files with 10 additions and 40 deletions

View File

@ -5,3 +5,4 @@ irc
python-daemon python-daemon
kitchen kitchen
python-twitter>=3.4 python-twitter>=3.4
ib3

View File

@ -48,6 +48,8 @@ access_token_secret=access_token_secret
import argparse import argparse
import ConfigParser import ConfigParser
import daemon import daemon
from ib3.auth import SASL
from ib3.connection import SSL
import irc.bot import irc.bot
import json import json
import logging.config import logging.config
@ -57,7 +59,6 @@ import time
import simplemediawiki import simplemediawiki
import datetime import datetime
import re import re
import ssl
import twitter import twitter
import urllib import urllib
@ -312,21 +313,16 @@ class AlertFile(UpdateInterface):
self.write(None) self.write(None)
class StatusBot(irc.bot.SingleServerIRCBot): class StatusBot(SASL, SSL, irc.bot.SingleServerIRCBot):
log = logging.getLogger("statusbot.bot") log = logging.getLogger("statusbot.bot")
def __init__(self, channels, nicks, publishers, successlog, thankslog, def __init__(self, channels, nicks, publishers, successlog, thankslog,
nickname, password, server, port=6667): nickname, password, server, port=6697):
if port == 6697: super(StatusBot, self).__init__(
factory = irc.connection.Factory(wrapper=ssl.wrap_socket) server_list=[(server, port)],
irc.bot.SingleServerIRCBot.__init__(self, nickname=nickname,
[(server, port)], realname=nickname,
nickname, nickname, ident_password=password)
connect_factory=factory)
else:
irc.bot.SingleServerIRCBot.__init__(self,
[(server, port)],
nickname, nickname)
self.channel_list = channels self.channel_list = channels
self.nicks = nicks self.nicks = nicks
self.nickname = nickname self.nickname = nickname
@ -338,33 +334,6 @@ class StatusBot(irc.bot.SingleServerIRCBot):
self.successlog = successlog self.successlog = successlog
self.thankslog = thankslog self.thankslog = thankslog
def on_nicknameinuse(self, c, e):
self.log.debug("Nickname in use, releasing")
c.nick(c.get_nickname() + "_")
c.privmsg("nickserv", "identify %s " % self.password)
c.privmsg("nickserv", "ghost %s %s" % (self.nickname, self.password))
c.privmsg("nickserv", "release %s %s" % (self.nickname, self.password))
time.sleep(ANTI_FLOOD_SLEEP)
c.nick(self.nickname)
def on_welcome(self, c, e):
self.identify_msg_cap = False
self.log.debug("Requesting identify-msg capability")
c.cap('REQ', 'identify-msg')
c.cap('END')
self.log.debug("Identifying to nickserv")
c.privmsg("nickserv", "identify %s " % self.password)
for channel in self.channel_list:
self.log.info("Joining %s" % channel)
c.join(channel)
time.sleep(ANTI_FLOOD_SLEEP)
def on_cap(self, c, e):
self.log.debug("Received cap response %s" % repr(e.arguments))
if e.arguments[0] == 'ACK' and 'identify-msg' in e.arguments[1]:
self.log.debug("identify-msg cap acked")
self.identify_msg_cap = True
def on_pubmsg(self, c, e): def on_pubmsg(self, c, e):
if not self.identify_msg_cap: if not self.identify_msg_cap:
self.log.debug("Ignoring message because identify-msg " self.log.debug("Ignoring message because identify-msg "