--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/havp/scanners/drwebscanner.cpp Wed Jun 18 16:16:36 2014 +0200
@@ -0,0 +1,322 @@
+/***************************************************************************
+ drwebscanner.cpp - description
+ -------------------
+ begin : Sa Feb 12 2005
+ copyright : (C) 2005 by Christian Hilgers
+ email : christian@hilgers.ag
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "drwebscanner.h"
+
+/* drweb-clients-4.33-sources */
+
+/* -- SCAN_COMMANDS -------------------------------------------------- */
+#define DRWEBD_SCAN_CMD (1) /* scan file, buffer or diskfile */
+#define DRWEBD_VERSION_CMD (2) /* get daemon version */
+#define DRWEBD_BASEINFO_CMD (3) /* get info about viruses bases */
+#define DRWEBD_IDSTRING_CMD (4) /* get id-string of daemon */
+#define DRWEBD_SCANPART_CMD (5) /* scan part of diskfile */
+#define DRWEBD_SPAMCHECK_CMD (6) /* check mail by anti-spam */
+#define DRWEBD_GET_UUID_CMD (7) /* get daemon uuid (unique for each customer) */
+
+/* -- SCAN_OPTIONS ---------------------------------------------------- */
+#define DRWEBD_RETURN_VIRUSES (1<<0) /* ask daemon return to us viruses names from report */
+#define DRWEBD_RETURN_REPORT (1<<1) /* ask daemon return to us return report line */
+#define DRWEBD_RETURN_CODES (1<<2) /* ask daemon return to us return codes */
+#define DRWEBD_HEURISTIC_ON (1<<3) /* enables heuristic in finding module */
+#define DRWEBD_RULE_FILTER_ON (1<<5) /* Unix only: enables FilterRules in daemon */
+#define DRWEBD_INFECTED_CURE (1<<6) /* Unix only: try to cure infected files - if fails file decided incureable */
+#define DRWEBD_INFECTED_MOVE (1<<7) /* move infected files */
+#define DRWEBD_INFECTED_RENAME (1<<8) /* just rename infected files */
+#define DRWEBD_INFECTED_DELETE (1<<9) /* delete infected files */
+#define DRWEBD_INCURABLE_MOVE (1<<10) /* move incureable files */
+#define DRWEBD_INCURABLE_RENAME (1<<11) /* just rename incureable files */
+#define DRWEBD_INCURABLE_DELETE (1<<12) /* delete incureable files */
+#define DRWEBD_SUSPECTED_MOVE (1<<13) /* move suspicious files */
+#define DRWEBD_SUSPECTED_RENAME (1<<14) /* just rename suspicious files */
+#define DRWEBD_SUSPECTED_DELETE (1<<15) /* delete suspicious files */
+#define DRWEBD_ARCHIVE_MOVE (1<<16) /* move archive with infected/suspected files */
+#define DRWEBD_ARCHIVE_RENAME (1<<17) /* rename archive with infected/suspected files */
+#define DRWEBD_ARCHIVE_DELETE (1<<18) /* delete archive with infected/suspected files */
+#define DRWEBD_IS_MAIL (1<<19) /* Unix only: say to daemon that format is "archive MAIL" */
+#define DRWEBD_DONT_CHANGEMAIL (1<<21) /* Unix only: say to daemon that mail file cannot be changed */
+#define DRWEBD_RETURN_SHORT_VIRUSES (1<<22) /* ask daemon return to us pairs of virusnames and infection type {K|M|S} */
+#define DRWEBD_RETURN_FILTER_RULE (1<<23) /* ask daemon return to us filtering rule that has been altered */
+#define DRWEBD_HAVE_ENVELOPE (1<<24) /* say to daemon that filter will send mail envelope */
+#define DRWEBD_CHECK_ARX (1<<25) /* Windows only: say to WinEngine scans into archives (RAR,ZIP etc) */
+#define DRWEBD_USE_TCPNODELAY (1<<26) /* use TCP_NODELAY option */
+#define DRWEBD_HAVE_EXTENDED (1<<31) /* client knows about extended options */
+
+/* -- SCAN_EXTENDED_OPTIONS ------------------------------------------- */
+#define DRWEBD_EXT_ADWARE_IGNORE (1<<1) /* ignore adware */
+#define DRWEBD_EXT_ADWARE_MOVE (1<<2) /* move adware */
+#define DRWEBD_EXT_ADWARE_RENAME (1<<3) /* rename adware */
+#define DRWEBD_EXT_ADWARE_DELETE (1<<4) /* delete adware */
+#define DRWEBD_EXT_DIALER_IGNORE (1<<5) /* ignore adware */
+#define DRWEBD_EXT_DIALER_MOVE (1<<6) /* move adware */
+#define DRWEBD_EXT_DIALER_RENAME (1<<7) /* rename adware */
+#define DRWEBD_EXT_DIALER_DELETE (1<<8) /* delete adware */
+#define DRWEBD_EXT_JOKE_IGNORE (1<<9) /* ignore adware */
+#define DRWEBD_EXT_JOKE_MOVE (1<<10) /* move adware */
+#define DRWEBD_EXT_JOKE_RENAME (1<<11) /* rename adware */
+#define DRWEBD_EXT_JOKE_DELETE (1<<12) /* delete adware */
+#define DRWEBD_EXT_RISKWARE_IGNORE (1<<13) /* ignore adware */
+#define DRWEBD_EXT_RISKWARE_MOVE (1<<14) /* move adware */
+#define DRWEBD_EXT_RISKWARE_RENAME (1<<15) /* rename adware */
+#define DRWEBD_EXT_RISKWARE_DELETE (1<<16) /* delete adware */
+#define DRWEBD_EXT_HACKTOOL_IGNORE (1<<17) /* ignore adware */
+#define DRWEBD_EXT_HACKTOOL_MOVE (1<<18) /* move adware */
+#define DRWEBD_EXT_HACKTOOL_RENAME (1<<19) /* rename adware */
+#define DRWEBD_EXT_HACKTOOL_DELETE (1<<20) /* delete adware */
+
+/* -- SCAN_RESULT ----------------------------------------------------- */
+#define DERR_NOERROR (0) /*= 0x00000000 */
+#define DERR_READ_ERR (1<<0) /*= 0x00000001 */
+#define DERR_WRITE_ERR (1<<1) /*= 0x00000002 */
+#define DERR_NOMEMORY (1<<2) /*= 0x00000004 */
+#define DERR_CRC_ERROR (1<<3) /*= 0x00000008 */
+#define DERR_READSOCKET (1<<4) /*= 0x00000010 */
+#define DERR_KNOWN_VIRUS (1<<5) /*= 0x00000020 */
+#define DERR_UNKNOWN_VIRUS (1<<6) /*= 0x00000040 */
+#define DERR_VIRUS_MODIFICATION (1<<7) /*= 0x00000080 */
+#define DERR_HAVE_CURED (1<<8) /*= 0x00000100 */
+#define DERR_TIMEOUT (1<<9) /*= 0x00000200 */
+#define DERR_SYMLINK (1<<10) /*= 0x00000400 */
+#define DERR_NO_REGFILE (1<<11) /*= 0x00000800 */
+#define DERR_SKIPPED (1<<12) /*= 0x00001000 */
+#define DERR_TOO_BIG (1<<13) /*= 0x00002000 */
+#define DERR_TOO_COMPRESSED (1<<14) /*= 0x00004000 */
+#define DERR_BAD_CALL (1<<15) /*= 0x00008000 */
+#define DERR_EVAL_KEY (1<<16) /*= 0x00010000 */
+#define DERR_FILTER_REJECT (1<<17) /*= 0x00020000 */
+#define DERR_ARCHIVE_LEVEL (1<<18) /*= 0x00040000 */
+#define DERR_HAVE_DELETED (1<<19) /*= 0x00080000 */
+#define DERR_IS_CLEAN (1<<20) /*= 0x00100000 */
+#define DERR_LICENSE_ERROR (1<<21) /*= 0x00200000 */
+#define DERR_ADWARE (1<<22) /*= 0x00400000 */
+#define DERR_DIALER (1<<23) /*= 0x00800000 */
+#define DERR_JOKE (1<<24) /*= 0x01000000 */
+#define DERR_RISKWARE (1<<25) /*= 0x02000000 */
+#define DERR_HACKTOOL (1<<26) /*= 0x04000000 */
+#define DERR_MASK (0x0FFFFFFF)
+#define DERR_NON_DAEMON_ERROR (~DERR_MASK)
+#define DERR_INFECTED (DERR_KNOWN_VIRUS | DERR_VIRUS_MODIFICATION)
+#define DERR_SUSPICIOUS (DERR_UNKNOWN_VIRUS)
+#define DERR_MALWARE (DERR_ADWARE | DERR_DIALER | DERR_JOKE | DERR_RISKWARE | DERR_HACKTOOL)
+#define DERR_VIRUS_MASK (DERR_INFECTED | DERR_SUSPICIOUS | DERR_MALWARE)
+#define DERR_SKIP_OBJECT (DERR_SYMLINK | DERR_NO_REGFILE | DERR_SKIPPED | DERR_CRC_ERROR | DERR_TIMEOUT)
+#define DERR_ARCHIVE_RESTRICTION (DERR_TOO_BIG | DERR_TOO_COMPRESSED | DERR_ARCHIVE_LEVEL)
+#define DERR_DAEMON_ERROR (DERR_READ_ERR | DERR_WRITE_ERR | DERR_NOMEMORY | DERR_READSOCKET | DERR_BAD_CALL)
+
+
+bool DrwebScanner::InitDatabase()
+{
+ return true;
+}
+
+
+int DrwebScanner::ReloadDatabase()
+{
+ return 0;
+}
+
+
+string DrwebScanner::Scan( const char *FileName )
+{
+ if ( ConnectScanner() == false )
+ {
+ ScannerAnswer = "2Could not connect to scanner socket";
+ return ScannerAnswer;
+ }
+
+ //Construct command for scanner
+ int scan_cmd = htonl( DRWEBD_SCAN_CMD );
+ int scan_flags = htonl( Opts );
+ int scan_slen = htonl( strlen(FileName) );
+ int scan_null = htonl( 0x0000 );
+
+ if ( Scanner.Send( (const char*)&scan_cmd, sizeof(scan_cmd) ) == false ||
+ Scanner.Send( (const char*)&scan_flags, sizeof(scan_flags) ) == false ||
+ Scanner.Send( (const char*)&scan_slen, sizeof(scan_slen) ) == false ||
+ Scanner.Send( FileName, strlen(FileName) ) == false ||
+ Scanner.Send( (const char*)&scan_null, sizeof(scan_null) ) == false )
+ {
+ Scanner.Close();
+ LogFile::ErrorMessage("Drweb: Could not write command to scanner\n");
+ ScannerAnswer = "2Scanner connection failed";
+ return ScannerAnswer;
+ }
+
+ int scan_rc, scan_vnum;
+ ssize_t read;
+
+ if ( (read = recv( Scanner.sock_fd, &scan_rc, sizeof(scan_rc), 0 )) != sizeof(scan_rc) )
+ {
+ Scanner.Close();
+ LogFile::ErrorMessage("Drweb: Could not read scanner response (rc, read: %d errno: %d)\n", read, errno);
+ ScannerAnswer = "2Could not read scanner response";
+ return ScannerAnswer;
+ }
+ if ( (read = recv( Scanner.sock_fd, &scan_vnum, sizeof(scan_vnum), 0 )) != sizeof(scan_vnum) )
+ {
+ Scanner.Close();
+ LogFile::ErrorMessage("Drweb: Could not read scanner response (vnum, read: %d errno: %d)\n", read, errno);
+ ScannerAnswer = "2Could not read scanner response";
+ return ScannerAnswer;
+ }
+
+ scan_rc = ntohl(scan_rc);
+ scan_vnum = ntohl(scan_vnum);
+
+ if ( scan_rc == DERR_IS_CLEAN ||
+ scan_rc & DERR_ARCHIVE_RESTRICTION ||
+ scan_rc & DERR_SKIP_OBJECT
+ )
+ {
+ Scanner.Close();
+ ScannerAnswer = "0Clean";
+ return ScannerAnswer;
+ }
+
+ char code[512];
+ memset(&code, 0, sizeof(code));
+ snprintf(code, 500, "%d", scan_rc);
+ string Code = code;
+
+ if (scan_rc & DERR_INFECTED || scan_rc & DERR_SUSPICIOUS ||
+ (Params::GetConfigBool("DRWEBMALWARE") && scan_rc & DERR_MALWARE) )
+ {
+ ScannerAnswer = "1unknown (" + Code + ")";
+ string VirusNames = "";
+
+ for (int i=0;i<scan_vnum;i++)
+ {
+ char vname[256];
+ memset(&vname, 0, sizeof(vname));
+
+ if ( (read = recv( Scanner.sock_fd, &scan_slen, sizeof(scan_slen), 0 )) != sizeof(scan_slen) )
+ {
+ Scanner.Close();
+ LogFile::ErrorMessage("Drweb: Could not read scanner response (vnamelen, read: %d errno: %d)\n", read, errno);
+ return ScannerAnswer;
+ }
+
+ scan_slen = ntohl(scan_slen);
+ if ( scan_slen > 250 ) scan_slen = 250;
+
+ if ( (read = recv( Scanner.sock_fd, &vname, scan_slen, 0 )) != scan_slen )
+ {
+ Scanner.Close();
+ LogFile::ErrorMessage("Drweb: Could not read scanner response (vname, read: %d errno: %d)\n", read, errno);
+ return ScannerAnswer;
+ }
+
+ string tmp = vname;
+ if (i==0) { VirusNames = tmp; } else { VirusNames += ", " + tmp; }
+ }
+
+ SearchReplace( VirusNames, "infected with ", "" );
+ if ( VirusNames != "" ) ScannerAnswer = "1" + VirusNames;
+ }
+ else if (scan_rc & DERR_DAEMON_ERROR)
+ {
+ if (scan_rc & DERR_READ_ERR)
+ {
+ ScannerAnswer = "2Daemon could not read tempfile";
+ }
+ else
+ {
+ ScannerAnswer = "2Daemon error (" + Code + ")";
+ }
+ }
+ else
+ {
+ ScannerAnswer = "2Unknown error (" + Code + ")";
+ }
+
+ Scanner.Close();
+ return ScannerAnswer;
+}
+
+
+void DrwebScanner::FreeDatabase()
+{
+}
+
+
+bool DrwebScanner::ConnectScanner()
+{
+ bool SockAnswer;
+
+ if ( UseSocket )
+ {
+ SockAnswer = Scanner.ConnectToSocket( Params::GetConfigString("DRWEBSOCKET"), 1 );
+ }
+ else
+ {
+ SockAnswer = Scanner.ConnectToServer();
+ }
+
+ if ( SockAnswer == false )
+ {
+ //Prevent log flooding, show error only once per minute
+ if ( (LastError == 0) || (LastError + 60 < time(NULL)) )
+ {
+ LogFile::ErrorMessage("Drweb: Could not connect to scanner! Scanner down?\n");
+ LastError = time(NULL);
+ }
+
+ return false;
+ }
+
+ return true;
+}
+
+
+//Constructor
+DrwebScanner::DrwebScanner()
+{
+ ScannerName = "Drweb Socket Scanner";
+ ScannerNameShort = "Drweb";
+
+ LastError = 0;
+
+ if ( Params::GetConfigString("DRWEBSERVER") != "" )
+ {
+ UseSocket = false;
+
+ if ( Scanner.SetDomainAndPort( Params::GetConfigString("DRWEBSERVER"), Params::GetConfigInt("DRWEBPORT") ) == false )
+ {
+ LogFile::ErrorMessage("Drweb: Could not resolve scanner host\n");
+ }
+ }
+ else
+ {
+ UseSocket = true;
+ }
+
+ Opts = DRWEBD_RETURN_VIRUSES;
+
+ if ( Params::GetConfigBool("DRWEBHEURISTIC") == true )
+ {
+ Opts = Opts | DRWEBD_HEURISTIC_ON;
+ }
+
+ ScannerAnswer.reserve(100);
+}
+
+
+//Destructor
+DrwebScanner::~DrwebScanner()
+{
+}
+