From de4607f9460ae00bd92f5317ed0a289511bc23b2 Mon Sep 17 00:00:00 2001 From: equa Date: Tue, 14 Mar 2023 17:42:05 +0000 Subject: [PATCH] init --- README.md | 47 ++++++++++++++++++++++++++++++++++++++++++ make_lists.sh | 15 ++++++++++++++ procmailrc | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 README.md create mode 100755 make_lists.sh create mode 100644 procmailrc diff --git a/README.md b/README.md new file mode 100644 index 0000000..04d0ea5 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# town mailing list manager + +our little bespoke town engine. it runs on a janky procmail script + + +## setup + +our system is very particular to running on public unix systems and probably +wouldn't be advisable for anything with external mail. + +we have our local mail set up so that it's impossible to spoof the +envelope sender of an email with `local_login_sender_maps` in postfix; +the list handles this to make the emails look pretty and to evade spoofing + +the software works on the assumption that everything lives in the home dir +of a user named `list`. +our list account needs two directories, `lists/` and `archive/`. +our scripts can autopopulate everything here, but you can also do manual +configuration in `lists/` to change access control to certain mailing lists. + +copy procailrc to `~/.procmailrc` and set up `~/.forward` to filter all mail +through it: + +``` +|/usr/bin/procmail +``` + +if you want to have any special read-only mailing lists, you can populate +`lists/LISTNAME.senders` with a list of allowed senders, one on each line + +a user can subscribe by naming the lists they want to subscribe to in a +`.townlists` file in their home directory +rather than checking these lists every post, we populate some internal +subscription lists with `make_lists.sh`, which should run on a cron job. + +## assumptions +- mailing list names are `[a-z0-9_]{1,16}` + - we check this in the .townlists files and in sending +- everything lives in our home directory + - `lists/` and `archive/` directories exist +- usernames don't contain special characters + - i don't actually know which ones would be an issue + but town doesn't usually allow anything too crazy anyway + +### subscriptions +- everyone we care about lives in /home and their usernames correspond to the directories +- list subscriptions are stored per-line in `.townlists` diff --git a/make_lists.sh b/make_lists.sh new file mode 100755 index 0000000..974970e --- /dev/null +++ b/make_lists.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +rm -- "${HOME}/lists/"*.users.new + +for listfile in /home/*/.townlists; do + user="$(basename "$(dirname "$listfile")")" + for x in $(grep '^[a-z0-9_]\{1,16\}$' "$listfile"); do + echo "$user" >> "${HOME}/lists/${x}.users.new" + done +done + +rm -- "${HOME}/lists"/*.users +for i in "${HOME}/lists"/*.users.new; do + mv -- "$i" "$(dirname "$i")"/"$(basename "$i" .new)" +done diff --git a/procmailrc b/procmailrc new file mode 100644 index 0000000..c3e53a0 --- /dev/null +++ b/procmailrc @@ -0,0 +1,56 @@ +# mailing list protocol! +# depends on a bunch of files in $HOME/lists -- +# a "listname.users" containing all of the users +# and (optionally) a "listname.senders" if you want to restrict that +SHELL=/bin/sh +SENDMAIL=/usr/sbin/sendmail +LINEBUF=10000000 + +:0 +* ^To:.*list\+\/[a-z0-9_]+@tilde\.town +LIST=| echo "$MATCH" | sed 's/@.*//' | sed 's/\(.\{16\}\).*/\1/' | tr '[:upper:]' '[:lower:]' + +:0A +{ + :0A + * ? [ -e ${HOME}/lists/${LIST}.users ] + RECIPIENTS=| cat ${HOME}/lists/${LIST}.users | tr '\n' ' ' + + :0E + { RECIPIENTS="" } +} + +# Extract envelope sender. Email addresses are actually very complex +# but we're on tilde.town so our email addresses aren't going to have spaces +:0A +* ^From \/[^ ]* +ENV_SENDER=|echo "$MATCH" | sed "s/ .*//" + +:0A +ENV_USER=|echo "$ENV_SENDER" | sed "s/@.*//" + +:0A +{ + # If we have a restricted list of senders we should abort if it's not in there + :0A + * ? [ -e "${HOME}/lists/${LIST}.senders" ] + { + :0A + * !? grep -F "${ENV_USER}" "${HOME}/lists/${LIST}.senders" + # hack to quit procmailrc immediately (WHY) + { EXITCODE=77 HOST= } + } +} + +:0Af +| formail -a "X-Loop: list+${LIST}@tilde.town" -I "Reply-To: ${LIST} " -I "From: ${ENV_SENDER}" + +:0A +{ + UMASK=003 + :0c: + archive/${LIST} +} + +:0A +! ${RECIPIENTS}