Exemple #1
0
 public function test_manager_get_antivirus()
 {
     // We are using clamav plugin in the test,
     // as the only plugin we know exists for sure.
     $antivirusviaget = \core\antivirus\manager::get_antivirus('clamav');
     $antivirusdirect = new \antivirus_clamav\scanner();
     $this->assertEquals($antivirusdirect, $antivirusviaget);
 }
Exemple #2
0
 /**
  * Do the actual processing of the uploaded file
  * @param string $saveas_filename name to give to the file
  * @param int $maxbytes maximum file size
  * @param mixed $types optional array of file extensions that are allowed or '*' for all
  * @param string $savepath optional path to save the file to
  * @param int $itemid optional the ID for this item within the file area
  * @param string $license optional the license to use for this file
  * @param string $author optional the name of the author of this file
  * @param bool $overwriteexisting optional user has asked to overwrite the existing file
  * @param int $areamaxbytes maximum size of the file area.
  * @return object containing details of the file uploaded
  */
 public function process_upload($saveas_filename, $maxbytes, $types = '*', $savepath = '/', $itemid = 0, $license = null, $author = '', $overwriteexisting = false, $areamaxbytes = FILE_AREA_MAX_BYTES_UNLIMITED)
 {
     global $USER, $CFG;
     if (is_array($types) and in_array('*', $types) or $types == '*') {
         $this->mimetypes = '*';
     } else {
         foreach ($types as $type) {
             $this->mimetypes[] = mimeinfo('type', $type);
         }
     }
     if ($license == null) {
         $license = $CFG->sitedefaultlicense;
     }
     $record = new stdClass();
     $record->filearea = 'draft';
     $record->component = 'user';
     $record->filepath = $savepath;
     $record->itemid = $itemid;
     $record->license = $license;
     $record->author = $author;
     $context = context_user::instance($USER->id);
     $elname = 'repo_upload_file';
     $fs = get_file_storage();
     $sm = get_string_manager();
     if ($record->filepath !== '/') {
         $record->filepath = file_correct_filepath($record->filepath);
     }
     if (!isset($_FILES[$elname])) {
         throw new moodle_exception('nofile');
     }
     if (!empty($_FILES[$elname]['error'])) {
         switch ($_FILES[$elname]['error']) {
             case UPLOAD_ERR_INI_SIZE:
                 throw new moodle_exception('upload_error_ini_size', 'repository_upload');
                 break;
             case UPLOAD_ERR_FORM_SIZE:
                 throw new moodle_exception('upload_error_form_size', 'repository_upload');
                 break;
             case UPLOAD_ERR_PARTIAL:
                 throw new moodle_exception('upload_error_partial', 'repository_upload');
                 break;
             case UPLOAD_ERR_NO_FILE:
                 throw new moodle_exception('upload_error_no_file', 'repository_upload');
                 break;
             case UPLOAD_ERR_NO_TMP_DIR:
                 throw new moodle_exception('upload_error_no_tmp_dir', 'repository_upload');
                 break;
             case UPLOAD_ERR_CANT_WRITE:
                 throw new moodle_exception('upload_error_cant_write', 'repository_upload');
                 break;
             case UPLOAD_ERR_EXTENSION:
                 throw new moodle_exception('upload_error_extension', 'repository_upload');
                 break;
             default:
                 throw new moodle_exception('nofile');
         }
     }
     \core\antivirus\manager::scan_file($_FILES[$elname]['tmp_name'], $_FILES[$elname]['name'], true);
     // {@link repository::build_source_field()}
     $sourcefield = $this->get_file_source_info($_FILES[$elname]['name']);
     $record->source = self::build_source_field($sourcefield);
     if (empty($saveas_filename)) {
         $record->filename = clean_param($_FILES[$elname]['name'], PARAM_FILE);
     } else {
         $ext = '';
         $match = array();
         $filename = clean_param($_FILES[$elname]['name'], PARAM_FILE);
         if (strpos($filename, '.') === false) {
             // File has no extension at all - do not add a dot.
             $record->filename = $saveas_filename;
         } else {
             if (preg_match('/\\.([a-z0-9]+)$/i', $filename, $match)) {
                 if (isset($match[1])) {
                     $ext = $match[1];
                 }
             }
             $ext = !empty($ext) ? $ext : '';
             if (preg_match('#\\.(' . $ext . ')$#i', $saveas_filename)) {
                 // saveas filename contains file extension already
                 $record->filename = $saveas_filename;
             } else {
                 $record->filename = $saveas_filename . '.' . $ext;
             }
         }
     }
     // Check the file has some non-null contents - usually an indication that a user has
     // tried to upload a folder by mistake
     if (!$this->check_valid_contents($_FILES[$elname]['tmp_name'])) {
         throw new moodle_exception('upload_error_invalid_file', 'repository_upload', '', $record->filename);
     }
     if ($this->mimetypes != '*') {
         // check filetype
         $filemimetype = file_storage::mimetype($_FILES[$elname]['tmp_name'], $record->filename);
         if (!in_array($filemimetype, $this->mimetypes)) {
             throw new moodle_exception('invalidfiletype', 'repository', '', get_mimetype_description(array('filename' => $_FILES[$elname]['name'])));
         }
     }
     if (empty($record->itemid)) {
         $record->itemid = 0;
     }
     if ($maxbytes !== -1 && filesize($_FILES[$elname]['tmp_name']) > $maxbytes) {
         $maxbytesdisplay = display_size($maxbytes);
         throw new file_exception('maxbytesfile', (object) array('file' => $record->filename, 'size' => $maxbytesdisplay));
     }
     if (file_is_draft_area_limit_reached($record->itemid, $areamaxbytes, filesize($_FILES[$elname]['tmp_name']))) {
         throw new file_exception('maxareabytes');
     }
     $record->contextid = $context->id;
     $record->userid = $USER->id;
     if (repository::draftfile_exists($record->itemid, $record->filepath, $record->filename)) {
         $existingfilename = $record->filename;
         $unused_filename = repository::get_unused_filename($record->itemid, $record->filepath, $record->filename);
         $record->filename = $unused_filename;
         $stored_file = $fs->create_file_from_pathname($record, $_FILES[$elname]['tmp_name']);
         if ($overwriteexisting) {
             repository::overwrite_existing_draftfile($record->itemid, $record->filepath, $existingfilename, $record->filepath, $record->filename);
             $record->filename = $existingfilename;
         } else {
             $event = array();
             $event['event'] = 'fileexists';
             $event['newfile'] = new stdClass();
             $event['newfile']->filepath = $record->filepath;
             $event['newfile']->filename = $unused_filename;
             $event['newfile']->url = moodle_url::make_draftfile_url($record->itemid, $record->filepath, $unused_filename)->out(false);
             $event['existingfile'] = new stdClass();
             $event['existingfile']->filepath = $record->filepath;
             $event['existingfile']->filename = $existingfilename;
             $event['existingfile']->url = moodle_url::make_draftfile_url($record->itemid, $record->filepath, $existingfilename)->out(false);
             return $event;
         }
     } else {
         $stored_file = $fs->create_file_from_pathname($record, $_FILES[$elname]['tmp_name']);
     }
     return array('url' => moodle_url::make_draftfile_url($record->itemid, $record->filepath, $record->filename)->out(false), 'id' => $record->itemid, 'file' => $record->filename);
 }
