git-svn: trunk@4790
aCaB authored on 2009/02/15 23:57:22... | ... |
@@ -55,7 +55,7 @@ struct smfiDesc descr = { |
55 | 55 |
NULL, /* end of header */ |
56 | 56 |
clamfi_body, /* body block */ |
57 | 57 |
clamfi_eom, /* end of message */ |
58 |
- NULL, /* message aborted */ |
|
58 |
+ clamfi_abort, /* message aborted */ |
|
59 | 59 |
NULL, /* connection cleanup */ |
60 | 60 |
NULL, /* any unrecognized or unimplemented command filter */ |
61 | 61 |
NULL, /* SMTP DATA command filter */ |
... | ... |
@@ -71,6 +71,24 @@ static void add_x_header(SMFICTX *ctx, char *st) { |
71 | 71 |
smfi_chgheader(ctx, (char *)"X-Virus-Status", 1, st); |
72 | 72 |
} |
73 | 73 |
|
74 |
+enum CFWHAT { |
|
75 |
+ CF_NONE, /* 0 */ |
|
76 |
+ CF_MAIN, /* 1 */ |
|
77 |
+ CF_ALT, /* 2 */ |
|
78 |
+ CF_BOTH, /* 3 */ |
|
79 |
+ CF_ANY /* 4 */ |
|
80 |
+}; |
|
81 |
+ |
|
82 |
+ |
|
83 |
+static void nullify(SMFICTX *ctx, struct CLAMFI *cf, enum CFWHAT closewhat) { |
|
84 |
+ if(closewhat & CF_MAIN || ((closewhat & CF_ANY) && cf->main >= 0)) |
|
85 |
+ close(cf->main); |
|
86 |
+ if(closewhat & CF_ALT || ((closewhat & CF_ANY) && cf->alt >= 0)) |
|
87 |
+ close(cf->alt); |
|
88 |
+ smfi_setpriv(ctx, NULL); |
|
89 |
+ free(cf); |
|
90 |
+} |
|
91 |
+ |
|
74 | 92 |
|
75 | 93 |
static sfsistat sendchunk(struct CLAMFI *cf, unsigned char *bodyp, size_t len, SMFICTX *ctx) { |
76 | 94 |
if(cf->totsz >= maxfilesize) |
... | ... |
@@ -86,10 +104,7 @@ static sfsistat sendchunk(struct CLAMFI *cf, unsigned char *bodyp, size_t len, S |
86 | 86 |
|
87 | 87 |
if (n==-1) { |
88 | 88 |
logg("!Failed to write temporary file\n"); |
89 |
- close(cf->main); |
|
90 |
- close(cf->alt); |
|
91 |
- smfi_setpriv(ctx, NULL); |
|
92 |
- free(cf); |
|
89 |
+ nullify(ctx, cf, CF_BOTH); |
|
93 | 90 |
return FailAction; |
94 | 91 |
} |
95 | 92 |
len -= n; |
... | ... |
@@ -114,9 +129,7 @@ static sfsistat sendchunk(struct CLAMFI *cf, unsigned char *bodyp, size_t len, S |
114 | 114 |
} |
115 | 115 |
if(sendfailed) { |
116 | 116 |
logg("!Streaming failed\n"); |
117 |
- close(cf->main); |
|
118 |
- smfi_setpriv(ctx, NULL); |
|
119 |
- free(cf); |
|
117 |
+ nullify(ctx, cf, CF_MAIN); |
|
120 | 118 |
return FailAction; |
121 | 119 |
} |
122 | 120 |
} |
... | ... |
@@ -134,14 +147,12 @@ sfsistat clamfi_header(SMFICTX *ctx, char *headerf, char *headerv) { |
134 | 134 |
if(!cf->totsz) { |
135 | 135 |
if(cf->all_whitelisted) { |
136 | 136 |
logg("*Skipping scan (all destinations whitelisted)\n"); |
137 |
- smfi_setpriv(ctx, NULL); |
|
138 |
- free(cf); |
|
137 |
+ nullify(ctx, cf, CF_NONE); |
|
139 | 138 |
return SMFIS_ACCEPT; |
140 | 139 |
} |
141 | 140 |
if(nc_connect_rand(&cf->main, &cf->alt, &cf->local)) { |
142 | 141 |
logg("!Failed to initiate streaming/fdpassing\n"); |
143 |
- smfi_setpriv(ctx, NULL); |
|
144 |
- free(cf); |
|
142 |
+ nullify(ctx, cf, CF_NONE); |
|
145 | 143 |
return FailAction; |
146 | 144 |
} |
147 | 145 |
if((ret = sendchunk(cf, (unsigned char *)"From clamav-milter\n", 19, ctx)) != SMFIS_CONTINUE) |
... | ... |
@@ -167,6 +178,14 @@ sfsistat clamfi_body(SMFICTX *ctx, unsigned char *bodyp, size_t len) { |
167 | 167 |
} |
168 | 168 |
|
169 | 169 |
|
170 |
+sfsistat clamfi_abort(SMFICTX *ctx) { |
|
171 |
+ struct CLAMFI *cf; |
|
172 |
+ |
|
173 |
+ if((cf = (struct CLAMFI *)smfi_getpriv(ctx))) |
|
174 |
+ nullify(ctx, cf, CF_ANY); |
|
175 |
+ return SMFIS_CONTINUE; |
|
176 |
+} |
|
177 |
+ |
|
170 | 178 |
sfsistat clamfi_eom(SMFICTX *ctx) { |
171 | 179 |
struct CLAMFI *cf; |
172 | 180 |
char *reply; |
... | ... |
@@ -178,9 +197,7 @@ sfsistat clamfi_eom(SMFICTX *ctx) { |
178 | 178 |
if(cf->local) { |
179 | 179 |
if(nc_send(cf->main, "nFILDES\n", 8)) { |
180 | 180 |
logg("!FD scan request failed\n"); |
181 |
- close(cf->alt); |
|
182 |
- smfi_setpriv(ctx, NULL); |
|
183 |
- free(cf); |
|
181 |
+ nullify(ctx, cf, CF_ALT); |
|
184 | 182 |
return FailAction; |
185 | 183 |
} |
186 | 184 |
|
... | ... |
@@ -188,17 +205,13 @@ sfsistat clamfi_eom(SMFICTX *ctx) { |
188 | 188 |
|
189 | 189 |
if(nc_sendmsg(cf->main, cf->alt) == -1) { |
190 | 190 |
logg("!FD send failed\n"); |
191 |
- close(cf->alt); |
|
192 |
- smfi_setpriv(ctx, NULL); |
|
193 |
- free(cf); |
|
191 |
+ nullify(ctx, cf, CF_ALT); |
|
194 | 192 |
return FailAction; |
195 | 193 |
} |
196 | 194 |
} else { |
197 | 195 |
if(cf->bufsz && nc_send(cf->alt, cf->buffer, cf->bufsz)) { |
198 | 196 |
logg("!Failed to flush STREAM\n"); |
199 |
- close(cf->main); |
|
200 |
- smfi_setpriv(ctx, NULL); |
|
201 |
- free(cf); |
|
197 |
+ nullify(ctx, cf, CF_MAIN); |
|
202 | 198 |
return FailAction; |
203 | 199 |
} |
204 | 200 |
close(cf->alt); |
... | ... |
@@ -209,15 +222,14 @@ sfsistat clamfi_eom(SMFICTX *ctx) { |
209 | 209 |
if(cf->local) |
210 | 210 |
close(cf->alt); |
211 | 211 |
|
212 |
+ cf->alt = -1; |
|
213 |
+ |
|
212 | 214 |
if(!reply) { |
213 | 215 |
logg("!No reply from clamd\n"); |
214 |
- smfi_setpriv(ctx, NULL); |
|
215 |
- free(cf); |
|
216 |
+ nullify(ctx, cf, CF_NONE); |
|
216 | 217 |
return FailAction; |
217 | 218 |
} |
218 |
- close(cf->main); |
|
219 |
- smfi_setpriv(ctx, NULL); |
|
220 |
- free(cf); |
|
219 |
+ nullify(ctx, cf, CF_MAIN); |
|
221 | 220 |
|
222 | 221 |
len = strlen(reply); |
223 | 222 |
if(len>5 && !strcmp(reply + len - 5, ": OK\n")) { |
... | ... |
@@ -392,6 +404,7 @@ sfsistat clamfi_envfrom(SMFICTX *ctx, char **argv) { |
392 | 392 |
} |
393 | 393 |
cf->totsz = 0; |
394 | 394 |
cf->bufsz = 0; |
395 |
+ cf->main = cf->alt = -1; |
|
395 | 396 |
cf->all_whitelisted = 1; |
396 | 397 |
smfi_setpriv(ctx, (void *)cf); |
397 | 398 |
|
... | ... |
@@ -30,6 +30,7 @@ extern char xvirushdr[255]; |
30 | 30 |
|
31 | 31 |
|
32 | 32 |
sfsistat clamfi_body(SMFICTX *ctx, unsigned char *bodyp, size_t len); |
33 |
+sfsistat clamfi_abort(SMFICTX *ctx); |
|
33 | 34 |
sfsistat clamfi_eom(SMFICTX *ctx); |
34 | 35 |
sfsistat clamfi_header(SMFICTX *ctx, char *headerf, char *headerv); |
35 | 36 |
sfsistat clamfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr); |