PageRenderTime 59ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

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

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