if (word(2 $loadinfo()) != [pf]) { load -pf $word(1 $loadinfo()); return; }; package sasl_external; ## SASL EXTERNAL authentication script for EPIC5. ## Written by zlonix@efnet, public domain. ## ## Version: 1.0 (January, 2022) ## - Initial roll-out ## To use this script you will need to generate a certificate and add it to ## NickServ fingerprint list. Instructions for Libera.Chat can be obtained here: ## https://libera.chat/guides/certfp ## ## Add the following line to your ircII.servers file: ## irc.libera.chat:7000:nick=YOURNICK:type=IRC-SSL:cert= ## ## Note full path restrictment, you can't use tildes there. ## ## Then put the following in your .epicrc or .ircrc file: ## sasl_external *.libera.chat ## This will try EXTERNAL auth on all Libera.Chat servers load capctl; alias sasl_external (server) { if (@server) { if (findw($server $sasl_external.servers) == -1) { @ push(sasl_external.servers $server); }; }; }; alias sasl_external.setstate (server, state, void) { @ :enc = encode($server); if (state != [null]) { assign sasl_external.status.$enc $state; } else { assign -sasl_external.status.$enc; }; }; alias sasl_external.getstate (server, void) { @ :enc = encode($server); return $sasl_external.status[$enc]; }; on #-server_established 100 '\\\\[$$sasl_external.servers\\\\] %' { @ :server = servername(); @ :server_enc = encode($server); @ :state = sasl_external.getstate($server); @ ::sasl_in_progress[$server_enc] = 1; if (serverctl(GET $servernum() CERT) == []) { xecho -b sasl_external: no client certificate, disconnecting from the server $server; disconnect; }; if (state == []) { sasl_external.setstate $server req_sent; quote CAP REQ :sasl; } else { xecho -b sasl_external: server_established: server $server is in a wrong state [$state] (should be ); sasl_external.setstate $server null; }; }; on ^odd_server_stuff '\\\\[$$sasl_external.servers\\\\] CAP % ACK *sasl*' { @ :server = servername(); @ :state = sasl_external.getstate($server); if (state == [req_sent]) { sasl_external.setstate $server meth_sent; quote AUTHENTICATE EXTERNAL; } else { xecho -b sasl_external: odd_server_stuff: CAP ACK: server $server \(real: $0\) is in a wrong state [$state] (should be "req_sent"); sasl_external.setstate $server null; }; }; on ^odd_server_stuff '\* AUTHENTICATE \+' { @ :server = servername(); @ :state = sasl_external.getstate($server); if (state == [meth_sent]) { sasl_external.setstate $server auth_sent; quote AUTHENTICATE +; } else { xecho -b sasl_external: odd_server_stuff: AUTHENTICATE: server $server \(real: $0\) is in a wrong state [$state] (should be "meth_sent"); sasl_external.setstate $server null; }; }; on -903 '\\\\[$$sasl_external.servers\\\\] *' { @ :server = servername(); @ :state = sasl_external.getstate($server); if (state == [auth_sent]) { sasl_external.setstate $server null; # quote CAP END; } else { xecho -b sasl_external: 903: server $server \(real: $0\) is in a wrong state [$state] (should be "auth_sent"); sasl_external.setstate $server null; }; };