Browse Source

Switch from CertFP to the more reliable and secure SASL EXTERNAL

master
JustAnotherArchivist 4 years ago
parent
commit
471290356d
2 changed files with 19 additions and 1 deletions
  1. +1
    -1
      config.example.toml
  2. +18
    -0
      http2irc.py

+ 1
- 1
config.example.toml View File

@@ -5,7 +5,7 @@
#ssl = 'yes'
#nick = 'h2ibot'
#real = 'I am an http2irc bot.'
# Certificate and key for CertFP authentication with NickServ; certfile is a string containing the path to a .pem file which has the certificate and the key, certkeyfile similarly for one containing only the key; default values are empty (None in Python) to disable CertFP authentication
# Certificate and key for SASL EXTERNAL authentication with NickServ; certfile is a string containing the path to a .pem file which has the certificate and the key, certkeyfile similarly for one containing only the key; default values are empty (None in Python) to disable authentication; the connection is terminated if authentication fails
#certfile =
#certkeyfile =



+ 18
- 0
http2irc.py View File

@@ -255,12 +255,16 @@ class IRCClientProtocol(asyncio.Protocol):
self.channels = channels # Currently joined/supposed-to-be-joined channels; set(str)
self.unconfirmedMessages = []
self.pongReceivedEvent = asyncio.Event()
self.sasl = bool(self.config['irc']['certfile'] and self.config['irc']['certkeyfile'])
self.authenticated = False

def connection_made(self, transport):
self.logger.info('IRC connected')
self.transport = transport
self.connected = True
nickb = self.config['irc']['nick'].encode('utf-8')
if self.sasl:
self.send(b'CAP REQ :sasl')
self.send(b'NICK ' + nickb)
self.send(b'USER ' + nickb + b' ' + nickb + b' ' + nickb + b' :' + self.config['irc']['real'].encode('utf-8'))

@@ -357,8 +361,22 @@ class IRCClientProtocol(asyncio.Protocol):
self.send(b'PONG ' + message[5:])
elif message.startswith(b'PONG '):
self.pongReceivedEvent.set()
elif message.startswith(b'CAP ') and self.sasl and message[message.find(b' ', 4) + 1:] == b'ACK :sasl':
self.send(b'AUTHENTICATE EXTERNAL')
elif message == b'AUTHENTICATE +':
self.send(b'AUTHENTICATE +')
elif message.startswith(b'903 '): # SASL auth successful
self.authenticated = True
self.send(b'CAP END')
elif any(message.startswith(x) for x in (b'902 ', b'904 ', b'905 ', b'906 ', b'908 ')):
self.logger.error('SASL error, terminating connection')
self.transport.close()
elif message.startswith(b'001 '):
self.logger.info('IRC connection registered')
if self.sasl and not self.authenticated:
self.logger.error('IRC connection registered but not authenticated, terminating connection')
self.transport.close()
return
self.send(b'JOIN ' + ','.join(self.channels).encode('utf-8')) #TODO: Split if too long
asyncio.create_task(self.send_messages())
asyncio.create_task(self.confirm_messages())


Loading…
Cancel
Save