X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Flistsub%2Fserv_listsub.c;fp=citadel%2Fmodules%2Flistsub%2Fserv_listsub.c;h=0000000000000000000000000000000000000000;hb=f6fcf350671e3661f8f22696eb35133014ab6a14;hp=7d7e93693ac6359147815ff6a20aed7cecb71b61;hpb=2e4e67a1f7f65568abace99d13a71024ad06ebde;p=citadel.git diff --git a/citadel/modules/listsub/serv_listsub.c b/citadel/modules/listsub/serv_listsub.c deleted file mode 100644 index 7d7e93693..000000000 --- a/citadel/modules/listsub/serv_listsub.c +++ /dev/null @@ -1,306 +0,0 @@ -// This module handles self-service subscription/unsubscription to mail lists. -// -// Copyright (c) 2002-2022 by the citadel.org team -// -// This program is open source software. It runs great on the -// Linux operating system (and probably elsewhere). You can use, -// copy, and run it under the terms of the GNU General Public -// License version 3. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -#include "sysdep.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "citadel.h" -#include "server.h" -#include "citserver.h" -#include "support.h" -#include "config.h" -#include "user_ops.h" -#include "database.h" -#include "msgbase.h" -#include "internet_addressing.h" -#include "clientsocket.h" -#include "ctdl_module.h" - - -enum { // one of these gets passed to do_subscribe_or_unsubscribe() so it knows what we asked for - UNSUBSCRIBE, - SUBSCRIBE -}; - - -// The confirmation token will be generated by combining the room name and email address with the host key, -// and then generating an encrypted hash of that string. The encrypted hash is included as part of the -// confirmation link. -void generate_confirmation_token(char *token_buf, size_t token_buf_len, char *roomname, char *emailaddr) { - char string_to_hash[1024]; - struct crypt_data cd; - char *ptr; - - snprintf(string_to_hash, sizeof string_to_hash, "%s|%s|%s", roomname, emailaddr, CtdlGetConfigStr("host_key")); - memset(&cd, 0, sizeof cd); - - strncpy(token_buf, crypt_r(string_to_hash, "$1$ctdl", &cd), token_buf_len); - - for (ptr=token_buf; *ptr; ++ptr) { - if (!isalnum((char)*ptr)) *ptr='X'; - } -} - - -// This generates an email with a link the user clicks to confirm a list subscription. -void send_subscribe_confirmation_email(char *roomname, char *emailaddr, char *url, char *confirmation_token) { - // We need a URL-safe representation of the room name - char urlroom[ROOMNAMELEN+10]; - urlesc(urlroom, sizeof(urlroom), roomname); - - char from_address[1024]; - snprintf(from_address, sizeof from_address, "noreply@%s", CtdlGetConfigStr("c_fqdn")); - - char emailtext[SIZ]; - snprintf(emailtext, sizeof emailtext, - "MIME-Version: 1.0\n" - "Content-Type: multipart/alternative; boundary=\"__ctdlmultipart__\"\n" - "\n" - "This is a multipart message in MIME format.\n" - "\n" - "--__ctdlmultipart__\n" - "Content-type: text/plain\n" - "\n" - "Someone (probably you) has submitted a request to subscribe\n" - "<%s> to the <%s> mailing list.\n" - "\n" - "Please go here to confirm this request:\n" - "%s?cmd=confirm_subscribe&email=%s&room=%s&token=%s\n" - "\n" - "If this request has been submitted in error and you do not\n" - "wish to receive the <%s> mailing list, simply do nothing,\n" - "and you will not receive any further mailings.\n" - "\n" - "--__ctdlmultipart__\n" - "Content-type: text/html\n" - "\n" - "

Someone (probably you) has submitted a request to subscribe " - "%s to the %s mailing list.

" - "

Please go here to confirm this request:

" - "

" - "%s?cmd=confirm_subscribe&email=%s&room=%s&token=%s

" - "

If this request has been submitted in error and you do not " - "wish to receive the %s mailing list, simply do nothing, " - "and you will not receive any further mailings.

" - "\n" - "\n" - "--__ctdlmultipart__--\n" - , - emailaddr, roomname, - url, emailaddr, urlroom, confirmation_token, - roomname - , - emailaddr, roomname, - url, emailaddr, urlroom, confirmation_token, - url, emailaddr, urlroom, confirmation_token, - roomname - ); - - quickie_message("Citadel", from_address, emailaddr, NULL, emailtext, FMT_RFC822, "Please confirm your list subscription"); - cprintf("%d confirmation email sent\n", CIT_OK); -} - - -// This generates an email with a link the user clicks to confirm a list unsubscription. -void send_unsubscribe_confirmation_email(char *roomname, char *emailaddr, char *url, char *confirmation_token) { - // We need a URL-safe representation of the room name - char urlroom[ROOMNAMELEN+10]; - urlesc(urlroom, sizeof(urlroom), roomname); - - char from_address[1024]; - snprintf(from_address, sizeof from_address, "noreply@%s", CtdlGetConfigStr("c_fqdn")); - - char emailtext[SIZ]; - snprintf(emailtext, sizeof emailtext, - "MIME-Version: 1.0\n" - "Content-Type: multipart/alternative; boundary=\"__ctdlmultipart__\"\n" - "\n" - "This is a multipart message in MIME format.\n" - "\n" - "--__ctdlmultipart__\n" - "Content-type: text/plain\n" - "\n" - "Someone (probably you) has submitted a request to unsubscribe\n" - "<%s> from the <%s> mailing list.\n" - "\n" - "Please go here to confirm this request:\n" - "%s?cmd=confirm_unsubscribe&email=%s&room=%s&token=%s\n" - "\n" - "If this request has been submitted in error and you still\n" - "wish to receive the <%s> mailing list, simply do nothing,\n" - "and you will remain subscribed.\n" - "\n" - "--__ctdlmultipart__\n" - "Content-type: text/html\n" - "\n" - "

Someone (probably you) has submitted a request to unsubscribe " - "%s from the %s mailing list.

" - "

Please go here to confirm this request:

" - "

" - "%s?cmd=confirm_unsubscribe&email=%s&room=%s&token=%s

" - "

If this request has been submitted in error and you still " - "wish to receive the %s mailing list, simply do nothing, " - "and you will remain subscribed.

" - "\n" - "\n" - "--__ctdlmultipart__--\n" - , - emailaddr, roomname, - url, emailaddr, urlroom, confirmation_token, - roomname - , - emailaddr, roomname, - url, emailaddr, urlroom, confirmation_token, - url, emailaddr, urlroom, confirmation_token, - roomname - ); - - quickie_message("Citadel", from_address, emailaddr, NULL, emailtext, FMT_RFC822, "Please confirm your list unsubscription"); - cprintf("%d confirmation email sent\n", CIT_OK); -} - - -// Confirm a list subscription or unsubscription -void do_confirm(int cmd, char *roomname, char *emailaddr, char *url, char *generated_token, char *supplied_token) { - int i; - char buf[1024]; - int config_lines = 0; - char *oldnetconfig, *newnetconfig; - - // During opt #1, the server generated a persistent confirmation token for the user+room combination. - // Let's see if the user has supplied the same token during opt #2. - if (strcmp(generated_token, supplied_token)) { - cprintf("%d This request could not be authenticated.\n", ERROR + PASSWORD_REQUIRED); - return; - } - - // If the generated token matches the supplied token, the request is authentic. Do what it says. - - // Load the room's network configuration... - oldnetconfig = LoadRoomNetConfigFile(CC->room.QRnumber); - if (!oldnetconfig) { - oldnetconfig = strdup(""); - } - - // The new netconfig begins with an empty buffer... - begin_critical_section(S_NETCONFIGS); - newnetconfig = malloc(strlen(oldnetconfig) + 1024); - newnetconfig[0] = 0; - - // Load the config lines in one by one, skipping any that reference this subscriber. Also remove blank lines. - config_lines = num_tokens(oldnetconfig, '\n'); - for (i=0; iroom.QRnumber, newnetconfig); - end_critical_section(S_NETCONFIGS); - free(oldnetconfig); - free(newnetconfig); - cprintf("%d The pending request was confirmed.\n", CIT_OK); -} - - -// process subscribe/unsubscribe requests and confirmations -void cmd_lsub(char *cmdbuf) { - char cmd[20]; - char roomname[ROOMNAMELEN]; - char emailaddr[1024]; - char url[1024]; - char generated_token[128]; - char supplied_token[128]; - - extract_token(cmd, cmdbuf, 0, '|', sizeof cmd); // token 0 is the sub-command being sent - extract_token(roomname, cmdbuf, 1, '|', sizeof roomname); // token 1 is always a room name - extract_token(emailaddr, cmdbuf, 2, '|', sizeof emailaddr); // token 2 is the subscriber's email address - extract_token(url, cmdbuf, 3, '|', sizeof url); // token 3 is the URL at which we subscribed - extract_token(supplied_token, cmdbuf, 4, '|', sizeof supplied_token); // token 4 is the token supplied by the caller - - // First confirm that the caller is referencing a room that actually exists. - if (CtdlGetRoom(&CC->room, roomname) != 0) { - cprintf("%d There is no list called '%s'\n", ERROR + ROOM_NOT_FOUND, roomname); - return; - } - - if ((CC->room.QRflags2 & QR2_SELFLIST) == 0) { - cprintf("%d '%s' does not accept subscribe/unsubscribe requests.\n", ERROR + ROOM_NOT_FOUND, roomname); - return; - } - - // Generate a confirmation token -- either to supply to the user for opt #1 or to compare for opt #2 - generate_confirmation_token(generated_token, sizeof generated_token, roomname, emailaddr); - - // Now parse the command. - if (!strcasecmp(cmd, "subscribe")) { - send_subscribe_confirmation_email(roomname, emailaddr, url, generated_token); - } - - else if (!strcasecmp(cmd, "unsubscribe")) { - send_unsubscribe_confirmation_email(roomname, emailaddr, url, generated_token); - } - - else if (!strcasecmp(cmd, "confirm_subscribe")) { - do_confirm(SUBSCRIBE, roomname, emailaddr, url, generated_token, supplied_token); - } - - else if (!strcasecmp(cmd, "confirm_unsubscribe")) { - do_confirm(UNSUBSCRIBE, roomname, emailaddr, url, generated_token, supplied_token); - } - - else { // sorry man, I can't deal with that - cprintf("%d Invalid command '%s'\n", ERROR + ILLEGAL_VALUE, cmd); - } -} - - -/* - * Module entry point - */ -CTDL_MODULE_INIT(listsub) -{ - if (!threading) - { - CtdlRegisterProtoHook(cmd_lsub, "LSUB", "List subscribe/unsubscribe"); - } - - /* return our module name for the log */ - return "listsub"; -}