summaryrefslogtreecommitdiff
path: root/src/clamsmtpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/clamsmtpd.c')
-rw-r--r--src/clamsmtpd.c77
1 files changed, 67 insertions, 10 deletions
diff --git a/src/clamsmtpd.c b/src/clamsmtpd.c
index 93d773f..52921dc 100644
--- a/src/clamsmtpd.c
+++ b/src/clamsmtpd.c
@@ -58,6 +58,12 @@
* STRUCTURES
*/
+enum {
+ ACTION_DROP,
+ ACTION_BOUNCE,
+ ACTION_PASS
+};
+
typedef struct clstate
{
/* Settings ------------------------------- */
@@ -65,9 +71,10 @@ typedef struct clstate
const char* clamname;
const char* directory; /* The directory for temp files */
const char* virusaction; /* Program to run when event occurs */
- int bounce; /* Send back a reject line */
+ int action; /* Which action to take on a virus */
int quarantine; /* Leave virus files in temp dir */
int debug_files; /* Leave all files in temp dir */
+ const char* header; /* A header to include in emails */
}
clstate_t;
@@ -102,6 +109,7 @@ clctx_t;
#define DEFAULT_CONFIG CONF_PREFIX "/clamsmtpd.conf"
#define DEFAULT_CLAMAV "/var/run/clamav/clamd"
#define DEFAULT_HEADER "X-Virus-Scanned: ClamAV using ClamSMTP"
+#define VIRUS_HEADER "X-Virus-Infected: Virus Detected!"
/* -----------------------------------------------------------------------
* CONFIGURATION OPTIONS
@@ -122,11 +130,17 @@ clctx_t;
#define CFG_DIRECTORY "TempDirectory"
#define CFG_HEADER "Header"
#define CFG_SCANHEADER "ScanHeader"
+#define CFG_HEADER "Header"
#define CFG_BOUNCE "Bounce"
+#define CFG_ACTION "Action"
#define CFG_QUARANTINE "Quarantine"
#define CFG_DEBUGFILES "DebugFiles"
#define CFG_VIRUSACTION "VirusAction"
+#define VAL_BOUNCE "bounce"
+#define VAL_DROP "drop"
+#define VAL_PASS "pass"
+
/* -----------------------------------------------------------------------
* GLOBALS
*/
@@ -208,7 +222,7 @@ int main(int argc, char* argv[])
warnargs = 1;
break;
- /* Don't daemonize */
+ /* Don't daemonize */
case 'd':
dbg_level = strtol(optarg, &t, 10);
if(*t) /* parse error */
@@ -366,7 +380,7 @@ int cb_check_data(spctx_t* sp)
* and transfer the file to it.
*/
case 0:
- if(sp_done_data(sp) == -1)
+ if(sp_done_data(sp, g_clstate.header) == -1)
return -1;
break;
@@ -380,9 +394,25 @@ int cb_check_data(spctx_t* sp)
/* Any special post operation actions on the virus */
virus_action(ctx, virus);
- if(sp_fail_data(sp, g_clstate.bounce ?
- SMTP_DATAVIRUS : SMTP_DATAVIRUSOK) == -1)
- return -1;
+ switch(g_clstate.action)
+ {
+ case ACTION_DROP:
+ if(sp_fail_data(sp, SMTP_DATAVIRUSOK) == -1)
+ return -1;
+ break;
+ case ACTION_BOUNCE:
+ if(sp_fail_data(sp, SMTP_DATAVIRUS) == -1)
+ return -1;
+ break;
+ case ACTION_PASS:
+ if(sp_done_data(sp, VIRUS_HEADER) == -1)
+ return -1;
+ break;
+ default:
+ ASSERT(0 && "Invalid action");
+ break;
+ }
+
break;
default:
@@ -403,11 +433,21 @@ int cb_parse_option(const char* name, const char* value)
return 1;
}
- /* COMPAT: Parse old header option */
+ /* COMPAT: Parse old header option */
else if(strcasecmp(CFG_SCANHEADER, name) == 0)
{
warnx("please use \"Header\" option instead of \"ScanHeader\"");
- return sp_parse_option(CFG_HEADER, value);
+ g_clstate.header = trim_start(value);
+ if(strlen(g_clstate.header) == 0)
+ g_clstate.header = NULL;
+ }
+
+ else if(strcasecmp(CFG_HEADER, name) == 0)
+ {
+ g_clstate.header = trim_start(value);
+ if(strlen(g_clstate.header) == 0)
+ g_clstate.header = NULL;
+ return 1;
}
else if(strcasecmp(CFG_DIRECTORY, name) == 0)
@@ -416,17 +456,34 @@ int cb_parse_option(const char* name, const char* value)
return 1;
}
+ /* COMPAT: Subsumed by the 'Action' option */
else if(strcasecmp(CFG_BOUNCE, name) == 0)
{
- if((g_clstate.bounce = strtob(value)) == -1)
+ int bounce = strtob(value);
+ if(bounce == -1)
errx(2, "invalid value for " CFG_BOUNCE);
+ if(bounce)
+ g_clstate.action = ACTION_BOUNCE;
+ warnx("please use \"Action\" option instead of \"Bounce\"");
return 1;
}
+ else if(strcasecmp(CFG_ACTION, name) == 0)
+ {
+ if(strcasecmp(VAL_BOUNCE, value) == 0)
+ g_clstate.action = ACTION_BOUNCE;
+ else if(strcasecmp(VAL_DROP, value) == 0)
+ g_clstate.action = ACTION_DROP;
+ else if(strcasecmp(VAL_PASS, value) == 0)
+ g_clstate.action = ACTION_PASS;
+ else
+ errx(2, "invalid value for " CFG_ACTION);
+ }
+
else if(strcasecmp(CFG_QUARANTINE, name) == 0)
{
if((g_clstate.quarantine = strtob(value)) == -1)
- errx(2, "invalid value for " CFG_BOUNCE);
+ errx(2, "invalid value for " CFG_QUARANTINE);
return 1;
}