Ticket #434
Error with AV routine if an empty file was uploaded. This includes any infected files being intercepted by the server's AV scanner. git-svn-id: http://locode01.ad.dom/svn/WEBMIP/trunk@4159 248e525c-4dfb-0310-94bc-949c084e9493
This commit is contained in:
@@ -11,7 +11,7 @@ CREATE OR REPLACE PACKAGE mip_virus_check IS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
check_file - allows MIP to run an anti-virus scan on a given file
|
check_file - allows MIP to run an anti-virus scan on a given file
|
||||||
|
|
||||||
%param p_name - the APEX name of the file
|
%param p_name - the APEX name of the file
|
||||||
%param p_location - the directory on the server where the file will be tested
|
%param p_location - the directory on the server where the file will be tested
|
||||||
*/
|
*/
|
||||||
@@ -21,7 +21,7 @@ CREATE OR REPLACE PACKAGE mip_virus_check IS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
get_fs_name - returns the file name from teh APEX doc's URI
|
get_fs_name - returns the file name from teh APEX doc's URI
|
||||||
|
|
||||||
%param p_name - the APEX doc URI (in format unique ID/filename)
|
%param p_name - the APEX doc URI (in format unique ID/filename)
|
||||||
%return VARCHAR2 - the actual name of the file
|
%return VARCHAR2 - the actual name of the file
|
||||||
*/
|
*/
|
||||||
@@ -57,7 +57,7 @@ CREATE OR REPLACE PACKAGE BODY mip_virus_check IS
|
|||||||
l_offset NUMBER(38) := 1;
|
l_offset NUMBER(38) := 1;
|
||||||
l_chunksize INTEGER;
|
l_chunksize INTEGER;
|
||||||
l_out_file utl_file.file_type;
|
l_out_file utl_file.file_type;
|
||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
pl('Writing file ' || p_name || ', ' || p_fs_name);
|
pl('Writing file ' || p_name || ', ' || p_fs_name);
|
||||||
SELECT blob_content
|
SELECT blob_content
|
||||||
@@ -66,50 +66,50 @@ CREATE OR REPLACE PACKAGE BODY mip_virus_check IS
|
|||||||
WHERE upper(NAME) = upper(p_name);
|
WHERE upper(NAME) = upper(p_name);
|
||||||
pl('Got file from APEX. Downloading');
|
pl('Got file from APEX. Downloading');
|
||||||
l_chunksize := dbms_lob.getchunksize(l_lob_loc);
|
l_chunksize := dbms_lob.getchunksize(l_lob_loc);
|
||||||
|
|
||||||
IF (l_chunksize < 32767) THEN
|
IF (l_chunksize < 32767) THEN
|
||||||
l_buffer_size := l_chunksize;
|
l_buffer_size := l_chunksize;
|
||||||
ELSE
|
ELSE
|
||||||
l_buffer_size := 32767;
|
l_buffer_size := 32767;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
l_amount := l_buffer_size;
|
l_amount := l_buffer_size;
|
||||||
|
|
||||||
dbms_lob.OPEN(l_lob_loc, dbms_lob.lob_readonly);
|
dbms_lob.OPEN(l_lob_loc, dbms_lob.lob_readonly);
|
||||||
|
|
||||||
l_out_file := utl_file.fopen(location => p_location,
|
l_out_file := utl_file.fopen(location => p_location,
|
||||||
filename => p_fs_name,
|
filename => p_fs_name,
|
||||||
open_mode => 'wb',
|
open_mode => 'wb',
|
||||||
max_linesize => 32767);
|
max_linesize => 32767);
|
||||||
|
|
||||||
WHILE l_amount >= l_buffer_size LOOP
|
WHILE l_amount >= l_buffer_size LOOP
|
||||||
|
|
||||||
dbms_lob.READ(lob_loc => l_lob_loc,
|
dbms_lob.READ(lob_loc => l_lob_loc,
|
||||||
amount => l_amount,
|
amount => l_amount,
|
||||||
offset => l_offset,
|
offset => l_offset,
|
||||||
buffer => l_buffer);
|
buffer => l_buffer);
|
||||||
|
|
||||||
l_offset := l_offset + l_amount;
|
l_offset := l_offset + l_amount;
|
||||||
|
|
||||||
utl_file.put_raw(file => l_out_file,
|
utl_file.put_raw(file => l_out_file,
|
||||||
buffer => l_buffer,
|
buffer => l_buffer,
|
||||||
autoflush => TRUE);
|
autoflush => TRUE);
|
||||||
|
|
||||||
--utl_file.fflush(file => l_out_file);
|
--utl_file.fflush(file => l_out_file);
|
||||||
|
|
||||||
END LOOP;
|
END LOOP;
|
||||||
|
|
||||||
utl_file.fflush(file => l_out_file);
|
utl_file.fflush(file => l_out_file);
|
||||||
|
|
||||||
utl_file.fclose(l_out_file);
|
utl_file.fclose(l_out_file);
|
||||||
|
|
||||||
dbms_lob.CLOSE(l_lob_loc);
|
dbms_lob.CLOSE(l_lob_loc);
|
||||||
END write_file;
|
END write_file;
|
||||||
--
|
--
|
||||||
|
|
||||||
/**
|
/**
|
||||||
load_file - procedure to reload the resultant file after virus checking is complete.
|
load_file - procedure to reload the resultant file after virus checking is complete.
|
||||||
|
|
||||||
%param p_uri - the file's unique URI as stored in the Apex view
|
%param p_uri - the file's unique URI as stored in the Apex view
|
||||||
*/
|
*/
|
||||||
PROCEDURE load_file(p_uri wwv_flow_files.NAME%TYPE) IS
|
PROCEDURE load_file(p_uri wwv_flow_files.NAME%TYPE) IS
|
||||||
@@ -119,49 +119,49 @@ CREATE OR REPLACE PACKAGE BODY mip_virus_check IS
|
|||||||
l_blob BLOB;
|
l_blob BLOB;
|
||||||
l_filename VARCHAR2(250);
|
l_filename VARCHAR2(250);
|
||||||
BEGIN
|
BEGIN
|
||||||
|
|
||||||
pl('reload_after_av');
|
pl('reload_after_av');
|
||||||
dbms_lob.createtemporary(lob_loc => l_blob, cache => TRUE);
|
dbms_lob.createtemporary(lob_loc => l_blob, cache => TRUE);
|
||||||
-- lock the table by selecting for update
|
-- lock the table by selecting for update
|
||||||
SELECT f.blob_content
|
SELECT f.blob_content
|
||||||
INTO l_blob
|
INTO l_blob
|
||||||
FROM wwv_flow_files f
|
FROM wwv_flow_files f
|
||||||
|
|
||||||
WHERE f.NAME = p_uri
|
WHERE f.NAME = p_uri
|
||||||
FOR UPDATE;
|
FOR UPDATE;
|
||||||
|
|
||||||
SELECT directory_path
|
SELECT directory_path
|
||||||
INTO l_directory_path
|
INTO l_directory_path
|
||||||
FROM all_directories
|
FROM all_directories
|
||||||
WHERE directory_name = 'WEBMIP_VIRUS';
|
WHERE directory_name = 'WEBMIP_VIRUS';
|
||||||
|
|
||||||
l_filename := REPLACE(p_uri, '/', '!');
|
l_filename := REPLACE(p_uri, '/', '!');
|
||||||
|
|
||||||
l_source_file := bfilename('WEBMIP_VIRUS', l_filename);
|
l_source_file := bfilename('WEBMIP_VIRUS', l_filename);
|
||||||
l_source_file_length := dbms_lob.getlength(l_source_file);
|
l_source_file_length := dbms_lob.getlength(l_source_file);
|
||||||
|
|
||||||
dbms_lob.OPEN(file_loc => l_source_file,
|
dbms_lob.OPEN(file_loc => l_source_file,
|
||||||
open_mode => dbms_lob.lob_readonly);
|
open_mode => dbms_lob.lob_readonly);
|
||||||
|
|
||||||
dbms_lob.loadfromfile(dest_lob => l_blob,
|
dbms_lob.loadfromfile(dest_lob => l_blob,
|
||||||
src_lob => l_source_file,
|
src_lob => l_source_file,
|
||||||
amount => l_source_file_length);
|
amount => l_source_file_length);
|
||||||
|
|
||||||
-- update the BLOB
|
-- update the BLOB
|
||||||
UPDATE wwv_flow_files f
|
UPDATE wwv_flow_files f
|
||||||
SET f.blob_content = l_blob
|
SET f.blob_content = l_blob
|
||||||
WHERE f.NAME = p_uri;
|
WHERE f.NAME = p_uri;
|
||||||
|
|
||||||
--close the file
|
--close the file
|
||||||
dbms_lob.fileclose(file_loc => l_source_file);
|
dbms_lob.fileclose(file_loc => l_source_file);
|
||||||
|
|
||||||
pl('Loaded:' || l_filename);
|
pl('Loaded:' || l_filename);
|
||||||
END load_file;
|
END load_file;
|
||||||
--
|
--
|
||||||
|
|
||||||
/*\**
|
/*\**
|
||||||
trigger_av_scan - triggers the anti-virus scan on the file
|
trigger_av_scan - triggers the anti-virus scan on the file
|
||||||
|
|
||||||
%param p_location - the location of the file on the file server
|
%param p_location - the location of the file on the file server
|
||||||
%param p_fs_name - the name of the file to check
|
%param p_fs_name - the name of the file to check
|
||||||
*\
|
*\
|
||||||
@@ -173,16 +173,16 @@ CREATE OR REPLACE PACKAGE BODY mip_virus_check IS
|
|||||||
dbms_output.put_line('Checking file.');
|
dbms_output.put_line('Checking file.');
|
||||||
av_checker := cout_system_configuration.get_configuration_item('AV_LOCATION');
|
av_checker := cout_system_configuration.get_configuration_item('AV_LOCATION');
|
||||||
l_location := cout_system_configuration.get_configuration_item('AV_DIRECTORY');
|
l_location := cout_system_configuration.get_configuration_item('AV_DIRECTORY');
|
||||||
|
|
||||||
av_cmd := '"' || av_checker ||'" /automation '||l_location||'\'||p_fs_name;
|
av_cmd := '"' || av_checker ||'" /automation '||l_location||'\'||p_fs_name;
|
||||||
|
|
||||||
dbms_output.put_line('about to check');
|
dbms_output.put_line('about to check');
|
||||||
dbms_output.put_line(av_cmd);
|
dbms_output.put_line(av_cmd);
|
||||||
|
|
||||||
mip_systemcall.syscall(p_cmd_str => av_cmd);
|
mip_systemcall.syscall(p_cmd_str => av_cmd);
|
||||||
|
|
||||||
dbms_output.put_line('Finished checking');
|
dbms_output.put_line('Finished checking');
|
||||||
|
|
||||||
RETURN TRUE;
|
RETURN TRUE;
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN OTHERS THEN
|
WHEN OTHERS THEN
|
||||||
@@ -195,7 +195,7 @@ CREATE OR REPLACE PACKAGE BODY mip_virus_check IS
|
|||||||
check_file_exists - tests if the file is still on the server
|
check_file_exists - tests if the file is still on the server
|
||||||
if the file is no longer there then it has
|
if the file is no longer there then it has
|
||||||
failed the virus scan and been quarantined
|
failed the virus scan and been quarantined
|
||||||
|
|
||||||
%param p_location - the location of the file on the file server
|
%param p_location - the location of the file on the file server
|
||||||
%param p_fs_name - the name of the file to check
|
%param p_fs_name - the name of the file to check
|
||||||
*/
|
*/
|
||||||
@@ -221,7 +221,7 @@ CREATE OR REPLACE PACKAGE BODY mip_virus_check IS
|
|||||||
/**
|
/**
|
||||||
delete_file_from_server - removes the files from the server once AV
|
delete_file_from_server - removes the files from the server once AV
|
||||||
scan is complete. Housekeeping.
|
scan is complete. Housekeeping.
|
||||||
|
|
||||||
%param p_location - the location of the file on the file server
|
%param p_location - the location of the file on the file server
|
||||||
%param p_fs_name - the name of the file to check
|
%param p_fs_name - the name of the file to check
|
||||||
*/
|
*/
|
||||||
@@ -234,7 +234,7 @@ CREATE OR REPLACE PACKAGE BODY mip_virus_check IS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
delete_file_from_MIP - removes an infected file from the MIP system
|
delete_file_from_MIP - removes an infected file from the MIP system
|
||||||
|
|
||||||
%param p_location - the location of the file on the file server
|
%param p_location - the location of the file on the file server
|
||||||
%param p_fs_name - the name of the file to check
|
%param p_fs_name - the name of the file to check
|
||||||
*/
|
*/
|
||||||
@@ -244,13 +244,13 @@ CREATE OR REPLACE PACKAGE BODY mip_virus_check IS
|
|||||||
l_result := mip_files.delete_file(p_id => p_doc_id,
|
l_result := mip_files.delete_file(p_id => p_doc_id,
|
||||||
p_doc_status => 'REMOVED MALICIOUS',
|
p_doc_status => 'REMOVED MALICIOUS',
|
||||||
p_reason => 'Malicious content found - deleted by Anti-virus.');
|
p_reason => 'Malicious content found - deleted by Anti-virus.');
|
||||||
|
|
||||||
END delete_file_from_mip;
|
END delete_file_from_mip;
|
||||||
--
|
--
|
||||||
|
|
||||||
/**
|
/**
|
||||||
check_file - allows MIP to run an anti-virus scan on a given file
|
check_file - allows MIP to run an anti-virus scan on a given file
|
||||||
|
|
||||||
%param p_name - the APEX name of the file
|
%param p_name - the APEX name of the file
|
||||||
%param p_location - the directory on the server where the file will be tested
|
%param p_location - the directory on the server where the file will be tested
|
||||||
*/
|
*/
|
||||||
@@ -264,42 +264,46 @@ CREATE OR REPLACE PACKAGE BODY mip_virus_check IS
|
|||||||
-- need to remove the slash from the URI so we can store multiple files
|
-- need to remove the slash from the URI so we can store multiple files
|
||||||
-- change it to a "!" for now.
|
-- change it to a "!" for now.
|
||||||
l_fs_name := REPLACE(p_name, '/', '!');
|
l_fs_name := REPLACE(p_name, '/', '!');
|
||||||
|
|
||||||
SELECT doc.id INTO l_doc_id FROM documents doc WHERE doc.uri = p_name;
|
SELECT doc.id INTO l_doc_id FROM documents doc WHERE doc.uri = p_name;
|
||||||
|
|
||||||
-- write the file to the file system, trigger a scan, check if the file is still there
|
-- write the file to the file system, trigger a scan, check if the file is still there
|
||||||
-- and then act accordingly if it isn't.
|
-- and then act accordingly if it isn't.
|
||||||
write_file(p_name => p_name,
|
write_file(p_name => p_name,
|
||||||
p_location => p_location,
|
p_location => p_location,
|
||||||
p_fs_name => l_fs_name);
|
p_fs_name => l_fs_name);
|
||||||
|
|
||||||
--dbms_lock.sleep(5);
|
--dbms_lock.sleep(5);
|
||||||
|
|
||||||
pl('Checking file exists:' || l_fs_name);
|
pl('Checking file exists:' || l_fs_name);
|
||||||
file_result := check_file_exists(p_fs_name => l_fs_name);
|
file_result := check_file_exists(p_fs_name => l_fs_name);
|
||||||
|
|
||||||
IF NOT file_result THEN
|
IF NOT file_result THEN
|
||||||
delete_file_from_mip(p_doc_id => l_doc_id);
|
delete_file_from_mip(p_doc_id => l_doc_id);
|
||||||
pl('File removed from MIP');
|
pl('File removed from MIP');
|
||||||
ELSE
|
ELSE
|
||||||
-- reload the leftovers into MIP
|
-- reload the leftovers into MIP
|
||||||
load_file(p_uri => p_name);
|
load_file(p_uri => p_name);
|
||||||
|
|
||||||
pl('Delete file from server');
|
pl('Delete file from server');
|
||||||
delete_file_from_server(p_location => p_location,
|
delete_file_from_server(p_location => p_location,
|
||||||
p_fs_name => l_fs_name);
|
p_fs_name => l_fs_name);
|
||||||
|
|
||||||
mip_documents.set_doc_available(p_docu_id => l_doc_id,
|
mip_documents.set_doc_available(p_docu_id => l_doc_id,
|
||||||
p_description => 'Virus checked by MIP');
|
p_description => 'Virus checked by MIP');
|
||||||
|
|
||||||
END IF;
|
END IF;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN no_data_found THEN
|
||||||
|
delete_file_from_mip(p_doc_id => l_doc_id);
|
||||||
|
pl('File uploaded was empty and has been removed from MIP');
|
||||||
|
|
||||||
END check_file;
|
END check_file;
|
||||||
--
|
--
|
||||||
|
|
||||||
/**
|
/**
|
||||||
get_fs_name - returns the file name from the APEX doc's URI
|
get_fs_name - returns the file name from the APEX doc's URI
|
||||||
|
|
||||||
%param p_name - the APEX doc URI (in format unique ID/filename)
|
%param p_name - the APEX doc URI (in format unique ID/filename)
|
||||||
%return VARCHAR2 - the actual name of the file
|
%return VARCHAR2 - the actual name of the file
|
||||||
*/
|
*/
|
||||||
@@ -308,10 +312,10 @@ CREATE OR REPLACE PACKAGE BODY mip_virus_check IS
|
|||||||
seperator_pos NUMBER;
|
seperator_pos NUMBER;
|
||||||
BEGIN
|
BEGIN
|
||||||
seperator_pos := instr(p_name, '/', -1);
|
seperator_pos := instr(p_name, '/', -1);
|
||||||
|
|
||||||
IF NOT seperator_pos = 0 THEN
|
IF NOT seperator_pos = 0 THEN
|
||||||
ret_fs_name := substr(p_name, seperator_pos + 1);
|
ret_fs_name := substr(p_name, seperator_pos + 1);
|
||||||
|
|
||||||
RETURN ret_fs_name;
|
RETURN ret_fs_name;
|
||||||
ELSE
|
ELSE
|
||||||
RETURN NULL;
|
RETURN NULL;
|
||||||
|
|||||||
Reference in New Issue
Block a user