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