From 281661c01e4a7562c9579a950036f82dbc7c04d4 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 29 Nov 2021 14:24:06 -0500 Subject: [PATCH] Mail to a mailing list room must be from a subscriber (or a logged in user) otherwise incoming message is rejected. --- citadel/internet_addressing.c | 33 ++++++++++++++++++++++++++++++-- citadel/internet_addressing.h | 1 + citadel/modules/smtp/serv_smtp.c | 10 ++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/citadel/internet_addressing.c b/citadel/internet_addressing.c index 429272586..6fb485b1a 100644 --- a/citadel/internet_addressing.c +++ b/citadel/internet_addressing.c @@ -1655,8 +1655,7 @@ void CtdlSetEmailAddressesForUser(char *requested_user, char *new_emailaddrs) /* * Auto-generate an Internet email address for a user account */ -void AutoGenerateEmailAddressForUser(struct ctdluser *user) -{ +void AutoGenerateEmailAddressForUser(struct ctdluser *user) { char synthetic_email_addr[1024]; int i, j; int u = 0; @@ -1688,3 +1687,33 @@ void AutoGenerateEmailAddressForUser(struct ctdluser *user) strncpy(CC->user.emailaddrs, synthetic_email_addr, sizeof(user->emailaddrs)); syslog(LOG_DEBUG, "user_ops: auto-generated email address <%s> for <%s>", synthetic_email_addr, user->fullname); } + + +// Determine whether the supplied email address is subscribed to the supplied room's mailing list service. +int is_email_subscribed_to_list(char *email, char *room_name) { + struct ctdlroom room; + long roomnum; + char *roomnetconfig; + int found_it = 0; + + if (CtdlGetRoom(&room, room_name)) { + return(0); // room not found, so definitely not subscribed + } + roomnum = room.QRnumber; + roomnetconfig = LoadRoomNetConfigFile(roomnum); + if (roomnetconfig == NULL) { + return(0); + } + + // We're going to do a very sloppy match here and simply search for the specified email address + // anywhere in the room's netconfig. If you don't like this, fix it yourself. + if (bmstrcasestr(roomnetconfig, email)) { + found_it = 1; + } + else { + found_it = 0; + } + + free(roomnetconfig); + return(found_it); +} diff --git a/citadel/internet_addressing.h b/citadel/internet_addressing.h index 4b12ee74d..443033561 100644 --- a/citadel/internet_addressing.h +++ b/citadel/internet_addressing.h @@ -21,6 +21,7 @@ struct CtdlMessage *convert_internet_message_buf(StrBuf **rfc822); int CtdlIsMe(char *addr, int addr_buf_len); int CtdlHostAlias(char *fqdn); char *harvest_collected_addresses(struct CtdlMessage *msg); +int is_email_subscribed_to_list(char *email, char *room_name); /* * Values that can be returned by CtdlHostAlias() diff --git a/citadel/modules/smtp/serv_smtp.c b/citadel/modules/smtp/serv_smtp.c index a74e2bb9f..549a29165 100644 --- a/citadel/modules/smtp/serv_smtp.c +++ b/citadel/modules/smtp/serv_smtp.c @@ -715,6 +715,16 @@ void smtp_rcpt(void) { return; } + if ( + (valid->num_room > 0) // If it's mail to a room (mailing list)... + && (SMTP->message_originated_locally == 0) // ...and also inbound Internet mail... + && (is_email_subscribed_to_list((char *)ChrPtr(SMTP->from), valid->recp_room) == 0) // ...and not a subscriber + ) { + cprintf("551 <%s> - This mailing list only accepts messages from subscribers.\r\n", ChrPtr(SMTP->OneRcpt)); + free_recipients(valid); + return; + } + cprintf("250 RCPT ok <%s>\r\n", ChrPtr(SMTP->OneRcpt)); if (StrLength(SMTP->recipients) > 0) { StrBufAppendBufPlain(SMTP->recipients, HKEY(","), 0); -- 2.30.2