with an extra header instead of rejecting it.
cprintf("%d\n", config.c_xmpp_s2s_port);
cprintf("%ld\n", config.c_pop3_fetch);
cprintf("%ld\n", config.c_pop3_fastest);
+ cprintf("%d\n", config.c_spam_flag_only);
cprintf("000\n");
}
case 65:
config.c_pop3_fastest = atol(buf);
break;
+ case 66:
+ config.c_spam_flag_only = atoi(buf);
+ break;
}
++a;
}
CFG_VALUE(INTEGER(c_xmpp_s2s_port), " XMPP server-to-server port (usually 5269)");
CFG_VALUE(TIME(c_pop3_fetch), " How often to fetch POP3 messages");
CFG_VALUE(TIME(c_pop3_fastest), " Users can specify POP3 fetching this often");
+CFG_VALUE(INTEGER(c_spam_flag_only), " 1 = flag instead of reject spam");
goto bail;
}
CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
- if (!strncasecmp(buf, "Spam: True", 10)) {
- is_spam = 1;
- }
+ CtdlLogPrintf(CTDL_DEBUG, "c_spam_flag_only setting %d\n", config.c_spam_flag_only);
+ if (config.c_spam_flag_only) {
+ CtdlLogPrintf(CTDL_DEBUG, "flag spam code used");
+ int headerlen;
+ int newmsgsize;
+ int oldmsgsize;
+
+ char sastatus[10];
+ char sascore[10];
+ char saoutof[10];
+ int numscore;
+
+ extract_token(sastatus, buf, 1, ' ', sizeof sastatus);
+ extract_token(sascore, buf, 3, ' ', sizeof sascore);
+ extract_token(saoutof, buf, 5, ' ', sizeof saoutof);
+
+ sprintf(buf,"X-Spam-Level: ");
+ char *cur = buf + 14;
+ for (numscore = atoi(sascore); numscore>0; numscore--)
+ *(cur++) = '*';
+ *cur = '\0';
+
+ sprintf(cur,"\r\nX-Spam-Status: %s, score=%s required=%s\r\n", sastatus, sascore, saoutof);
+ headerlen = strlen(buf);
+ oldmsgsize = strlen(msg->cm_fields['M']) + 1;
+ newmsgsize = headerlen + oldmsgsize;
+
+ msg->cm_fields['M'] = realloc(msg->cm_fields['M'], newmsgsize);
+
+ memmove(msg->cm_fields['M']+headerlen,msg->cm_fields['M'],oldmsgsize);
+ memcpy(msg->cm_fields['M'],buf,headerlen);
+
+ } else {
+ CtdlLogPrintf(CTDL_DEBUG, "reject spam code used");
+ if (!strncasecmp(buf, "Spam: True", 10)) {
+ is_spam = 1;
+ }
- if (is_spam) {
- if (msg->cm_fields['0'] != NULL) {
- free(msg->cm_fields['0']);
+ if (is_spam) {
+ if (msg->cm_fields['0'] != NULL) {
+ free(msg->cm_fields['0']);
+ }
+ msg->cm_fields['0'] = strdup("message rejected by spam filter");
}
- msg->cm_fields['0'] = strdup("message rejected by spam filter");
}
bail: close(sock);
void do_system_configuration(CtdlIPC *ipc)
{
-#define NUM_CONFIGS 65
+#define NUM_CONFIGS 67
char buf[256];
char sc[NUM_CONFIGS][256];
a = (a ? 0 : 1);
snprintf(sc[25], sizeof sc[25], "%d", a);
+ snprintf(sc[66], sizeof sc[66], "%d", (boolprompt(
+ "Flag messages as spam instead of rejecting",
+ atoi(&sc[66][0]))));
+
/* This logic flips the question around, because it's one of those
* situations where 0=yes and 1=no
*/
sprintf(&pop3[strlen(pop3)], "<input type=\"text\" name=\"c_pop3_fastest\" MAXLENGTH=\"5\" value=\"%s\">\n", buf);
sprintf(&pop3[strlen(pop3)], "</TD></TR>\n");
break;
+ case 66: /* Flag spam */
+ sprintf(&network[strlen(network)], "<TR><TD>");
+ sprintf(&network[strlen(network)], _("Flag message as spam, instead of rejecting it"));
+ sprintf(&network[strlen(network)], "</TD><TD>");
+ sprintf(&network[strlen(network)], "<input type=\"checkbox\" NAME=\"c_spam_flag_only\" VALUE=\"yes\" %s>",
+ (atoi(buf) ? "CHECKED" : ""));
+ sprintf(&network[strlen(network)], "</TD></TR>\n");
+ break;
}
{CFG_STR, HKEY("c_xmpp_c2s_port")},
{CFG_STR, HKEY("c_xmpp_s2s_port")},
{CFG_STR, HKEY("c_pop3_fetch")},
- {CFG_STR, HKEY("c_pop3_fastest")}
+ {CFG_STR, HKEY("c_pop3_fastest")},
+ {CFG_YES , HKEY("c_spam_flag_only")}
};
<tr><td><?_("Correct forged From: lines during authenticated SMTP")></td><td>
<input type="checkbox" NAME="c_rfc822_strict_from" VALUE="yes" <?%("COND:SERVCFG", 1, "c_rfc822_strict_from", 1, "", "CHECKED")>></td></tr>
+<tr><td><?_("Flag message as spam, instead of rejecting it")></td><td>
+<input type="checkbox" NAME="c_spam_flag_only" VALUE="yes" <?%("COND:SERVCFG", 1, "c_spam_flag_only", 1, "CHECKED", "")>></td></tr>
+
<tr><td><?_("IMAP listener port (-1 to disable)")></td><td>
<input type="text" NAME="c_imap_port" MAXLENGTH="5" VALUE='<?SERV:CFG("c_imap_port")>'></td></tr>