示例#1
0
文件: lib.php 项目: isuruAb/moodle
 /**
  * Scan file, throws exception in case of infected file.
  *
  * Please note that the scanning engine must be able to access the file,
  * permissions of the file are not modified here!
  *
  * @static
  * @param string $thefile
  * @param string $filename name of the file
  * @param bool $deleteinfected
  */
 public static function antivir_scan_file($thefile, $filename, $deleteinfected)
 {
     global $CFG;
     if (!is_readable($thefile)) {
         // this should not happen
         return;
     }
     if (empty($CFG->runclamonupload) or empty($CFG->pathtoclam)) {
         // clam not enabled
         return;
     }
     $CFG->pathtoclam = trim($CFG->pathtoclam);
     if (!file_exists($CFG->pathtoclam) or !is_executable($CFG->pathtoclam)) {
         // misconfigured clam - use the old notification for now
         require "{$CFG->libdir}/uploadlib.php";
         $notice = get_string('clamlost', 'moodle', $CFG->pathtoclam);
         clam_message_admins($notice);
         return;
     }
     $clamparam = ' --stdout ';
     // If we are dealing with clamdscan, clamd is likely run as a different user
     // that might not have permissions to access your file.
     // To make clamdscan work, we use --fdpass parameter that passes the file
     // descriptor permissions to clamd, which allows it to scan given file
     // irrespective of directory and file permissions.
     if (basename($CFG->pathtoclam) == 'clamdscan') {
         $clamparam .= '--fdpass ';
     }
     // execute test
     $cmd = escapeshellcmd($CFG->pathtoclam) . $clamparam . escapeshellarg($thefile);
     exec($cmd, $output, $return);
     if ($return == 0) {
         // perfect, no problem found
         return;
     } else {
         if ($return == 1) {
             // infection found
             if ($deleteinfected) {
                 unlink($thefile);
             }
             throw new moodle_exception('virusfounduser', 'moodle', '', array('filename' => $filename));
         } else {
             //unknown problem
             require "{$CFG->libdir}/uploadlib.php";
             $notice = get_string('clamfailed', 'moodle', get_clam_error_code($return));
             $notice .= "\n\n" . implode("\n", $output);
             clam_message_admins($notice);
             if ($CFG->clamfailureonupload === 'actlikevirus') {
                 if ($deleteinfected) {
                     unlink($thefile);
                 }
                 throw new moodle_exception('virusfounduser', 'moodle', '', array('filename' => $filename));
             } else {
                 return;
             }
         }
     }
 }
示例#2
0
/**
 * If $CFG->runclamonupload is set, we scan a given file. (called from {@link preprocess_files()})
 *
 * This function will add on a uploadlog index in $file.
 *
 * @global object
 * @global object
 * @param mixed $file The file to scan from $files. or an absolute path to a file.
 * @param course $course {@link $COURSE}
 * @return int 1 if good, 0 if something goes wrong (opposite from actual error code from clam)
 */
