372,
(375, 376),
396,
+ 900,
+ 903,
+ 904
)
_NUMERICS_TO_IGNORE = (
(1, 4), # nothing in this login info we're interested in
connection_state: str
client_host: str
nickname: str
+ sasl_account: str
sasl_auth_state: str
user_modes: str
+ username: str = ''
class _ClientDb(_Db, SharedClientDbFields):
self.client_id = conn_setup.hostname
super().__init__(client_id=self.client_id, **kwargs)
self._db = _ClientDb(on_update=self._on_update)
+ self._db.username = getuser()
self._caps = _CapsManager(self.send, self._db.caps)
for k in conn_setup.__annotations__:
setattr(self._db, k, getattr(conn_setup, k))
assert self.conn is not None
self._db.connection_state = 'connected'
self._caps.start_negotation()
- self.send(IrcMessage(verb='USER',
- params=(getuser(), '0', '*', self._db.realname)))
+ self.send(IrcMessage(verb='USER', params=(self._db.username, '0', '*',
+ self._db.realname)))
self.send(IrcMessage(verb='NICK', params=(self._db.nick_wanted,)))
@abstractmethod
elif msg.match('433', 3): # ERR_NICKNAMEINUSE
self._log('nickname already in use, trying increment', alert=True)
self.set_nick(self._db.nick_incremented)
- elif msg.match('903', 2) or msg.match('904', 2): # RPL_SUCESS, or …
+ elif msg.match('900', 4): # RPL_LOGGEDIN
+ nick, remainder = msg.params[1].split('!', maxsplit=1)
+ assert nick == self._db.nickname
+ self._db.username, self._db.client_host = remainder.split('@')
+ self._db.sasl_account = msg.params[2]
+ elif msg.match('903', 2) or msg.match('904', 2): # RPL_SASLSUCCESS, …
self._db.sasl_auth_state = 'WIN' if msg.verb == '903' else 'FAIL'
- self._caps.end_negotiation() # … ERR_SASLFAIL
+ self._caps.end_negotiation() # … or ERR_SASLFAIL
elif msg.match('AUTHENTICATE') and msg.params[0] == '+':
- auth = b64encode((self._db.nickname + '\0'
- + self._db.nickname + '\0'
+ auth = b64encode((self._db.nick_wanted + '\0'
+ + self._db.nick_wanted + '\0'
+ self._db.password
).encode('utf-8')).decode('utf-8')
self.send(IrcMessage('AUTHENTICATE', (auth,)))