havp/scanners/arcavirscanner.cpp
changeset 0 8baf084f58c5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/havp/scanners/arcavirscanner.cpp	Wed Jun 18 16:16:36 2014 +0200
@@ -0,0 +1,240 @@
+/***************************************************************************
+                          arcavirscanner.cpp  -  description
+                             -------------------
+    begin                : Sa Feb 12 2005
+    copyright            : (C) 2005 by Christian Hilgers
+    email                : christian@hilgers.ag
+
+ Help for Version 2008 received from Anthony Have (a.have@sysun-technologies.com)
+
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "arcavirscanner.h"
+
+
+bool ArcavirScanner::InitDatabase()
+{
+    return true;
+}
+
+
+int ArcavirScanner::ReloadDatabase()
+{
+    return 0;
+}
+
+string ArcavirScanner::Scan( const char *FileName )
+{
+    if ( Connected == false && ConnectScanner() == false )
+    {
+        ScannerAnswer = "2Could not connect to scanner";
+        return ScannerAnswer;
+    }
+
+    if ( Version == 2008 ) return ScanV2008( FileName );
+
+    return ScanV2007( FileName );
+}
+
+string ArcavirScanner::ScanV2008( const char *FileName )
+{
+    //Scan command
+    string ScannerCmd = "SCAN ";
+    ScannerCmd += FileName;
+    ScannerCmd += "\n";
+
+    //Send command
+    if ( Scanner.Send( ScannerCmd ) == false )
+    {
+        Scanner.Close();
+
+        //Retry one time
+        if ( ConnectScanner() == false || Scanner.Send( ScannerCmd ) == false )
+        {
+            Scanner.Close();
+            Connected = false;
+            LogFile::ErrorMessage("Arcavir: Could not write command to scanner\n");
+            ScannerAnswer = "2Scanner connection failed";
+            return ScannerAnswer;
+        }
+    }
+
+    string Response;
+    string VirusName = "";
+
+    do
+    {
+        if ( Scanner.GetLine( Response, "\n", 600 ) == false )
+        {
+            Scanner.Close();
+            Connected = false;
+            LogFile::ErrorMessage("Arcavir: Could not read scanner response\n");
+            ScannerAnswer = "2Could not read scanner response";
+            return ScannerAnswer;
+        }
+
+        if ( VirusName != "" ) continue;
+
+        if ( MatchSubstr( Response, " ERROR", -1 ) )
+        {
+            Scanner.Close();
+            Connected = false;
+            LogFile::ErrorMessage("Arcavir: %s\n", Response.substr( Response.find(": ") + 2 ).c_str() );
+            ScannerAnswer = "2Scanner error";
+            return ScannerAnswer;
+        }
+
+        if ( MatchSubstr( Response, " FOUND", -1 ) )
+        {
+            string::size_type Position = Response.find(": ") + 2;
+            string::size_type PositionEnd = Response.find(" ", Position);
+            VirusName = Response.substr( Position, PositionEnd - Position );
+        }
+    }
+    while ( Response != "" && !MatchSubstr( Response, " END", -1 ) );
+
+    if ( VirusName != "" )
+    {
+        ScannerAnswer = "1" + VirusName;
+        return ScannerAnswer;
+    }
+
+    ScannerAnswer = "0Clean";
+    return ScannerAnswer;
+}
+
+
+string ArcavirScanner::ScanV2007( const char *FileName )
+{
+    //Scan command
+    string ScannerCmd = "S ";
+    ScannerCmd += FileName;
+    ScannerCmd += "\n";
+
+    //Send command
+    if ( Scanner.Send( ScannerCmd ) == false )
+    {
+        Scanner.Close();
+        Connected = false;
+
+        LogFile::ErrorMessage("Arcavir: Could not write command to scanner\n");
+        ScannerAnswer = "2Scanner connection failed";
+        return ScannerAnswer;
+    }
+
+    string Response;
+
+    if ( Scanner.GetLine( Response, "\n", 600 ) == false )
+    {
+        Scanner.Close();
+        Connected = false;
+        LogFile::ErrorMessage("Arcavir: Could not read scanner response\n");
+        ScannerAnswer = "2Could not read scanner response";
+        return ScannerAnswer;
+    }
+
+    Scanner.Close();
+    Connected = false;
+
+    //Clean
+    if ( MatchBegin( Response, "OK", 2 ) )
+    {
+        ScannerAnswer = "0Clean";
+        return ScannerAnswer;
+    }
+
+    //Infected
+    if ( MatchBegin( Response, "VIR", 3 ) )
+    {
+        ScannerAnswer = "1" + Response.substr( 4, Response.find( " ", 4 ) - 4 );
+        return ScannerAnswer;
+    }
+
+    //Error
+    if ( MatchBegin( Response, "ERR", 3 ) )
+    {
+        ScannerAnswer = "2" + Response.substr( 4, Response.find( " ", 4 ) - 4 );
+        return ScannerAnswer;
+    }
+
+    LogFile::ErrorMessage("Arcavir: Unknown response from scanner: %s\n", Response.c_str());
+    ScannerAnswer = "2Unknown scanner response";
+    return ScannerAnswer;
+}
+
+bool ArcavirScanner::ConnectScanner()
+{
+    //Connect
+    if ( Scanner.ConnectToSocket( Params::GetConfigString("ARCAVIRSOCKET"), 1 ) == false )
+    {
+        //Prevent log flooding, show error only once per minute
+        if ( (LastError == 0) || (LastError + 60 < time(NULL)) )
+        {
+            LogFile::ErrorMessage("Arcavir: Could not connect to scanner! Scanner down?\n");
+            LastError = time(NULL);
+        }
+
+        return false;
+    }
+
+    if ( Version == 2008 )
+    {
+        //Persistent connection for version 2008+
+        string ScannerCmd = "SESSION\n";
+
+        //Send command
+        if ( Scanner.Send( ScannerCmd ) == false )
+        {
+            Scanner.Close();
+            LogFile::ErrorMessage("Arcavir: Could not write command to scanner\n");
+            return false;
+        }
+    }
+    
+    Connected = true;
+    return true;
+}
+
+void ArcavirScanner::FreeDatabase()
+{
+}
+
+//Close persistent connection from HAVP scanner initialization
+//Needed because it will fork later
+void ArcavirScanner::CloseSocket()
+{
+    Scanner.Close();
+    Connected = false;
+}
+
+
+//Constructor
+ArcavirScanner::ArcavirScanner()
+{
+    ScannerName = "Arcavir Socket Scanner";
+    ScannerNameShort = "Arcavir";
+
+    Connected = false;
+
+    Version = Params::GetConfigInt("ARCAVIRVERSION");
+
+    LastError = 0;
+
+    ScannerAnswer.reserve(100);
+}
+
+
+//Destructor
+ArcavirScanner::~ArcavirScanner()
+{
+}
+