Skip to content

Commit

Permalink
Add command to manually initiate SASL
Browse files Browse the repository at this point in the history
  • Loading branch information
glguy authored and progval committed Sep 5, 2023
1 parent c66b973 commit 9e82e3f
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 20 deletions.
11 changes: 11 additions & 0 deletions plugins/Network/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,17 @@ def capabilities(self, irc, msg, args, otherIrc):
irc.reply(format("%L", sorted(otherIrc.state.capabilities_ls)))
capabilities = wrap(capabilities, ['networkIrc'])

def authenticate(self, irc, msg, args):
"""takes no arguments
Manually initiate SASL authentication.
"""
if 'sasl' in irc.state.capabilities_ack:
irc.startSasl(msg)
irc.replySuccess()
else:
irc.error(_('SASL not supported'))
authenticate = wrap(authenticate)

Class = Network

Expand Down
39 changes: 19 additions & 20 deletions src/irclib.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,14 +559,14 @@ def on_init_messages_sent(self, irc):
self.States.UNINITIALIZED,
])

def on_sasl_cap(self, irc, msg):
'''Whenever we see the 'sasl' capability in a CAP LS response'''
def on_sasl_start(self, irc, msg):
'''Whenever we initiate a SASL transaction.'''
if self.state == self.States.INIT_CAP_NEGOTIATION:
self._transition(irc, msg, self.States.INIT_SASL)
elif self.state == self.States.CONNECTED:
self._transition(irc, msg, self.States.CONNECTED_SASL)
else:
raise ValueError('Got sasl cap while in state %s' % self.state)
raise ValueError('Started SASL while in state %s' % self.state)

def on_sasl_auth_finished(self, irc, msg):
'''When sasl auth either succeeded or failed.'''
Expand Down Expand Up @@ -1729,7 +1729,6 @@ def resetSasl(self):
self.authenticate_decoder = None
self.sasl_next_mechanisms = []
self.sasl_current_mechanism = None

for mechanism in network_config.sasl.mechanisms():
if mechanism == 'ecdsa-nist256p-challenge':
if not crypto:
Expand Down Expand Up @@ -1767,17 +1766,13 @@ def resetSasl(self):
else:
self.sasl_next_mechanisms.append(mechanism)

if self.sasl_next_mechanisms:
self.REQUEST_CAPABILITIES.add('sasl')


# Note: echo-message is only requested if labeled-response is available.
REQUEST_CAPABILITIES = set(['account-notify', 'extended-join',
'multi-prefix', 'metadata-notify', 'account-tag',
'userhost-in-names', 'invite-notify', 'server-time',
'chghost', 'batch', 'away-notify', 'message-tags',
'msgid', 'setname', 'labeled-response', 'echo-message',
'standard-replies'])
'sasl', 'standard-replies'])
"""IRCv3 capabilities requested when they are available.
echo-message is special-cased to be requested only with labeled-response.
Expand Down Expand Up @@ -1901,17 +1896,21 @@ def tryNextSaslMechanism(self, msg):
def _maybeStartSasl(self, msg):
if not self.sasl_authenticated and \
'sasl' in self.state.capabilities_ack:
self.state.fsm.on_sasl_cap(self, msg)
assert 'sasl' in self.state.capabilities_ls, (
'Got "CAP ACK sasl" without receiving "CAP LS sasl" or '
'"CAP NEW sasl" first.')
s = self.state.capabilities_ls['sasl']
if s is not None:
available = set(map(str.lower, s.split(',')))
self.sasl_next_mechanisms = [
x for x in self.sasl_next_mechanisms
if x.lower() in available]
self.tryNextSaslMechanism(msg)
self.startSasl(msg)

def startSasl(self, msg):
self.state.fsm.on_sasl_start(self, msg)
assert 'sasl' in self.state.capabilities_ls, (
'Starting SASL without receiving "CAP LS sasl" or '
'"CAP NEW sasl" first.')
self.resetSasl()
s = self.state.capabilities_ls['sasl']
if s is not None:
available = set(map(str.lower, s.split(',')))
self.sasl_next_mechanisms = [
x for x in self.sasl_next_mechanisms
if x.lower() in available]
self.tryNextSaslMechanism(msg)

def doAuthenticate(self, msg):
self.state.fsm.expect_state([
Expand Down

0 comments on commit 9e82e3f

Please sign in to comment.