[Avcheck] patch (clamav)

Piotr Klaban makler+avcheck at man.torun.pl
Tue Mar 2 14:38:37 MSK 2004


On Tue, Feb 24, 2004 at 03:15:50PM +0300, Michael Tokarev wrote:
> How does clamav return message looks like?
> 
> It seems unsafe to
> 
>  a) search for "OK" (it may be part of virus name for example)

Right it is better to search for OK\n etc.
I enclose a similar patch for clamav that I made some time ago.
It is a bit different from Ilya Kiselyov's patch:
- it checks for \n at the end of the clamav message and space
  in the beggining
- it uses CONTSCAN command instead of SCAN, but it is better to use
  just SCAN (as in Ilya Kiselyov's patch) - with "SCAN" clamav
  would stop checking of the message when first virus is found
- it uses file socket instead of TCP socket

>  b) assume that "ERROR" (and the like) is placed AFTER the
>    beginning of message buffer, not exactly AT the beginning
>    *(q-1)='\0' assumes that there's some text BEFORE "ERROR").
> 
> If the message looks like:
> 
>  filename: OK\n
>  filename: foobar virus FOUND\n
> 
> then the code should strip out the "filename: " part
> and return the rest of the line, together with " FOUND"
> etc.

My patch discards " FOUND" when virus is found.

> So, how does clamav messages looks like?

E.g.:

/path/eicar.com: Eicar-Test-Signature FOUND

 From clamd/scanner.c:

 mdprintf(odesc, "%s: Can't access the file ERROR\n", filename);
 mdprintf(odesc, "%s: Can't lstat() the file ERROR\n", filename);
 mdprintf(odesc, "%s: Empty file\n", filename)
 mdprintf(odesc, "%s: %s FOUND\n", filename, virname);
 mdprintf(odesc, "%s: %s ERROR\n", filename, cl_strerror(ret));
 mdprintf(odesc, "%s: OK\n", filename);

Best regards,

-- 
Piotr Klaban
-------------- next part --------------
diff -ruwp avcheck-0.9pre2/avcheck.c avcheck-0.9pre2-new/avcheck.c
--- avcheck-0.9pre2/avcheck.c	Sat Jul 27 14:52:06 2002
+++ avcheck-0.9pre2-new/avcheck.c	Fri Oct 10 11:46:57 2003
@@ -43,6 +43,9 @@
 #ifndef TROPHIE
 # define TROPHIE 0  /* trophie can't handle MIME */
 #endif
+#ifndef CLAMAV
+# define CLAMAV 1
+#endif
 
 static char *progname;
 static char *path;		/* temporary file name */
@@ -677,6 +680,58 @@ scan_sophie_trophie(int fd, const char *
 
 #endif /* SOPHIE_TROPHIE */
 
+#if CLAMAV
+static int
+scan_clamav(int fd, const char *path, const char *avname) {
+  int l;
+  char *p, *r;
+
+  l = strlen(path);
+  memcpy(buf, "CONTSCAN ", 9);
+  memcpy(buf+9, path, l);
+  l+=9;
+  buf[l++] = '\n';
+  if (write(fd, buf, l) != l)
+    err(l < 0 ? errno : 0, "unable to send a command to %s", avname);
+  printf("write %s\n", buf);
+
+#define sp_msg "Infected by "
+#define sp_extra sizeof(sp_msg)
+
+  r = buf + sp_extra;
+  if ((l = read(fd, r, sizeof(buf) - 1 - sp_extra)) < 1)
+    err(l < 0 ? errno : 0, "unable to read answer from %s", avname);
+  if (*r == '0')
+    return 0;
+  r[l] = '\0';
+  if ((p = strstr(r, " OK\n")) != NULL)
+    return 0;
+  if ((p = strstr(r, " FOUND\n")) != NULL) {
+    *p = '\0';
+  } else {
+    if ((p = strstr(r, " ERROR\n")) != NULL) {
+      *p = '\0';
+      err(0, "error in %s: return message %s", avname, r);
+    }
+  }
+  if ((p = strchr(r, '\n')) != NULL)
+    *p = '\0';
+  if (*r == '-')
+    err(0, "error in %s: return code %s", avname, r);
+  if ((p = strchr(r, ':')) != NULL) {
+    ++p;
+    while(*p == ' ' || *p == '\t') ++p;
+    if (*p)
+      sprintf(buf, "%s%s", sp_msg, p);
+    else
+      *buf = '\0';
+  }
+  else
+    *buf = '\0';
+  return 1;
+}
+#endif /* CLAMAV */
+
 static const struct avengine {
   const char *name;
   char *defsock;
@@ -693,6 +748,9 @@ static const struct avengine {
 #endif
 #if TROPHIE
   { "Trophie", "/var/run/trophie", scan_sophie_trophie },
+#endif
+#if CLAMAV
+  { "Clamav", "/var/run/clamd.sock", scan_clamav },
 #endif
   { NULL, NULL, NULL }
 };


More information about the Avcheck mailing list