mirror of https://github.com/Cisco-Talos/clamav
parent
8340e55660
commit
a4e6868cea
@ -0,0 +1,90 @@ |
||||
/*
|
||||
* Compilation: gcc -Wall ex1.c -o ex1 -lclamav |
||||
* |
||||
* Copyright (C) 2013-2022 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
||||
* Copyright (C) 2007-2013 Sourcefire, Inc. |
||||
* Author: Tomasz Kojm <tkojm@clamav.net> |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation; either version 2 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
||||
* MA 02110-1301, USA. |
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#ifndef _WIN32 |
||||
#include <unistd.h> |
||||
#endif |
||||
#include <sys/types.h> |
||||
#include <sys/stat.h> |
||||
#include <fcntl.h> |
||||
#include <clamav.h> |
||||
|
||||
#ifndef O_BINARY |
||||
#define O_BINARY 0 |
||||
#endif |
||||
|
||||
/*
|
||||
* Exit codes: 0 is success. See `cl_error_t` enum from clamav.h. |
||||
*/ |
||||
int main(int argc, char **argv) |
||||
{ |
||||
int fd; |
||||
cl_error_t ret; |
||||
|
||||
const char *filename; |
||||
const char *destination_directory; |
||||
bool dont_verify = false; |
||||
|
||||
char dest_buff[1024]; |
||||
|
||||
unsigned long int size = 0; |
||||
unsigned int sigs = 0; |
||||
long double mb; |
||||
const char *virname; |
||||
struct cl_engine *engine; |
||||
struct cl_scan_options options; |
||||
|
||||
switch (argc) { |
||||
case 2: |
||||
filename = argv[1]; |
||||
destination_directory = "."; |
||||
break; |
||||
case 3: |
||||
filename = argv[1]; |
||||
destination_directory = argv[2]; |
||||
break; |
||||
case 4: |
||||
if (strcmp(argv[1], "--no-verify") == 0) { |
||||
filename = argv[2]; |
||||
destination_directory = argv[3]; |
||||
dont_verify = true; |
||||
} else { |
||||
printf("Usage: %s [--no-verify] file [destination_directory]\n", argv[0]); |
||||
return CL_EARG; |
||||
} |
||||
break; |
||||
default: |
||||
printf("Usage: %s [--no-verify] file [destination_directory]\n", argv[0]); |
||||
return CL_EARG; |
||||
} |
||||
|
||||
ret = cl_cvdunpack(filename, destination_directory, dont_verify); |
||||
if (ret != CL_SUCCESS) { |
||||
printf("ERROR: %s\n", cl_strerror(ret)); |
||||
} |
||||
|
||||
return (int)ret; |
||||
} |
@ -0,0 +1,139 @@ |
||||
# Copyright (C) 2020-2022 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
||||
|
||||
""" |
||||
Run sigtool tests. |
||||
""" |
||||
|
||||
import os |
||||
import platform |
||||
import shutil |
||||
import sys |
||||
|
||||
sys.path.append('../unit_tests') |
||||
import testcase |
||||
|
||||
|
||||
os_platform = platform.platform() |
||||
operating_system = os_platform.split('-')[0].lower() |
||||
|
||||
program_name = 'ex_cl_cvdunpack' |
||||
|
||||
class TC(testcase.TestCase): |
||||
@classmethod |
||||
def setUpClass(cls): |
||||
super(TC, cls).setUpClass() |
||||
|
||||
# Find the example program |
||||
if operating_system == 'windows': |
||||
# Windows needs the example program to be in the same directory as libclamav and the rest. |
||||
shutil.copy( |
||||
str(TC.path_build / 'examples' / program_name + '.exe'), |
||||
str(TC.path_build / 'unit_tests' / program_name + '.exe'), |
||||
) |
||||
|
||||
TC.example_program = TC.path_build / 'unit_tests' / program_name + '.exe' |
||||
if not TC.example_program.exists(): |
||||
# Try the static version. |
||||
TC.example_program = TC.path_build / 'unit_tests' / program_name + '_static.exe' |
||||
if not TC.example_program.exists(): |
||||
raise Exception('Could not find the example program.') |
||||
else: |
||||
# Linux and macOS can use the LD_LIBRARY_PATH environment variable to find libclamav |
||||
TC.example_program = TC.path_build / 'examples' / program_name |
||||
if not TC.example_program.exists(): |
||||
# Try the static version. |
||||
TC.example_program = TC.path_build / 'examples' / program_name + '_static' |
||||
if not TC.example_program.exists(): |
||||
raise Exception('Could not find the example program.') |
||||
|
||||
# Copy the test cvd to the temp directory |
||||
shutil.copyfile( |
||||
str(TC.path_source / 'unit_tests' / 'input' / 'freshclam_testfiles' / 'test-2.cvd'), |
||||
str(TC.path_tmp / 'verify_good.cvd') |
||||
) |
||||
|
||||
# Also get a corrupted version of the cvd |
||||
shutil.copyfile( |
||||
str(TC.path_source / 'unit_tests' / 'input' / 'freshclam_testfiles' / 'test-2.cvd'), |
||||
str(TC.path_tmp / 'verify_bad.cvd') |
||||
) |
||||
with open(str(TC.path_tmp / 'verify_bad.cvd'), 'r+b') as f: |
||||
f.seek(0, os.SEEK_END) |
||||
f.write(b'egad bad cvd') |
||||
|
||||
@classmethod |
||||
def tearDownClass(cls): |
||||
super(TC, cls).tearDownClass() |
||||
|
||||
def setUp(self): |
||||
super(TC, self).setUp() |
||||
|
||||
def tearDown(self): |
||||
super(TC, self).tearDown() |
||||
self.verify_valgrind_log() |
||||
|
||||
def test_cl_cvdunpack_verify_success(self): |
||||
self.step_name('test with good cvd, verify extraction') |
||||
|
||||
# Make temp directory to store extracted stuffs |
||||
(TC.path_tmp / 'verify_good').mkdir(parents=True) |
||||
|
||||
command = '{valgrind} {valgrind_args} {example} {database} {tmp}'.format( |
||||
valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, example=TC.example_program, |
||||
database=TC.path_tmp / 'verify_good.cvd', |
||||
tmp=TC.path_tmp / 'verify_good' |
||||
) |
||||
output = self.execute_command(command) |
||||
|
||||
assert output.ec == 0 # success |
||||
for each in (TC.path_tmp / 'verify_good').iterdir(): |
||||
if each.name == 'test.info': |
||||
return |
||||
# could not find test.info |
||||
assert False |
||||
|
||||
def test_cl_cvdunpack_verify_failure(self): |
||||
self.step_name('test with bad cvd, verify failure') |
||||
|
||||
# Make temp directory to store extracted stuffs |
||||
(TC.path_tmp / 'verify_bad').mkdir(parents=True) |
||||
|
||||
command = '{valgrind} {valgrind_args} {example} {database} {tmp}'.format( |
||||
valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, example=TC.example_program, |
||||
database=TC.path_tmp / 'verify_bad.cvd', |
||||
tmp=TC.path_tmp / 'verify_bad' |
||||
) |
||||
output = self.execute_command(command) |
||||
|
||||
assert output.ec != 0 # success |
||||
for each in (TC.path_tmp / 'verify_bad').iterdir(): |
||||
if each.name == 'test.info': |
||||
# found test.info |
||||
assert False |
||||
|
||||
expected_results = [ |
||||
'ERROR: Can\'t verify database integrity', |
||||
] |
||||
self.verify_output(output.out, expected=expected_results) |
||||
|
||||
def test_cl_cvdunpack_noverify(self): |
||||
self.step_name('test with bad cvd, use --no-verify') |
||||
|
||||
# Make temp directory to store extracted stuffs |
||||
(TC.path_tmp / 'no_verify_bad').mkdir(parents=True) |
||||
|
||||
command = '{valgrind} {valgrind_args} {example} --no-verify {database} {tmp}'.format( |
||||
valgrind=TC.valgrind, valgrind_args=TC.valgrind_args, example=TC.example_program, |
||||
database=TC.path_tmp / 'verify_bad.cvd', |
||||
tmp=TC.path_tmp / 'no_verify_bad' |
||||
) |
||||
output = self.execute_command(command) |
||||
|
||||
# In this case, because we just tacked on bytes at the end, it will |
||||
# probably still extract at least some stuff. |
||||
assert output.ec == 0 # success |
||||
for each in (TC.path_tmp / 'no_verify_bad').iterdir(): |
||||
if each.name == 'test.info': |
||||
return |
||||
# could not find test.info |
||||
assert False |
Loading…
Reference in new issue