Skip to content

Commit

Permalink
Enable the ClamAV check to run correctly. Any error is now shown corr…
Browse files Browse the repository at this point in the history
…ectly.
  • Loading branch information
John Horne committed Oct 25, 2017
1 parent 4e4da8f commit e23c421
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 28 deletions.
59 changes: 41 additions & 18 deletions library/Xerte/Validate/VirusScanClamAv.php
Expand Up @@ -9,7 +9,7 @@
* compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand All @@ -25,35 +25,59 @@
class Xerte_Validate_VirusScanClamAv {

protected $messages = array();
// perhaps needs changing on other platforms.
public static $BINARY = '/usr/bin/clamscan';

public static $ClamAV_Cmd = '';
public static $ClamAV_Opts = '';


public static function canRun() {
return file_exists(self::$BINARY);
return is_file(self::$ClamAV_Cmd) && is_executable(self::$ClamAV_Cmd);
}

public function isValid($filename) {
$this->messages = array();
if(file_exists($filename)) {
/* Chmod the file to allow ClamAV access to it. */
chmod($filename, 0644);
$command = self::$BINARY . " --no-summary " . escapeshellarg($filename);
$retval = -1;
exec($command, $output, $retval);
if(self::canRun()) {
if(file_exists($filename)) {
/* If required, chmod the file to allow ClamAV access to it. */
clearstatcache();
$file_perms = fileperms($filename);
$world_read = ($file_perms & 0x0004) != 0 ? true : false;
if (! $world_read) {
chmod($filename, 0644);
}

$command = escapeshellcmd(self::$ClamAV_Cmd) . ' ' . self::$ClamAV_Opts . ' ' . escapeshellarg($filename);
$retval = -1;
exec($command, $output, $retval);

if($retval == 0) {
return true;
if($retval == 0) {
/* If required, restore the original file permissions. */
if (! $world_read) {
chmod($filename, $file_perms & 0777);
}

return true;
}
elseif($retval == 1) {
$output_str = implode(' ', $output);
_debug("Virus found in file '$filename': " . $output_str);
$this->messages['VIRUS_FOUND'] = "Virus found: " . $output_str;
}
else {
$output_str = empty($output) ? '' : (': ' . implode(' ', $output));
$output_str = 'Unable to run virus check' . $output_str;
_debug($output_str);
$this->messages['OTHER_ERROR'] = $output_str;
}
}
else {
$output_str = implode(' ', $output);
error_log("Virus found in file upload? $filename --- From " . __FILE__ . " - ClamAV output: {$retval} / {$output_str}");
_debug("Virus found? {$retval} / {$output_str} (When scanning : $filename)");
$this->messages['VIRUS_FOUND'] = "Virus found? $output_str";
$this->messages['FILE_NOT_FOUND'] = "File not found - $filename";
}
}
else {
$this->messages['FILE_NOT_FOUND'] = "$filename doesn't exist. Cannot scan";
$this->messages['UNSUPPORTED'] = "Can't run - AV command not found: " . self::$ClamAV_Cmd;
}

return false;
}

Expand All @@ -65,4 +89,3 @@ public function getErrors() {
return array_keys($this->messages);
}
}

70 changes: 60 additions & 10 deletions plugins/file_uploading-clamav.php
Expand Up @@ -9,7 +9,7 @@
* compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand All @@ -30,22 +30,72 @@
* @param string $filename (as in $_FILES['xxx']['tmp_name'])
* @return string filename (as in $_FILES['xxx']['tmp_name']) or boolean false if we can't upload it.
*/

require_once(dirname(__FILE__) . '/../config.php');

function virus_check_file() {

global $last_file_check_error;

$args = func_get_args();
$files = $args[0]; /* $_FILES like */
$files = array();

if(!Xerte_Validate_VirusScanClamAv::canRun() || !is_array($args[0])) {
return $args[0];
}

$last_file_check_error = null;

/*
* The file names may be supplied in two slightly different formats.
* As such we dig out the real and temporary file names, and store them
* in a local array for easier processing.
*/

if (isset($args[0]['filenameuploaded'])) {
$files['file_name'][] = $args[0]['filenameuploaded']['name'];
$files['temp_name'][] = $args[0]['filenameuploaded']['tmp_name'];
}
else {
foreach ($args[0]['name'] as $key => $name) {
$files['file_name'][] = $name;
$files['temp_name'][] = $args[0]['tmp_name'][$key];
}
}

if(Xerte_Validate_VirusScanClamAv::canRun()){
foreach($files as $file) {
$validator = new Xerte_Validate_VirusScanClamAv();
if(!$validator->isValid($file['tmp_name'])) {
die("Possible virus found in upload; Consult server log files for more information.");
foreach($files['temp_name'] as $key => $file) {
$validator = new Xerte_Validate_VirusScanClamAv();
if(!$validator->isValid($file)) {
if (file_exists($file)) {
_debug("Antivirus check of {$files['file_name'][$key]} failed.");
error_log("Antivirus check of {$files['file_name'][$key]} ($file) failed.");

unlink($file);
}
else {
_debug("Antivirus check of {$files['file_name'][$key]} failed - file does not exist");
error_log("antivirus check of {$files['file_name'][$key]} ($file) failed - file does not exist");
}

$last_file_check_error = $validator->GetMessages();

/* Shorten the full pathname to something more user meaningful. */
$full_path = '/' . preg_quote($file, '/') . '/';
$last_file_check_error = preg_replace($full_path, $files['file_name'][$key], $last_file_check_error);

return false;
}
}
return $files;

return $args[0];
}


// perhaps have 'pre-flight check here' ?? e.g. explode if /usr/bin/clamscan doesn't exist.
add_filter('editor_upload_file', 'virus_check_file');
/* Clear the file cache because of the file check below. */
clearstatcache();

if ($xerte_toolkits_site->enable_clamav_check && is_file($xerte_toolkits_site->clamav_cmd) && is_executable($xerte_toolkits_site->clamav_cmd)) {
Xerte_Validate_VirusScanClamAv::$ClamAV_Cmd = $xerte_toolkits_site->clamav_cmd;
Xerte_Validate_VirusScanClamAv::$ClamAV_Opts = $xerte_toolkits_site->clamav_opts;
add_filter('editor_upload_file', 'virus_check_file');
}

0 comments on commit e23c421

Please sign in to comment.