clamav

package module
v0.0.0-...-f5593db Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 24, 2019 License: GPL-2.0 Imports: 4 Imported by: 0

README

clamav

Go bindings for the ClamAV antivirus library (http://clamav.net)

This is a thin wrapper around the ClamAV antivirus library. The code includes a small scanner as an example in the avclient directory.

To learn more about ClamAV and to install antivirus databases see http://www.clamav.net/lang/en/.

To build make sure the C compiler can see the libclamav shared library, if not you may have to specify it as LDFLAGS: -L/path/to/dylib in the CGo header of each file importing "C". Alternatively, if you have compiled ClamAV in a non-standard directory you can use the following arguments to the go tool:

CGO_CFLAGS=-I/path/to/include CGO_LDFLAGS=-L/path/to/lib go install

For example, on Mountain Lion, after compiling ClamAV by hand, the library gets installed in /usr/local/lib/x86_64. The following command then works to compile the wrappers:

CGO_CFLAGS=-I/usr/local/include CGO_LDFLAGS=-L/usr/local/lib/x86_64 go install

Run go build and, if you have copied the virus files from ClamAV's test/ subdirectory, you can run go test. Run go test -test.bench=Bench to run the benchmarks.

The examples/avclient directory contains a simple filesystem scanner. To compile it run go build in that directory.

Update:

The library is updated to be used with newer versions of libclamav (currently tested with go 1.12 and libclamav version 0.101.4 on Debian 10).

To test the library you will require the testdata that is generated during the clamav build process. The command to test the library is go test ./test

Requirements to build:

  • clamav - version 0.101.4
  • libclamav-dev - version 0.101.4

Documentation

Overview

Package clamav is a wrapper around libclamav. For more information about libclamav see http://www.clamav.net

Package clamav is a wrapper around libclamav. For more information about libclamav see http://www.clamav.net

Index

Constants

View Source
const (
	Success           ErrorCode = C.CL_SUCCESS
	Clean                       = C.CL_CLEAN
	Virus                       = C.CL_VIRUS
	Enullarg                    = C.CL_ENULLARG
	Earg                        = C.CL_EARG
	Emalfdb                     = C.CL_EMALFDB
	Ecvd                        = C.CL_ECVD
	Everify                     = C.CL_EVERIFY
	Eunpack                     = C.CL_EUNPACK
	Eopen                       = C.CL_EOPEN // IO and memory errors below
	Ecreat                      = C.CL_ECREAT
	Eunlink                     = C.CL_EUNLINK
	Estat                       = C.CL_ESTAT
	Eread                       = C.CL_EREAD
	Eseek                       = C.CL_ESEEK
	Ewrite                      = C.CL_EWRITE
	Edup                        = C.CL_EDUP
	Eacces                      = C.CL_EACCES
	Etmpfile                    = C.CL_ETMPFILE
	Etmpdir                     = C.CL_ETMPDIR
	Emap                        = C.CL_EMAP
	Emem                        = C.CL_EMEM
	Etimeout                    = C.CL_ETIMEOUT
	Break                       = C.CL_BREAK // internal (not reported outside libclamav)
	Emaxrec                     = C.CL_EMAXREC
	Emaxsize                    = C.CL_EMAXSIZE
	Emaxfiles                   = C.CL_EMAXFILES
	Eformat                     = C.CL_EFORMAT
	Eparse                      = C.CL_EPARSE
	Ebytecode                   = C.CL_EBYTECODE
	EbytecodeTestfail           = C.CL_EBYTECODE_TESTFAIL
	Elock                       = C.CL_ELOCK // c4w error codes
	Ebusy                       = C.CL_EBUSY
	Estate                      = C.CL_ESTATE
	ELast                       = C.CL_ELAST_ERROR // no error codes below this line please
)

return codes

View Source
const (
	EngineMaxScansize      EngineField = C.CL_ENGINE_MAX_SCANSIZE      // uint64_t
	EngineMaxFilesize                  = C.CL_ENGINE_MAX_FILESIZE      // uint64_t
	EngineMaxRecursion                 = C.CL_ENGINE_MAX_RECURSION     // uint32_t
	EngineMaxFiles                     = C.CL_ENGINE_MAX_FILES         // uint32_t
	EngineMinCcCount                   = C.CL_ENGINE_MIN_CC_COUNT      // uint32_t
	EngineMinSsnCount                  = C.CL_ENGINE_MIN_SSN_COUNT     // uint32_t
	EnginePuaCategories                = C.CL_ENGINE_PUA_CATEGORIES    // (char *)
	EngineDbOptions                    = C.CL_ENGINE_DB_OPTIONS        // uint32_t
	EngineDbVersion                    = C.CL_ENGINE_DB_VERSION        // uint32_t
	EngineDbTime                       = C.CL_ENGINE_DB_TIME           // time_t
	EngineAcOnly                       = C.CL_ENGINE_AC_ONLY           // uint32_t
	EngineAcMindepth                   = C.CL_ENGINE_AC_MINDEPTH       // uint32_t
	EngineAcMaxdepth                   = C.CL_ENGINE_AC_MAXDEPTH       // uint32_t
	EngineTmpdir                       = C.CL_ENGINE_TMPDIR            // (char *)
	EngineKeeptmp                      = C.CL_ENGINE_KEEPTMP           // uint32_t
	EngineBytecodeSecurity             = C.CL_ENGINE_BYTECODE_SECURITY // uint32_t
	EngineBytecodeTimeout              = C.CL_ENGINE_BYTECODE_TIMEOUT  // uint32_t
	EngineBytecodeMode                 = C.CL_ENGINE_BYTECODE_MODE     // uint32_t
)

Engine settings

View Source
const (
	BytecodeTrustAll     BytecodeSecurity = C.CL_BYTECODE_TRUST_ALL     // obsolete
	BytecodeTrustSigned                   = C.CL_BYTECODE_TRUST_SIGNED  // default
	BytecodeTrustNothing                  = C.CL_BYTECODE_TRUST_NOTHING // paranoid setting
)

Bytecode security settings

View Source
const (
	BytecodeModeAuto        BytecodeMode = C.CL_BYTECODE_MODE_AUTO        // JIT if possible, fallback to interpreter
	BytecodeModeJit                      = C.CL_BYTECODE_MODE_JIT         // force JIT
	BytecodeModeInterpreter              = C.CL_BYTECODE_MODE_INTERPRETER // force interpreter
	BytecodeModeTest                     = C.CL_BYTECODE_MODE_TEST        // both JIT and interpreter, compare results, all failures are fatal
	BytecodeModeOff                      = C.CL_BYTECODE_MODE_OFF         // for query only, not settable
)

Bytecode mode settings

View Source
const (
	DbPhishing         = 0x2
	DbPhishingUrls     = 0x8
	DbPua              = 0x10
	DbCvdnotmp         = 0x20 // obsolete
	DbOfficial         = 0x40 // internal
	DbPuaMode          = 0x80
	DbPuaInclude       = 0x100
	DbPuaExclude       = 0x200
	DbCompiled         = 0x400 // internal
	DbDirectory        = 0x800 // internal
	DbOfficialOnly     = 0x1000
	DbBytecode         = 0x2000
	DbSigned           = 0x4000 // internal
	DbBytecodeUnsigned = 0x8000

	// recommended db settings
	DbStdopt = (DbPhishing | DbPhishingUrls | DbBytecode)
)

Virus signature database options

View Source
const (
	// scan options
	// General capabilities options
	ScanAllmatches          = 0x1  // scan in all-match mode
	ScanCollectMetadata     = 0x2  // collect metadata
	ScanHeuristics          = 0x4  // option to enable heuristic alerts
	ScanHeuristicPrecedence = 0x8  // allow heuristic match to take precedence
	ScanUnprivileged        = 0x10 // scanner will not have read access to files

	// Parsing capabilities options
	ScanParseArchive = 0x1
	ScanParseElf     = 0x2
	ScanParsePDF     = 0x4
	ScanParseSWF     = 0x8
	ScanParseHWP3    = 0x10
	ScanParseXMLDocs = 0x20
	ScanParseMail    = 0x40
	ScanParseOLE2    = 0x80
	ScanParseHTML    = 0x100
	ScanParsePE      = 0x200

	// Heuristics alerting options
	ScanHeuristicBroken                = 0x2   /* alert on broken PE and broken ELF files */
	ScanHeuristicExceedsMax            = 0x4   /* alert when files exceed scan limits (filesize, max scansize, or max recursion depth) */
	ScanHeuristicPhishingSSLMismatch   = 0x8   /* alert on SSL mismatches */
	ScanHeuristicPhishingCloak         = 0x10  /* alert on cloaked URLs in emails */
	ScanHeuristicMacros                = 0x20  /* alert on OLE2 files containing macros */
	ScanHeuristicEncryptedArchive      = 0x40  /* alert if archive is encrypted (rar, zip, etc) */
	ScanHeuristicEncryptedDoc          = 0x80  /* alert if a document is encrypted (pdf, docx, etc) */
	ScanHeuristicPartitionIntxn        = 0x100 /* alert if partition table size doesn't make sense */
	ScanHeuristicStructured            = 0x200 /* data loss prevention options, i.e. alert when detecting personal information */
	ScanHeuristicStructuredSSNNormal   = 0x400 /* alert when detecting social security numbers */
	ScanHeuristicStructuredSSNStripped = 0x800 /* alert when detecting stripped social security numbers */

	// Mail scanning options
	ScanMailPartialMessage = 0x1

	// Developer options
	ScanDevCollectSha             = 0x1 /* Enables hash output in sha-collect builds - for internal use only */
	ScanDevCollectPerformanceInfo = 0x2 /* collect performance timings */

)

Scanner options

View Source
const (
	CountSigsOfficial = iota
	CountSigsUnofficial
	CountSigsAll = (CountSigsOfficial | CountSigsUnofficial)
)

Signature count options

View Source
const (
	// engine options
	EngineOptionsNone = iota
	EngineOptionsDisableCache
	EngineOptionsForceToDisk
	EngineOptionsDisablePEStats
)

Engine options

View Source
const (
	MaxScansize           = iota // uint64
	MaxFilesize                  // uint64
	MaxRecursion                 // uint32
	MaxFiles                     // uint32
	MinCCCount                   // uint32
	MinSSNCount                  // uint32
	PuaCategories                // string
	DbOptions                    // uint32
	DbVersion                    // uint32
	DbTime                       // time
	AcOnly                       // uint32
	AcMindepth                   // uint32
	AcMaxdepth                   // uint32
	Tmpdir                       // string
	Keeptmp                      // uint32
	BytecodeSecurityField        // uint32
	BytecodeTimeout              // uint32
	BytecodeModeField            // uint32
	MaxEmbeddedpe                // uint64
	MaxHtmlnormalize             // uint64
	MaxHtmlnotags                // uint64
	MaxScriptnormalize           // uint64
	MaxZiptypercg                // uint64
	Forcetodisk                  // uint32
	DisableCache                 // uint32
	DisablePEStats               // uint32
	StatsTimeout                 // uint32
	MaxPartitions                // uint32
	MaxIconspe                   // uint32

)

Engine fields

View Source
const (
	MsgInfoVerbose Msg = C.CL_MSG_INFO_VERBOSE
	MsgWarn            = C.CL_MSG_WARN
	NsgError           = C.CL_MSG_ERROR
)

Logging severity

View Source
const InitDefault = 0

InitDefault has default initialization settings

Variables

ScanStdopt is the standard set of scanning options

Functions

func CloseMemory

func CloseMemory(f *Fmap)

CloseMemory destroys the fmap associated with an in-memory object

func CountSigs

func CountSigs(path string, options uint) (uint, error)

CountSigs counts the number of signatures that can be loaded from the directory in path.

func DBDir

func DBDir() string

DBDir returns the directory where the virus database is located

func Debug

func Debug()

Debug enables debug messages from libclamav

func DeinitCrypto

func DeinitCrypto()

DeinitCrypto cleans up the crypto subsystem prior to program exit

func FreeSettings

func FreeSettings(s *Settings) error

FreeSettings frees the given settings

func Init

func Init(flags uint) error

Init initializes the ClamAV library. A suitable initialization can be achieved by passing clamav.InitDefault to this function.

func InitCrypto

func InitCrypto()

InitCrypto initializes the crypto subsystem

func Retflevel

func Retflevel() uint

Retflevel returns the engine database minimum level

func Retver

func Retver() string

Retver returns the engine version

func SetMsgCallback

func SetMsgCallback(cb CallbackMsg)

SetMsgCallback will set the callback function ClamAV will call for any error and warning messages. The specified callback will be called instead of logging to stderr. Messages of lower severity than specified are logged as usual.

Just like with cl_debug() this must be called before going multithreaded. Callable before cl_init, if you want to log messages from cl_init() itself.

func StatChkDir

func StatChkDir(stat *Stat) bool

StatChkDir returns 0 if no change to the directory pointed to by the Stat structure occurred, or 1 if some change occurred.

func StatChkReload

func StatChkReload(stat *Stat) (bool, error)

StatChkReload updates the internal state of the database if a change in the path referenced by stat occurred

func StatFree

func StatFree(stat *Stat) error

StatFree releases the engine stat

func StatIniDir

func StatIniDir(dir string, stat *Stat) error

StatIniDir initializes the Stat structure so the internal state of the database can be checked for errors stat should not be reused across calls to Stat*

func StrError

func StrError(errno ErrorCode) string

StrError converts LibClam error codes to human readable format

Types

type BytecodeMode

type BytecodeMode C.enum_bytecode_mode

BytecodeMode selects mode for the bytecode scanner

type BytecodeSecurity

type BytecodeSecurity C.enum_bytecode_security

BytecodeSecurity models security settings for the bytecode scanner

type Callback

type Callback struct {
	sync.Mutex
	// contains filtered or unexported fields
}

Callback is used to store the interface passed to ScanFileCb. This object is then returned in each ClamAV callback for the duration of the file scan

type CallbackHash

type CallbackHash func(fd int, size uint64, md5 []byte, virusName string, context interface{})

CallbackHash is a callback that provides hash statistics for a particular file

type CallbackMsg

type CallbackMsg func(m Msg, full, msg string, context interface{})

CallbackMsg will be called instead of logging to stderr. Messages of lower severity than specified are logged as usual. This must be called before going multithreaded. Callable before cl_init, if you want to log messages from cl_init() itself.

You can use context of cl_scandesc_callback to convey more information to the callback (such as the filename!) Note: setting a 2nd callbacks overwrites previous, multiple callbacks are not supported

type CallbackPostScan

type CallbackPostScan func(fd int, result ErrorCode, virname string, context interface{}) ErrorCode

CallbackPostScan is called for each processed file (inner and outer), after the scanning is complete.

Input: fd = File descriptor which is was scanned result = The scan result for the file virname = Virus name if infected context = Opaque application provided data

Output: Clean = Scan result is not overridden Break = Whitelisted by callback - scan result is set to Clean Virus = Blacklisted by callback - scan result is set to Virus

type CallbackPreCache

type CallbackPreCache func(fd int, ftype string, context interface{}) ErrorCode

CallbackPreCache is called for each processed file (both the entry level - AKA 'outer' - file and inner files - those generated when processing archive and container files), before the actual scanning takes place.

Input: fd = File descriptor which is about to be scanned type = File type detected via magic - i.e. NOT on the fly - (e.g. "CL_TYPE_MSEXE") context = Opaque application provided data

Output: Clean = File is scanned Break = Whitelisted by callback - file is skipped and marked as Clean Virus = Blacklisted by callback - file is skipped and marked as Virus

type CallbackPreScan

type CallbackPreScan func(fd int, ftype string, context interface{}) ErrorCode

CallbackPreScan is called for each NEW file (inner and outer) before the scanning takes place. This is roughly the the same as CallbackPreCache, but it is affected by clean file caching. This means that it won't be called if a clean cached file (inner or outer) is scanned a second time.

Input: fd = File descriptor which is about to be scanned type = File type detected via magic - i.e. NOT on the fly - (e.g. "CL_TYPE_MSEXE") context = Opaque application provided data

Output: Clean = File is scanned Break = Whitelisted by callback - file is skipped and marked as Clean Virus = Blacklisted by callback - file is skipped and marked as Virus

type CallbackPread

type CallbackPread func(handle *interface{}, buf []byte, offset int64) int64

CallbackPread is a callback that will be called by ClamAV to fill in part of an object represented by an fmap handle (file in memory, memory location, etc)

type Cvd

type Cvd C.struct_cl_cvd

Cvd models an engine virus database

type Engine

type Engine C.struct_cl_engine

Engine is a ClamAV virus scanning engine

func New

func New() *Engine

New allocates a new ClamAV engine.

func (*Engine) ApplySettings

func (e *Engine) ApplySettings(s *Settings) error

ApplySettings applies the given settings to the engine

func (*Engine) Compile

func (e *Engine) Compile() error

Compile makes the engine functional

func (*Engine) CopySettings

func (e *Engine) CopySettings() *Settings

CopySettings returns a copy of the current engine settings

func (*Engine) Free

func (e *Engine) Free() int

Free relleases the memory associated with ClamAV. Since the ClamAV engine can consume several megabytes of memory which is not visible by the Go garbage collector, Free should be called when the engine is no longer in use.

func (*Engine) GetNum

func (e *Engine) GetNum(field EngineField) (uint64, error)

GetNum acquires a number from the specified field of the engine configuration. Tests show that the ClamAV library will not overflow 32-bit fields, so a GetNum on a 32-bit field can safely be cast to uint32.

func (*Engine) GetString

func (e *Engine) GetString(field EngineField) (string, error)

GetString returns a string from the corresponding field of the engine configuration.

func (*Engine) Load

func (e *Engine) Load(path string, dbopts uint) (uint, error)

Load loads a single database file or all databases depending on whether its first argument (path) points to a file or a directory. A number of loaded signatures will be added to signo (the virus counter should be initialized to zero initially)

func (*Engine) ScanDesc

func (e *Engine) ScanDesc(desc int, opts *ScanOptions) (string, uint, error)

ScanDesc scans a file descriptor with the provided engine

Required arguments (as of version 0.101.4 of libclamav)

* @param desc File descriptor of an open file. The caller must provide this or the map. * @param filename (optional) Filepath of the open file descriptor or file map. * @param[out] virname Will be set to a statically allocated (i.e. needs not be freed) signature name if the scan matches against a signature. * @param[out] scanned The number of bytes scanned. * @param engine The scanning engine. * @param scanoptions Scanning options.

func (*Engine) ScanFile

func (e *Engine) ScanFile(path string, opts *C.struct_cl_scan_options) (string, uint, error)

ScanFile scans a single file for viruses using the ClamAV databases. It returns the virus name (if found), the number of bytes read from the file, in CountPrecision units, and a status code. If the file is clean the error code will be Success (Clean) and virus name will be empty. If a virus is found the error code will be the corresponding string for Virus (currently "Virus(es) detected").

func (*Engine) ScanFileCb

func (e *Engine) ScanFileCb(path string, opts *C.struct_cl_scan_options, context interface{}) (string, uint, error)

ScanFileCb scans a single file for viruses using the ClamAV databases and using callbacks from ClamAV to read/resolve file data. The callbacks can be used to scan files in memory, to scan multiple files inside archives, etc. The function returns the virus name (if found), the number of bytes read from the file in CountPrecision units, and a status code. If the file is clean the error code will be Success (Clean) and virus name will be empty. If a virus is found the error code will be the corresponding string for Virus (currently "Virus(es) detected"). The context argument will be sent back to the callbacks, so effort must be made to retain it throughout the execution of the scan from garbage collection

func (*Engine) ScanMapCb

func (e *Engine) ScanMapCb(fmap *Fmap, opts *C.struct_cl_scan_options, context interface{}) (string, uint, error)

ScanMapCb scans custom data

func (*Engine) SetHashCallback

func (e *Engine) SetHashCallback(cb CallbackHash)

SetHashCallback will set the callback function ClamAV will call with statistics about the scanned file

func (*Engine) SetNum

func (e *Engine) SetNum(field EngineField, num uint64) error

SetNum sets a number in the specified field of the engine configuration. Certain fields accept only 32-bit numbers, silently truncating the higher bits of the engine config. See dat.go for more information.

func (*Engine) SetPostScanCallback

func (e *Engine) SetPostScanCallback(cb CallbackPostScan)

SetPostScanCallback will set the callback function ClamAV will call before the cache is consulted for a particular scan to cb

func (*Engine) SetPreCacheCallback

func (e *Engine) SetPreCacheCallback(cb CallbackPreCache)

SetPreCacheCallback sets the callback function to use with ClamAV's pre_cache callback

func (*Engine) SetPreScanCallback

func (e *Engine) SetPreScanCallback(cb CallbackPreScan)

SetPreScanCallback will set the callback function ClamAV will call before a scan commences to the specified function

func (*Engine) SetString

func (e *Engine) SetString(field EngineField, s string) error

SetString sets a string in the corresponding field of the engine configuration. See dat.go for the corresponding (char *) fields in ClamAV.

type EngineField

type EngineField C.enum_cl_engine_field

EngineField selects a particular engine settings field

type ErrorCode

type ErrorCode C.cl_error_t

ErrorCode models ClamAV errors

func (ErrorCode) String

func (e ErrorCode) String() string

String converts the error code to human readable format

type Fmap

type Fmap C.cl_fmap_t

Fmap models in-memory files

func FmapOpenHandle

func FmapOpenHandle(handle *interface{}, offset int64, length uint32, cb CallbackPread, age bool) *Fmap

FmapOpenHandle opens a file map for scanning custom data accessed by a handle and pread (lseek + read)-like interface, for example a WIN32 HANDLE. By default fmap will use aging to discard old data, unless you tell it not to via the parameter "age". The handle will be passed to the callback each time.

FmapOpenHandle is currently unumplemented

func FmapOpenMemory

func FmapOpenMemory(buf []byte) *Fmap

FmapOpenMemory opens a map for scanning custom data, where the data is already in memory, either in the form of a buffer, a memory mapped file, etc. Note that the memory [start, start+len) must be the _entire_ file, you can't give it parts of a file and expect detection to work.

func OpenMemory

func OpenMemory(start []byte) *Fmap

OpenMemory creates an object from the given memory that can be scanned using ScanMapCb

func (*Fmap) Close

func (f *Fmap) Close()

Close resources associated with the map, you should release any resources you hold only after (handles, maps) calling this function */

type Msg

type Msg C.enum_cl_msg

Msg selects the logging severity for an engine

type ScanOptions

type ScanOptions C.struct_cl_scan_options

ScanOptions allows to select options for the scanning engine Available options are for the following categories: general, parse, heuristic, mail, dev

type Settings

type Settings C.struct_cl_settings

Settings models the settings applied to a ClamAV engine

type Stat

type Stat C.struct_cl_stat

Stat holds engine statistics

Directories

Path Synopsis
examples
avclient
This is an implementation of a client for the ClamAV library which uses the callback mechanism of ClamAV to scan files for viruses.
This is an implementation of a client for the ClamAV library which uses the callback mechanism of ClamAV to scan files for viruses.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL