Skip to content

Latest commit

 

History

History
519 lines (417 loc) · 20.4 KB

API.md

File metadata and controls

519 lines (417 loc) · 20.4 KB

Classes

NodeClam

NodeClam class definition.

NodeClamError

Clamscan-specific extension of the Javascript Error object

NOTE: If string is passed to first param, it will be msg and data will be {}

NodeClamTransform

A NodeClam - specific Transform extension that coddles chunks into the correct format for a ClamAV socket.

Members

pingPromise.<object>

Quick check to see if the remote/local socket is working. Callback/Resolve response is an instance to a ClamAV socket client.

Functions

getFiles(dir, [recursive])Array

Gets a listing of all files (no directories) within a given path. By default, it will retrieve files recursively.

NodeClam

NodeClam class definition.

Kind: global class
Access: public

new NodeClam()

This sets up all the defaults of the instance but does not necessarily return an initialized instance. Use .init for that.

nodeClam.init([options], [cb]) ⇒ Promise.<object>

Initialization method.

Kind: instance method of NodeClam
Returns: Promise.<object> - An initated instance of NodeClam
Access: public

Param Type Default Description
[options] object User options for the Clamscan module
[options.removeInfected] boolean false If true, removes infected files when found
[options.quarantineInfected] boolean | string false If not false, should be a string to a path to quarantine infected files
[options.scanLog] string null Path to a writeable log file to write scan results into
[options.debugMode] boolean false If true, a lot of info will be spewed to the logs
[options.fileList] string null Path to file containing list of files to scan (for scanFiles method)
[options.scanRecursively] boolean true If true, deep scan folders recursively (for scanDir method)
[options.clamscan] object Options specific to the clamscan binary
[options.clamscan.path] string "'/usr/bin/clamscan'" Path to clamscan binary on your server
[options.clamscan.db] string null Path to a custom virus definition database
[options.clamscan.scanArchives] boolean true If true, scan archives (ex. zip, rar, tar, dmg, iso, etc...)
[options.clamscan.active] boolean true If true, this module will consider using the clamscan binary
[options.clamdscan] object Options specific to the clamdscan binary
[options.clamdscan.socket] string false Path to socket file for connecting via TCP
[options.clamdscan.host] string false IP of host to connec to TCP interface
[options.clamdscan.port] string false Port of host to use when connecting via TCP interface
[options.clamdscan.timeout] number 60000 Timeout for scanning files
[options.clamdscan.localFallback] boolean false If false, do not fallback to a local binary-method of scanning
[options.clamdscan.path] string "'/usr/bin/clamdscan'" Path to the clamdscan binary on your server
[options.clamdscan.configFile] string null Specify config file if it's in an usual place
[options.clamdscan.multiscan] boolean true If true, scan using all available cores
[options.clamdscan.reloadDb] boolean false If true, will re-load the DB on ever call (slow)
[options.clamdscan.active] boolean true If true, this module will consider using the clamdscan binary
[options.clamdscan.bypassTest] boolean false If true, check to see if socket is avaliable
[options.clamdscan.tls] boolean false If true, connect to a TLS-Termination proxy in front of ClamAV
[options.preference] object 'clamdscan' If preferred binary is found and active, it will be used by default
[cb] function Callback method. Prototype: (err, <instance of NodeClam>)

Example

const NodeClam = require('clamscan');
const ClamScan = new NodeClam().init({
    removeInfected: false,
    quarantineInfected: false,
    scanLog: null,
    debugMode: false,
    fileList: null,
    scanRecursively: true,
    clamscan: {
        path: '/usr/bin/clamscan',
        db: null,
        scanArchives: true,
        active: true
    },
    clamdscan: {
        socket: false,
        host: false,
        port: false,
        timeout: 60000,
        localFallback: false,
        path: '/usr/bin/clamdscan',
        configFile: null,
        multiscan: true,
        reloadDb: false,
        active: true,
        bypassTest: false,
    },
    preference: 'clamdscan'
     });

nodeClam.reset([options], [cb]) ⇒ Promise.<object>

Allows one to create a new instances of clamscan with new options.

Kind: instance method of NodeClam
Returns: Promise.<object> - A reset instance of NodeClam
Access: public

Param Type Default Description
[options] object {} Same options as the init method
[cb] function What to do after reset (repsponds with reset instance of NodeClam)

nodeClam.getVersion([cb]) ⇒ Promise.<string>

Establish the clamav version of a local or remote clamav daemon.

Kind: instance method of NodeClam
Returns: Promise.<string> - - The version of ClamAV that is being interfaced with
Access: public

Param Type Description
[cb] function What to do when version is established

Example

// Callback example
clamscan.getVersion((err, version) => {
    if (err) return console.error(err);
    console.log(`ClamAV Version: ${version}`);
});