Exemple #3
0
/**
 * Returns the string equivalent of a numeric clam error code
 *
 * @deprecated since Moodle 3.0 - this is a part of clamav plugin now.
 * @param int $returncode The numeric error code in question.
 * @return string The definition of the error code
 */
function get_clam_error_code($returncode)
{
    debugging('get_clam_error_code() is deprecated, please use get_clam_error_code() method of \\antivirus_clamav\\scanner class.', DEBUG_DEVELOPER);
    $antivirus = \core\antivirus\manager::get_antivirus('clamav');
    return $antivirus->get_clam_error_code($returncode);
}
 /**
  * Process a message again to add body and attachment data.
  *
  * @param \Horde_Imap_Client_Data_Fetch $messagedata The structure and part of the message body
  * @param \Horde_Mime_Part $partdata The part data
  * @param string $part The part ID.
  * @param string $filename The filename of the attachment
  * @return \stdClass
  * @throws \core\message\inbound\processing_failed_exception If the attachment can't be saved to disk.
  */
 private function process_message_part_attachment($messagedata, $partdata, $part, $filename)
 {
     global $CFG;
     // If a filename is present, assume that this part is an attachment.
     $attachment = new \stdClass();
     $attachment->filename = $filename;
     $attachment->type = $partdata->getType();
     $attachment->content = $partdata->getContents();
     $attachment->charset = $partdata->getCharset();
     $attachment->description = $partdata->getDescription();
     $attachment->contentid = $partdata->getContentId();
     $attachment->filesize = $messagedata->getBodyPartSize($part);
     if (!empty($CFG->antiviruses)) {
         mtrace("--> Attempting virus scan of '{$attachment->filename}'");
         // Store the file on disk - it will need to be virus scanned first.
         $itemid = rand(1, 999999999);
         $directory = make_temp_directory("/messageinbound/{$itemid}", false);
         $filepath = $directory . "/" . $attachment->filename;
         if (!($fp = fopen($filepath, "w"))) {
             // Unable to open the temporary file to write this to disk.
             mtrace("--> Unable to save the file to disk for virus scanning. Check file permissions.");
             throw new \core\message\inbound\processing_failed_exception('attachmentfilepermissionsfailed', 'tool_messageinbound');
         }
         fwrite($fp, $attachment->content);
         fclose($fp);
         // Perform a virus scan now.
         try {
             \core\antivirus\manager::scan_file($filepath, $attachment->filename, true);
         } catch (\core\antivirus\scanner_exception $e) {
             mtrace("--> A virus was found in the attachment '{$attachment->filename}'.");
             $this->inform_attachment_virus();
             return;
         }
     }
     return $attachment;
 }
