git-svn: trunk@3150
Nigel Horne authored on 2007/07/15 22:21:50... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Sun Jul 15 13:27:46 BST 2007 (njh) |
|
2 |
+---------------------------------- |
|
3 |
+ * clamav-milter: Experimental mode: Reduce the number of SPF DNS queries |
|
4 |
+ |
|
1 | 5 |
Sun Jul 15 10:26:49 BST 2007 (njh) |
2 | 6 |
---------------------------------- |
3 | 7 |
* clamav-milter: Experimental mode: Handle A: MX: INCLUDE: in SPF |
... | ... |
@@ -567,7 +567,7 @@ static table_t *mx(const char *host, table_t *t); |
567 | 567 |
#ifdef HAVE_RESOLV_H |
568 | 568 |
static table_t *resolve(const char *host, table_t *t); |
569 | 569 |
#ifdef CL_EXPERIMENTAL |
570 |
-static void spf(struct privdata *privdata); |
|
570 |
+static int spf(struct privdata *privdata); |
|
571 | 571 |
static void spf_ip(char *ip, int zero, void *v); |
572 | 572 |
#endif |
573 | 573 |
#endif |
... | ... |
@@ -2891,14 +2891,6 @@ clamfi_envfrom(SMFICTX *ctx, char **argv) |
2891 | 2891 |
if(hflag) |
2892 | 2892 |
privdata->headers = header_list_new(); |
2893 | 2893 |
|
2894 |
-#ifdef CL_EXPERIMENTAL |
|
2895 |
- /* |
|
2896 |
- * FIXME: This should only be done when a phish is found. It's done |
|
2897 |
- * on every email for now to test the SPF code |
|
2898 |
- */ |
|
2899 |
- spf(privdata); |
|
2900 |
-#endif /*CL_EXPERIMENTAL*/ |
|
2901 |
- |
|
2902 | 2894 |
return SMFIS_CONTINUE; |
2903 | 2895 |
} |
2904 | 2896 |
|
... | ... |
@@ -3457,14 +3449,11 @@ clamfi_eom(SMFICTX *ctx) |
3457 | 3457 |
* exceeded |
3458 | 3458 |
*/ |
3459 | 3459 |
#ifdef CL_EXPERIMENTAL |
3460 |
- /* |
|
3461 |
- * FIXME: SPF lookup should only be done when a phish is found, see |
|
3462 |
- * above |
|
3463 |
- */ |
|
3464 |
- if(privdata->spf_ok && (strstr(mess, "FOUND") != NULL) && (strstr(mess, "Phishing") != NULL)) { |
|
3465 |
- logg(_("%s: Ignoring phish false positive\n"), sendmailId); |
|
3466 |
- strcpy(mess, "OK"); |
|
3467 |
- } |
|
3460 |
+ if((strstr(mess, "FOUND") != NULL) && (strstr(mess, "Phishing") != NULL)) |
|
3461 |
+ if(spf(privdata)) { |
|
3462 |
+ logg(_("%s: Ignoring phish false positive\n"), sendmailId); |
|
3463 |
+ strcpy(mess, "OK"); |
|
3464 |
+ } |
|
3468 | 3465 |
#endif |
3469 | 3466 |
if(strstr(mess, "ERROR") != NULL) { |
3470 | 3467 |
if(strstr(mess, "Size limit reached") != NULL) { |
... | ... |
@@ -6134,8 +6123,11 @@ resolve(const char *host, table_t *t) |
6134 | 6134 |
* TODO: ptr |
6135 | 6135 |
* TODO: IPv6? |
6136 | 6136 |
* TODO: cache queries |
6137 |
+ * |
|
6138 |
+ * Return 1 if SPF says this email is from a legitimate source |
|
6139 |
+ * 0 for fail or unknown |
|
6137 | 6140 |
*/ |
6138 |
-static void |
|
6141 |
+static int |
|
6139 | 6142 |
spf(struct privdata *privdata) |
6140 | 6143 |
{ |
6141 | 6144 |
char *host, *ptr; |
... | ... |
@@ -6149,27 +6141,27 @@ spf(struct privdata *privdata) |
6149 | 6149 |
char buf[BUFSIZ]; |
6150 | 6150 |
|
6151 | 6151 |
if(privdata->ip[0] == '\0') |
6152 |
- return; |
|
6152 |
+ return 0; |
|
6153 | 6153 |
if(strcmp(privdata->ip, "127.0.0.1") == 0) { |
6154 | 6154 |
/* Loopback always pass SPF */ |
6155 | 6155 |
privdata->spf_ok = 1; |
6156 |
- return; |
|
6156 |
+ return 1; |
|
6157 | 6157 |
} |
6158 | 6158 |
if(isLocal(privdata->ip)) { |
6159 | 6159 |
/* Local addresses always pass SPF */ |
6160 | 6160 |
privdata->spf_ok = 1; |
6161 |
- return; |
|
6161 |
+ return 1; |
|
6162 | 6162 |
} |
6163 | 6163 |
|
6164 | 6164 |
if(privdata->from == NULL) |
6165 |
- return; |
|
6165 |
+ return 0; |
|
6166 | 6166 |
if((host = strchr(privdata->from, '@')) == NULL) |
6167 |
- return; |
|
6167 |
+ return 0; |
|
6168 | 6168 |
|
6169 | 6169 |
host = cli_strdup(++host); |
6170 | 6170 |
|
6171 | 6171 |
if(host == NULL) |
6172 |
- return; |
|
6172 |
+ return 0; |
|
6173 | 6173 |
|
6174 | 6174 |
ptr = strchr(host, '>'); |
6175 | 6175 |
|
... | ... |
@@ -6179,12 +6171,12 @@ spf(struct privdata *privdata) |
6179 | 6179 |
len = res_query(host, C_IN, T_TXT, (u_char *)&q, sizeof(q)); |
6180 | 6180 |
if(len < 0) { |
6181 | 6181 |
free(host); |
6182 |
- return; /* Host has no TXT records */ |
|
6182 |
+ return 0; /* Host has no TXT records */ |
|
6183 | 6183 |
} |
6184 | 6184 |
|
6185 | 6185 |
if((unsigned int)len > sizeof(q)) { |
6186 | 6186 |
free(host); |
6187 |
- return; |
|
6187 |
+ return 0; |
|
6188 | 6188 |
} |
6189 | 6189 |
|
6190 | 6190 |
hp = &(q.h); |
... | ... |
@@ -6194,7 +6186,7 @@ spf(struct privdata *privdata) |
6194 | 6194 |
for(i = ntohs(hp->qdcount); i--; p += len + QFIXEDSZ) |
6195 | 6195 |
if((len = dn_skipname(p, end)) < 0) { |
6196 | 6196 |
free(host); |
6197 |
- return; |
|
6197 |
+ return 0; |
|
6198 | 6198 |
} |
6199 | 6199 |
|
6200 | 6200 |
i = ntohs(hp->ancount); |
... | ... |
@@ -6206,7 +6198,7 @@ spf(struct privdata *privdata) |
6206 | 6206 |
|
6207 | 6207 |
if((len = dn_expand(q.u, end, p, buf, sizeof(buf) - 1)) < 0) { |
6208 | 6208 |
free(host); |
6209 |
- return; |
|
6209 |
+ return 0; |
|
6210 | 6210 |
} |
6211 | 6211 |
p += len; |
6212 | 6212 |
GETSHORT(type, p); |
... | ... |
@@ -6224,7 +6216,7 @@ spf(struct privdata *privdata) |
6224 | 6224 |
char *record; |
6225 | 6225 |
struct in_addr remote_ip; /* IP connecting to us */ |
6226 | 6226 |
|
6227 |
- logg("%s(%s): SPF record %s\n", |
|
6227 |
+ logg("#%s(%s): SPF record %s\n", |
|
6228 | 6228 |
host, privdata->ip, txt); |
6229 | 6229 |
#ifdef HAVE_INET_NTOP |
6230 | 6230 |
/* IPv4 address ? */ |
... | ... |
@@ -6267,7 +6259,7 @@ spf(struct privdata *privdata) |
6267 | 6267 |
#endif |
6268 | 6268 |
mask = MAKEMASK(preflen); |
6269 | 6269 |
if((ntohl(remote_ip.s_addr) & mask) == (ntohl(spf_range.s_addr) & mask)) { |
6270 |
- logg("SPF ip4 pass\n"); |
|
6270 |
+ logg("#SPF ip4 pass\n"); |
|
6271 | 6271 |
privdata->spf_ok = 1; |
6272 | 6272 |
} |
6273 | 6273 |
} else if(strcmp(record, "mx") == 0) { |
... | ... |
@@ -6335,6 +6327,8 @@ spf(struct privdata *privdata) |
6335 | 6335 |
p += len; |
6336 | 6336 |
} |
6337 | 6337 |
free(host); |
6338 |
+ |
|
6339 |
+ return privdata->spf_ok; |
|
6338 | 6340 |
} |
6339 | 6341 |
|
6340 | 6342 |
static void |
... | ... |
@@ -6343,7 +6337,7 @@ spf_ip(char *ip, int zero, void *v) |
6343 | 6343 |
struct privdata *privdata = (struct privdata *)v; |
6344 | 6344 |
|
6345 | 6345 |
if(strcmp(ip, privdata->ip) == 0) { |
6346 |
- logg("SPF mx/a pass %s\n", ip); |
|
6346 |
+ logg("#SPF mx/a pass %s\n", ip); |
|
6347 | 6347 |
privdata->spf_ok = 1; |
6348 | 6348 |
} |
6349 | 6349 |
} |