From 758b1a8c74fcd37e290ab217f2ab9a9ebeeadf90 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Tue, 17 Oct 2006 04:07:03 +0000 Subject: [PATCH] Implemented the REJECT extension --- citadel/serv_sieve.c | 116 +++++++++++++++++++++++++++++++------------ citadel/serv_sieve.h | 1 + citadel/serv_smtp.c | 2 - 3 files changed, 85 insertions(+), 34 deletions(-) diff --git a/citadel/serv_sieve.c b/citadel/serv_sieve.c index 0faaf3980..664763a40 100644 --- a/citadel/serv_sieve.c +++ b/citadel/serv_sieve.c @@ -192,7 +192,7 @@ int ctdl_fileinto(sieve2_context_t *s, void *my) } /* Yes, we actually have to go there */ - usergoto(NULL, 0, 0, NULL, NULL); + usergoto(NULL, 0, 0, NULL, NULL); c = CtdlSaveMsgPointersInRoom(NULL, &cs->msgnum, 1, 0, NULL); @@ -211,14 +211,70 @@ int ctdl_fileinto(sieve2_context_t *s, void *my) } +/* + * Callback function to indicate that a message should be discarded. + */ +int ctdl_discard(sieve2_context_t *s, void *my) +{ + struct ctdl_sieve *cs = (struct ctdl_sieve *)my; + + lprintf(CTDL_DEBUG, "Action is DISCARD\n"); + + /* Yes, this is really all there is to it. Since we are not setting "keep" to 1, + * the message will be discarded because "some other action" was successfully taken. + */ + cs->actiontaken = 1; + return SIEVE2_OK; +} + + + /* * Callback function to indicate that a message should be rejected - * FIXME implement this */ int ctdl_reject(sieve2_context_t *s, void *my) { + struct ctdl_sieve *cs = (struct ctdl_sieve *)my; + char *reject_text = NULL; + lprintf(CTDL_DEBUG, "Action is REJECT\n"); - return SIEVE2_ERROR_UNSUPPORTED; + + /* If we don't know who sent the message, do a DISCARD instead. */ + if (strlen(cs->sender) == 0) { + lprintf(CTDL_INFO, "Unknown sender. Doing DISCARD instead of REJECT.\n"); + return ctdl_discard(s, my); + } + + /* Assemble the reject message. */ + reject_text = malloc(strlen(sieve2_getvalue_string(s, "message")) + 1024); + if (reject_text == NULL) { + return SIEVE2_ERROR_FAIL; + } + + sprintf(reject_text, + "Content-type: text/plain\n" + "\n" + "The message was refused by the recipient's mail filtering program.\n" + "The reason given was as follows:\n" + "\n" + "%s\n" + "\n" + , + sieve2_getvalue_string(s, "message") + ); + + quickie_message( /* This delivers the message */ + "Citadel", + cs->sender, + NULL, + reject_text, + FMT_RFC822, + "Delivery status notification" + ); + + free(reject_text); + cs->actiontaken = 1; + return SIEVE2_OK; } @@ -298,24 +354,6 @@ int ctdl_getsize(sieve2_context_t *s, void *my) } -/* - * Callback function to indicate that a message should be discarded. - */ -int ctdl_discard(sieve2_context_t *s, void *my) -{ - struct ctdl_sieve *cs = (struct ctdl_sieve *)my; - - lprintf(CTDL_DEBUG, "Action is DISCARD\n"); - - /* Yes, this is really all there is to it. Since we are not setting "keep" to 1, - * the message will be discarded because "some other action" was successfully taken. - */ - cs->actiontaken = 1; - return SIEVE2_OK; -} - - - /* * Callback function to retrieve the sieve script */ @@ -327,12 +365,12 @@ int ctdl_getscript(sieve2_context_t *s, void *my) { if (sptr->script_active > 0) { lprintf(CTDL_DEBUG, "ctdl_getscript() is using script '%s'\n", sptr->script_name); sieve2_setvalue_string(s, "script", sptr->script_content); - return SIEVE2_OK; + return SIEVE2_OK; } } lprintf(CTDL_DEBUG, "ctdl_getscript() found no active script\n"); - return SIEVE2_ERROR_GETSCRIPT; + return SIEVE2_ERROR_GETSCRIPT; } /* @@ -401,6 +439,20 @@ void sieve_do_msg(long msgnum, void *userdata) { /* Keep track of the recipient so we can do handling based on it later */ process_rfc822_addr(msg->cm_fields['R'], my.recp_user, my.recp_node, my.recp_name); + /* Keep track of the sender so we can use it for REJECT and VACATION responses */ + if (msg->cm_fields['F'] != NULL) { + safestrncpy(my.sender, msg->cm_fields['F'], sizeof my.sender); + } + else if ( (msg->cm_fields['A'] != NULL) && (msg->cm_fields['N'] != NULL) ) { + snprintf(my.sender, sizeof my.sender, "%s@%s", msg->cm_fields['A'], msg->cm_fields['N']); + } + else if (msg->cm_fields['A'] != NULL) { + safestrncpy(my.sender, msg->cm_fields['A'], sizeof my.sender); + } + else { + strcpy(my.sender, ""); + } + free(msg); sieve2_setvalue_string(sieve2_context, "allheaders", my.rfc822headers); @@ -560,17 +612,17 @@ void sieve_do_room(char *roomname) { * This is our callback registration table for libSieve. */ sieve2_callback_t ctdl_sieve_callbacks[] = { - { SIEVE2_ACTION_REJECT, ctdl_reject }, - { SIEVE2_ACTION_NOTIFY, ctdl_notify }, + { SIEVE2_ACTION_REJECT, ctdl_reject }, + { SIEVE2_ACTION_NOTIFY, ctdl_notify }, { SIEVE2_ACTION_VACATION, ctdl_vacation }, - { SIEVE2_ERRCALL_PARSE, ctdl_errparse }, + { SIEVE2_ERRCALL_PARSE, ctdl_errparse }, { SIEVE2_ERRCALL_RUNTIME, ctdl_errexec }, { SIEVE2_ACTION_FILEINTO, ctdl_fileinto }, { SIEVE2_ACTION_REDIRECT, ctdl_redirect }, - { SIEVE2_ACTION_DISCARD, ctdl_discard }, - { SIEVE2_ACTION_KEEP, ctdl_keep }, + { SIEVE2_ACTION_DISCARD, ctdl_discard }, + { SIEVE2_ACTION_KEEP, ctdl_keep }, { SIEVE2_SCRIPT_GETSCRIPT, ctdl_getscript }, - { SIEVE2_DEBUG_TRACE, ctdl_debug }, + { SIEVE2_DEBUG_TRACE, ctdl_debug }, { SIEVE2_MESSAGE_GETALLHEADERS, ctdl_getheaders }, { SIEVE2_MESSAGE_GETSUBADDRESS, ctdl_getsubaddress }, { SIEVE2_MESSAGE_GETENVELOPE, ctdl_getenvelope }, @@ -777,8 +829,8 @@ char *msiv_getscript(struct sdm_userdata *u, char *script_name) { * Delete a script by name. * * Returns 0 if the script was deleted. - * 1 if the script was not found. - * 2 if the script cannot be deleted because it is active. + * 1 if the script was not found. + * 2 if the script cannot be deleted because it is active. */ int msiv_deletescript(struct sdm_userdata *u, char *script_name) { struct sdm_script *s = NULL; @@ -963,7 +1015,7 @@ void log_the_sieve2_credits(void) { char *serv_sieve_init(void) { log_the_sieve2_credits(); - CtdlRegisterProtoHook(cmd_msiv, "MSIV", "Manage Sieve scripts"); + CtdlRegisterProtoHook(cmd_msiv, "MSIV", "Manage Sieve scripts"); return "$Id: serv_sieve.c 3850 2005-09-13 14:00:24Z ajc $"; } diff --git a/citadel/serv_sieve.h b/citadel/serv_sieve.h index a8c6f52af..9c02ed649 100644 --- a/citadel/serv_sieve.h +++ b/citadel/serv_sieve.h @@ -33,6 +33,7 @@ struct ctdl_sieve { char recp_user[256]; char recp_node[256]; char recp_name[256]; + char sender[256]; /* To whom shall we send reject bounces or vacation messages? */ }; diff --git a/citadel/serv_smtp.c b/citadel/serv_smtp.c index ac12d1eaa..718439093 100644 --- a/citadel/serv_smtp.c +++ b/citadel/serv_smtp.c @@ -1334,8 +1334,6 @@ void smtp_do_bounce(char *instr) { give_up = 1; } - - bmsg = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage)); if (bmsg == NULL) return; memset(bmsg, 0, sizeof(struct CtdlMessage)); -- 2.39.2