]> git.gir.st - ircpipe.git/summary
 
descriptionnetcat® for IRC™
last changeThu, 30 May 2024 07:26:46 +0000 (09:26 +0200)
readme

ircpipe - netcat for IRC

Sets up an irc connection, and takes care of PINGs and PONGs.

Usage

ircpipe [-pP] [-sSk] [-n NICK] [-j CHAN] HOST [PORT]

Theory of Operation

ircpipe aims to abstract away the annoying parts of connecting to IRC with netcat. It handles authentication (including initial channel joins) and sends out and responds to pings to avoid the connection from timing out. During setup, received IRC messages are partially parsed and checked for common error numerics to check for failures. Until this point, data on stdin is not read and kept buffered by the operating system to avoid sending commands before the connectino is ready. Afterwards, ircpipe only listens to pings (to which it automatically responds) and fatal ERROR messages (on which ircpipe exits). When exiting due to an IRC protocol level error, ircpipe prints the full line of the responsible response to stderr and exits with code 1.

ircpipe reads from stdin and writes to stdout and does not modify in- or output. The user is expected to pass (or parse) raw IRC messages, as per RFC 1459 or 2812. While ircpipe is meant to be used in shell pipelines to implement half-duplex bots, it can easily be used as a quick and dirty interactive IRC client as well (especially using the highlight script in contrib). By setting up a fifo (named pipe) and redirecting one of the streams though it and piping the other, both to the same program, it is possible to implement bidirectional bots as well.

While only the last -j flag is processed, it is still possible to supply multiple channels by seperating them with a comma (no space). To join a password protected channel, append a space and a comma seperated list of passwords for each channel. This behaviour emerges from how IRC specifies the argument of the JOIN message (same syntax) to which we forward CHAN unmodified.

For TLS, the only sane option, OpenBSD's libTLS or libreTLS (the reimplemen- tation on top of OpenSSL for other operating systems) was chosen. It removes all the complexity of using TLS and therefore prevents accidental misuse.

No nickserv (or chanserv or similar) support is implemented or planned. Modern IRC networks should support authenticating with SASL (as specified by IRCv3); for bouncers, IRC server passwords work well. Patches for SASL certificate authentication may be accepted, assuming they don't add an unproportional amount of code and complexity. Similarly, no fallback nicks can be configured and when the chosen nick is already in use, ircpipe exits with an error. Patches to improve this situation might get accepted (once again barring too much added complexity).

Examples

Connect to an IRC bouncer and highlight incoming messages. Timestamps are provided by ts, part of the moreutils suite. This is a surprisingly usable interactive IRC client. Posting to a channel (or messaging a user) is possible by sending the raw command, e.g. privmsg #myChan :hello, world! (most ircd implementations are matching commands case-insensitively).

IRC_PASSWD=myNick/myNet:myPass ircpipe -n myNick -p -s bouncer.example.org | ./contrib/highlight | ts

Forward some error logs to a special IRC channel. This is the original use case ircpipe was built for. It's easy to trigger anti-flood protections when using this, so only critical stuff should end up here. A client on your phone can then audibly alert you to important events (e.g by mentioning your nick in a prefix).

tail -f /var/log/myProgram | grep -i error | sed 's/^/PRIVMSG #myChan :/' | ircpipe -n myNick -j '#myChan' -s irc.example.com

Keep a very rudimentary log of conversations from multiple channels. Since you are not supposed to create too many connections to a network, this example exploits how the server interprets JOIN messages with multiple channels.

ircpipe -n myNick -j '#myChan1,#myChan2' -s irc.example.com >> /var/log/irc

Caveats

The spec caps line length at 512 bytes; longer messages may or may not make it through the network unscathed. Since ircpipe doesn't understand PRIVMSG (the most likely message to go over that limit) it can't split messages up for you. Either make sure to only send relatively short payloads, or use an input filter to split them up into multiple privmsgs. Be sure to keep flooding limits in mind to avoid getting kicked when doing so.

IRC specifies that lines must be terminated by CR LF, but most if not all servers accept UNIX style (plain LF) line endings, too. ircpipe also relays lines from the IRC server unmodified, so it is likely that responses are CR LF terminated. If either of this is a problem, a simple pair of input and output filters, e.g. unix2dos(1) and dos2unix(1), can be placed around ircpipe.

Note that there is one known vulnerability: we don't guard against escape sequences in responses. when used interactively, a bad actor could send malicious sequences causing terminal corruption. causing data leaks (by querying terminal information) is unlikely, as the responses won't be proper irc PRIVMSGs. An output filter (like the included highlight) is recommended to strip them out.

Building

Make sure libreTLS (or libTLS when on OpenBSD) library and development headers are installed, then simply run make. Sensible CFLAGS are provided by default, unless given from either the environment or as an argument to make(1). The resulting executable, ircpipe, can then simply be copied to $PATH e.g. with install(1).

Licensing

This software is made available at https://git.gir.st/ircpipe.git under the terms of the GNU General Public License Version 3.

shortlog
2024-05-30 Tobias Girstmairhighlight: keep C1 controls intact master
2024-05-29 Tobias Girstmairadd license (gplv3)
2024-05-29 Tobias Girstmairtune connect and setup timeouts
2024-05-29 Tobias Girstmairadd examples, split out caveats, and other readme impro...
2024-05-29 Tobias Girstmairimplement 'display version' command line switch
2024-05-29 Tobias Girstmairmake highlight strip control characters
2024-05-29 Tobias GirstmairProvide the beginnings of some proper documentation
2024-05-29 Tobias Girstmairclean up makefile
2024-05-29 Tobias GirstmairRevert "allow building without libtls"
2024-05-29 Tobias Girstmairallow building without libtls
2024-05-29 Tobias Girstmairimplement setup timeout
2024-05-29 Tobias GirstmairRevert "send all initialization commands at once"
2024-05-26 Tobias Girstmairsend all initialization commands at once
2024-05-26 Tobias Girstmairmove todos from spec file to todon'ts
2024-05-25 Tobias Girstmairclean up some todos
2024-05-25 Tobias Girstmairparams cannot be empty
...
heads
2 weeks ago master
Imprint / Impressum