Exemple #5
0
 * @copyright  2015 Ruslan Kabalin, Lancaster University.
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
require_once '../config.php';
require_once $CFG->libdir . '/adminlib.php';
require_once $CFG->libdir . '/tablelib.php';
$action = required_param('action', PARAM_ALPHANUMEXT);
$antivirus = required_param('antivirus', PARAM_PLUGIN);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$PAGE->set_url('/admin/antiviruses.php', array('action' => $action, 'antivirus' => $antivirus));
$PAGE->set_context(context_system::instance());
require_login();
require_capability('moodle/site:config', context_system::instance());
$returnurl = "{$CFG->wwwroot}/{$CFG->admin}/settings.php?section=manageantiviruses";
// Get currently installed and enabled antivirus plugins.
$availableantiviruses = \core\antivirus\manager::get_available();
if (!empty($antivirus) and empty($availableantiviruses[$antivirus])) {
    redirect($returnurl);
}
$activeantiviruses = explode(',', $CFG->antiviruses);
foreach ($activeantiviruses as $key => $active) {
    if (empty($availableantiviruses[$active])) {
        unset($activeantiviruses[$key]);
    }
}
if (!confirm_sesskey()) {
    redirect($returnurl);
}
switch ($action) {
    case 'disable':
        // Remove from enabled list.
Exemple #6
0
 /**
  * Builds the XHTML to display the control
  *
  * @param string $data Unused
  * @param string $query
  * @return string
  */
 public function output_html($data, $query = '')
 {
     global $CFG, $OUTPUT;
     // Display strings.
     $txt = get_strings(array('administration', 'settings', 'edit', 'name', 'enable', 'disable', 'up', 'down', 'none'));
     $struninstall = get_string('uninstallplugin', 'core_admin');
     $txt->updown = "{$txt->up}/{$txt->down}";
     $antivirusesavailable = \core\antivirus\manager::get_available();
     $activeantiviruses = explode(',', $CFG->antiviruses);
     $activeantiviruses = array_reverse($activeantiviruses);
     foreach ($activeantiviruses as $key => $antivirus) {
         if (empty($antivirusesavailable[$antivirus])) {
             unset($activeantiviruses[$key]);
         } else {
             $name = $antivirusesavailable[$antivirus];
             unset($antivirusesavailable[$antivirus]);
             $antivirusesavailable[$antivirus] = $name;
         }
     }
     $antivirusesavailable = array_reverse($antivirusesavailable, true);
     $return = $OUTPUT->heading(get_string('actantivirushdr', 'antivirus'), 3, 'main', true);
     $return .= $OUTPUT->box_start('generalbox antivirusesui');
     $table = new html_table();
     $table->head = array($txt->name, $txt->enable, $txt->updown, $txt->settings, $struninstall);
     $table->colclasses = array('leftalign', 'centeralign', 'centeralign', 'centeralign', 'centeralign');
     $table->id = 'antivirusmanagement';
     $table->attributes['class'] = 'admintable generaltable';
     $table->data = array();
     // Iterate through auth plugins and add to the display table.
     $updowncount = 1;
     $antiviruscount = count($activeantiviruses);
     $baseurl = new moodle_url('/admin/antiviruses.php', array('sesskey' => sesskey()));
     foreach ($antivirusesavailable as $antivirus => $name) {
         // Hide/show link.
         $class = '';
         if (in_array($antivirus, $activeantiviruses)) {
             $hideshowurl = $baseurl;
             $hideshowurl->params(array('action' => 'disable', 'antivirus' => $antivirus));
             $hideshowimg = html_writer::img($OUTPUT->pix_url('t/hide'), 'disable', array('class' => 'iconsmall'));
             $hideshow = html_writer::link($hideshowurl, $hideshowimg);
             $enabled = true;
             $displayname = $name;
         } else {
             $hideshowurl = $baseurl;
             $hideshowurl->params(array('action' => 'enable', 'antivirus' => $antivirus));
             $hideshowimg = html_writer::img($OUTPUT->pix_url('t/show'), 'enable', array('class' => 'iconsmall'));
             $hideshow = html_writer::link($hideshowurl, $hideshowimg);
             $enabled = false;
             $displayname = $name;
             $class = 'dimmed_text';
         }
         // Up/down link.
         $updown = '';
         if ($enabled) {
             if ($updowncount > 1) {
                 $updownurl = $baseurl;
                 $updownurl->params(array('action' => 'up', 'antivirus' => $antivirus));
                 $updownimg = html_writer::img($OUTPUT->pix_url('t/up'), 'up', array('class' => 'iconsmall'));
                 $updown = html_writer::link($updownurl, $updownimg);
             } else {
                 $updown .= html_writer::img($OUTPUT->pix_url('spacer'), '', array('class' => 'iconsmall'));
             }
             if ($updowncount < $antiviruscount) {
                 $updownurl = $baseurl;
                 $updownurl->params(array('action' => 'down', 'antivirus' => $antivirus));
                 $updownimg = html_writer::img($OUTPUT->pix_url('t/down'), 'down', array('class' => 'iconsmall'));
                 $updown = html_writer::link($updownurl, $updownimg);
             } else {
                 $updown .= html_writer::img($OUTPUT->pix_url('spacer'), '', array('class' => 'iconsmall'));
             }
             ++$updowncount;
         }
         // Settings link.
         if (file_exists($CFG->dirroot . '/lib/antivirus/' . $antivirus . '/settings.php')) {
             $eurl = new moodle_url('/admin/settings.php', array('section' => 'antivirussettings' . $antivirus));
             $settings = html_writer::link($eurl, $txt->settings);
         } else {
             $settings = '';
         }
         $uninstall = '';
         if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url('antivirus_' . $antivirus, 'manage')) {
             $uninstall = html_writer::link($uninstallurl, $struninstall);
         }
         // Add a row to the table.
         $row = new html_table_row(array($displayname, $hideshow, $updown, $settings, $uninstall));
         if ($class) {
             $row->attributes['class'] = $class;
         }
         $table->data[] = $row;
     }
     $return .= html_writer::table($table);
     $return .= get_string('configantivirusplugins', 'antivirus') . html_writer::empty_tag('br') . get_string('tablenosave', 'admin');
     $return .= $OUTPUT->box_end();
     return highlight($query, $return);
 }
