PageRenderTime 68ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/core/src/plugins/action.antivirus/class.AntivirusScanner.php

https://github.com/sheafferusa/pydio-core
PHP | 228 lines | 164 code | 20 blank | 44 comment | 39 complexity | bf211334e5fca5b8be06c9ad184c3eaf MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-3.0, GPL-3.0, BSD-3-Clause, LGPL-2.1, LGPL-2.0, AGPL-3.0, Apache-2.0
  1. <?php
  2. defined('AJXP_EXEC') or die( 'Access not allowed');
  3. class AntivirusScanner extends AJXP_Plugin
  4. {
  5. const DEBUG_ON = 0;
  6. protected $path;
  7. protected $file_extension;
  8. protected $extension_scan;
  9. protected $scan_all;
  10. protected $scan_diff_folder;
  11. protected $scan_max_size;
  12. protected $file_size;
  13. /**
  14. * @param AJXP_Node $oldNode
  15. * @param AJXP_Node $newNode
  16. * Main function, it is called by the hook.
  17. */
  18. public function scanFile ($oldNode = null, $newNode = null)
  19. {
  20. if ($oldNode!=null || $newNode == null) {
  21. return;
  22. }
  23. $this->callSet($newNode); //initializes attributes
  24. // This block scans or doesn't scan the file. This is based on plugin parameters
  25. if ($this->file_size < $this->scan_max_size) {
  26. if ($this->scan_all == true) {
  27. if ($this->inList()==true) {
  28. if ($this->getFilteredOption("TRACE") == false) {return;}
  29. $this->scanLater();
  30. return ;
  31. } else {
  32. $this->scanNow();
  33. return ;
  34. }
  35. } else {
  36. if ($this->inList()==true) {
  37. $this->scanNow();
  38. return ;
  39. } else {
  40. if ($this->getFilteredOption("TRACE") == false) {return;}
  41. $this->scanLater();
  42. return ;
  43. }
  44. }
  45. } else {
  46. $this->scanLater();
  47. return ;
  48. }
  49. }
  50. /**
  51. * @return bool true if file_extension is in the list extension_scan
  52. */
  53. private function inList()
  54. {
  55. while (strripos($this->extension_scan, $this->file_extension)) {
  56. $start_pos = strripos($this->extension_scan, $this->file_extension);
  57. $leng_ext = strlen($this->file_extension);
  58. $result = substr($this->extension_scan, $start_pos);
  59. $result = substr($result, $leng_ext, 1);
  60. if (preg_match("/[A-Za-z0-9]+/",$result)) {
  61. $this->extension_scan = substr($this->extension_scan, $start_pos + $leng_ext);
  62. } else {
  63. return true;
  64. }
  65. }
  66. return false;
  67. }
  68. /**
  69. * This function immediatly scans the file, it calls the antivirus command
  70. */
  71. private function scanNow()
  72. {
  73. $command = $this->getFilteredOption("COMMAND");
  74. $command = str_replace('$' . 'FILE', escapeshellarg($this->path), $command);
  75. ob_start();
  76. passthru($command, $int);
  77. $output=ob_get_contents();
  78. ob_end_clean();
  79. if ($int != 0) {
  80. if (self::DEBUG_ON == 1) {
  81. echo $output;
  82. } else {
  83. $filename = strrchr($this->path, DIRECTORY_SEPARATOR);
  84. $filename = substr($filename, 1);
  85. echo 'Virus has been found in : ' . $filename . ' File removed';
  86. }
  87. //$this->logInfo("Upload Virus File" . $this->path, array("file"=>SystemTextEncoding::fromUTF8($dir).DIRECTORY_SEPARATOR.$realpath));
  88. }
  89. return;
  90. }
  91. /**
  92. * This function generates a trace of the file
  93. */
  94. private function scanLater()
  95. {
  96. $numero=0;
  97. $scanned=false;
  98. if (is_dir($this->scan_diff_folder) == false) {
  99. $create_folder = mkdir($this->scan_diff_folder, 0755);
  100. if ($create_folder == false) {
  101. throw new Exception("can-t create scan_diff_folder, check permission");
  102. return;
  103. }
  104. }
  105. while ($scanned == false) {
  106. if (file_exists( $this->scan_diff_folder .DIRECTORY_SEPARATOR. 'file_' . $numero)) {
  107. $numero++;
  108. } else {
  109. $command = 'echo "'. '\"' . $this->path . '\"' . '" >' . $this->scan_diff_folder .DIRECTORY_SEPARATOR. 'file_' . $numero;
  110. passthru($command);
  111. $scanned=true;
  112. return;
  113. }
  114. }
  115. }
  116. /**
  117. * @param AJXP_Node $nodeObject
  118. */
  119. private function callSet($nodeObject)
  120. {
  121. $this->setPath($nodeObject);
  122. $this->setFileExtension($nodeObject);
  123. $this->setExtensionScan();
  124. $this->setScanDiffFolder ();
  125. $this->setScanMaxSize ();
  126. $this->setFileSize($nodeObject);
  127. $this->setScanAll();
  128. //debug option, put in a file attribute values
  129. if (self::DEBUG_ON == 1) {
  130. $debug = 'echo "' . $this->path . " " . $this->file_extension . " " . $this->extension_scan . " " . $this->scan_all . " " . $this->scan_diff_folder . " " . $this->scan_max_size . " " . $this->file_size . '" >> plugins/action.antivirus/debug';
  131. passthru($debug);
  132. }
  133. return ;
  134. }
  135. /**
  136. * This function initializes the file path
  137. * @param $nodeObject
  138. */
  139. public function setPath($nodeObject)
  140. {
  141. $realpath = $nodeObject->getRealFile();
  142. $realpath = realpath($realpath);
  143. $this->path= $realpath;
  144. return ;
  145. }
  146. /**
  147. * This function initializes the file extension
  148. * @param $nodeObject
  149. */
  150. public function setFileExtension ($nodeObject)
  151. {
  152. $realpath = $nodeObject->getRealFile();
  153. $realpath = realpath($realpath);
  154. $realpath = str_replace(" ", "_",$realpath );
  155. $realpath = strrchr($realpath, DIRECTORY_SEPARATOR);
  156. $this->file_extension=strrchr($realpath, '.');
  157. if ($this->file_extension == ( "") ) {$this->file_extension = ".no_ext";}
  158. return ;
  159. }
  160. /**
  161. * This function initializes the extension list
  162. */
  163. public function setExtensionScan()
  164. {
  165. $this->extension_scan = $this->getFilteredOption("EXT");
  166. return ;
  167. }
  168. /**
  169. * this function initializes attribute scan_all
  170. */
  171. public function setScanAll()
  172. {
  173. $extension = $this->getFilteredOption("EXT");
  174. if (substr($extension, 0, 2) == "*/") {
  175. $this->scan_all = true;
  176. } else {
  177. $this->scan_all = false;
  178. }
  179. return ;
  180. }
  181. /**
  182. * this function initializes the trace folder
  183. */
  184. public function setScanDiffFolder ()
  185. {
  186. $this->scan_diff_folder = $this->getFilteredOption("PATH");
  187. return ;
  188. }
  189. /**
  190. * this function initializes max size of the scanned file
  191. */
  192. public function setScanMaxSize ()
  193. {
  194. $this->scan_max_size = AJXP_Utils::convertBytes($this->getFilteredOption("SIZE"));
  195. return ;
  196. }
  197. /**
  198. * This function initializes the size of the file
  199. * @param AJXP_Node $nodeObject
  200. */
  201. public function setFileSize ($nodeObject)
  202. {
  203. $realpath = $nodeObject->getRealFile();
  204. $realpath = realpath($realpath);
  205. $this->file_size = filesize($realpath);
  206. return ;
  207. }
  208. }