# ircpipe sets up an irc connection, and not much more. ## on connection - [x] connect - [x] tls (optional cert validation) - [?] sasl plain (untested) - [x] set user and nick - [x] wait for motd/001-message - [x] optionally, do an initial join ## in the background - respond to server pings - keep track of when we last received an irc mesasge; if t > $timeout, send ping ourselves. (first implementation can just send a ping every $timeout (milli)seconds) (should $timeout be the time between last message and send-ping or between last message and ping-reponse?) - different timeouts: - ping interval - connect timeout - time between sent message and received response - send/recv block: invalid, due to polling ## interfaces - read from stdin, write to stdout - cli for setting timeout, user/nick, server info, ... - netcat-like (everything but host[{: }port] optional - how to specify tls? - how to specify auth? - relatively secure password handling! ## vulnerabilities - 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. ## minor TODOs - check if port is valid - irc_poll: handle poll() EINTR (don't exit on nonfatal signal received) ## future todos: - flood protection! ## dropped features (patches accepted) - nickserv: freenode and hackint support sasl, efenet neither. rest don't care. - sasl cert: don't care for it - optionally use socket instead of stdin/stdout? - checking responses to NICK, JOIN, CAP-REQ, AUTHENTICATE for now, we're just assuming everything went ok. - NICK/USER ok: 001 (checked, to block further commands) err: 432 433 436 437 - JOIN ok: JOIN err: 471 473 474 475 403 405 437 - CAP REQ/CAP END ok: CAP ACK err: CAP NAK err: 421 - AUTHENTICATE ok: 900 903 err: 902 904 905 908 - maybe allow HOST:PORT (nc doesn't) - maybe allow HOST +PORT and/or HOST:+PORT for tls - maybe allow irc://HOST:PORT and ircs://HOST:PORT - what to do when nick is taken - use random nick - use fallback nick (append '_') - allow specifying alternate nicks - exit (this is what we do now on receiving the numeric error response) ## discarded ideas all of these would require modifying the streaming data, which is more trouble than it's worth. these could be implemented as external filters, though. - -C flag to translate CRLF to LF (from server) and LF to CRLF (from stdin) - -A flag to strip ctrlchars (formatting, colors, etc) from stdout - enforce max line length (512 bytes, including CRLF) by splitting PRIVMSG ## for responses we need to check and handle multiple responses to commands we've send: - ping: pong (everytime, everywhere. keep current hack) - sasl: cap-ack, 900+903 or 90x (when authenticating, during setup) - (after connecting/authenticating): 001, nick-in-use (everytime, during setup) the server may send unrelated responses in-between - including pings - and we want to enforce a timeout in which we expect the response (2000ms). essentially, we send a command, then block until we receive a response or an error. commands we send that we need to wait for are: - PING ok: PONG :