antivir.class.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <?php
  2. /* Copyright (C) 2000-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org>
  4. * Copyright (C) 2004-2009 Laurent Destailleur <eldy@users.sourceforge.net>
  5. * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  19. * or see https://www.gnu.org/
  20. */
  21. /**
  22. * \file htdocs/core/class/antivir.class.php
  23. * \brief File of class to scan viruses
  24. */
  25. /**
  26. * Class to scan for virus
  27. */
  28. class AntiVir
  29. {
  30. /**
  31. * @var string Error code (or message)
  32. */
  33. public $error = '';
  34. /**
  35. * @var string[] Error codes (or messages)
  36. */
  37. public $errors = array();
  38. /**
  39. * @var string Used to return message
  40. */
  41. public $output;
  42. /**
  43. * @var DoliDB Database handler.
  44. */
  45. public $db;
  46. /**
  47. * Constructor
  48. *
  49. * @param DoliDB $db Database handler
  50. */
  51. public function __construct($db)
  52. {
  53. $this->db = $db;
  54. }
  55. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  56. /**
  57. * Scan a file with antivirus.
  58. * This function runs the command defined in setup. This antivirus command must return 0 if OK.
  59. * Return also true (virus found) if file end with '.virus' (so we can make test safely).
  60. *
  61. * @param string $file File to scan
  62. * @return int <0 if KO (-98 if error, -99 if virus), 0 if OK
  63. */
  64. public function dol_avscan_file($file)
  65. {
  66. // phpcs:enable
  67. global $conf;
  68. $return = 0;
  69. if (preg_match('/\.virus$/i', $file)) {
  70. $this->errors[] = 'File has an extension saying file is a virus';
  71. return -97;
  72. }
  73. $fullcommand = $this->getCliCommand($file);
  74. //$fullcommand='"c:\Program Files (x86)\ClamWin\bin\clamscan.exe" --database="C:\Program Files (x86)\ClamWin\lib" "c:\temp\aaa.txt"';
  75. $fullcommand .= ' 2>&1'; // This is to get error output
  76. $output = array();
  77. $return_var = 0;
  78. $safemode = ini_get("safe_mode");
  79. // Create a clean fullcommand
  80. dol_syslog("AntiVir::dol_avscan_file Run command=".$fullcommand." with safe_mode ".($safemode ? "on" : "off"));
  81. // Run CLI command. If run of Windows, you can get return with echo %ERRORLEVEL%
  82. $lastline = exec($fullcommand, $output, $return_var);
  83. if (is_null($output)) {
  84. $output = array();
  85. }
  86. //print "x".$lastline." - ".join(',',$output)." - ".$return_var."y";exit;
  87. /*
  88. $outputfile=$conf->admin->dir_temp.'/dol_avscan_file.out.'.session_id();
  89. $handle = fopen($outputfile, 'w');
  90. if ($handle)
  91. {
  92. $handlein = popen($fullcommand, 'r');
  93. while (!feof($handlein))
  94. {
  95. $read = fgets($handlein);
  96. fwrite($handle,$read);
  97. }
  98. pclose($handlein);
  99. $errormsg = fgets($handle,2048);
  100. $this->output=$errormsg;
  101. fclose($handle);
  102. if (!empty($conf->global->MAIN_UMASK))
  103. @chmod($outputfile, octdec($conf->global->MAIN_UMASK));
  104. }
  105. else
  106. {
  107. $langs->load("errors");
  108. dol_syslog("Failed to open file ".$outputfile,LOG_ERR);
  109. $this->error="ErrorFailedToWriteInDir";
  110. $return=-1;
  111. }
  112. */
  113. dol_syslog("AntiVir::dol_avscan_file Result return_var=".$return_var." output=".join(',', $output));
  114. $returncodevirus = 1;
  115. if ($return_var == $returncodevirus) { // Virus found
  116. $this->errors = $output;
  117. return -99;
  118. }
  119. if ($return_var > 0) { // If other error
  120. $this->errors = $output;
  121. return -98;
  122. }
  123. // If return code = 0
  124. return 1;
  125. }
  126. /**
  127. * Get full Command Line to run
  128. *
  129. * @param string $file File to scan
  130. * @return string Full command line to run
  131. */
  132. public function getCliCommand($file)
  133. {
  134. global $conf;
  135. $maxreclevel = 5; // maximal recursion level
  136. $maxfiles = 1000; // maximal number of files to be scanned within archive
  137. $maxratio = 200; // maximal compression ratio
  138. $bz2archivememlim = 0; // limit memory usage for bzip2 (0/1)
  139. $maxfilesize = 10485760; // archived files larger than this value (in bytes) will not be scanned
  140. $command = $conf->global->MAIN_ANTIVIRUS_COMMAND;
  141. $param = $conf->global->MAIN_ANTIVIRUS_PARAM;
  142. $param = preg_replace('/%maxreclevel/', $maxreclevel, $param);
  143. $param = preg_replace('/%maxfiles/', $maxfiles, $param);
  144. $param = preg_replace('/%maxratio/', $maxratio, $param);
  145. $param = preg_replace('/%bz2archivememlim/', $bz2archivememlim, $param);
  146. $param = preg_replace('/%maxfilesize/', $maxfilesize, $param);
  147. $param = preg_replace('/%file/', trim($file), $param);
  148. if (!preg_match('/%file/', $conf->global->MAIN_ANTIVIRUS_PARAM)) {
  149. $param = $param." ".escapeshellarg(trim($file));
  150. }
  151. if (preg_match("/\s/", $command)) {
  152. $command = escapeshellarg($command); // Use quotes on command. Using escapeshellcmd fails.
  153. }
  154. $ret = $command.' '.$param;
  155. //$ret=$command.' '.$param.' 2>&1';
  156. //print "xx".$ret."xx";exit;
  157. return $ret;
  158. }
  159. }