Skip to content

Commit

Permalink
ClamD: Add new zOPTSCAN command w. scan options like ALLMATCH
Browse files Browse the repository at this point in the history
Added a new ClamD command which can pass options along with the actual
scan command.

Current options are just `ALLMATCH`.

Current scan commands are:
- `CONTSCAN`
- `FILDES`
- `INSTREAM`
- `MULTISCAN`

For example, you can send:

  zOPTSCAN CONTSCAN /some/file/path\0

or:

  zOPTSCAN ALLMATCH INSTREAM \0
  <4-byte length><length-bytes data chunk>
  <4-byte length><length-bytes data chunk>
  <4-byte zero>

Note that a space is presently required between the final option
before the path or before the \0 for INSTREAM and FDPASS where the
subsequent bytes appear are sent in the next message.
  • Loading branch information
micahsnyder committed Feb 5, 2024
1 parent ebe3c50 commit a33c6d2
Show file tree
Hide file tree
Showing 22 changed files with 475 additions and 191 deletions.
44 changes: 27 additions & 17 deletions clamd/scanner.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,8 @@ cl_error_t scanfd(
struct cl_scan_options *options,
const struct optstruct *opts,
int odesc,
int stream)
int stream,
struct scan_cb_data *scandata)
{
cl_error_t ret = -1;
int fd = conn->scanfd;
Expand Down Expand Up @@ -426,7 +427,7 @@ cl_error_t scanfd(
thrmgr_setactivetask(fdstr, NULL);
context.filename = fdstr;
context.virsize = 0;
context.scandata = NULL;
context.scandata = scandata;
ret = cl_scandesc_callback(fd, log_filename, &virname, scanned, engine, options, &context);
thrmgr_setactivetask(NULL, NULL);

Expand All @@ -437,13 +438,17 @@ cl_error_t scanfd(
}

if (ret == CL_VIRUS) {
virusaction(log_filename, virname, opts);
if (conn_reply_virus(conn, reply_fdstr, virname) == -1)
ret = CL_ETIMEOUT;
if (context.virsize && optget(opts, "ExtendedDetectionInfo")->enabled)
logg(LOGG_INFO, "%s: %s(%s:%llu) FOUND\n", log_filename, virname, context.virhash, context.virsize);
else
logg(LOGG_INFO, "%s: %s FOUND\n", log_filename, virname);
if (options->general & CL_SCAN_GENERAL_ALLMATCHES || options->general & CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE) {
virusaction(log_filename, virname, opts);
} else {
virusaction(log_filename, virname, opts);
if (conn_reply_virus(conn, reply_fdstr, virname) == -1)
ret = CL_ETIMEOUT;
if (context.virsize && optget(opts, "ExtendedDetectionInfo")->enabled)
logg(LOGG_INFO, "%s: %s(%s:%llu) FOUND\n", log_filename, virname, context.virhash, context.virsize);
else
logg(LOGG_INFO, "%s: %s FOUND\n", log_filename, virname);
}
} else if (ret != CL_CLEAN) {
if (conn_reply(conn, reply_fdstr, cl_strerror(ret), "ERROR") == -1)
ret = CL_ETIMEOUT;
Expand All @@ -469,7 +474,8 @@ int scanstream(
const struct cl_engine *engine,
struct cl_scan_options *options,
const struct optstruct *opts,
char term)
char term,
struct scan_cb_data *scandata)
{
int ret, sockfd, acceptd;
int tmpd, bread, retval, firsttimeout, timeout, btread;
Expand Down Expand Up @@ -606,7 +612,7 @@ int scanstream(
thrmgr_setactivetask(peer_addr, NULL);
context.filename = peer_addr;
context.virsize = 0;
context.scandata = NULL;
context.scandata = scandata;
ret = cl_scandesc_callback(tmpd, tmpname, &virname, scanned, engine, options, &context);
thrmgr_setactivetask(NULL, NULL);
} else {
Expand All @@ -621,14 +627,18 @@ int scanstream(
closesocket(sockfd);

if (ret == CL_VIRUS) {
if (context.virsize && optget(opts, "ExtendedDetectionInfo")->enabled) {
mdprintf(odesc, "stream: %s(%s:%llu) FOUND%c", virname, context.virhash, context.virsize, term);
logg(LOGG_INFO, "stream(%s@%u): %s(%s:%llu) FOUND\n", peer_addr, port, virname, context.virhash, context.virsize);
if (options->general & CL_SCAN_GENERAL_ALLMATCHES || options->general & CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE) {
virusaction("stream", virname, opts);
} else {
mdprintf(odesc, "stream: %s FOUND%c", virname, term);
logg(LOGG_INFO, "stream(%s@%u): %s FOUND\n", peer_addr, port, virname);
if (context.virsize && optget(opts, "ExtendedDetectionInfo")->enabled) {
mdprintf(odesc, "stream: %s(%s:%llu) FOUND%c", virname, context.virhash, context.virsize, term);
logg(LOGG_INFO, "stream(%s@%u): %s(%s:%llu) FOUND\n", peer_addr, port, virname, context.virhash, context.virsize);
} else {
mdprintf(odesc, "stream: %s FOUND%c", virname, term);
logg(LOGG_INFO, "stream(%s@%u): %s FOUND\n", peer_addr, port, virname);
}
virusaction("stream", virname, opts);
}
virusaction("stream", virname, opts);
} else if (ret != CL_CLEAN) {
if (retval == 1) {
mdprintf(odesc, "stream: %s ERROR%c", cl_strerror(ret), term);
Expand Down
7 changes: 4 additions & 3 deletions clamd/scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@

#include "thrmgr.h"
#include "session.h"
#include "clamdcom.h"

enum scan_type { TYPE_INIT = -1,
TYPE_SCAN = 0,
TYPE_CONTSCAN = 1,
TYPE_MULTISCAN = 2 };

struct scan_cb_data {
int scantype;
scantype_t scantype;
int odesc;
int type;
int infected;
Expand All @@ -65,8 +66,8 @@ struct cb_context {
struct scan_cb_data *scandata;
};

cl_error_t scanfd(const client_conn_t *conn, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *options, const struct optstruct *opts, int odesc, int stream);
int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *options, const struct optstruct *opts, char term);
cl_error_t scanfd(const client_conn_t *conn, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *options, const struct optstruct *opts, int odesc, int stream, struct scan_cb_data *scandata);
int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *options, const struct optstruct *opts, char term, struct scan_cb_data *scandata);
cl_error_t scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_reason reason, struct cli_ftw_cbdata *data);
int scan_pathchk(const char *path, struct cli_ftw_cbdata *data);
void hash_callback(int fd, unsigned long long size, const unsigned char *md5, const char *virname, void *ctx);
Expand Down
Loading

0 comments on commit a33c6d2

Please sign in to comment.