X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Flistsub%2Fserv_listsub.c;h=ae41d1746f8b3a639b5564ac1a51dc53273f7d47;hb=924b8cd997f56b68e16fa1dfc1be55722596f5d8;hp=bc00efa00b24ba956231b9f534bc747ac08edcc5;hpb=ace3b2c330af622a0f0a79edd369fca8e13a71a2;p=citadel.git diff --git a/citadel/modules/listsub/serv_listsub.c b/citadel/modules/listsub/serv_listsub.c index bc00efa00..ae41d1746 100644 --- a/citadel/modules/listsub/serv_listsub.c +++ b/citadel/modules/listsub/serv_listsub.c @@ -1,15 +1,15 @@ /* * This module handles self-service subscription/unsubscription to mail lists. * - * Copyright (c) 2002-2012 by the citadel.org team + * Copyright (c) 2002-2016 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * 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. + * 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" @@ -48,7 +48,6 @@ #include "msgbase.h" #include "internet_addressing.h" #include "clientsocket.h" -#include "file_ops.h" #include "ctdl_module.h" /* @@ -58,17 +57,21 @@ void listsub_generate_token(char *buf) { char sourcebuf[SIZ]; static int seq = 0; + size_t len; /* Theo, please sit down and shut up. This key doesn't have to be * tinfoil-hat secure, it just needs to be reasonably unguessable * and unique. */ - sprintf(sourcebuf, "%lx", + len = sprintf(sourcebuf, "%lx", (long) (++seq + getpid() + time(NULL)) ); /* Convert it to base64 so it looks cool */ - CtdlEncodeBase64(buf, sourcebuf, strlen(sourcebuf), 0); + len = CtdlEncodeBase64(buf, sourcebuf, len, 0); + if (buf[len - 1] == '\n') { + buf[len - 1] = '\0'; + } } const RoomNetCfg ActiveSubscribers[] = {listrecp, digestrecp}; @@ -79,7 +82,7 @@ int CountThisSubscriber(OneRoomNetCfg *OneRNCfg, StrBuf *email) int found_sub = 0; int i; - for (i = 0; i < sizeof (ActiveSubscribers); i++) + for (i = 0; i < 2; i++) { Line = OneRNCfg->NetConfigs[ActiveSubscribers[i]]; while (Line != NULL) @@ -97,18 +100,6 @@ int CountThisSubscriber(OneRoomNetCfg *OneRNCfg, StrBuf *email) } /* - subpending, - unsubpending, - ignet_push_share, - listrecp, - digestrecp, - pop3client, - rssclient, - participate, - roommailalias, - maxRoomNetCfg - -/ * * Enter a subscription request */ void do_subscribe(StrBuf **room, StrBuf **email, StrBuf **subtype, StrBuf **webpage) { @@ -121,6 +112,7 @@ void do_subscribe(StrBuf **room, StrBuf **email, StrBuf **subtype, StrBuf **webp const char *RoomMailAddress; OneRoomNetCfg *OneRNCfg; RoomNetCfgLine *Line; + const char *EmailSender = NULL; long RoomMailAddressLen; if (CtdlGetRoom(&qrbuf, ChrPtr(*room)) != 0) { @@ -142,10 +134,11 @@ void do_subscribe(StrBuf **room, StrBuf **email, StrBuf **subtype, StrBuf **webp RoomMailAddress = qrbuf.QRname; OneRNCfg = CtdlGetNetCfgForRoom(qrbuf.QRnumber); - if (OneRNCfg!=NULL) { + if (OneRNCfg != NULL) { found_sub = CountThisSubscriber(OneRNCfg, *email); - if (StrLength(OneRNCfg->Sender) > 0) - RoomMailAddress = ChrPtr(OneRNCfg->Sender); + if (StrLength(OneRNCfg->Sender) > 0) { + EmailSender = RoomMailAddress = ChrPtr(OneRNCfg->Sender); + } } if (found_sub != 0) { @@ -154,6 +147,7 @@ void do_subscribe(StrBuf **room, StrBuf **email, StrBuf **subtype, StrBuf **webp ChrPtr(*email), RoomMailAddress); + FreeRoomNetworkStruct(&OneRNCfg); end_critical_section(S_NETCONFIGS); return; } @@ -169,7 +163,7 @@ void do_subscribe(StrBuf **room, StrBuf **email, StrBuf **subtype, StrBuf **webp Line->Value = (StrBuf**) malloc(sizeof(StrBuf*) * 5); - Line->Value[0] = *email; *email = NULL; + Line->Value[0] = NewStrBufDup(*email); Line->Value[1] = *subtype; *subtype = NULL; Line->Value[2] = NewStrBufPlain(token, -1); Line->Value[3] = NewStrBufPlain(NULL, 10); @@ -277,19 +271,21 @@ void do_subscribe(StrBuf **room, StrBuf **email, StrBuf **subtype, StrBuf **webp "\n" "--__ctdlmultipart__--\n"), 0); + SaveRoomNetConfigFile(OneRNCfg, qrbuf.QRnumber); + FreeRoomNetworkStruct(&OneRNCfg); end_critical_section(S_NETCONFIGS); pcf_req = SmashStrBuf(&cf_req); quickie_message( /* This delivers the message */ "Citadel", - NULL, + EmailSender, ChrPtr(*email), NULL, pcf_req, FMT_RFC822, "Please confirm your list subscription" ); - free(cf_req); + free(pcf_req); cprintf("%d Subscription entered; confirmation request sent\n", CIT_OK); FreeStrBuf(&UrlRoom); @@ -301,6 +297,7 @@ void do_subscribe(StrBuf **room, StrBuf **email, StrBuf **subtype, StrBuf **webp */ void do_unsubscribe(StrBuf **room, StrBuf **email, StrBuf **webpage) { struct ctdlroom qrbuf; + const char *EmailSender = NULL; char token[256]; char *pcf_req; StrBuf *cf_req; @@ -335,15 +332,12 @@ void do_unsubscribe(StrBuf **room, StrBuf **email, StrBuf **webpage) { if (OneRNCfg!=NULL) { found_sub = CountThisSubscriber(OneRNCfg, *email); if (StrLength(OneRNCfg->Sender) > 0) - RoomMailAddress = ChrPtr(OneRNCfg->Sender); + EmailSender = RoomMailAddress = ChrPtr(OneRNCfg->Sender); } if (found_sub == 0) { - cprintf("%d '%s' is not subscribed to '%s'.\n", - ERROR + NO_SUCH_USER, - ChrPtr(*email), - qrbuf.QRname); - + cprintf("%d '%s' is not subscribed to '%s'.\n", ERROR + NO_SUCH_USER, ChrPtr(*email), qrbuf.QRname); + FreeRoomNetworkStruct(&OneRNCfg); end_critical_section(S_NETCONFIGS); return; } @@ -356,14 +350,14 @@ void do_unsubscribe(StrBuf **room, StrBuf **email, StrBuf **webpage) { Line = (RoomNetCfgLine*)malloc(sizeof(RoomNetCfgLine)); memset(Line, 0, sizeof(RoomNetCfgLine)); - Line->Value = (StrBuf**) malloc(sizeof(StrBuf*) * 5); + Line->Value = (StrBuf**) malloc(sizeof(StrBuf*) * 4); - Line->Value[0] = *email; *email = NULL; - Line->Value[2] = NewStrBufPlain(token, -1); - Line->Value[3] = NewStrBufPlain(NULL, 10); - StrBufPrintf(Line->Value[3], "%ld", time(NULL)); - Line->Value[4] = *webpage; *webpage = NULL; - Line->nValues = 5; + Line->Value[0] = NewStrBufDup(*email); + Line->Value[1] = NewStrBufPlain(token, -1); + Line->Value[2] = NewStrBufPlain(NULL, 10); + StrBufPrintf(Line->Value[2], "%ld", time(NULL)); + Line->Value[3] = *webpage; *webpage = NULL; + Line->nValues = 4; AddRoomCfgLine(OneRNCfg, &qrbuf, unsubpending, Line); @@ -398,11 +392,11 @@ void do_unsubscribe(StrBuf **room, StrBuf **email, StrBuf **webpage) { HKEY("' mailing list.\n" "\n" "Please go here to confirm this request:\n "), 0); - StrBufAppendBuf(cf_req, Line->Value[4], 0); + StrBufAppendBuf(cf_req, Line->Value[3], 0); StrBufAppendBufPlain(cf_req, HKEY("?room="), 0); StrBufAppendBuf(cf_req, UrlRoom, 0); StrBufAppendBufPlain(cf_req, HKEY("&token="), 0); - StrBufAppendBuf(cf_req, Line->Value[2], 0); + StrBufAppendBuf(cf_req, Line->Value[1], 0); StrBufAppendBufPlain( cf_req, @@ -434,22 +428,22 @@ void do_unsubscribe(StrBuf **room, StrBuf **email, StrBuf **webpage) { HKEY(" mailing list.

\n" "Please click here to confirm this request:
\n" "Value[4], 0); + StrBufAppendBuf(cf_req, Line->Value[3], 0); StrBufAppendBufPlain(cf_req, HKEY("?room="), 0); StrBufAppendBuf(cf_req, UrlRoom, 0); StrBufAppendBufPlain(cf_req, HKEY("&token="), 0); - StrBufAppendBuf(cf_req, Line->Value[2], 0); + StrBufAppendBuf(cf_req, Line->Value[1], 0); StrBufAppendBufPlain(cf_req, HKEY("&cmd=confirm\">"), 0); - StrBufAppendBuf(cf_req, Line->Value[4], 0); + StrBufAppendBuf(cf_req, Line->Value[3], 0); StrBufAppendBufPlain(cf_req, HKEY("?room="), 0); StrBufAppendBuf(cf_req, UrlRoom, 0); StrBufAppendBufPlain(cf_req, HKEY("&token="), 0); - StrBufAppendBuf(cf_req, Line->Value[2], 0); + StrBufAppendBuf(cf_req, Line->Value[1], 0); StrBufAppendBufPlain( @@ -467,12 +461,14 @@ void do_unsubscribe(StrBuf **room, StrBuf **email, StrBuf **webpage) { "\n" "--__ctdlmultipart__--\n"), 0); + SaveRoomNetConfigFile(OneRNCfg, qrbuf.QRnumber); + FreeRoomNetworkStruct(&OneRNCfg); end_critical_section(S_NETCONFIGS); pcf_req = SmashStrBuf(&cf_req); quickie_message( /* This delivers the message */ "Citadel", - NULL, + EmailSender, ChrPtr(*email), NULL, pcf_req, @@ -480,6 +476,8 @@ void do_unsubscribe(StrBuf **room, StrBuf **email, StrBuf **webpage) { "Please confirm your unsubscribe request" ); + free(pcf_req); + FreeStrBuf(&UrlRoom); cprintf("%d Unubscription noted; confirmation request sent\n", CIT_OK); } @@ -493,10 +491,12 @@ void do_confirm(StrBuf **room, StrBuf **token) { struct ctdlroom qrbuf; OneRoomNetCfg *OneRNCfg; RoomNetCfgLine *Line; - RoomNetCfgLine *ConfirmLine; + RoomNetCfgLine *ConfirmLine = NULL; + RoomNetCfgLine *RemoveLine = NULL; RoomNetCfgLine **PrevLine; int success = 0; RoomNetCfg ConfirmType; + const char *errmsg = ""; int i; if (CtdlGetRoom(&qrbuf, ChrPtr(*room)) != 0) { @@ -512,97 +512,134 @@ void do_confirm(StrBuf **room, StrBuf **token) { return; } + + if (StrLength(*token) == 0) { + cprintf("%d empty token.\n", ERROR + ILLEGAL_VALUE); + return; + } /* * Now start scanning this room's netconfig file for the * specified token. */ begin_critical_section(S_NETCONFIGS); OneRNCfg = CtdlGetNetCfgForRoom(qrbuf.QRnumber); - if (OneRNCfg==NULL) { -////TODO - } - ConfirmType = maxRoomNetCfg; - for (i = 0; i < sizeof (ConfirmSubscribers); i++) + if (OneRNCfg==NULL) { + errmsg = "no networking config found"; + } + else for (i = 0; i < 2; i++) + { + int offset; + + if (ConfirmSubscribers[i] == subpending) + offset = 2; + else + offset = 1; PrevLine = &OneRNCfg->NetConfigs[ConfirmSubscribers[i]]; Line = *PrevLine; while (Line != NULL) { if (!strcasecmp(ChrPtr(*token), - ChrPtr(Line->Value[2]))) + ChrPtr(Line->Value[offset]))) { - *PrevLine = Line->next; /* Remove it from the list */ ConfirmLine = Line; + *PrevLine = Line->next; /* Remove it from the list */ ConfirmType = ConfirmSubscribers[i]; + ConfirmLine->next = NULL; + i += 100; break; + } - PrevLine = &Line; + PrevLine = &(*PrevLine)->next; Line = Line->next; } + if (ConfirmType == maxRoomNetCfg) + { + errmsg = "No active un/subscribe request found"; + } } - if (ConfirmType == subpending) { - if (!strcasecmp(ChrPtr(ConfirmLine->Value[2]), - ("digest"))) + if (ConfirmType == subpending) + { + if (CountThisSubscriber(OneRNCfg, ConfirmLine->Value[0]) == 0) { - ConfirmType = digestrecp; + if (!strcasecmp(ChrPtr(ConfirmLine->Value[2]), + ("digest"))) + { + ConfirmType = digestrecp; + } + else /* "list" */ + { + ConfirmType = listrecp; + } + + syslog(LOG_NOTICE, + "Mailing list: %s subscribed to %s with token %s\n", + ChrPtr(ConfirmLine->Value[0]), + qrbuf.QRname, + ChrPtr(*token)); + + FreeStrBuf(&ConfirmLine->Value[1]); + FreeStrBuf(&ConfirmLine->Value[2]); + FreeStrBuf(&ConfirmLine->Value[3]); + FreeStrBuf(&ConfirmLine->Value[4]); + ConfirmLine->nValues = 1; + + AddRoomCfgLine(OneRNCfg, &qrbuf, ConfirmType, ConfirmLine); + success = 1; } else { - ConfirmType = listrecp; + /* whipe duplicate subscribe entry... */ + errmsg = "already subscribed"; } - - syslog(LOG_NOTICE, - "Mailing list: %s subscribed to %s with token %s\n", - ChrPtr(ConfirmLine->Value[0]), - qrbuf.QRname, - ChrPtr(*token)); - - FreeStrBuf(&ConfirmLine->Value[1]); - FreeStrBuf(&ConfirmLine->Value[2]); - FreeStrBuf(&ConfirmLine->Value[3]); - FreeStrBuf(&ConfirmLine->Value[4]); - ConfirmLine->nValues = 5; - - AddRoomCfgLine(OneRNCfg, &qrbuf, ConfirmType, ConfirmLine); - success = 1; } - else if (ConfirmType == unsubpending) { - for (i = 0; i < sizeof (ActiveSubscribers); i++) + else if (ConfirmType == unsubpending) + { + + for (i = 0; i < 2; i++) { PrevLine = &OneRNCfg->NetConfigs[ActiveSubscribers[i]]; Line = *PrevLine; while (Line != NULL) { if (!strcasecmp(ChrPtr(ConfirmLine->Value[0]), - ChrPtr(Line->Value[2]))) + ChrPtr(Line->Value[0]))) { + success = 1; + RemoveLine = Line; *PrevLine = Line->next; /* Remove it from the list */ - i += 100; - break; + RemoveLine->next = NULL; + if (RemoveLine != NULL) + DeleteGenericCfgLine(NULL/*TODO*/, &RemoveLine); + Line = *PrevLine; + continue; } - PrevLine = &Line; + PrevLine = &(*PrevLine)->next; Line = Line->next; } } - - syslog(LOG_NOTICE, - "Mailing list: %s unsubscribed to %s with token %s\n", - ChrPtr(ConfirmLine->Value[0]), - qrbuf.QRname, - ChrPtr(*token)); - - - if (Line != NULL) DeleteGenericCfgLine(NULL/*TODO*/, &Line); + if (success) + { + syslog(LOG_NOTICE, + "Mailing list: %s unsubscribed to %s with token %s\n", + ChrPtr(ConfirmLine->Value[0]), + qrbuf.QRname, + ChrPtr(*token)); + } + else + { + errmsg = "no subscriber found for this unsubscription request"; + } DeleteGenericCfgLine(NULL/*TODO*/, &ConfirmLine); - AddRoomCfgLine(OneRNCfg, &qrbuf, ConfirmType, NULL); - success = 1; } + SaveRoomNetConfigFile(OneRNCfg, qrbuf.QRnumber); + FreeRoomNetworkStruct(&OneRNCfg); end_critical_section(S_NETCONFIGS); /* @@ -612,6 +649,8 @@ void do_confirm(StrBuf **room, StrBuf **token) { cprintf("%d %d operation(s) confirmed.\n", CIT_OK, success); } else { + syslog(LOG_NOTICE, "failed processing (un)subscribe request: %s", + errmsg); cprintf("%d Invalid token.\n", ERROR + ILLEGAL_VALUE); } @@ -634,6 +673,7 @@ void cmd_subs(char *cmdbuf) { Segments[i] = NewStrBufPlain(NULL, StrLength(Segments[0])); StrBufExtract_NextToken(Segments[i], Segments[0], &Pos, '|'); + i++; } if (!strcasecmp(ChrPtr(Segments[1]), "subscribe")) { @@ -655,6 +695,11 @@ void cmd_subs(char *cmdbuf) else { cprintf("%d Invalid command\n", ERROR + ILLEGAL_VALUE); } + + for (; i>=0; i--) + { + FreeStrBuf(&Segments[i]); + } }