// Promise example
const clamscan = new NodeClam().init();
const version = await clamscan.getVersion();
console.log(`ClamAV Version: ${version}`);

nodeClam.isInfected(file, [cb]) ⇒ Promise.<object>

This method allows you to scan a single file. It supports a callback and Promise API. If no callback is supplied, a Promise will be returned. This method will likely be the most common use-case for this module.

Kind: instance method of NodeClam
Returns: Promise.<object> - Object like: { file: String, isInfected: Boolean, viruses: Array }
Access: public

Param Type Default Description
file string Path to the file to check
[cb] function What to do after the scan

Example

// Callback Example
clamscan.isInfected('/a/picture/for_example.jpg', (err, file, isInfected, viruses) => {
    if (err) return console.error(err);

    if (isInfected) {
        console.log(`${file} is infected with ${viruses.join(', ')}.`);
    }
});

// Promise Example
clamscan.isInfected('/a/picture/for_example.jpg').then(result => {
    const {file, isInfected, viruses} =  result;
    if (isInfected) console.log(`${file} is infected with ${viruses.join(', ')}.`);
}).then(err => {
    console.error(err);
});

// Async/Await Example
const {file, isInfected, viruses} = await clamscan.isInfected('/a/picture/for_example.jpg');

nodeClam.passthrough() ⇒ Transform

Returns a PassthroughStream object which allows you to pipe a ReadbleStream through it and on to another output. In the case of this implementation, it's actually forking the data to also go to ClamAV via TCP or Domain Sockets. Each data chunk is only passed on to the output if that chunk was successfully sent to and received by ClamAV. The PassthroughStream object returned from this method has a special event that is emitted when ClamAV finishes scanning the streamed data (scan-complete) so that you can decide if there's anything you need to do with the final output destination (ex. delete a file or S3 object).

Kind: instance method of NodeClam
Returns: Transform - A Transform stream for piping a Readable stream into
Access: public
Example

const NodeClam = require('clamscan');

// You'll need to specify your socket or TCP connection info
const clamscan = new NodeClam().init({
    clamdscan: {
        socket: '/var/run/clamd.scan/clamd.sock',
        host: '127.0.0.1',
        port: 3310,
    }
});

// For example's sake, we're using the Axios module
const axios = require('axios');

// Get a readable stream for a URL request
const input = axios.get(someUrl);

// Create a writable stream to a local file
const output = fs.createWriteStream(someLocalFile);

// Get instance of this module's PassthroughStream object
const av = clamscan.passthrough();

// Send output of Axios stream to ClamAV.
// Send output of Axios to `someLocalFile` if ClamAV receives data successfully
input.pipe(av).pipe(output);

// What happens when scan is completed
av.on('scan-complete', result => {
   const {isInfected, viruses} = result;
   // Do stuff if you want
});

// What happens when data has been fully written to `output`
output.on('finish', () => {
    // Do stuff if you want
});

// NOTE: no errors (or other events) are being handled in this example but standard errors will be emitted according to NodeJS's Stream specifications

nodeClam.scanFile(file, [cb]) ⇒ Promise.<object>

Just an alias to isInfected. See docs for that for usage examples.

Kind: instance method of NodeClam
Returns: Promise.<object> - Object like: { file: String, isInfected: Boolean, viruses: Array }
Access: public

Param Type Description
file string Path to the file to check
[cb] function What to do after the scan

nodeClam.scanFiles(files, [endCb], [fileCb]) ⇒ Promise.<object>

Scans an array of files or paths. You must provide the full paths of the files and/or paths. Also enables the ability to scan a file list.

This is essentially a wrapper for isInfected that simplifies the process of scanning many files or directories.

NOTE: The only way to get per-file notifications is through the callback API.

Kind: instance method of NodeClam
Returns: Promise.<object> - Object like: { goodFiles: Array, badFiles: Array, errors: Object, viruses: Array }
Access: public

Param Type Default Description
files Array A list of files or paths (full paths) to be scanned
[endCb] function What to do after the scan completes
[fileCb] function What to do after each file has been scanned

Example

// Callback Example
const scanStatus = {
    good: 0,
    bad: 0
};
const files = [
    '/path/to/file/1.jpg',
    '/path/to/file/2.mov',
    '/path/to/file/3.rb'
];
clamscan.scanFiles(files, (err, goodFiles, badFiles, viruses) => {
    if (err) return console.error(err);
    if (badFiles.length > 0) {
        console.log({
            msg: `${goodFiles.length} files were OK. ${badFiles.length} were infected!`,
            badFiles,
            goodFiles,
            viruses,
        });
    } else {
        res.send({msg: "Everything looks good! No problems here!."});
    }
}, (err, file, isInfected, viruses) => {
    ;(isInfected ? scanStatus.bad++ : scanStatus.good++);
    console.log(`${file} is ${(isInfected ? `infected with ${viruses}` : 'ok')}.`);
    console.log('Scan Status: ', `${(scanStatus.bad + scanStatus.good)}/${files.length}`);
});

