| ... | ... |
@@ -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 |
|