init
This commit is contained in:
		
						commit
						de4607f946
					
				
							
								
								
									
										47
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @ -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` | ||||
							
								
								
									
										15
									
								
								make_lists.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								make_lists.sh
									
									
									
									
									
										Executable file
									
								
							| @ -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 | ||||
							
								
								
									
										56
									
								
								procmailrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								procmailrc
									
									
									
									
									
										Normal file
									
								
							| @ -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} <list+${LIST}@tilde.town>" -I "From: ${ENV_SENDER}" | ||||
| 
 | ||||
| :0A | ||||
| { | ||||
| 	UMASK=003 | ||||
| 	:0c: | ||||
| 	archive/${LIST} | ||||
| } | ||||
| 
 | ||||
| :0A | ||||
| ! ${RECIPIENTS} | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user