Exemple #7
0
 /**
  * Move file from download folder to file pool using FILE API
  *
  * @todo MDL-28637
  * @static
  * @param string $thefile file path in download folder
  * @param stdClass $record
  * @return array containing the following keys:
  *           icon
  *           file
  *           id
  *           url
  */
 public static function move_to_filepool($thefile, $record)
 {
     global $DB, $CFG, $USER, $OUTPUT;
     // scan for viruses if possible, throws exception if problem found
     // TODO: MDL-28637 this repository_no_delete is a bloody hack!
     \core\antivirus\manager::scan_file($thefile, $record->filename, empty($CFG->repository_no_delete));
     $fs = get_file_storage();
     // If file name being used.
     if (repository::draftfile_exists($record->itemid, $record->filepath, $record->filename)) {
         $draftitemid = $record->itemid;
         $new_filename = repository::get_unused_filename($draftitemid, $record->filepath, $record->filename);
         $old_filename = $record->filename;
         // Create a tmp file.
         $record->filename = $new_filename;
         $newfile = $fs->create_file_from_pathname($record, $thefile);
         $event = array();
         $event['event'] = 'fileexists';
         $event['newfile'] = new stdClass();
         $event['newfile']->filepath = $record->filepath;
         $event['newfile']->filename = $new_filename;
         $event['newfile']->url = moodle_url::make_draftfile_url($draftitemid, $record->filepath, $new_filename)->out();
         $event['existingfile'] = new stdClass();
         $event['existingfile']->filepath = $record->filepath;
         $event['existingfile']->filename = $old_filename;
         $event['existingfile']->url = moodle_url::make_draftfile_url($draftitemid, $record->filepath, $old_filename)->out();
         return $event;
     }
     if ($file = $fs->create_file_from_pathname($record, $thefile)) {
         if (empty($CFG->repository_no_delete)) {
             $delete = unlink($thefile);
             unset($CFG->repository_no_delete);
         }
         return array('url' => moodle_url::make_draftfile_url($file->get_itemid(), $file->get_filepath(), $file->get_filename())->out(), 'id' => $file->get_itemid(), 'file' => $file->get_filename(), 'icon' => $OUTPUT->pix_url(file_extension_icon($thefile, 32))->out());
     } else {
         return null;
     }
 }
