53 0.4, 0.0, 0.0, 0,
TRUE,
54 "SMTP client resolve failed"},
58 0.4, 0.0, 0.0, 0,
TRUE,
59 "SMTP client resolve forged"},
63 0.5, 0.0, 0.0, 0,
TRUE,
64 "SMTP client resolve tempfail"},
68 1.2, 0.0, 0.0, 0,
TRUE,
69 "False localhost DNS declaration"},
73 1.2, 0.0, 0.0, 0,
TRUE,
74 "SMTP client sending mail to spamtrap"},
78 1.2, 0.0, 0.0, 0,
TRUE,
79 "Bad EHLO parameter"},
83 1.2, 0.0, 0.0, 0,
TRUE,
84 "Myself EHLO parameter - forged"},
88 1.2, 0.0, 0.0, 0,
TRUE,
89 "SMTP client listed at some RBL"},
96 0.5, 0.0, 0.0, 0,
TRUE,
97 "No HTML nor TEXT parts"},
101 0.2, 0.0, 0.0, 0,
TRUE,
102 "text/html without text/plain"},
106 0.4, 50.0, 0.0, 0,
TRUE,
111 0.4, 50.0, 0.0, 0,
TRUE,
112 "date in the future"},
116 0.4, 1.0, 0.0, 0,
TRUE,
121 0.4, 0.0, 0.0, 0,
TRUE,
126 1., 0.0, 0.0, 0,
TRUE,
131 1., 0.0, 0.0, 0,
TRUE,
132 "Forged postmaster"},
136 1., 0.0, 0.0, 0,
TRUE,
137 "Invalid sender address"},
141 1., 0.0, 0.0, 0,
TRUE,
142 "Invalid domain address"},
146 1., 0.0, 0.0, 0,
TRUE,
147 "No Subject header"},
151 1., 0.0, 0.0, 0,
TRUE,
152 "RFC2822 headers compliance"},
156 0.5, 0.0, 0.0, 0,
TRUE,
161 1., 0.0, 0.0, 0,
TRUE,
162 "Base 64 encoded message"},
166 0.5, 0.0, 0.0, 0,
TRUE,
167 "Base 64 encoded Subject"},
171 1., 0.0, 0.0, 0,
TRUE,
172 "multipart/* unwanted boundary"},
176 1.2, 0.0, 0.0, 0,
TRUE,
177 "message with bad recipients"},
181 1., 0.0, 0.0, 0,
TRUE,
186 1., 0.0, 0.0, 0,
TRUE,
191 0.5, 0.0, 0.0, 0,
TRUE,
192 "text text/html parts don't match"},
196 2., 0.0, 0.0, 0,
TRUE,
197 "message with spamtrap recipient"},
201 1., 0.0, 0.0, 0,
TRUE,
202 "message too short"},
206 2., 0.0, 0.0, 0,
TRUE,
211 0.5, 0.0, 0.0, 0,
TRUE,
216 2., 0.0, 0.0, 0,
TRUE,
217 "Unwanted MIME part with Content-ID"},
221 2., 0.0, 0.0, 0,
TRUE,
222 "Message with an empty attachment"},
226 0.5, 0.0, 0.0, 0,
TRUE,
235 1., 0.0, 0.0, 0,
TRUE,
240 0.5, 0.0, 0.0, 0,
TRUE,
241 "text/plain encoded base64"},
245 0.2, 0., 0.0, 0,
TRUE,
246 "text/plain wo charset"},
250 0.2, 0.0, 0.0, 0,
TRUE,
251 "text/plain too short"},
259 0.8, 0.0, 0.0, 0,
TRUE,
260 "cleaned HTML part too short"},
264 0.5, 0.0, 0.0, 0,
TRUE,
265 "text/html encoded base64"},
269 0.5, 0.0, 0.0, 0,
TRUE,
270 "HTML with unwanted tags"},
274 0.5, 0.0, 0.0, 0,
TRUE,
275 "HTML tag/text ratio"},
279 0.3, 0.0, 0.0, 0,
TRUE,
280 "invalid HTML tags"},
285 0.0, 0.0, 0.0, 0,
TRUE,
286 "number of tagged messages"},
288 {-1, -1, 0., 0.0, 0.0, 0,
TRUE, NULL}
295 static pthread_mutex_t ora_mutex = PTHREAD_MUTEX_INITIALIZER;
297 #define ORACLE_DATA_LOCK() MUTEX_LOCK(&ora_mutex) 298 #define ORACLE_DATA_UNLOCK() MUTEX_UNLOCK(&ora_mutex) 302 static long nb_tag = 0;
303 static long nb_tot = 0;
366 while (p->
type >= 0) {
367 if ((p->
type == type) && (p->
ind == ind))
387 while (p->
type >= 0) {
388 if ((p->
type == type) && (p->
ind == ind)) {
413 while (p->
type >= 0) {
414 if ((p->
type == type) && (p->
ind == ind)) {
439 while (p->
type >= 0) {
440 if ((p->
type == type) && (p->
ind == ind)) {
465 while (p->
type >= 0) {
466 if ((p->
type == type) && (p->
ind == ind)) {
491 while (p->
type >= 0) {
492 if ((p->
type == type) && (p->
ind == ind)) {
517 while (p->
type >= 0) {
518 if ((p->
type == type) && (p->
ind == ind)) {
544 while (p->
type >= 0) {
545 if ((p->
type == type) && (p->
ind == ind)) {
570 while (p->
type >= 0) {
571 if ((p->
type == type) && (p->
ind == ind)) {
572 count = p->
count = value;
595 while (p->
type >= 0) {
596 if ((p->
type == type) && (p->
ind == ind)) {
625 bool CloseOnQuit = (fd < 0);
634 strlcpy(fname, p,
sizeof (fname));
638 if ((fd = open(fname, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) {
647 time_t now = time(NULL);
653 if (localtime_r(&now, &tm) != NULL)
654 strftime(s,
sizeof (s),
"%b %e %T", &tm);
656 memset(s, 0,
sizeof (s));
658 FD_PRINTF(fd,
"++++++++++++++++ %ld %s\n", (
long) now, s);
675 FD_PRINTF(fd,
"C%02d %6ld - %5.2f %s\n", i, nb,
694 FD_PRINTF(fd,
"M%02d %6ld - %5.2f %s\n", i, nb,
713 FD_PRINTF(fd,
"P%02d %6ld - %5.2f %s\n", i, nb,
732 FD_PRINTF(fd,
"H%02d %6ld - %5.2f %s\n", i, nb,
740 double gm, gs, tm, ts;
745 FD_PRINTF(fd,
"MSGS : TOTAL - NB %8ld - MEAN %6.3f - STDDEV %6.3f\n",
747 FD_PRINTF(fd,
"MSGS : TAGGED - NB %8ld - MEAN %6.3f - STDDEV %6.3f\n",
819 #define KEYVALUE "^[a-z0-9_-]+=[^ \t]+" 822 read_oracle_def_string(v, arg)
826 char *s = (
char *) v;
833 switch (tolower(*s)) {
864 while (strlen(s) > 0) {
867 if (strncasecmp(s,
"ENABLE", strlen(
"ENABLE")) == 0) {
874 if (strncasecmp(s,
"DISABLE", strlen(
"DISABLE")) == 0) {
897 if (strspn(val,
"0123456789.") == strlen(val))
904 if (strspn(val,
"0123456789.") == strlen(val)) {
915 strlcpy(r.action, val, sizeof (r.action));
931 while (p->
type >= 0) {
932 if ((p->
type == type) && (p->
ind == ind)) {
961 r =
zm_RdFile(path, tag, read_oracle_def_string, NULL);
989 char *prefix =
"RCMHP.";
993 printf(
"<ORACLE-SCORES>\n");
994 for (q = oracle_messages; q->
type >= 0; q++) {
998 if (otype != q->
type)
1002 if (q->
type >= 0 && q->
type < strlen(prefix))
1003 c = prefix[q->
type];
1008 memset(sa, 0,
sizeof (sa));
1009 snprintf(sa,
sizeof (sa),
"odds=%.3f", exp(q->
pOdds));
1010 printf(
"%c%02d %-8s %-15s %s\n", c, q->
ind,
1013 printf(
"</ORACLE-SCORES>\n");
1026 bool enable =
FALSE;
1034 while (p->
type >= 0) {
1035 if ((p->
type == type) && (p->
ind == ind)) {
1058 double value = 0., score = 0., v;
1065 id =
STRNULL(
id,
"00000000.000");
1070 for (i = 0; i < (8 *
sizeof (
uint32_t)); i++) {
1077 if (
TRUE || value > 0) {
1111 for (i = 0; i < (8 *
sizeof (
uint32_t)); i++) {
1118 if (
TRUE || value > 0) {
1200 for (i = 0; i < (8 *
sizeof (
uint32_t)); i++) {
1207 if (
TRUE || value > 0) {
1233 for (i = 0; i < (8 *
sizeof (
uint32_t)); i++) {
1240 if (
TRUE || value > 0) {
1270 ZE_MessageInfo(12,
"%s ->Computed ORACLE score is %5.2f ...",
id, score);
1276 lam = 1. / (1 + exp(-odds));
1281 "%s ->Computed ORACLE score is %5.2f odds=%6.3f lam=%6.3f...",
1282 id, score, odds, lam);
1285 return ((
int) floor(score + 0.5));
bool oracle_save_counters()
bool oracle_set_nodds(int type, int ind, double value)
int zm_RdFile(char *fname, char *tag, RDFILE_F f, void *arg)
#define SPAM_MSG_NO_SUBJECT
bool bestof_init(bestof_T *b, int dim, bestcomp_F bcmp)
#define SPAM_MSG_TOO_OLD_DATE
#define SPAM_CONN_RESOLVE_FAIL
#define CF_ORACLE_STATS_FILE
#define SPAM_MSG_BAD_SENDER_ADDRESS
#define SPAM_CONN_FALSE_LOCALHOST
#define SPAM_MSG_HAS_SPAMTRAP
#define SPAM_HTML_UNWANTED_TAGS
#define SPAM_MSG_TOO_MUCH_HTML
bool oracle_read_counters()
int oracle_compute_score(char *id, char *ip, spamchk_T *data)
double bestof_average(bestof_T *b)
#define SPAM_PLAIN_TOO_SHORT
#define ORACLE_DATA_LOCK()
long oracle_get_count(int type, int ind)
#define SPAM_MSG_TOO_SHORT
bool zeStrRegex(char *, char *, long *, long *, bool)
#define SPAM_MSG_HAS_BADRCPT
bool oracle_set_score(int type, int ind, double value)
#define CF_LOG_LEVEL_ORACLE
int headers_syntax_errors
#define SPAM_MSG_SUBJECT_NO_ALPHA
#define FD_PRINTF(fdp,...)
bool read_conf_data_file(char *cfdir, char *fname, char *dfile, read_conf_data_file_F func)
#define SPAM_MSG_UNWANTED_CHARSET
#define SPAM_MSG_FUTURE_DATE
#define SPAM_PLAIN_NO_CHARSET
#define SPAM_MSG_EMPTY_ATTACHMENT
#define SPAM_MSG_BAD_DATE
void oracle_stats_get(double *gm, double *gs, long *gnb, double *tm, double *ts, long *tnb)
bool bestof_add(bestof_T *b, double v)
double oracle_get_score(int type, int ind)
#define SPAM_CONN_RESOLVE_TEMPFAIL
long oracle_inc_count(int type, int ind)
#define SPAM_MSG_HEADERS_SYNTAX
void zeKStatsUpdate(kstats_T *, double)
#define SPAM_MSG_BAD_DOMAIN_ADDRESS
bool load_oracle_defs(char *cfdir, char *fname)
#define ZE_MessageInfo(level,...)
#define SPAM_MSG_BAD_NULL_SENDER
#define SPAM_MSG_UNWANTED_BOUNDARY
#define ZE_MessageWarning(level,...)
#define SPAM_CONN_BL_SPAMTRAP
#define SPAM_CONN_FORGED_EHLO
long oracle_set_count(int type, int ind, long value)
#define SPAM_MSG_BAD_EXPRESSIONS
#define SPAM_CONN_BAD_EHLO
void oracle_stats_update(int score)
#define ZE_LogSysError(...)
#define KSTATS_INITIALIZER
double oracle_get_nodds(int type, int ind)
char * cf_get_str(int id)
#define SPAM_MSG_SUBJECT_HI_CAPS
#define SPAM_MSG_FORGED_POSTMASTER
char * oracle_get_label(int type, int ind)
#define SPAM_CONN_RESOLVE_FORGED
#define SPAM_MSG_RFC2822_HEADERS
#define ORACLE_TYPE_PLAIN
#define SPAM_MSG_CONTENT_ID
#define SPAM_MSG_UNWANTED_MAILER
#define STRCASEEQUAL(a, b)
#define SPAM_MSG_MATCH_MIME_PARTS
double zeKMean(kstats_T *s)
bool oracle_dump_counters(int fd, bool verbose)
#define SPAM_PLAIN_BASE64
double oracle_get_podds(int type, int ind)
#define SPAM_HTML_TAGS_RATIO
double zeKStdDev(kstats_T *s)
#define ORACLE_DATA_UNLOCK()
#define SPAM_MSG_MIME_ERRORS
bool oracle_check_enabled(int type, int ind)
bool oracle_read_scores()
#define SPAM_HTML_INVALID_TAGS
int nb_rfc2822_hdrs_errors
#define SPAM_HTML_CLEAN_TOO_SHORT
#define SPAM_MSG_BASE64_SUBJECT
bool oracle_set_podds(int type, int ind, double value)
#define SPAM_MSG_NO_TEXT_PART