function clam_scan_moodle_file(&$file, $course)
{
    global $CFG, $USER;
    if (is_array($file) && is_uploaded_file($file['tmp_name'])) {
        // it's from $_FILES
        $appendlog = true;
        $fullpath = $file['tmp_name'];
    } else {
        if (file_exists($file)) {
            // it's a path to somewhere on the filesystem!
            $fullpath = $file;
        } else {
            return false;
            // erm, what is this supposed to be then, huh?
        }
    }
    $CFG->pathtoclam = trim($CFG->pathtoclam);
    if (!$CFG->pathtoclam || !file_exists($CFG->pathtoclam) || !is_executable($CFG->pathtoclam)) {
        $newreturn = 1;
        $notice = get_string('clamlost', 'moodle', $CFG->pathtoclam);
        if ($CFG->clamfailureonupload == 'actlikevirus') {
            $notice .= "\n" . get_string('clamlostandactinglikevirus');
            $notice .= "\n" . clam_handle_infected_file($fullpath);
            $newreturn = false;
        }
        clam_message_admins($notice);
        if ($appendlog) {
            $file['uploadlog'] .= "\n" . get_string('clambroken');
            $file['clam'] = 1;
        }
        return $newreturn;
        // return 1 if we're allowing clam failures
    }
    $cmd = $CFG->pathtoclam . ' ' . $fullpath . " 2>&1";
    // before we do anything we need to change perms so that clamscan can read the file (clamdscan won't work otherwise)
    chmod($fullpath, $CFG->directorypermissions);
    exec($cmd, $output, $return);
    switch ($return) {
        case 0:
            // glee! we're ok.
            return 1;
            // translate clam return code into reasonable return code consistent with everything else.
        // translate clam return code into reasonable return code consistent with everything else.
        case 1:
            // bad wicked evil, we have a virus.
            $info = new stdClass();
            if (!empty($course)) {
                $info->course = format_string($course->fullname, true, array('context' => context_course::instance($course->id)));
            } else {
                $info->course = 'No course';
            }
            $info->user = fullname($USER);
            $notice = get_string('virusfound', 'moodle', $info);
            $notice .= "\n\n" . implode("\n", $output);
            $notice .= "\n\n" . clam_handle_infected_file($fullpath);
            clam_message_admins($notice);
            if ($appendlog) {
                $info->filename = $file['originalname'];
                $file['uploadlog'] .= "\n" . get_string('virusfounduser', 'moodle', $info);
                $file['virus'] = 1;
            }
            return false;
            // in this case, 0 means bad.
        // in this case, 0 means bad.
        default:
            // error - clam failed to run or something went wrong
            $notice .= get_string('clamfailed', 'moodle', get_clam_error_code($return));
            $notice .= "\n\n" . implode("\n", $output);
            $newreturn = true;
            if ($CFG->clamfailureonupload == 'actlikevirus') {
                $notice .= "\n" . clam_handle_infected_file($fullpath);
                $newreturn = false;
            }
            clam_message_admins($notice);
            if ($appendlog) {
                $file['uploadlog'] .= "\n" . get_string('clambroken');
                $file['clam'] = 1;
            }
            return $newreturn;
            // return 1 if we're allowing failures.
    }
}
示例#3
0
 /**
  * Scan file, throws exception in case of infected file.
  *
  * Please note that the scanning engine must be able to access the file,
  * permissions of the file are not modified here!
  *
  * @static
  * @param string $thefile
  * @param string $filename name of the file
  * @param bool $deleteinfected
  */
 public static function antivir_scan_file($thefile, $filename, $deleteinfected)
 {
     global $CFG;
     if (!is_readable($thefile)) {
         // this should not happen
         return;
     }
     if (empty($CFG->runclamonupload) or empty($CFG->pathtoclam)) {
         // clam not enabled
         return;
     }
     $CFG->pathtoclam = trim($CFG->pathtoclam);
     if (!file_exists($CFG->pathtoclam) or !is_executable($CFG->pathtoclam)) {
         // misconfigured clam - use the old notification for now
         require "{$CFG->libdir}/uploadlib.php";
         $notice = get_string('clamlost', 'moodle', $CFG->pathtoclam);
         clam_message_admins($notice);
         return;
     }
     // do NOT mess with permissions here, the calling party is responsible for making
     // sure the scanner engine can access the files!
     // execute test
     $cmd = escapeshellcmd($CFG->pathtoclam) . ' --stdout ' . escapeshellarg($thefile);
     exec($cmd, $output, $return);
     if ($return == 0) {
         // perfect, no problem found
         return;
     } else {
         if ($return == 1) {
             // infection found
             if ($deleteinfected) {
                 unlink($thefile);
             }
             throw new moodle_exception('virusfounduser', 'moodle', '', array('filename' => $filename));
         } else {
             //unknown problem
             require "{$CFG->libdir}/uploadlib.php";
             $notice = get_string('clamfailed', 'moodle', get_clam_error_code($return));
             $notice .= "\n\n" . implode("\n", $output);
             clam_message_admins($notice);
             if ($CFG->clamfailureonupload === 'actlikevirus') {
                 if ($deleteinfected) {
                     unlink($thefile);
                 }
                 throw new moodle_exception('virusfounduser', 'moodle', '', array('filename' => $filename));
             } else {
                 return;
             }
         }
     }
 }