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]);
+ }
}