// Async/Await method
const {goodFiles, badFiles, errors, viruses} = await clamscan.scanFiles(files);

nodeClam.scanDir(path, [endCb], [fileCb]) ⇒ Promise.<object>

Scans an entire directory. Provides 3 params to end callback: Error, path scanned, and whether its infected or not. To scan multiple directories, pass them as an array to the scanFiles method.

This obeys your recursive option even for clamdscan which does not have a native way to turn this feature off. If you have multiple paths, send them in an array to scanFiles.

NOTE: While possible, it is NOT advisable to use the fileCb parameter when using the clamscan binary. Doing so with clamdscan is okay, however. This method also allows for non-recursive scanning with the clamdscan binary.

Kind: instance method of NodeClam
Returns: Promise.<object> - Object like: { path: String, isInfected: Boolean, goodFiles: Array, badFiles: Array, viruses: Array }
Access: public

Param Type Default Description
path string The directory to scan files of
[endCb] function What to do when all files have been scanned
[fileCb] function What to do after each file has been scanned

Example

// Callback Method
clamscan.scanDir('/some/path/to/scan', (err, goodFiles, badFiles, viruses, numGoodFiles) {
    if (err) return console.error(err);

    if (badFiles.length > 0) {
        console.log(`${path} was infected. The offending files (${badFiles.map(v => `${v.file} (${v.virus})`).join (', ')}) have been quarantined.`);
        console.log(`Viruses Found: ${viruses.join(', ')}`);
    } else {
        console.log('Everything looks good! No problems here!.');
    }
});

// Async/Await Method
const {path, isInfected, goodFiles, badFiles, viruses} = await clamscan.scanDir('/some/path/to/scan');

nodeClam.scanStream(stream, [cb]) ⇒ Promise.<object>

Allows you to scan a binary stream.

NOTE: This method will only work if you've configured the module to allow the use of a TCP or UNIX Domain socket. In other words, this will not work if you only have access to a local ClamAV binary.

Kind: instance method of NodeClam
Returns: Promise.<object> - Object like: { file: String, isInfected: Boolean, viruses: Array }
Access: public

Param Type Description
stream Readable A readable stream to scan
[cb] function What to do when the socket response with results

Example

const NodeClam = require('clamscan');

// You'll need to specify your socket or TCP connection info
const clamscan = new NodeClam().init({
    clamdscan: {
        socket: '/var/run/clamd.scan/clamd.sock',
        host: '127.0.0.1',
        port: 3310,
    }
});
const Readable = require('stream').Readable;
const rs = Readable();

rs.push('foooooo');
rs.push('barrrrr');
rs.push(null);

// Callback Example
clamscan.scanStream(stream, (err, { isInfected, viruses }) => {
    if (err) return console.error(err);
    if (isInfected) return console.log('Stream is infected! Booo!', viruses);
    console.log('Stream is not infected! Yay!');
});

// Async/Await Example
const { isInfected, viruses } = await clamscan.scanStream(stream);

NodeClamError

Clamscan-specific extension of the Javascript Error object

NOTE: If string is passed to first param, it will be msg and data will be {}

Kind: global class

new NodeClamError(data, ...params)

Creates a new instance of a NodeClamError.

Param Type Description
data object Additional data we might want to have access to on error
...params any The usual params you'd pass to create an Error object

NodeClamTransform

A NodeClam - specific Transform extension that coddles chunks into the correct format for a ClamAV socket.

Kind: global class

new NodeClamTransform(options, debugMode)

Creates a new instance of NodeClamTransorm.

Param Type Default Description
options object Optional overrides to defaults (same as Node.js Transform)
debugMode boolean false If true, do special debug logging

nodeClamTransform._transform(chunk, encoding, cb)

Actually does the transorming of the data for ClamAV.

Kind: instance method of NodeClamTransform

Param Type Description
chunk Buffer The piece of data to push onto the stream
encoding string The encoding of the chunk
cb function What to do when done pushing chunk

nodeClamTransform._flush(cb)

This will flush out the stream when all data has been received.

Kind: instance method of NodeClamTransform

Param Type Description
cb function What to do when done

ping ⇒ Promise.<object>

Quick check to see if the remote/local socket is working. Callback/Resolve response is an instance to a ClamAV socket client.

Kind: global variable
Returns: Promise.<object> - A copy of the Socket/TCP client
Access: public

Param Type Description
[cb] function What to do after the ping

getFiles(dir, [recursive]) ⇒ Array

Gets a listing of all files (no directories) within a given path. By default, it will retrieve files recursively.

Kind: global function
Returns: Array - - List of all requested path files

Param Type Default Description
dir string The directory to get all files of
[recursive] boolean true If true (default), get all files recursively; False: only get files directly in path