Browse code

bb#1531

git-svn: trunk@5009

aCaB authored on 2009/04/02 22:36:31
Showing 2 changed files
... ...
@@ -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