003. A proof-of-concept IRC/mail bridge

Sat, 11 Jul 2020 00:34:50 +0200

As seen on Twitter.

# What?

A video's worth a few interrobangs, so:

Herein we can see:

The play-by-play:

# Why‽

Intrusive thought when I noticed that messages from whitenotifier hit #solvespace slightly sooner than my e-mail notifications. The gin helped.

# How?

Apart from blatant disregard for common decency:

# The IRC

Start with a simple connection:

mkfifo input output
sic -h irc.freenode.net < input > output &

Now cat < output & to see what's up and cat >> input to open the connection, something like

verne.freenode.net: 07/10/20 16:05 >< 372 (nabijaczleweli): -
verne.freenode.net: 07/10/20 16:05 >< 372 (nabijaczleweli): - Thank you for using freenode!
verne.freenode.net: 07/10/20 16:05 >< 376 (nabijaczleweli): End of /MOTD command.
nabijaczleweli: 07/10/20 16:05 >< MODE (nabijaczleweli): +i

should appear, and typing ":m hasix owo" should produce a message in the web client and:

hasix       : 07/10/20 16:07 <nabijaczleweli> owo

a message that comes back should show up as well:

nabijaczleweli: 07/10/20 16:09 <hasix> :)

# The mbox

Great. Suspend the input cat (killing it will slam sic's pipe and kill it) and kill the output cat, replacing it with a (GNU) AWK process running this

# /(?<poster>[^:]+): (?<month>[[:digit:]]{2})\/(?<day>[[:digit:]]{2})\/(?<year>[[:digit:]]{2}) (?<hour>[[:digit:]]{2}):(?<monute>[[:digit:]]{2}) <(?<channel>[^>]+)> (?<message>.+)/ {
/([^:]+): [[:digit:]]{2}\/[[:digit:]]{2}\/[[:digit:]]{2} [[:digit:]]{2}:[[:digit:]]{2} <([^>]+)> (.+)/ {
  poster = gensub(/([^:]+): [[:digit:]]{2}\/[[:digit:]]{2}\/[[:digit:]]{2} [[:digit:]]{2}:[[:digit:]]{2} <([^>]+)> (.+)/, "\\1", "g")
  channel = gensub(/([^:]+): [[:digit:]]{2}\/[[:digit:]]{2}\/[[:digit:]]{2} [[:digit:]]{2}:[[:digit:]]{2} <([^>]+)> (.+)/, "\\2", "g")
  message = gensub(/([^:]+): [[:digit:]]{2}\/[[:digit:]]{2}\/[[:digit:]]{2} [[:digit:]]{2}:[[:digit:]]{2} <([^>]+)> (.+)/, "\\3", "g")
  print "From " poster " " strftime("%a %b %e %H:%M:%S %Y")
  print "From: " poster "@irc."
  print "Date: " strftime("%a, %d %b %Y %T %z")
  print "Subject: <" channel "> " message
  print ""
  fflush()
}

i.e.

gawk '<<that>>' output | tee -a mbox &

Now if a message arrives (from the web client) or is sent (":m hasix msg"), it should show up with

From nabijaczleweli Fri Jul 10 16:17:13 2020
From: nabijaczleweli@irc.
Date: Fri, 10 Jul 2020 16:17:13 +0200
Subject: <hasix> owo

both in the teletype and the mailbox. At this point pointing the MUA at it should work and the messages should show up:

neomutt window showing two messages, one from nabijaczleweli@irc. with subject '<hasix> owo'; second from hasix@irc. with subject '<nabijaczleweli> owo'

If they don't, see if the messages are flushed, or if the MUA handles this in general.

# The MX

Now it's time to convince postfix to do a big crime, by:

ircmail should be executable and something like this (note that the From: parsing is entirely superfluous, but might be useful for scaling this to multi-user):

#!/bin/gawk -f
/^From: ([^ ]+)( .+)?/ {
  print >> "/home/nabijaczleweli/uwu/ircmaillog"
  from = gensub(/^From: ([^ ]+)( .+)?/, "\\1", 1)
}
/^To: ([^@]+)(@.+)?/ {
  print >> "/home/nabijaczleweli/uwu/ircmaillog"
  to = gensub(/^To: ([^@]+)(@.+)?/, "\\1", 1)
}
/^Subject: / {
  print >> "/home/nabijaczleweli/uwu/ircmaillog"
  print ":m " to " " gensub(/^Subject: /, "", 1) >> "/home/nabijaczleweli/uwu/ircmaillog"
  print ":m " to " " gensub(/^Subject: /, "", 1) >> "/home/nabijaczleweli/uwu/input"
}

Now, sending a mail to "hasix@irc", "##test@irc", &c. should yield something like

Jul 10 14:43:11 tarta postfix/submission/smtpd[32260]: connect from unknown[192.168.1.250]
Jul 10 14:43:12 tarta postfix/submission/smtpd[32260]: E291B360636: client=unknown[192.168.1.250], sasl_method=PLAIN, sasl_username=nabijaczleweli
Jul 10 14:43:12 tarta postfix/cleanup[32270]: E291B360636: message-id=<20200710124311.m26cki7rgslw6deg@tarta.local.nabijaczleweli.xyz>
Jul 10 14:43:12 tarta postfix/qmgr[32125]: E291B360636: from=<nabijaczleweli@nabijaczleweli.xyz>, size=596, nrcpt=1 (queue active)
Jul 10 14:43:12 tarta postfix/submission/smtpd[32260]: disconnect from unknown[192.168.1.250] ehlo=2 starttls=1 auth=1 mail=1 rcpt=1 data=1 quit=1 commands=8
Jul 10 14:43:13 tarta postfix/pipe[32271]: E291B360636: to=<nabijaczleweli@irc>, orig_to=<nabijaczleweli@irc.>, relay=irc, delay=0.09, delays=0.07/0.01/0/0, dsn=2.0.0, status=sent (delivered via irc service)
Jul 10 14:43:13 tarta postfix/qmgr[32125]: E291B360636: removed

in the journal, and the corresponding commands in sic's input.

# Conclusion?

Despite this technically making an open IRC relay, since anyone can connect on port 25 with RCPT TO:<whomever@irc>, this is perfect and I wholeheartedly recommend it for when your workflow includes a MUA but not IRC!

I am, as ever, morbidly curious so as to scaling this to a multi-user/auto-join solution, but, well, even I have my limits. Okay, I don't, but I don't really have much of a reason to Be On™ IRC. Watch me eat my words in, like, a year, I guess?


Nit-pick? Correction? Improvement? Annoying? Cute? Anything? Don't hesitate to post or open an issue!


Creative text licensed under CC-BY-SA 4.0, code licensed under The MIT License.
This page is open-source, you can find it at GitHub, and contribute and/or yell at me there.
Like what you see? Consider giving me a follow over at social medias listed here, or maybe even a sending a buck or two patreon my way if my software helped you in some significant way?
Automatically generated with GCC 5‍.‍4‍.‍0's C preprocessor on 15.03.2021 23:02:07 UTC from src/blogn_t/003-maircl-poc.html.pp.
See job on TravisCI.
RSS feed