diff -Naur moodle/admin/settings/security.php moodle-mod/admin/settings/security.php --- moodle/admin/settings/security.php 2011-04-21 01:01:22.000000000 +0100 +++ moodle-mod/admin/settings/security.php 2011-07-25 10:54:21.000000000 +0100 @@ -122,8 +122,13 @@ $temp->add(new admin_setting_configcheckbox('runclamonupload', get_string('runclamavonupload', 'admin'), get_string('configrunclamavonupload', 'admin'), 0)); $temp->add(new admin_setting_configexecutable('pathtoclam', get_string('pathtoclam', 'admin'), get_string('configpathtoclam', 'admin'), '')); $temp->add(new admin_setting_configdirectory('quarantinedir', get_string('quarantinedir', 'admin'), get_string('configquarantinedir', 'admin'), '')); - $temp->add(new admin_setting_configselect('clamfailureonupload', get_string('clamfailureonupload', 'admin'), get_string('configclamfailureonupload', 'admin'), 'donothing', array('donothing' => get_string('configclamdonothing', 'admin'), - 'actlikevirus' => get_string('configclamactlikevirus', 'admin')))); + if($CFG->ostype == 'WINDOWS') { + $temp->add(new admin_setting_configdirectory('clamdatabasedir', get_string('clamdatabasedir', 'admin'), get_string('configclamdatabasedir', 'admin'),'')); + } + + $temp->add(new admin_setting_configselect('clamfailureonupload', get_string('clamfailureonupload', 'admin'), get_string('configclamfailureonupload', 'admin'), 'donothing', array('donothing' => get_string('configclamdonothing', 'admin'), 'actlikevirus' => get_string('configclamactlikevirus', 'admin')))); + $temp->add(new admin_setting_configcheckbox('emailinfection', get_string('emailinfection', 'admin'), get_string('configemailinfection', 'admin'), 0)); + $ADMIN->add('security', $temp); } // end of speedup diff -Naur moodle/lang/en/admin.php moodle-mod/lang/en/admin.php --- moodle/lang/en/admin.php 2011-07-20 01:03:56.000000000 +0100 +++ moodle-mod/lang/en/admin.php 2011-07-25 10:30:07.000000000 +0100 @@ -95,6 +95,7 @@ $string['cannotdeletemodfilter'] = 'You cannot uninstall the \'{$a->filter}\' because it is part of the \'{$a->module}\' module.'; $string['cfgwwwrootslashwarning'] = 'You have defined $CFG->wwwroot incorrectly in your config.php file. You have included a \'/\' character at the end. Please remove it, or you will experience strange bugs like MDL-11061.'; $string['cfgwwwrootwarning'] = 'You have defined $CFG->wwwroot incorrectly in your config.php file. It does not match the URL you are using to access this page. Please correct it, or you will experience strange bugs like MDL-11061.'; +$string['clamdatabasedir'] = 'ClamWin database directory'; $string['clamfailureonupload'] = 'On clam AV failure'; $string['cleanup'] = 'Cleanup'; $string['clianswerno'] = 'n'; @@ -141,6 +142,7 @@ $string['configcachetype'] = 'Select a type of cache for Moodle to use. This will only configure the cache, remember to enable rcache so that the cache is used for something. Use only if you need to reduce the load on the database system -- otherwise Moodle will actually run slower. Medium-traffic sites may see benefits using \'internal\'. A single webserver with eAccelerator or Turckmmcache installed with the shared memory options enabled should try \'eaccelerator\'. If you have a multiple-server setup, and you have one or more memcached daemons running and the PHP-memcached extension, select \'memcached\' and configure the memached options below.
Note: make sure you test performance under load and tune accordingly -- the caches can make your site slower. In high-traffic situations, eAccelerator and memcached can yield the most benefits, but have the higher costs in CPU usage on the webserver.'; $string['configcalendarexportsalt'] = 'This random text is used for improving of security of authentication tokens used for exporting of calendars. Please note that all current tokens are invalidated if you change this hash salt.'; $string['configclamactlikevirus'] = 'Treat files like viruses'; +$string['configclamdatabasedir'] = 'ClamWin requires the path to it\'s database directory.'; $string['configclamdonothing'] = 'Treat files as OK'; $string['configclamfailureonupload'] = 'If you have configured clam to scan uploaded files, but it is configured incorrectly or fails to run for some unknown reason, how should it behave? If you choose \'Treat files like viruses\', they\'ll be moved into the quarantine area, or deleted. If you choose \'Treat files as OK\', the files will be moved to the destination directory like normal. Either way, admins will be alerted that clam has failed. If you choose \'Treat files like viruses\' and for some reason clam fails to run (usually because you have entered an invalid pathtoclam), ALL files that are uploaded will be moved to the given quarantine area, or deleted. Be careful with this setting.'; $string['configconvertformat'] = 'If latex, dvips and convert are available, the images are created using the specified format. If it is not, mimeTeX will be used and it will create GIF images.'; @@ -190,6 +192,7 @@ $string['configeditordictionary'] = 'This value will be used if aspell doesn\'t have dictionary for users own language.'; $string['configeditorfontlist'] = 'Select the fonts that should appear in the editor\'s drop-down list.'; $string['configemailchangeconfirmation'] = 'Require an email confirmation step when users change their email address in their profile.'; +$string['configemailinfection'] = 'When enabled, support will be emailed if a virus is detected on upload.'; $string['configenableajax'] = 'This setting allows you to control the use of AJAX (advanced client/server interfaces using Javascript) across the whole site. With this setting enabled users can still make a choice in their profile, otherwise AJAX is disabled for everybody.'; $string['configenablecalendarexport'] = 'Enable exporting or subscribing to calendars.'; $string['configenablecomments'] = 'Enable comments'; @@ -459,6 +462,7 @@ $string['editorspellinghelp'] = 'Enable or disable spell-checking. When enabled, aspell must be installed on the server.'; $string['editstrings'] = 'Edit words or phrases'; $string['emailchangeconfirmation'] = 'Email change confirmation'; +$string['emailinfection'] = 'Email support on virus detection'; $string['emoticontext'] = 'Text'; $string['emoticonimagename'] = 'Image name'; $string['emoticonalt'] = 'Alternative text'; diff -Naur moodle/repository/upload/lib.php moodle-mod/repository/upload/lib.php --- moodle/repository/upload/lib.php 2011-05-05 01:01:49.000000000 +0100 +++ moodle-mod/repository/upload/lib.php 2011-07-25 12:11:54.000000000 +0100 @@ -144,6 +144,58 @@ $record->userid = $USER->id; $record->source = ''; + if($CFG->runclamonupload == 1) + { + $return; + $output; + $tmpfile = escapeshellarg($_FILES[$elname]['tmp_name']); + + if($CFG->ostype == 'WINDOWS') { + $cmd = $CFG->pathtoclam . " " . $tmpfile . " --database=" . $CFG->clamdatabasedir; + } else { + $cmd = $CFG->pathtoclam . " " . $tmpfile . " 2>&1"; + chmod($_FILES[$elname]['tmp_name'], $CFG->directorypermissions); + } + + exec($cmd, $output, $return); + + switch($return) + { + case 0: + //clean + break; + case 1: + //infected + + move_uploaded_file($tmpfile, $CFG->quarantinedir . "\malware-" . time()); + $scanresults = explode(" ", $output[0]); + $virusname = $scanresults[1]; + $message = "A virus has been detected in a file upload attempt: \r\nUsername: " . $USER->username . "\r\nName: " . fullname($USER) . "\r\nFilename: " . $_FILES[$elname]['name'] . "\r\nVirus Name: " . $virusname; + if($CFG->emailinfection == 1) { + $supportuser = generate_email_supportuser(); + email_to_user($supportuser, $supportuser, "Virus Infected Upload", $message); + } + throw new moodle_exception('virusdetected', 'repository'); + break; + default: + //Clam has failed + + if($CFG->clamfailureonupload == 'actlikevirus') { + move_uploaded_file($tmpfile, $CFG->quarantinedir . "/malware-" . time()); + $scanresults = explode(" ", $output[0]); + $virusname = $scanresults[1]; + $message = "A virus has been detected in a file upload attempt: \r\nUsername: " . $USER->username . "\r\nName: " . fullname($USER) . "\r\nFilename: " . $_FILES[$elname]['name'] . "\r\nVirus Name: " . $virusname; + if($CFG->emailinfection == 1) { + $supportuser = generate_email_supportuser(); + email_to_user($supportuser, $supportuser, "Virus Infected Upload", $message); + } + throw new moodle_exception('virusdetected', 'repository'); + } + break; + } + } + + 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);