Connect IRC bot to Libera with SASL

Libera now requires SASL authentication for dedicated servers network ranges, for example IP ranges for Scaleway.

You can check quickly this behavior with nc irc.ipv4.libera.chat 6667 (IPv6 ranges seem less an issue than IPv4 ranges) or with openssl s_client -connect sodium.libera.chat:6697 command:
:mercury.libera.chat NOTICE Odderon :*** Notice -- SASL authentication to a NickServ account with a verified email address is required to connect from your current network. Please see https://libera.chat/guides/sasl for configuration assistance.

To connect to SASL can be done through a specialized library like Cyrus SASL, or just by sending some extra lines.

The simplest is to use SASL in plain mode, which requires to concatenate the identity you wish to login as, your login, and password, with NUL character as separator. For Libera it means someuser\0someuser\0somepass to send as Base64 string, for this example c29tZXVzZXIAc29tZXVzZXIAc29tZXBhc3MAAA==.

This method is safe to use if you connect through TLS, and can verify certificate. To connect to a plaintext server, a SCRAM-SHA-256 is probably relevant.

From there, SASL authentication workflow expected by the IRC server is:

  1. Require SASL capability
  2. Announce the authentication mechanism, e.g. PLAIN
  3. Send the authentication Base64 string

To send the messages to the server, you can send the following 4 instructions lines:

Those lines need to be sent before NICK, USER, PASS. Older IRC bot clients don’t always give you an opportunity for that and source code need to be modified. Others like eggdrops have been patched.

The server will output different RAW messages during your authentication, for example Libera server sends 900 to tell you you’re logged in to nickserv and 903 to confirm SASL authentication is successful. Those can be read to handle authentication errors.

To generate the authentication Base64 string is tricky in C: as it uses \0 as separator inside your string, you can’t use the functions offered in <string.h>, as they expect \0 to be the string termination. So don’t use sprintf or snprintf. You can manipulate bytes directly through memcpy, that’s fine here ; a working example can be found here.

This work allows us to run darkbot on Libera, and has been committed this Monday evening.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.