Exemple #8
0
                break;
            case UPLOAD_ERR_NO_TMP_DIR:
                throw new moodle_exception('upload_error_no_tmp_dir', 'repository_upload');
                break;
            case UPLOAD_ERR_CANT_WRITE:
                throw new moodle_exception('upload_error_cant_write', 'repository_upload');
                break;
            case UPLOAD_ERR_EXTENSION:
                throw new moodle_exception('upload_error_extension', 'repository_upload');
                break;
            default:
                throw new moodle_exception('nofile');
        }
    }
    // Scan for viruses.
    \core\antivirus\manager::scan_file($_FILES[$fieldname]['tmp_name'], $_FILES[$fieldname]['name'], true);
    $file = new stdClass();
    $file->filename = clean_param($_FILES[$fieldname]['name'], PARAM_FILE);
    // check system maxbytes setting
    if ($_FILES[$fieldname]['size'] > get_max_upload_file_size($CFG->maxbytes)) {
        // oversize file will be ignored, error added to array to notify
        // web service client
        $file->errortype = 'fileoversized';
        $file->error = get_string('maxbytes', 'error');
    } else {
        $file->filepath = $_FILES[$fieldname]['tmp_name'];
        // calculate total size of upload
        $totalsize += $_FILES[$fieldname]['size'];
    }
    $files[] = $file;
}
Exemple #9
0
 public function test_manager_scan_file_virus()
 {
     // Run mock scanning without deleting infected file.
     $this->assertFileExists($this->tempfile);
     try {
         \core\antivirus\manager::scan_file($this->tempfile, 'FOUND', false);
     } catch (\moodle_exception $e) {
         $this->assertInstanceOf('\\core\\antivirus\\scanner_exception', $e);
     }
     // File expected to remain in place.
     $this->assertFileExists($this->tempfile);
     // Run mock scanning with deleting infected file.
     try {
         \core\antivirus\manager::scan_file($this->tempfile, 'FOUND', true);
     } catch (\moodle_exception $e) {
         $this->assertInstanceOf('\\core\\antivirus\\scanner_exception', $e);
     }
     // File expected to be deleted.
     $this->assertFileNotExists($this->tempfile);
 }