Automatically Joining Password-Enabled Channels in ERC

If, like me, you are using ERC to chat with your IRC friends all over the world, then the next few paragraphs describe how you can set up automatically joining channels in a secure manner, even if the channels require a key.

Being able to auto-join channels after connecting to an IRC server is a must have for any serious IRC client. This way the user doesn’t have to laboriously type /join commands again and again, every time the IRC client start, or when there’s a network problem and the IRC server temporarily disconnects. Typing long lists of channel names gets old really fast if one has to type stuff like this for example:

/join #public
/join #secret somekeyword
/join #interest
/join #hobby hobbykey

Most serious IRC clients have some form of ‘autojoin’ feature, that lets you configure the channels they should join when connected to a specific IRC network or to a specific IRC server. ERC supports auto-joining with a loadable module called erc-join. You can load this module in your ERC startup code, and then use erc-autojoin-channels-alist to specify which channels to join on a per-server basis.

Loading the erc-join module and enabling auto-join support is the easy bit:

(require 'erc-join)             ; autojoin support is implemented by erc-join.el
(erc-autojoin-enable)           ; enable channel autojoin support, by default

Setting up the list of channels in erc-autojoin-channel-alist is also easy, but it does lend itself to a bit of upfront explanation. When auto-join code looks at erc-autojoin-channel-alist it expects to find there a list of ‘server patterns’ and their associated channels. So its value should look like this:

((SERVER-PATTERN-1 . CHANNEL-1 CHANNEL-2 ...)
 (SERVER-PATTERN-2 . CHANNEL-3 CHANNEL-4 CHANNEL-5 ...))

When a connection to a new IRC server is established, erc-join has set things up so that erc-autojoin-channels is called. The erc-autojoin-channels function iterates through erc-autojoin-channels-alist and checks if the server pattern matches the current server-name. If it does, it calls erc-server-join-channel for each of the channels attached to this server pattern.

The server pattern can be a regular expression and pattern matching for the ‘server’ part of each erc-autojoin-channels-alist item does not stop when it finds a match. This means that you can mix and match server patterns in all sorts of amusing ways, e.g. to set up a channel that is automatically joined for all IRC networks, by having an erc-autojoin-channels-alist entry whose server pattern is ".*":

(setq erc-autojoin-channels-alist
      '((".*" . "#everywhere")))

Now, for the interesting part. What happens when you want to automatically join channels that require a key. That’s where the real magic behind erc-server-join-channel kicks in, and lets you store your passwords in a secure place, like e.g. a PGP-encrypted ~/.authinfo file in your home directory!

Every time erc-server-join-channel is called it tries to look up a matching entry for the current IRC server and channel names in what Emacs calls “authentication sources”. These are, basically, files in ‘netrc’ file format (traditionally used by FTP clients). If a matching entry is found for the current combination of server and channel in one of the configured netrc files, the password key of this netrc file entry is used as the key for joining the IRC channel. The service name used for netrc entry lookup is also conveniently set to “irc”, so that ERC will not pick up unrelated passwords from your netrc files.

A valid netrc file entry, one which ERC can use to locate the key for an IRC channel, looks like this:

machine irc.freenode.net login "#mychannel" password "supersecret" port irc

If this line is present in your ~/.authinfo or ~/.netrc file, and one of the erc-autojoin-channels-alist entries specifies that “#mychannel” should be automatically joined when connected to the IRC server “irc.freenode.net”, then ERC will use “supersecret” as the key for joining the channel. This is a much safer alternative than typing the channel passwords yourself at an ERC prompt (because the channel passwords may then be logged on disk, if you have enabled server-buffer logging), and it’s definitely safer than listing the password in your ~/.emacs startup code or other place that can be world-readable.

Putting it All Together

To summarize, configuring ERC to automatically join channels “#public” and “#secret” when connecting to IRC server “irc.example.net”, and to use the secret key “supersecret” for the “#secret” channel, you can put the following in your ERC startup code:

(require 'erc-join)
(erc-autojoin-enable)

(setq erc-autojoin-channels-alist
      '(("irc.example.net" . "#public" "#secret"))))

and the following in your ~/.authinfo or ~/.netrc file:

machine irc.example.net login "#secret" password "supersecret" port irc