git-svn: trunk@5009
aCaB authored on 2009/04/02 22:36:31... | ... |
@@ -1,3 +1,8 @@ |
1 |
+Thu Apr 2 04:09:06 CEST 2009 (acab) |
|
2 |
+------------------------------------ |
|
3 |
+ * clamav-milter/clamfi.c: properly separate body from headers (bb#1531), |
|
4 |
+ minor optimizations and hardening |
|
5 |
+ |
|
1 | 6 |
Thu Apr 2 03:24:21 CEST 2009 (acab) |
2 | 7 |
------------------------------------ |
3 | 8 |
* clamav-milter/netcode.c:: fix logic bug in nc_recv (bb#1524) |
... | ... |
@@ -75,6 +75,7 @@ struct CLAMFI { |
75 | 75 |
unsigned int totsz; |
76 | 76 |
unsigned int bufsz; |
77 | 77 |
unsigned int all_whitelisted; |
78 |
+ unsigned int gotbody; |
|
78 | 79 |
}; |
79 | 80 |
|
80 | 81 |
|
... | ... |
@@ -117,13 +118,20 @@ static void nullify(SMFICTX *ctx, struct CLAMFI *cf, enum CFWHAT closewhat) { |
117 | 117 |
|
118 | 118 |
|
119 | 119 |
static sfsistat sendchunk(struct CLAMFI *cf, unsigned char *bodyp, size_t len, SMFICTX *ctx) { |
120 |
- if(cf->totsz >= maxfilesize) |
|
120 |
+ if(cf->totsz >= maxfilesize || len == 0) |
|
121 | 121 |
return SMFIS_CONTINUE; |
122 | 122 |
|
123 |
- if(!cf->totsz && nc_connect_rand(&cf->main, &cf->alt, &cf->local)) { |
|
124 |
- logg("!Failed to initiate streaming/fdpassing\n"); |
|
125 |
- nullify(ctx, cf, CF_NONE); |
|
126 |
- return FailAction; |
|
123 |
+ if(!cf->totsz) { |
|
124 |
+ sfsistat ret; |
|
125 |
+ if(nc_connect_rand(&cf->main, &cf->alt, &cf->local)) { |
|
126 |
+ logg("!Failed to initiate streaming/fdpassing\n"); |
|
127 |
+ nullify(ctx, cf, CF_NONE); |
|
128 |
+ return FailAction; |
|
129 |
+ } |
|
130 |
+ cf->totsz = 1; /* do not infloop */ |
|
131 |
+ if((ret = sendchunk(cf, (unsigned char *)"From clamav-milter\n", 19, ctx)) != SMFIS_CONTINUE) |
|
132 |
+ return ret; |
|
133 |
+ cf->totsz -= 1; |
|
127 | 134 |
} |
128 | 135 |
|
129 | 136 |
if(cf->totsz + len > maxfilesize) |
... | ... |
@@ -176,30 +184,28 @@ sfsistat clamfi_header(SMFICTX *ctx, char *headerf, char *headerv) { |
176 | 176 |
if(!(cf = (struct CLAMFI *)smfi_getpriv(ctx))) |
177 | 177 |
return SMFIS_CONTINUE; /* whatever */ |
178 | 178 |
|
179 |
- if(loginfected == LOGINF_FULL) { |
|
180 |
- if(headerf && !strcasecmp(headerf, "Subject") && !cf->msg_subj) |
|
181 |
- cf->msg_subj = strdup(headerv); |
|
182 |
- if(headerf && !strcasecmp(headerf, "Date") && !cf->msg_date) |
|
183 |
- cf->msg_date = strdup(headerv); |
|
184 |
- if(headerf && !strcasecmp(headerf, "Message-ID") && !cf->msg_id) |
|
185 |
- cf->msg_id = strdup(headerv); |
|
179 |
+ if(!cf->totsz && cf->all_whitelisted) { |
|
180 |
+ logg("*Skipping scan (all destinations whitelisted)\n"); |
|
181 |
+ nullify(ctx, cf, CF_NONE); |
|
182 |
+ return SMFIS_ACCEPT; |
|
186 | 183 |
} |
187 | 184 |
|
188 |
- if(!cf->totsz) { |
|
189 |
- if(cf->all_whitelisted) { |
|
190 |
- logg("*Skipping scan (all destinations whitelisted)\n"); |
|
191 |
- nullify(ctx, cf, CF_NONE); |
|
192 |
- return SMFIS_ACCEPT; |
|
193 |
- } |
|
194 |
- if((ret = sendchunk(cf, (unsigned char *)"From clamav-milter\n", 19, ctx)) != SMFIS_CONTINUE) |
|
195 |
- return ret; |
|
185 |
+ if(!headerf) return SMFIS_CONTINUE; /* just in case */ |
|
186 |
+ |
|
187 |
+ if(loginfected == LOGINF_FULL) { |
|
188 |
+ if(!cf->msg_subj && !strcasecmp(headerf, "Subject")) |
|
189 |
+ cf->msg_subj = strdup(headerv ? headerv : ""); |
|
190 |
+ if(!cf->msg_date && !strcasecmp(headerf, "Date")) |
|
191 |
+ cf->msg_date = strdup(headerv ? headerv : ""); |
|
192 |
+ if(!cf->msg_id && !strcasecmp(headerf, "Message-ID")) |
|
193 |
+ cf->msg_id = strdup(headerv ? headerv : ""); |
|
196 | 194 |
} |
197 | 195 |
|
198 | 196 |
if((ret = sendchunk(cf, (unsigned char *)headerf, strlen(headerf), ctx)) != SMFIS_CONTINUE) |
199 | 197 |
return ret; |
200 | 198 |
if((ret = sendchunk(cf, (unsigned char *)": ", 2, ctx)) != SMFIS_CONTINUE) |
201 | 199 |
return ret; |
202 |
- if((ret = sendchunk(cf, (unsigned char *)headerv, strlen(headerv), ctx)) != SMFIS_CONTINUE) |
|
200 |
+ if(headerv && (ret = sendchunk(cf, (unsigned char *)headerv, strlen(headerv), ctx)) != SMFIS_CONTINUE) |
|
203 | 201 |
return ret; |
204 | 202 |
return sendchunk(cf, (unsigned char *)"\r\n", 2, ctx); |
205 | 203 |
} |
... | ... |
@@ -210,6 +216,14 @@ sfsistat clamfi_body(SMFICTX *ctx, unsigned char *bodyp, size_t len) { |
210 | 210 |
|
211 | 211 |
if(!(cf = (struct CLAMFI *)smfi_getpriv(ctx))) |
212 | 212 |
return SMFIS_CONTINUE; /* whatever */ |
213 |
+ |
|
214 |
+ if(!cf->gotbody) { |
|
215 |
+ sfsistat ret = sendchunk(cf, (unsigned char *)"\r\n", 2, ctx); |
|
216 |
+ if(ret != SMFIS_CONTINUE) |
|
217 |
+ return ret; |
|
218 |
+ cf->gotbody = 1; |
|
219 |
+ } |
|
220 |
+ |
|
213 | 221 |
return sendchunk(cf, bodyp, len, ctx); |
214 | 222 |
} |
215 | 223 |
|
... | ... |
@@ -230,6 +244,14 @@ sfsistat clamfi_eom(SMFICTX *ctx) { |
230 | 230 |
if(!(cf = (struct CLAMFI *)smfi_getpriv(ctx))) |
231 | 231 |
return SMFIS_CONTINUE; /* whatever */ |
232 | 232 |
|
233 |
+ if(!cf->totsz) { |
|
234 |
+ /* got no headers and no body */ |
|
235 |
+ logg("*Not scanning an empty message\n"); |
|
236 |
+ ret = CleanAction(ctx); |
|
237 |
+ nullify(ctx, cf, CF_NONE); |
|
238 |
+ return ret; |
|
239 |
+ } |
|
240 |
+ |
|
233 | 241 |
if(cf->local) { |
234 | 242 |
if(nc_send(cf->main, "nFILDES\n", 8)) { |
235 | 243 |
logg("!FD scan request failed\n"); |
... | ... |
@@ -530,6 +552,7 @@ sfsistat clamfi_envfrom(SMFICTX *ctx, char **argv) { |
530 | 530 |
cf->bufsz = 0; |
531 | 531 |
cf->main = cf->alt = -1; |
532 | 532 |
cf->all_whitelisted = 1; |
533 |
+ cf->gotbody = 0; |
|
533 | 534 |
cf->msg_subj = cf->msg_date = cf->msg_id = NULL; |
534 | 535 |
smfi_setpriv(ctx, (void *)cf); |
535 | 536 |
|