clang-format'd using new .clang-format rules.

This commit is contained in:
Micah Snyder 2018-12-03 12:40:13 -05:00
parent 38fe8b69a0
commit 72fd33c8b2
335 changed files with 73102 additions and 74645 deletions

View file

@ -52,14 +52,15 @@
struct smfiDesc descr;
struct optstruct *opts;
static void milter_exit(int sig) {
static void milter_exit(int sig)
{
const struct optstruct *opt;
logg("*clamav-milter: milter_exit, signal %d\n", sig);
#ifndef _WIN32
if((opt = optget(opts, "MilterSocket"))) {
if(unlink(opt->strarg) == -1)
if ((opt = optget(opts, "MilterSocket"))) {
if (unlink(opt->strarg) == -1)
logg("!Can't unlink the socket file %s\n", opt->strarg);
else
logg("Socket file removed.\n");
@ -76,7 +77,8 @@ static void milter_exit(int sig) {
whitelist_free();
}
int main(int argc, char **argv) {
int main(int argc, char **argv)
{
char *my_socket, *pt;
const struct optstruct *opt;
time_t currtime;
@ -121,7 +123,7 @@ int main(int argc, char **argv) {
return 1;
}
if(optget(opts, "help")->enabled) {
if (optget(opts, "help")->enabled) {
printf("\n");
printf(" Clam AntiVirus: Milter Mail Scanner %s\n", get_version());
printf(" By The ClamAV Team: https://www.clamav.net/about.html#credits\n");
@ -137,13 +139,13 @@ int main(int argc, char **argv) {
return 0;
}
if(opts->filename) {
if (opts->filename) {
int x;
for(x = 0; opts->filename[x]; x++)
for (x = 0; opts->filename[x]; x++)
mprintf("^Ignoring option %s\n", opts->filename[x]);
}
if(optget(opts, "version")->enabled) {
if (optget(opts, "version")->enabled) {
printf("clamav-milter %s\n", get_version());
optfree(opts);
return 0;
@ -154,19 +156,19 @@ int main(int argc, char **argv) {
printf("Unable to allocate memory for config file\n");
return 1;
}
if((opts = optparse(pt, 0, NULL, 1, OPT_MILTER, 0, opts)) == NULL) {
if ((opts = optparse(pt, 0, NULL, 1, OPT_MILTER, 0, opts)) == NULL) {
printf("%s: cannot parse config file %s\n", argv[0], pt);
free(pt);
return 1;
}
free(pt);
if((opt = optget(opts, "Chroot"))->enabled) {
if(chdir(opt->strarg) != 0) {
if ((opt = optget(opts, "Chroot"))->enabled) {
if (chdir(opt->strarg) != 0) {
logg("!Cannot change directory to %s\n", opt->strarg);
return 1;
}
if(chroot(opt->strarg) != 0) {
if (chroot(opt->strarg) != 0) {
logg("!chroot to %s failed. Are you root?\n", opt->strarg);
return 1;
}
@ -180,14 +182,14 @@ int main(int argc, char **argv) {
strncpy(myname, opt->strarg, sizeof(myname))) ||
!gethostname(myname, sizeof(myname))) {
myname[sizeof(myname)-1] = '\0';
myname[sizeof(myname) - 1] = '\0';
snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s at %s",
get_version(), myname);
} else {
snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s",
get_version());
}
xvirushdr[sizeof(xvirushdr)-1] = '\0';
xvirushdr[sizeof(xvirushdr) - 1] = '\0';
descr.xxfi_flags |= SMFIF_ADDHDRS;
@ -199,20 +201,20 @@ int main(int argc, char **argv) {
}
}
if(!(my_socket = optget(opts, "MilterSocket")->strarg)) {
if (!(my_socket = optget(opts, "MilterSocket")->strarg)) {
logg("!Please configure the MilterSocket directive\n");
logg_close();
optfree(opts);
return 1;
}
if(smfi_setconn(my_socket) == MI_FAILURE) {
if (smfi_setconn(my_socket) == MI_FAILURE) {
logg("!smfi_setconn failed\n");
logg_close();
optfree(opts);
return 1;
}
if(smfi_register(descr) == MI_FAILURE) {
if (smfi_register(descr) == MI_FAILURE) {
logg("!smfi_register failed\n");
logg_close();
optfree(opts);
@ -220,30 +222,30 @@ int main(int argc, char **argv) {
}
opt = optget(opts, "FixStaleSocket");
umsk = umask(0777); /* socket is created with 000 to avoid races */
if(smfi_opensocket(opt->enabled) == MI_FAILURE) {
if (smfi_opensocket(opt->enabled) == MI_FAILURE) {
logg("!Failed to create socket %s\n", my_socket);
logg_close();
optfree(opts);
return 1;
}
umask(umsk); /* restore umask */
if(strncmp(my_socket, "inet:", 5) && strncmp(my_socket, "inet6:", 6)) {
if (strncmp(my_socket, "inet:", 5) && strncmp(my_socket, "inet6:", 6)) {
/* set group ownership and perms on the local socket */
char *sock_name = my_socket;
mode_t sock_mode;
if(!strncmp(my_socket, "unix:", 5))
if (!strncmp(my_socket, "unix:", 5))
sock_name += 5;
if(!strncmp(my_socket, "local:", 6))
if (!strncmp(my_socket, "local:", 6))
sock_name += 6;
if(*my_socket == ':')
sock_name ++;
if (*my_socket == ':')
sock_name++;
if(optget(opts, "MilterSocketGroup")->enabled) {
if (optget(opts, "MilterSocketGroup")->enabled) {
char *gname = optget(opts, "MilterSocketGroup")->strarg, *end;
gid_t sock_gid = strtol(gname, &end, 10);
if(*end) {
if (*end) {
struct group *pgrp = getgrnam(gname);
if(!pgrp) {
if (!pgrp) {
logg("!Unknown group %s\n", gname);
logg_close();
optfree(opts);
@ -251,7 +253,7 @@ int main(int argc, char **argv) {
}
sock_gid = pgrp->gr_gid;
}
if(chown(sock_name, -1, sock_gid)) {
if (chown(sock_name, -1, sock_gid)) {
logg("!Failed to change socket ownership to group %s\n", gname);
logg_close();
optfree(opts);
@ -269,7 +271,7 @@ int main(int argc, char **argv) {
return 1;
}
if(chown(sock_name, user->pw_uid, -1)) {
if (chown(sock_name, user->pw_uid, -1)) {
logg("!Failed to change socket ownership to user %s\n", user->pw_name);
optfree(opts);
logg_close();
@ -277,10 +279,10 @@ int main(int argc, char **argv) {
}
}
if(optget(opts, "MilterSocketMode")->enabled) {
if (optget(opts, "MilterSocketMode")->enabled) {
char *end;
sock_mode = strtol(optget(opts, "MilterSocketMode")->strarg, &end, 8);
if(*end) {
if (*end) {
logg("!Invalid MilterSocketMode %s\n", optget(opts, "MilterSocketMode")->strarg);
logg_close();
optfree(opts);
@ -289,7 +291,7 @@ int main(int argc, char **argv) {
} else
sock_mode = 0777 & ~umsk;
if(chmod(sock_name, sock_mode & 0666)) {
if (chmod(sock_name, sock_mode & 0666)) {
logg("!Cannot set milter socket permission to %s\n", optget(opts, "MilterSocketMode")->strarg);
logg_close();
optfree(opts);
@ -297,35 +299,35 @@ int main(int argc, char **argv) {
}
}
if(geteuid() == 0 && (opt = optget(opts, "User"))->enabled) {
if (geteuid() == 0 && (opt = optget(opts, "User"))->enabled) {
struct passwd *user = NULL;
if((user = getpwnam(opt->strarg)) == NULL) {
if ((user = getpwnam(opt->strarg)) == NULL) {
fprintf(stderr, "ERROR: Can't get information about user %s.\n", opt->strarg);
optfree(opts);
return 1;
}
#ifdef HAVE_INITGROUPS
if(initgroups(opt->strarg, user->pw_gid)) {
if (initgroups(opt->strarg, user->pw_gid)) {
fprintf(stderr, "ERROR: initgroups() failed.\n");
optfree(opts);
return 1;
}
#elif HAVE_SETGROUPS
if(setgroups(1, &user->pw_gid)) {
if (setgroups(1, &user->pw_gid)) {
fprintf(stderr, "ERROR: setgroups() failed.\n");
optfree(opts);
return 1;
}
#endif
if(setgid(user->pw_gid)) {
fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid);
if (setgid(user->pw_gid)) {
fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int)user->pw_gid);
optfree(opts);
return 1;
}
if(setuid(user->pw_uid)) {
fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid);
if (setuid(user->pw_uid)) {
fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int)user->pw_uid);
optfree(opts);
return 1;
}
@ -338,9 +340,9 @@ int main(int argc, char **argv) {
if (logg_size)
logg_rotate = optget(opts, "LogRotate")->enabled;
if((opt = optget(opts, "LogFile"))->enabled) {
if ((opt = optget(opts, "LogFile"))->enabled) {
logg_file = opt->strarg;
if(!cli_is_abspath(logg_file)) {
if (!cli_is_abspath(logg_file)) {
fprintf(stderr, "ERROR: LogFile requires full path.\n");
logg_close();
optfree(opts);
@ -350,11 +352,11 @@ int main(int argc, char **argv) {
logg_file = NULL;
#if defined(USE_SYSLOG) && !defined(C_AIX)
if(optget(opts, "LogSyslog")->enabled) {
if (optget(opts, "LogSyslog")->enabled) {
int fac;
opt = optget(opts, "LogFacility");
if((fac = logg_facility(opt->strarg)) == -1) {
if ((fac = logg_facility(opt->strarg)) == -1) {
logg("!LogFacility: %s: No such facility.\n", opt->strarg);
logg_close();
optfree(opts);
@ -367,29 +369,29 @@ int main(int argc, char **argv) {
#endif
time(&currtime);
if(logg("#+++ Started at %s", ctime(&currtime))) {
if (logg("#+++ Started at %s", ctime(&currtime))) {
fprintf(stderr, "ERROR: Can't initialize the internal logger\n");
logg_close();
optfree(opts);
return 1;
}
if((opt = optget(opts, "TemporaryDirectory"))->enabled)
if ((opt = optget(opts, "TemporaryDirectory"))->enabled)
tempdir = opt->strarg;
if(localnets_init(opts) || init_actions(opts)) {
if (localnets_init(opts) || init_actions(opts)) {
logg_close();
optfree(opts);
return 1;
}
if((opt = optget(opts, "Whitelist"))->enabled && whitelist_init(opt->strarg)) {
if ((opt = optget(opts, "Whitelist"))->enabled && whitelist_init(opt->strarg)) {
localnets_free();
logg_close();
optfree(opts);
return 1;
}
if((opt = optget(opts, "SkipAuthenticated"))->enabled && smtpauth_init(opt->strarg)) {
if ((opt = optget(opts, "SkipAuthenticated"))->enabled && smtpauth_init(opt->strarg)) {
localnets_free();
whitelist_free();
logg_close();
@ -399,8 +401,8 @@ int main(int argc, char **argv) {
multircpt = optget(opts, "SupportMultipleRecipients")->enabled;
if(!optget(opts, "Foreground")->enabled) {
if(daemonize() == -1) {
if (!optget(opts, "Foreground")->enabled) {
if (daemonize() == -1) {
logg("!daemonize() failed\n");
localnets_free();
whitelist_free();
@ -409,12 +411,12 @@ int main(int argc, char **argv) {
optfree(opts);
return 1;
}
if(chdir("/") == -1)
if (chdir("/") == -1)
logg("^Can't change current working directory to root\n");
}
maxfilesize = optget(opts, "MaxFileSize")->numarg;
if(!maxfilesize) {
if (!maxfilesize) {
logg("^Invalid MaxFileSize, using default (%d)\n", CLI_DEFAULT_MAXFILESIZE);
maxfilesize = CLI_DEFAULT_MAXFILESIZE;
}
@ -430,14 +432,14 @@ int main(int argc, char **argv) {
return 1;
}
if((opt = optget(opts, "PidFile"))->enabled) {
if ((opt = optget(opts, "PidFile"))->enabled) {
FILE *fd;
mode_t old_umask = umask(0002);
if((fd = fopen(opt->strarg, "w")) == NULL) {
if ((fd = fopen(opt->strarg, "w")) == NULL) {
logg("!Can't save PID in file %s\n", opt->strarg);
} else {
if (fprintf(fd, "%u\n", (unsigned int)getpid())<0) {
if (fprintf(fd, "%u\n", (unsigned int)getpid()) < 0) {
logg("!Can't save PID in file %s\n", opt->strarg);
}
fclose(fd);

View file

@ -45,7 +45,7 @@
#include "clamfi.h"
#if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
#define _UNUSED_ __attribute__ ((__unused__))
#define _UNUSED_ __attribute__((__unused__))
#else
#define _UNUSED_
#endif
@ -93,23 +93,23 @@ struct CLAMFI {
char buffer[CLAMFIBUFSZ];
};
static void add_x_header(SMFICTX *ctx, char *st, unsigned int scanned, unsigned int status) {
if(addxvirus == 1) { /* Replace/Yes */
while(scanned)
if(smfi_chgheader(ctx, (char *)"X-Virus-Scanned", scanned--, NULL) != MI_SUCCESS)
static void add_x_header(SMFICTX *ctx, char *st, unsigned int scanned, unsigned int status)
{
if (addxvirus == 1) { /* Replace/Yes */
while (scanned)
if (smfi_chgheader(ctx, (char *)"X-Virus-Scanned", scanned--, NULL) != MI_SUCCESS)
logg("^Failed to remove existing X-Virus-Scanned header\n");
while(status)
if(smfi_chgheader(ctx, (char *)"X-Virus-Status", status--, NULL) != MI_SUCCESS)
while (status)
if (smfi_chgheader(ctx, (char *)"X-Virus-Status", status--, NULL) != MI_SUCCESS)
logg("^Failed to remove existing X-Virus-Status header\n");
if(smfi_addheader(ctx, (char *)"X-Virus-Scanned", xvirushdr) != MI_SUCCESS)
if (smfi_addheader(ctx, (char *)"X-Virus-Scanned", xvirushdr) != MI_SUCCESS)
logg("^Failed to add X-Virus-Scanned header\n");
if(smfi_addheader(ctx, (char *)"X-Virus-Status", st) != MI_SUCCESS)
if (smfi_addheader(ctx, (char *)"X-Virus-Status", st) != MI_SUCCESS)
logg("^Failed to add X-Virus-Status header\n");
} else { /* Add */
if(smfi_insheader(ctx, 1, (char *)"X-Virus-Scanned", xvirushdr) != MI_SUCCESS)
if (smfi_insheader(ctx, 1, (char *)"X-Virus-Scanned", xvirushdr) != MI_SUCCESS)
logg("^Failed to insert X-Virus-Scanned header\n");
if(smfi_insheader(ctx, 1, (char *)"X-Virus-Status", st) != MI_SUCCESS)
if (smfi_insheader(ctx, 1, (char *)"X-Virus-Status", st) != MI_SUCCESS)
logg("^Failed to insert X-Virus-Status header\n");
}
}
@ -122,28 +122,29 @@ enum CFWHAT {
CF_ANY /* 4 */
};
static const char *makesanehdr(char *hdr) {
static const char *makesanehdr(char *hdr)
{
char *ret = hdr;
if(!hdr) return HDR_UNAVAIL;
while(*hdr) {
if(*hdr=='\'' || *hdr=='\t' || *hdr=='\r' || *hdr=='\n' || !isprint(*hdr))
if (!hdr) return HDR_UNAVAIL;
while (*hdr) {
if (*hdr == '\'' || *hdr == '\t' || *hdr == '\r' || *hdr == '\n' || !isprint(*hdr))
*hdr = ' ';
hdr++;
}
return ret;
}
static void nullify(SMFICTX *ctx, struct CLAMFI *cf, enum CFWHAT closewhat) {
if(closewhat & CF_MAIN || ((closewhat & CF_ANY) && cf->main >= 0))
static void nullify(SMFICTX *ctx, struct CLAMFI *cf, enum CFWHAT closewhat)
{
if (closewhat & CF_MAIN || ((closewhat & CF_ANY) && cf->main >= 0))
close(cf->main);
if(closewhat & CF_ALT || ((closewhat & CF_ANY) && cf->alt >= 0))
if (closewhat & CF_ALT || ((closewhat & CF_ANY) && cf->alt >= 0))
close(cf->alt);
if(cf->msg_subj) free(cf->msg_subj);
if(cf->msg_date) free(cf->msg_date);
if(cf->msg_id) free(cf->msg_id);
if(multircpt && cf->nrecipients) {
while(cf->nrecipients) {
if (cf->msg_subj) free(cf->msg_subj);
if (cf->msg_date) free(cf->msg_date);
if (cf->msg_id) free(cf->msg_id);
if (multircpt && cf->nrecipients) {
while (cf->nrecipients) {
cf->nrecipients--;
free(cf->recipients[cf->nrecipients]);
}
@ -152,33 +153,33 @@ static void nullify(SMFICTX *ctx, struct CLAMFI *cf, enum CFWHAT closewhat) {
smfi_setpriv(ctx, NULL);
}
static sfsistat sendchunk(struct CLAMFI *cf, unsigned char *bodyp, size_t len, SMFICTX *ctx) {
if(cf->totsz >= maxfilesize || len == 0)
static sfsistat sendchunk(struct CLAMFI *cf, unsigned char *bodyp, size_t len, SMFICTX *ctx)
{
if (cf->totsz >= maxfilesize || len == 0)
return SMFIS_CONTINUE;
if(!cf->totsz) {
if (!cf->totsz) {
sfsistat ret;
if(nc_connect_rand(&cf->main, &cf->alt, &cf->local)) {
if (nc_connect_rand(&cf->main, &cf->alt, &cf->local)) {
logg("!Failed to initiate streaming/fdpassing\n");
nullify(ctx, cf, CF_NONE);
return FailAction;
}
cf->totsz = 1; /* do not infloop */
if((ret = sendchunk(cf, (unsigned char *)"From clamav-milter\n", 19, ctx)) != SMFIS_CONTINUE)
if ((ret = sendchunk(cf, (unsigned char *)"From clamav-milter\n", 19, ctx)) != SMFIS_CONTINUE)
return ret;
cf->totsz -= 1;
}
if(cf->totsz + len > maxfilesize)
if (cf->totsz + len > maxfilesize)
len = maxfilesize - cf->totsz;
cf->totsz += len;
if(cf->local) {
while(len) {
if (cf->local) {
while (len) {
int n = write(cf->alt, bodyp, len);
if (n==-1) {
if (n == -1) {
logg("!Failed to write temporary file\n");
nullify(ctx, cf, CF_BOTH);
return FailAction;
@ -189,10 +190,10 @@ static sfsistat sendchunk(struct CLAMFI *cf, unsigned char *bodyp, size_t len, S
} else {
int sendfailed = 0;
if(len < CLAMFIBUFSZ - cf->bufsz) {
if (len < CLAMFIBUFSZ - cf->bufsz) {
memcpy(&cf->buffer[cf->bufsz], bodyp, len);
cf->bufsz += len;
} else if(len < CLAMFIBUFSZ) {
} else if (len < CLAMFIBUFSZ) {
memcpy(&cf->buffer[cf->bufsz], bodyp, CLAMFIBUFSZ - cf->bufsz);
cf->sendme = htonl(CLAMFIBUFSZ);
sendfailed = nc_send(cf->main, &cf->sendme, CLAMFIBUFSZ + 4);
@ -202,11 +203,11 @@ static sfsistat sendchunk(struct CLAMFI *cf, unsigned char *bodyp, size_t len, S
} else {
uint32_t sendmetoo = htonl(len);
cf->sendme = htonl(cf->bufsz);
if((cf->bufsz && nc_send(cf->main, &cf->sendme, cf->bufsz + 4)) || nc_send(cf->main, &sendmetoo, 4) || nc_send(cf->main, bodyp, len))
if ((cf->bufsz && nc_send(cf->main, &cf->sendme, cf->bufsz + 4)) || nc_send(cf->main, &sendmetoo, 4) || nc_send(cf->main, bodyp, len))
sendfailed = 1;
cf->bufsz = 0;
}
if(sendfailed) {
if (sendfailed) {
logg("!Streaming failed\n");
nullify(ctx, cf, CF_NONE);
return FailAction;
@ -215,66 +216,66 @@ static sfsistat sendchunk(struct CLAMFI *cf, unsigned char *bodyp, size_t len, S
return SMFIS_CONTINUE;
}
sfsistat clamfi_header(SMFICTX *ctx, char *headerf, char *headerv) {
sfsistat clamfi_header(SMFICTX *ctx, char *headerf, char *headerv)
{
struct CLAMFI *cf;
sfsistat ret;
if(!(cf = (struct CLAMFI *)smfi_getpriv(ctx)))
if (!(cf = (struct CLAMFI *)smfi_getpriv(ctx)))
return SMFIS_CONTINUE; /* whatever */
if(!cf->totsz && cf->all_whitelisted) {
if (!cf->totsz && cf->all_whitelisted) {
logg("*Skipping scan (all destinations whitelisted)\n");
nullify(ctx, cf, CF_NONE);
free(cf);
return SMFIS_ACCEPT;
}
if(!headerf) return SMFIS_CONTINUE; /* just in case */
if (!headerf) return SMFIS_CONTINUE; /* just in case */
if((loginfected & (LOGINF_FULL | LOGCLN_FULL)) || viraction) {
if(!cf->msg_subj && !strcasecmp(headerf, "Subject"))
if ((loginfected & (LOGINF_FULL | LOGCLN_FULL)) || viraction) {
if (!cf->msg_subj && !strcasecmp(headerf, "Subject"))
cf->msg_subj = strdup(headerv ? headerv : "");
if(!cf->msg_date && !strcasecmp(headerf, "Date"))
if (!cf->msg_date && !strcasecmp(headerf, "Date"))
cf->msg_date = strdup(headerv ? headerv : "");
if(!cf->msg_id && !strcasecmp(headerf, "Message-ID"))
if (!cf->msg_id && !strcasecmp(headerf, "Message-ID"))
cf->msg_id = strdup(headerv ? headerv : "");
}
if(addxvirus==1) {
if(!strcasecmp(headerf, "X-Virus-Scanned")) cf->scanned_count++;
if(!strcasecmp(headerf, "X-Virus-Status")) cf->status_count++;
if (addxvirus == 1) {
if (!strcasecmp(headerf, "X-Virus-Scanned")) cf->scanned_count++;
if (!strcasecmp(headerf, "X-Virus-Status")) cf->status_count++;
}
if((ret = sendchunk(cf, (unsigned char *)headerf, strlen(headerf), ctx)) != SMFIS_CONTINUE) {
if ((ret = sendchunk(cf, (unsigned char *)headerf, strlen(headerf), ctx)) != SMFIS_CONTINUE) {
free(cf);
return ret;
}
if((ret = sendchunk(cf, (unsigned char *)": ", 2, ctx)) != SMFIS_CONTINUE) {
if ((ret = sendchunk(cf, (unsigned char *)": ", 2, ctx)) != SMFIS_CONTINUE) {
free(cf);
return ret;
}
if(headerv && (ret = sendchunk(cf, (unsigned char *)headerv, strlen(headerv), ctx)) != SMFIS_CONTINUE) {
if (headerv && (ret = sendchunk(cf, (unsigned char *)headerv, strlen(headerv), ctx)) != SMFIS_CONTINUE) {
free(cf);
return ret;
}
ret = sendchunk(cf, (unsigned char *)"\r\n", 2, ctx);
if(ret != SMFIS_CONTINUE)
if (ret != SMFIS_CONTINUE)
free(cf);
return ret;
}
sfsistat clamfi_body(SMFICTX *ctx, unsigned char *bodyp, size_t len) {
sfsistat clamfi_body(SMFICTX *ctx, unsigned char *bodyp, size_t len)
{
struct CLAMFI *cf;
sfsistat ret;
if(!(cf = (struct CLAMFI *)smfi_getpriv(ctx)))
if (!(cf = (struct CLAMFI *)smfi_getpriv(ctx)))
return SMFIS_CONTINUE; /* whatever */
if(!cf->gotbody) {
if (!cf->gotbody) {
ret = sendchunk(cf, (unsigned char *)"\r\n", 2, ctx);
if(ret != SMFIS_CONTINUE) {
if (ret != SMFIS_CONTINUE) {
free(cf);
return ret;
}
@ -282,32 +283,33 @@ sfsistat clamfi_body(SMFICTX *ctx, unsigned char *bodyp, size_t len) {
}
ret = sendchunk(cf, bodyp, len, ctx);
if(ret != SMFIS_CONTINUE)
if (ret != SMFIS_CONTINUE)
free(cf);
return ret;
}
sfsistat clamfi_abort(SMFICTX *ctx) {
sfsistat clamfi_abort(SMFICTX *ctx)
{
struct CLAMFI *cf;
if((cf = (struct CLAMFI *)smfi_getpriv(ctx))) {
if ((cf = (struct CLAMFI *)smfi_getpriv(ctx))) {
nullify(ctx, cf, CF_ANY);
free(cf);
}
return SMFIS_CONTINUE;
}
sfsistat clamfi_eom(SMFICTX *ctx) {
sfsistat clamfi_eom(SMFICTX *ctx)
{
struct CLAMFI *cf;
char *reply;
int len, ret;
unsigned int crcpt;
if(!(cf = (struct CLAMFI *)smfi_getpriv(ctx)))
if (!(cf = (struct CLAMFI *)smfi_getpriv(ctx)))
return SMFIS_CONTINUE; /* whatever */
if(!cf->totsz) {
if (!cf->totsz) {
/* got no headers and no body */
logg("*Not scanning an empty message\n");
ret = CleanAction(ctx);
@ -316,10 +318,10 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
return ret;
}
if(cf->local) {
if (cf->local) {
lseek(cf->alt, 0, SEEK_SET);
if(nc_sendmsg(cf->main, cf->alt) == -1) {
if (nc_sendmsg(cf->main, cf->alt) == -1) {
logg("!FD send failed\n");
nullify(ctx, cf, CF_ALT);
free(cf);
@ -328,7 +330,7 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
} else {
uint32_t sendmetoo = 0;
cf->sendme = htonl(cf->bufsz);
if((cf->bufsz && nc_send(cf->main, &cf->sendme, cf->bufsz + 4)) || nc_send(cf->main, &sendmetoo, 4)) {
if ((cf->bufsz && nc_send(cf->main, &cf->sendme, cf->bufsz + 4)) || nc_send(cf->main, &sendmetoo, 4)) {
logg("!Failed to flush STREAM\n");
nullify(ctx, cf, CF_NONE);
free(cf);
@ -338,12 +340,12 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
reply = nc_recv(cf->main);
if(cf->local)
if (cf->local)
close(cf->alt);
cf->alt = -1;
if(!reply) {
if (!reply) {
logg("!No reply from clamd\n");
nullify(ctx, cf, CF_NONE);
free(cf);
@ -351,25 +353,25 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
}
len = strlen(reply);
if(len>5 && !strcmp(reply + len - 5, ": OK\n")) {
if(addxvirus) add_x_header(ctx, "Clean", cf->scanned_count, cf->status_count);
if(loginfected & LOGCLN_FULL) {
if (len > 5 && !strcmp(reply + len - 5, ": OK\n")) {
if (addxvirus) add_x_header(ctx, "Clean", cf->scanned_count, cf->status_count);
if (loginfected & LOGCLN_FULL) {
const char *id = smfi_getsymval(ctx, "{i}");
const char *from = smfi_getsymval(ctx, "{mail_addr}");
const char *msg_subj = makesanehdr(cf->msg_subj);
const char *msg_date = makesanehdr(cf->msg_date);
const char *msg_id = makesanehdr(cf->msg_id);
if(multircpt && cf->nrecipients) {
for(crcpt = 0; crcpt < cf->nrecipients; crcpt++)
if (multircpt && cf->nrecipients) {
for (crcpt = 0; crcpt < cf->nrecipients; crcpt++)
logg("~Clean message %s from <%s> to <%s> with subject '%s' message-id '%s' date '%s'\n", id, from, cf->recipients[crcpt], msg_subj, msg_id, msg_date);
} else {
const char *to = smfi_getsymval(ctx, "{rcpt_addr}");
logg("~Clean message %s from <%s> to <%s> with subject '%s' message-id '%s' date '%s'\n", id, from, to ? to : HDR_UNAVAIL, msg_subj, msg_id, msg_date);
}
} else if(loginfected & LOGCLN_BASIC) {
} else if (loginfected & LOGCLN_BASIC) {
const char *from = smfi_getsymval(ctx, "{mail_addr}");
if(multircpt && cf->nrecipients) {
for(crcpt = 0; crcpt < cf->nrecipients; crcpt++)
if (multircpt && cf->nrecipients) {
for (crcpt = 0; crcpt < cf->nrecipients; crcpt++)
logg("~Clean message from <%s> to <%s>\n", from, cf->recipients[crcpt]);
} else {
const char *to = smfi_getsymval(ctx, "{rcpt_addr}");
@ -377,47 +379,47 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
}
}
ret = CleanAction(ctx);
} else if (len>7 && !strcmp(reply + len - 7, " FOUND\n")) {
} else if (len > 7 && !strcmp(reply + len - 7, " FOUND\n")) {
cf->virusname = NULL;
if((loginfected & (LOGINF_BASIC | LOGINF_FULL)) || addxvirus || rejectfmt || viraction) {
if ((loginfected & (LOGINF_BASIC | LOGINF_FULL)) || addxvirus || rejectfmt || viraction) {
char *vir;
reply[len-7] = '\0';
reply[len - 7] = '\0';
vir = strrchr(reply, ' ');
if(vir) {
if (vir) {
unsigned int have_multi = (multircpt != 0 && cf->nrecipients);
unsigned int lst_rcpt = (have_multi * (cf->nrecipients - 1)) + 1;
vir++;
if(rejectfmt)
if (rejectfmt)
cf->virusname = vir;
if(addxvirus) {
if (addxvirus) {
char msg[255];
snprintf(msg, sizeof(msg), "Infected (%s)", vir);
msg[sizeof(msg)-1] = '\0';
msg[sizeof(msg) - 1] = '\0';
add_x_header(ctx, msg, cf->scanned_count, cf->status_count);
}
for(crcpt = 0; crcpt < lst_rcpt; crcpt++) {
if(loginfected || viraction) {
for (crcpt = 0; crcpt < lst_rcpt; crcpt++) {
if (loginfected || viraction) {
const char *from = smfi_getsymval(ctx, "{mail_addr}");
const char *to = have_multi ? cf->recipients[crcpt] : smfi_getsymval(ctx, "{rcpt_addr}");
if(!from) from = HDR_UNAVAIL;
if(!to) to = HDR_UNAVAIL;
if((loginfected & LOGINF_FULL) || viraction) {
if (!from) from = HDR_UNAVAIL;
if (!to) to = HDR_UNAVAIL;
if ((loginfected & LOGINF_FULL) || viraction) {
const char *id = smfi_getsymval(ctx, "{i}");
const char *msg_subj = makesanehdr(cf->msg_subj);
const char *msg_date = makesanehdr(cf->msg_date);
const char *msg_id = makesanehdr(cf->msg_id);
if(!id) id = HDR_UNAVAIL;
if (!id) id = HDR_UNAVAIL;
if(loginfected & LOGINF_FULL)
if (loginfected & LOGINF_FULL)
logg("~Message %s from <%s> to <%s> with subject '%s' message-id '%s' date '%s' infected by %s\n", id, from, to, msg_subj, msg_id, msg_date, vir);
if(viraction) {
if (viraction) {
char er[256];
char *e_id = strdup(id);
char *e_from = strdup(from);
@ -431,9 +433,9 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
pthread_mutex_lock(&virusaction_lock);
pid = fork();
if(!pid) {
char * args[9]; /* avoid element is not computable at load time warns */
args[0]= viraction;
if (!pid) {
char *args[9]; /* avoid element is not computable at load time warns */
args[0] = viraction;
args[1] = vir;
args[2] = e_id;
args[3] = e_from;
@ -443,16 +445,16 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
args[7] = e_msg_date;
args[8] = NULL;
exit(execvp(viraction, args));
} else if(pid > 0) {
} else if (pid > 0) {
int wret;
pthread_mutex_unlock(&virusaction_lock);
while ((wret = waitpid(pid, &ret, 0)) == -1 && errno == EINTR) continue;
if(wret<0)
if (wret < 0)
logg("!VirusEvent: waitpid() failed: %s\n", cli_strerror(errno, er, sizeof(er)));
else {
if(WIFEXITED(ret))
if (WIFEXITED(ret))
logg("*VirusEvent: child exited with code %d\n", WEXITSTATUS(ret));
else if(WIFSIGNALED(ret))
else if (WIFSIGNALED(ret))
logg("*VirusEvent: child killed by signal %d\n", WTERMSIG(ret));
else
logg("*VirusEvent: child lost\n");
@ -468,7 +470,7 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
free(e_msg_id);
}
}
if(loginfected & LOGINF_BASIC)
if (loginfected & LOGINF_BASIC)
logg("~Message from <%s> to <%s> infected by %s\n", from, to, vir);
}
}
@ -486,22 +488,22 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
return ret;
}
sfsistat clamfi_connect(_UNUSED_ SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr) {
while(1) {
sfsistat clamfi_connect(_UNUSED_ SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr)
{
while (1) {
/* Postfix doesn't seem to honor passing a NULL hostaddr and hostname
set to "localhost" for non-smtp messages (they still appear as SMTP
messages from 127.0.0.1). Here's a small workaround. */
if(hostaddr) {
if(islocalnet_sock(hostaddr)) {
if (hostaddr) {
if (islocalnet_sock(hostaddr)) {
logg("*Skipping scan for %s (in LocalNet)\n", hostname);
return SMFIS_ACCEPT;
}
break;
}
if(!strcasecmp(hostname, "localhost"))
if (!strcasecmp(hostname, "localhost"))
hostname = NULL;
if(islocalnet_name(hostname)) {
if (islocalnet_name(hostname)) {
logg("*Skipping scan for %s (in LocalNet)\n", hostname ? hostname : "local");
return SMFIS_ACCEPT;
}
@ -510,86 +512,92 @@ sfsistat clamfi_connect(_UNUSED_ SMFICTX *ctx, char *hostname, _SOCK_ADDR *hosta
return SMFIS_CONTINUE;
}
static int parse_action(char *action) {
if(!strcasecmp(action, "Accept"))
static int parse_action(char *action)
{
if (!strcasecmp(action, "Accept"))
return 0;
if(!strcasecmp(action, "Defer"))
if (!strcasecmp(action, "Defer"))
return 1;
if(!strcasecmp(action, "Reject"))
if (!strcasecmp(action, "Reject"))
return 2;
if(!strcasecmp(action, "Blackhole"))
if (!strcasecmp(action, "Blackhole"))
return 3;
if(!strcasecmp(action, "Quarantine"))
if (!strcasecmp(action, "Quarantine"))
return 4;
logg("!Unknown action %s\n", action);
return -1;
}
static sfsistat action_accept(_UNUSED_ SMFICTX *ctx) {
static sfsistat action_accept(_UNUSED_ SMFICTX *ctx)
{
return SMFIS_ACCEPT;
}
static sfsistat action_defer(_UNUSED_ SMFICTX *ctx) {
static sfsistat action_defer(_UNUSED_ SMFICTX *ctx)
{
return SMFIS_TEMPFAIL;
}
static sfsistat action_reject(_UNUSED_ SMFICTX *ctx) {
static sfsistat action_reject(_UNUSED_ SMFICTX *ctx)
{
return SMFIS_REJECT;
}
static sfsistat action_blackhole(_UNUSED_ SMFICTX *ctx) {
static sfsistat action_blackhole(_UNUSED_ SMFICTX *ctx)
{
return SMFIS_DISCARD;
}
static sfsistat action_quarantine(SMFICTX *ctx) {
if(smfi_quarantine(ctx, "quarantined by clamav-milter") != MI_SUCCESS) {
static sfsistat action_quarantine(SMFICTX *ctx)
{
if (smfi_quarantine(ctx, "quarantined by clamav-milter") != MI_SUCCESS) {
logg("^Failed to quarantine message\n");
return SMFIS_TEMPFAIL;
}
return SMFIS_ACCEPT;
}
static sfsistat action_reject_msg(SMFICTX *ctx) {
static sfsistat action_reject_msg(SMFICTX *ctx)
{
struct CLAMFI *cf;
char buf[1024];
if(!rejectfmt || !(cf = (struct CLAMFI *)smfi_getpriv(ctx)))
if (!rejectfmt || !(cf = (struct CLAMFI *)smfi_getpriv(ctx)))
return SMFIS_REJECT;
snprintf(buf, sizeof(buf), rejectfmt, cf->virusname);
buf[sizeof(buf)-1] = '\0';
buf[sizeof(buf) - 1] = '\0';
smfi_setreply(ctx, "550", "5.7.1", buf);
return SMFIS_REJECT;
}
int init_actions(struct optstruct *opts) {
int init_actions(struct optstruct *opts)
{
const struct optstruct *opt;
if(!(opt = optget(opts, "LogInfected"))->enabled || !strcasecmp(opt->strarg, "Off"))
if (!(opt = optget(opts, "LogInfected"))->enabled || !strcasecmp(opt->strarg, "Off"))
loginfected = LOGINF_NONE;
else if(!strcasecmp(opt->strarg, "Basic"))
else if (!strcasecmp(opt->strarg, "Basic"))
loginfected = LOGINF_BASIC;
else if(!strcasecmp(opt->strarg, "Full"))
else if (!strcasecmp(opt->strarg, "Full"))
loginfected = LOGINF_FULL;
else {
logg("!Invalid setting %s for option LogInfected\n", opt->strarg);
return 1;
}
if((opt = optget(opts, "LogClean"))->enabled) {
if(!strcasecmp(opt->strarg, "Basic"))
if ((opt = optget(opts, "LogClean"))->enabled) {
if (!strcasecmp(opt->strarg, "Basic"))
loginfected |= LOGCLN_BASIC;
else if(!strcasecmp(opt->strarg, "Full"))
else if (!strcasecmp(opt->strarg, "Full"))
loginfected |= LOGCLN_FULL;
else if(strcasecmp(opt->strarg, "Off")) {
else if (strcasecmp(opt->strarg, "Off")) {
logg("!Invalid setting %s for option LogClean\n", opt->strarg);
return 1;
}
}
if((opt = optget(opts, "VirusAction"))->enabled)
if ((opt = optget(opts, "VirusAction"))->enabled)
viraction = strdup(opt->strarg);
if((opt = optget(opts, "OnFail"))->enabled) {
switch(parse_action(opt->strarg)) {
if ((opt = optget(opts, "OnFail"))->enabled) {
switch (parse_action(opt->strarg)) {
case 0:
FailAction = SMFIS_ACCEPT;
break;
@ -603,10 +611,11 @@ int init_actions(struct optstruct *opts) {
logg("!Invalid action %s for option OnFail\n", opt->strarg);
return 1;
}
} else FailAction = SMFIS_TEMPFAIL;
} else
FailAction = SMFIS_TEMPFAIL;
if((opt = optget(opts, "OnClean"))->enabled) {
switch(parse_action(opt->strarg)) {
if ((opt = optget(opts, "OnClean"))->enabled) {
switch (parse_action(opt->strarg)) {
case 0:
CleanAction = action_accept;
break;
@ -626,10 +635,11 @@ int init_actions(struct optstruct *opts) {
logg("!Invalid action %s for option OnClean\n", opt->strarg);
return 1;
}
} else CleanAction = action_accept;
} else
CleanAction = action_accept;
if((opt = optget(opts, "OnInfected"))->enabled) {
switch(parse_action(opt->strarg)) {
if ((opt = optget(opts, "OnInfected"))->enabled) {
switch (parse_action(opt->strarg)) {
case 0:
InfectedAction = action_accept;
break;
@ -644,26 +654,26 @@ int init_actions(struct optstruct *opts) {
break;
case 2:
InfectedAction = action_reject_msg;
if((opt = optget(opts, "RejectMsg"))->enabled) {
if ((opt = optget(opts, "RejectMsg"))->enabled) {
const char *src = opt->strarg;
char *dst, c;
int gotpctv = 0;
rejectfmt = dst = malloc(strlen(src) * 4 + 1);
if(!dst) {
if (!dst) {
logg("!Failed to allocate memory for RejectMsg\n");
return 1;
}
while ((c = *src++)) {
if(!isprint(c)) {
if (!isprint(c)) {
logg("!RejectMsg contains non printable characters\n");
free(rejectfmt);
return 1;
}
*dst++ = c;
if(c == '%') {
if(*src == 'v') {
if(gotpctv) {
if (c == '%') {
if (*src == 'v') {
if (gotpctv) {
logg("!%%v may appear at most once in RejectMsg\n");
free(rejectfmt);
return 1;
@ -684,26 +694,27 @@ int init_actions(struct optstruct *opts) {
logg("!Invalid action %s for option OnInfected\n", opt->strarg);
return 1;
}
} else InfectedAction = action_quarantine;
} else
InfectedAction = action_quarantine;
return 0;
}
sfsistat clamfi_envfrom(SMFICTX *ctx, char **argv) {
sfsistat clamfi_envfrom(SMFICTX *ctx, char **argv)
{
struct CLAMFI *cf;
const char *login = smfi_getsymval(ctx, "{auth_authen}");
if(login && smtpauthed(login)) {
if (login && smtpauthed(login)) {
logg("*Skipping scan for authenticated user %s\n", login);
return SMFIS_ACCEPT;
}
if(whitelisted(argv[0], 1)) {
if (whitelisted(argv[0], 1)) {
logg("*Skipping scan for %s (whitelisted from)\n", argv[0]);
return SMFIS_ACCEPT;
}
if(!(cf = (struct CLAMFI *)malloc(sizeof(*cf)))) {
if (!(cf = (struct CLAMFI *)malloc(sizeof(*cf)))) {
logg("!Failed to allocate CLAMFI struct\n");
return FailAction;
}
@ -713,11 +724,11 @@ sfsistat clamfi_envfrom(SMFICTX *ctx, char **argv) {
cf->all_whitelisted = 1;
cf->gotbody = 0;
cf->msg_subj = cf->msg_date = cf->msg_id = NULL;
if(multircpt) {
if (multircpt) {
cf->recipients = NULL;
cf->nrecipients = 0;
}
if(addxvirus==1) {
if (addxvirus == 1) {
cf->scanned_count = 0;
cf->status_count = 0;
}
@ -726,20 +737,20 @@ sfsistat clamfi_envfrom(SMFICTX *ctx, char **argv) {
return SMFIS_CONTINUE;
}
sfsistat clamfi_envrcpt(SMFICTX *ctx, char **argv) {
sfsistat clamfi_envrcpt(SMFICTX *ctx, char **argv)
{
struct CLAMFI *cf;
if(!(cf = (struct CLAMFI *)smfi_getpriv(ctx)))
if (!(cf = (struct CLAMFI *)smfi_getpriv(ctx)))
return SMFIS_CONTINUE; /* whatever */
if(cf->all_whitelisted)
if (cf->all_whitelisted)
cf->all_whitelisted &= whitelisted(argv[0], 0);
if(multircpt) {
if (multircpt) {
void *new_rcpt = realloc(cf->recipients, (cf->nrecipients + 1) * sizeof(*(cf->recipients)));
unsigned int rcpt_cnt;
if(!new_rcpt) {
if (!new_rcpt) {
logg("!Failed to allocate array for new recipient\n");
nullify(ctx, cf, CF_ANY);
free(cf);
@ -747,7 +758,7 @@ sfsistat clamfi_envrcpt(SMFICTX *ctx, char **argv) {
}
cf->recipients = new_rcpt;
rcpt_cnt = cf->nrecipients++;
if(!(cf->recipients[rcpt_cnt] = strdup(argv[0]))) {
if (!(cf->recipients[rcpt_cnt] = strdup(argv[0]))) {
logg("!Failed to allocate space for new recipient\n");
nullify(ctx, cf, CF_ANY);
free(cf);

View file

@ -30,7 +30,6 @@ extern int addxvirus;
extern char xvirushdr[255];
extern int multircpt;
sfsistat clamfi_body(SMFICTX *ctx, unsigned char *bodyp, size_t len);
sfsistat clamfi_abort(SMFICTX *ctx);
sfsistat clamfi_eom(SMFICTX *ctx);

View file

@ -43,11 +43,22 @@
#include "connpool.h"
#include "netcode.h"
#define SETGAI(k, v) {(k)->gai = (void *)(v);} while(0)
#define FREESRV(k) { if((k).gai) freeaddrinfo((k).gai); else if((k).server) free((k).server); } while(0)
#define SETGAI(k, v) \
{ \
(k)->gai = (void *)(v); \
} \
while (0)
#define FREESRV(k) \
{ \
if ((k).gai) \
freeaddrinfo((k).gai); \
else if ((k).server) \
free((k).server); \
} \
while (0)
#if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
#define _UNUSED_ __attribute__ ((__unused__))
#define _UNUSED_ __attribute__((__unused__))
#else
#define _UNUSED_
#endif
@ -57,22 +68,23 @@ static pthread_cond_t mon_cond = PTHREAD_COND_INITIALIZER;
static int quitting = 1;
static pthread_t probe_th;
static int cpool_addunix(char *path) {
static int cpool_addunix(char *path)
{
struct sockaddr_un *srv;
struct CP_ENTRY *cpe = &cp->pool[cp->entries-1];
struct CP_ENTRY *cpe = &cp->pool[cp->entries - 1];
if(!cli_is_abspath(path)) {
if (!cli_is_abspath(path)) {
logg("!Unix clamd socket must be an absolute path\n");
return 1;
}
if(!(srv = (struct sockaddr_un *)malloc(sizeof(*srv)))) {
if (!(srv = (struct sockaddr_un *)malloc(sizeof(*srv)))) {
logg("!Out of memory allocating unix socket space\n");
return 1;
}
srv->sun_family = AF_UNIX;
strncpy(srv->sun_path, path, sizeof(srv->sun_path));
srv->sun_path[sizeof(srv->sun_path)-1]='\0';
srv->sun_path[sizeof(srv->sun_path) - 1] = '\0';
cpe->type = 0;
cpe->dead = 1;
cpe->local = 1;
@ -80,13 +92,13 @@ static int cpool_addunix(char *path) {
cpe->server = (struct sockaddr *)srv;
cpe->socklen = sizeof(*srv);
SETGAI(cpe, NULL);
if(!cp->local_cpe) cp->local_cpe = cpe;
if (!cp->local_cpe) cp->local_cpe = cpe;
logg("*Local socket unix:%s added to the pool (slot %d)\n", srv->sun_path, cp->entries);
return 0;
}
static int islocal(struct sockaddr *sa, socklen_t addrlen) {
static int islocal(struct sockaddr *sa, socklen_t addrlen)
{
int s = socket(sa->sa_family, SOCK_STREAM, 0);
int ret;
if (s < 0) return 0;
@ -95,16 +107,16 @@ static int islocal(struct sockaddr *sa, socklen_t addrlen) {
return ret;
}
static int cpool_addtcp(char *addr, char *port) {
static int cpool_addtcp(char *addr, char *port)
{
struct addrinfo hints, *res, *res2;
struct CP_ENTRY *cpe = (struct CP_ENTRY *)&cp->pool[cp->entries-1];
struct CP_ENTRY *cpe = (struct CP_ENTRY *)&cp->pool[cp->entries - 1];
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if(getaddrinfo(addr, port ? port : "3310", &hints, &res)) {
if (getaddrinfo(addr, port ? port : "3310", &hints, &res)) {
logg("^Can't resolve hostname %s\n", addr ? addr : "");
return 1;
}
@ -115,10 +127,11 @@ static int cpool_addtcp(char *addr, char *port) {
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_UNSPEC;
if(!getaddrinfo(addr, NULL, &hints, &res2)) {
if (!getaddrinfo(addr, NULL, &hints, &res2)) {
cpe->local = islocal(res2->ai_addr, res2->ai_addrlen);
freeaddrinfo(res2);
} else cpe->local = 0;
} else
cpe->local = 0;
cpe->last_poll = 0;
cpe->server = res->ai_addr;
cpe->socklen = res->ai_addrlen;
@ -127,16 +140,16 @@ static int cpool_addtcp(char *addr, char *port) {
return 0;
}
static int addslot(void) {
static int addslot(void)
{
struct CP_ENTRY *cpe;
if(!(cpe = realloc(cp->pool, (cp->entries + 1) * sizeof(struct CP_ENTRY)))) {
if (!(cpe = realloc(cp->pool, (cp->entries + 1) * sizeof(struct CP_ENTRY)))) {
logg("!Out of memory while initializing the connection pool\n");
cpool_free();
return 1;
}
if(cp->local_cpe)
if (cp->local_cpe)
cp->local_cpe = (struct CP_ENTRY *)((char *)cp->local_cpe + ((char *)cpe - (char *)cp->pool));
memset(&cpe[cp->entries], 0, sizeof(*cpe));
cp->pool = cpe;
@ -144,20 +157,20 @@ static int addslot(void) {
return 0;
}
/* Probe strategy:
- wake up every minute
- probe alive if last check > 15 min
- probe dead if (last check > 2 min || no clamd available)
*/
static void cpool_probe(void) {
unsigned int i, dead=0;
static void cpool_probe(void)
{
unsigned int i, dead = 0;
struct CP_ENTRY *cpe = cp->pool;
time_t now = time(NULL);
for(i=1; i<=cp->entries; i++) {
if((cpe->dead && (cpe->last_poll < now - 120 || !cp->alive)) || cpe->last_poll < now - 15*60*60) {
for (i = 1; i <= cp->entries; i++) {
if ((cpe->dead && (cpe->last_poll < now - 120 || !cp->alive)) || cpe->last_poll < now - 15 * 60 * 60) {
cpe->last_poll = time(NULL);
nc_ping_entry(cpe);
logg("*Probe for slot %u returned: %s\n", i, cpe->dead ? "failed" : "success");
@ -167,18 +180,18 @@ static void cpool_probe(void) {
}
cp->alive = cp->entries - dead;
if(!cp->alive)
if (!cp->alive)
logg("^No clamd server appears to be available\n");
}
static void *cpool_mon(_UNUSED_ void *v) {
static void *cpool_mon(_UNUSED_ void *v)
{
pthread_mutex_t conv;
pthread_mutex_init(&conv, NULL);
pthread_mutex_lock(&conv);
while(!quitting) {
while (!quitting) {
struct timespec t;
cpool_probe();
@ -191,46 +204,46 @@ static void *cpool_mon(_UNUSED_ void *v) {
return NULL;
}
void cpool_init(struct optstruct *opts) {
void cpool_init(struct optstruct *opts)
{
const struct optstruct *opt;
int failed = 0;
if(!(cp=calloc(sizeof(*cp), 1))) {
if (!(cp = calloc(sizeof(*cp), 1))) {
logg("!Out of memory while initializing the connection pool");
return;
}
cp->local_cpe = NULL;
if((opt = optget(opts, "ClamdSocket"))->enabled) {
while(opt) {
if ((opt = optget(opts, "ClamdSocket"))->enabled) {
while (opt) {
char *socktype = opt->strarg;
if(addslot()) return;
if(!strncasecmp(socktype, "unix:", 5)) {
failed = cpool_addunix(socktype+5);
} else if(!strncasecmp(socktype, "tcp:", 4)) {
char *port = strrchr(socktype+4, ':');
if(port) {
*port='\0';
if (addslot()) return;
if (!strncasecmp(socktype, "unix:", 5)) {
failed = cpool_addunix(socktype + 5);
} else if (!strncasecmp(socktype, "tcp:", 4)) {
char *port = strrchr(socktype + 4, ':');
if (port) {
*port = '\0';
port++;
}
failed = cpool_addtcp(socktype+4, port);
failed = cpool_addtcp(socktype + 4, port);
} else {
logg("!Failed to parse ClamdSocket directive '%s'\n", socktype);
failed = 1;
}
if(failed) break;
if (failed) break;
opt = opt->nextarg;
}
if(failed) {
if (failed) {
cpool_free();
return;
}
}
if(!cp->entries) {
if (!cp->entries) {
logg("!No ClamdSocket specified\n");
cpool_free();
return;
@ -240,20 +253,20 @@ void cpool_init(struct optstruct *opts) {
srand(time(NULL));
}
void cpool_free(void) {
void cpool_free(void)
{
unsigned int i;
if(!quitting) {
if (!quitting) {
logg("*Killing the monitor and stopping\n");
quitting = 1;
pthread_cond_signal(&mon_cond);
pthread_join(probe_th, NULL);
}
if(cp) {
if(cp->pool) {
for(i=0; i<cp->entries; i++)
if (cp) {
if (cp->pool) {
for (i = 0; i < cp->entries; i++)
FREESRV(cp->pool[i]);
free(cp->pool);
}
@ -262,19 +275,19 @@ void cpool_free(void) {
}
}
struct CP_ENTRY *cpool_get_rand(int *s) {
struct CP_ENTRY *cpool_get_rand(int *s)
{
unsigned int start, i;
struct CP_ENTRY *cpe;
if(cp->alive) {
if (cp->alive) {
start = rand() % cp->entries;
for(i=0; i<cp->entries; i++) {
cpe = &cp->pool[(i+start) % cp->entries];
if(cpe->dead) continue;
if(cpe->local && cp->local_cpe && !cp->local_cpe->dead)
for (i = 0; i < cp->entries; i++) {
cpe = &cp->pool[(i + start) % cp->entries];
if (cpe->dead) continue;
if (cpe->local && cp->local_cpe && !cp->local_cpe->dead)
cpe = cp->local_cpe;
if((*s = nc_connect_entry(cpe)) == -1) {
if ((*s = nc_connect_entry(cpe)) == -1) {
cpe->dead = 1;
continue;
}
@ -285,7 +298,6 @@ struct CP_ENTRY *cpool_get_rand(int *s) {
return NULL;
}
/*
* Local Variables:
* mode: c

View file

@ -51,7 +51,7 @@
#include "libclamav/others.h"
#include "netcode.h"
#define strerror_print(msg) logg(msg": %s\n", cli_strerror(errno, er, sizeof(er)))
#define strerror_print(msg) logg(msg ": %s\n", cli_strerror(errno, er, sizeof(er)))
enum {
NON_SMTP,
@ -75,8 +75,8 @@ char *tempdir = NULL;
/* for recv */
long readtimeout;
static int nc_socket(struct CP_ENTRY *cpe) {
static int nc_socket(struct CP_ENTRY *cpe)
{
int flags, s = socket(cpe->server->sa_family, SOCK_STREAM, 0);
char er[256];
@ -99,8 +99,8 @@ static int nc_socket(struct CP_ENTRY *cpe) {
return s;
}
static int nc_connect(int s, struct CP_ENTRY *cpe) {
static int nc_connect(int s, struct CP_ENTRY *cpe)
{
time_t timeout = time(NULL) + TIMEOUT;
int res = connect(s, cpe->server, cpe->socklen);
struct timeval tv;
@ -115,15 +115,15 @@ static int nc_connect(int s, struct CP_ENTRY *cpe) {
tv.tv_sec = TIMEOUT;
tv.tv_usec = 0;
while(1) {
while (1) {
fd_set fds;
int s_err;
socklen_t s_len = sizeof(s_err);
FD_ZERO(&fds);
FD_SET(s, &fds);
res = select(s+1, NULL, &fds, NULL, &tv);
if(res < 1) {
res = select(s + 1, NULL, &fds, NULL, &tv);
if (res < 1) {
time_t now;
if (res == -1 && errno == EINTR && ((now = time(NULL)) < timeout)) {
@ -135,7 +135,7 @@ static int nc_connect(int s, struct CP_ENTRY *cpe) {
close(s);
return -1;
}
if(getsockopt(s, SOL_SOCKET, SO_ERROR, &s_err, (socklen_t *)&s_len) || s_err) {
if (getsockopt(s, SOL_SOCKET, SO_ERROR, &s_err, (socklen_t *)&s_len) || s_err) {
logg("*Failed to establish a connection to clamd\n");
close(s);
return -1;
@ -144,27 +144,27 @@ static int nc_connect(int s, struct CP_ENTRY *cpe) {
}
}
int nc_send(int s, const void *buff, size_t len) {
int nc_send(int s, const void *buff, size_t len)
{
char *buf = (char *)buff;
while(len) {
while (len) {
int res = send(s, buf, len, 0);
time_t timeout = time(NULL) + TIMEOUT;
struct timeval tv;
char er[256];
if(!res) {
if (!res) {
logg("!Connection closed while sending data\n");
close(s);
return 1;
}
if(res!=-1) {
len-=res;
buf+=res;
if (res != -1) {
len -= res;
buf += res;
continue;
}
if(errno != EAGAIN && errno != EWOULDBLOCK) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
strerror_print("!send failed");
close(s);
return 1;
@ -172,13 +172,13 @@ int nc_send(int s, const void *buff, size_t len) {
tv.tv_sec = TIMEOUT;
tv.tv_usec = 0;
while(1) {
while (1) {
fd_set fds;
FD_ZERO(&fds);
FD_SET(s, &fds);
res = select(s+1, NULL, &fds, NULL, &tv);
if(res < 1) {
res = select(s + 1, NULL, &fds, NULL, &tv);
if (res < 1) {
time_t now;
if (res == -1 && errno == EINTR && ((now = time(NULL)) < timeout)) {
@ -196,14 +196,14 @@ int nc_send(int s, const void *buff, size_t len) {
return 0;
}
int nc_sendmsg(int s, int fd) {
int nc_sendmsg(int s, int fd)
{
struct iovec iov[1];
struct msghdr msg;
struct cmsghdr *cmsg;
int ret;
unsigned char fdbuf[CMSG_SPACE(sizeof(int))];
char dummy[]="";
char dummy[] = "";
iov[0].iov_base = dummy;
iov[0].iov_len = 1;
@ -219,7 +219,7 @@ int nc_sendmsg(int s, int fd) {
*(int *)CMSG_DATA(cmsg) = fd;
/* FIXME: nonblock code needed (?) */
if((ret = sendmsg(s, &msg, 0)) == -1) {
if ((ret = sendmsg(s, &msg, 0)) == -1) {
char er[256];
strerror_print("!clamfi_eom: FD send failed");
close(s);
@ -227,17 +227,18 @@ int nc_sendmsg(int s, int fd) {
return ret;
}
char *nc_recv(int s) {
char buf[128], *ret=NULL;
char *nc_recv(int s)
{
char buf[128], *ret = NULL;
time_t now, timeout = time(NULL) + readtimeout;
struct timeval tv;
fd_set fds;
int res;
unsigned int len = 0;
while(1) {
while (1) {
now = time(NULL);
if(now >= timeout) {
if (now >= timeout) {
logg("!Timed out while reading clamd reply\n");
close(s);
return NULL;
@ -248,20 +249,20 @@ char *nc_recv(int s) {
FD_ZERO(&fds);
FD_SET(s, &fds);
res = select(s+1, &fds, NULL, NULL, readtimeout ? &tv : NULL);
if(res<1) {
res = select(s + 1, &fds, NULL, NULL, readtimeout ? &tv : NULL);
if (res < 1) {
if (res != -1 || errno != EINTR)
timeout = 0;
continue;
}
res = recv(s, &buf[len], sizeof(buf) - len, 0);
if(!res) {
if (!res) {
logg("!Connection closed while reading from socket\n");
close(s);
return NULL;
}
if(res==-1) {
if (res == -1) {
char er[256];
if (errno == EAGAIN)
continue;
@ -270,38 +271,38 @@ char *nc_recv(int s) {
return NULL;
}
len += res;
if(len && buf[len-1] == '\n') break;
if(len >= sizeof(buf)) {
if (len && buf[len - 1] == '\n') break;
if (len >= sizeof(buf)) {
logg("!Overlong reply from clamd\n");
close(s);
return NULL;
}
}
if(!(ret = (char *)malloc(len+1))) {
logg("!malloc(%d) failed\n", len+1);
if (!(ret = (char *)malloc(len + 1))) {
logg("!malloc(%d) failed\n", len + 1);
close(s);
return NULL;
}
memcpy(ret, buf, len);
ret[len]='\0';
ret[len] = '\0';
return ret;
}
int nc_connect_entry(struct CP_ENTRY *cpe) {
int nc_connect_entry(struct CP_ENTRY *cpe)
{
int s = nc_socket(cpe);
if(s==-1) return -1;
if (s == -1) return -1;
return nc_connect(s, cpe) ? -1 : s;
}
void nc_ping_entry(struct CP_ENTRY *cpe) {
void nc_ping_entry(struct CP_ENTRY *cpe)
{
int s = nc_connect_entry(cpe);
char *reply;
if(s>=0) {
if(!nc_send(s, "nPING\n", 6) && (reply = nc_recv(s))) {
cpe->dead = strcmp(reply, "PONG\n")!=0;
if (s >= 0) {
if (!nc_send(s, "nPING\n", 6) && (reply = nc_recv(s))) {
cpe->dead = strcmp(reply, "PONG\n") != 0;
free(reply);
close(s);
return;
@ -311,29 +312,29 @@ void nc_ping_entry(struct CP_ENTRY *cpe) {
cpe->dead = 1;
}
int nc_connect_rand(int *main, int *alt, int *local) {
int nc_connect_rand(int *main, int *alt, int *local)
{
struct CP_ENTRY *cpe = cpool_get_rand(main);
if(!cpe) return 1;
if (!cpe) return 1;
*local = (cpe->server->sa_family == AF_UNIX);
if(*local) {
if (*local) {
char *unlinkme;
if(cli_gentempfd(tempdir, &unlinkme, alt) != CL_SUCCESS) {
if (cli_gentempfd(tempdir, &unlinkme, alt) != CL_SUCCESS) {
logg("!Failed to create temporary file\n");
close(*main);
return 1;
}
unlink(unlinkme);
free(unlinkme);
if(nc_send(*main, "nFILDES\n", 8)) {
if (nc_send(*main, "nFILDES\n", 8)) {
logg("!FD scan request failed\n");
close(*alt);
close(*main);
return 1;
}
} else {
if(nc_send(*main, "nINSTREAM\n", 10)) {
if (nc_send(*main, "nINSTREAM\n", 10)) {
logg("!Failed to communicate with clamd\n");
close(*main);
return 1;
@ -342,11 +343,11 @@ int nc_connect_rand(int *main, int *alt, int *local) {
return 0;
}
static int resolve(char *name, uint32_t *family, uint32_t *host) {
static int resolve(char *name, uint32_t *family, uint32_t *host)
{
struct addrinfo hints, *res;
if(!name) {
if (!name) {
/* l->basehost[0] = l->basehost[1] = l->basehost[2] = l->basehost[3] = 0; DONT BOTHER*/
*family = NON_SMTP;
return 0;
@ -356,26 +357,26 @@ static int resolve(char *name, uint32_t *family, uint32_t *host) {
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if(getaddrinfo(name, NULL, &hints, &res)) {
if (getaddrinfo(name, NULL, &hints, &res)) {
logg("!Can't resolve LocalNet hostname %s\n", name);
return 1;
}
if(res->ai_addrlen == sizeof(struct sockaddr_in) && res->ai_addr->sa_family == AF_INET) {
if (res->ai_addrlen == sizeof(struct sockaddr_in) && res->ai_addr->sa_family == AF_INET) {
struct sockaddr_in *sa = (struct sockaddr_in *)res->ai_addr;
*family = INET_HOST;
host[0] = htonl(sa->sin_addr.s_addr);
/* host[1] = host[2] = host[3] = 0; DONT BOTHER*/
} else if(res->ai_addrlen == sizeof(struct sockaddr_in6) && res->ai_addr->sa_family == AF_INET6) {
} else if (res->ai_addrlen == sizeof(struct sockaddr_in6) && res->ai_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sa = (struct sockaddr_in6 *)res->ai_addr;
unsigned int i, j;
uint32_t u = 0;
*family = INET6_HOST;
for(i=0, j=0; i<16; i++) {
u += (sa->sin6_addr.s6_addr[i] << (8*j));
if(++j == 4) {
host[i>>2] = u;
for (i = 0, j = 0; i < 16; i++) {
u += (sa->sin6_addr.s6_addr[i] << (8 * j));
if (++j == 4) {
host[i >> 2] = u;
j = u = 0;
}
}
@ -388,39 +389,41 @@ static int resolve(char *name, uint32_t *family, uint32_t *host) {
return 0;
}
static struct LOCALNET *localnet(char *name, char *mask) {
static struct LOCALNET *localnet(char *name, char *mask)
{
struct LOCALNET *l = (struct LOCALNET *)malloc(sizeof(*l));
uint32_t nmask;
unsigned int i;
if(!l) {
if (!l) {
logg("!Out of memory while resolving LocalNet\n");
return NULL;
}
if(resolve(name, &l->family, l->basehost)) {
if (resolve(name, &l->family, l->basehost)) {
free(l);
return NULL;
}
if(l->family == NON_SMTP) {
if (l->family == NON_SMTP) {
l->mask[0] = l->mask[1] = l->mask[2] = l->mask[3] = 0x0;
return l;
}
if(!mask || !*mask) nmask = 32 + 96*(l->family == INET6_HOST);
else nmask = atoi(mask);
if (!mask || !*mask)
nmask = 32 + 96 * (l->family == INET6_HOST);
else
nmask = atoi(mask);
if((l->family == INET6_HOST && nmask > 128) || (l->family == INET_HOST && nmask > 32)) {
if ((l->family == INET6_HOST && nmask > 128) || (l->family == INET_HOST && nmask > 32)) {
logg("!Bad netmask '/%s' for LocalNet %s\n", mask, name);
free(l);
return NULL;
}
l->mask[0] = l->mask[1] = l->mask[2] = l->mask[3] = 0;
for(i=0; i<nmask; i++)
l->mask[i>>5] |= 1<<(31-(i & 31));
for (i = 0; i < nmask; i++)
l->mask[i >> 5] |= 1 << (31 - (i & 31));
l->basehost[0] &= l->mask[0];
l->basehost[1] &= l->mask[1];
@ -430,65 +433,65 @@ static struct LOCALNET *localnet(char *name, char *mask) {
return l;
}
static int islocalnet(uint32_t family, uint32_t *host)
{
struct LOCALNET *l = lnet;
static int islocalnet(uint32_t family, uint32_t *host) {
struct LOCALNET* l = lnet;
if(!l) return 0;
while(l) {
if(
if (!l) return 0;
while (l) {
if (
(l->family == family) &&
(l->basehost[0] == (host[0] & l->mask[0])) && (l->basehost[1] == (host[1] & l->mask[1])) &&
(l->basehost[2] == (host[2] & l->mask[2])) && (l->basehost[3] == (host[3] & l->mask[3]))
) return 1;
l=l->next;
(l->basehost[2] == (host[2] & l->mask[2])) && (l->basehost[3] == (host[3] & l->mask[3]))) return 1;
l = l->next;
}
return 0;
}
int islocalnet_name(char *name) {
int islocalnet_name(char *name)
{
uint32_t host[4], family;
if(!lnet) return 0;
if(resolve(name, &family, host)) {
if (!lnet) return 0;
if (resolve(name, &family, host)) {
logg("*Cannot resolv %s\n", name);
return 0;
}
return islocalnet(family, host);
}
int islocalnet_sock(struct sockaddr *sa) {
int islocalnet_sock(struct sockaddr *sa)
{
uint32_t host[4], family;
if(!lnet) return 0;
if (!lnet) return 0;
if(sa->sa_family == AF_INET) {
if (sa->sa_family == AF_INET) {
struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
family = INET_HOST;
host[0] = htonl(sa4->sin_addr.s_addr);
} else if(sa->sa_family == AF_INET6) {
} else if (sa->sa_family == AF_INET6) {
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
unsigned int i, j;
uint32_t u = 0;
family = INET6_HOST;
for(i=0, j=0; i<16; i++) {
u += (sa6->sin6_addr.s6_addr[i] << (8*j));
if(++j == 4) {
host[i>>2] = u;
for (i = 0, j = 0; i < 16; i++) {
u += (sa6->sin6_addr.s6_addr[i] << (8 * j));
if (++j == 4) {
host[i >> 2] = u;
j = u = 0;
}
}
} else return 0;
} else
return 0;
return islocalnet(family, host);
}
void localnets_free(void) {
while(lnet) {
void localnets_free(void)
{
while (lnet) {
struct LOCALNET *l = lnet->next;
free(lnet);
@ -496,22 +499,22 @@ void localnets_free(void) {
}
}
int localnets_init(struct optstruct *opts) {
int localnets_init(struct optstruct *opts)
{
const struct optstruct *opt;
if((opt = optget(opts, "LocalNet"))->enabled) {
while(opt) {
if ((opt = optget(opts, "LocalNet"))->enabled) {
while (opt) {
char *lnetname = opt->strarg;
struct LOCALNET *l;
char *mask = strrchr(lnetname, *PATHSEP);
if(mask) {
*mask='\0';
if (mask) {
*mask = '\0';
mask++;
}
if(!strcasecmp(lnetname, "local")) lnetname = NULL;
if((l = localnet(lnetname, mask)) == NULL) {
if (!strcasecmp(lnetname, "local")) lnetname = NULL;
if ((l = localnet(lnetname, mask)) == NULL) {
localnets_free();
return 1;
}

View file

@ -42,15 +42,16 @@ struct WHLST *wto = NULL;
int skipauth = 0;
regex_t authreg;
void whitelist_free(void) {
void whitelist_free(void)
{
struct WHLST *w;
while(wfrom) {
while (wfrom) {
w = wfrom->next;
cli_regfree(&wfrom->preg);
free(wfrom);
wfrom = w;
}
while(wto) {
while (wto) {
w = wto->next;
cli_regfree(&wto->preg);
free(wto);
@ -58,36 +59,37 @@ void whitelist_free(void) {
}
}
int whitelist_init(const char *fname) {
int whitelist_init(const char *fname)
{
char buf[2048];
FILE *f;
struct WHLST *w;
if(!(f = fopen(fname, "r"))) {
if (!(f = fopen(fname, "r"))) {
logg("!Cannot open whitelist file '%s'\n", fname);
return 1;
}
while(fgets(buf, sizeof(buf), f) != NULL) {
while (fgets(buf, sizeof(buf), f) != NULL) {
struct WHLST **addto = &wto;
char *ptr = buf;
int len;
if(*buf == '#' || *buf == ':' || *buf == '!')
if (*buf == '#' || *buf == ':' || *buf == '!')
continue;
if(!strncasecmp("From:", buf, 5)) {
ptr+=5;
if (!strncasecmp("From:", buf, 5)) {
ptr += 5;
addto = &wfrom;
} else if (!strncasecmp("To:", buf, 3))
ptr+=3;
ptr += 3;
len = strlen(ptr) - 1;
for(;len>=0; len--) {
if(ptr[len] != '\n' && ptr[len] != '\r') break;
for (; len >= 0; len--) {
if (ptr[len] != '\n' && ptr[len] != '\r') break;
ptr[len] = '\0';
}
if(!len) continue;
if (!len) continue;
if (!(w = (struct WHLST *)malloc(sizeof(*w)))) {
logg("!Out of memory loading whitelist file\n");
whitelist_free();
@ -96,7 +98,7 @@ int whitelist_init(const char *fname) {
}
w->next = (*addto);
(*addto) = w;
if (cli_regcomp(&w->preg, ptr, REG_ICASE|REG_NOSUB)) {
if (cli_regcomp(&w->preg, ptr, REG_ICASE | REG_NOSUB)) {
logg("!Failed to compile regex '%s' in whitelist file\n", ptr);
whitelist_free();
fclose(f);
@ -107,57 +109,59 @@ int whitelist_init(const char *fname) {
return 0;
}
int whitelisted(const char *addr, int from) {
int whitelisted(const char *addr, int from)
{
struct WHLST *w;
if(from) w = wfrom;
else w = wto;
if (from)
w = wfrom;
else
w = wto;
while(w) {
if(!cli_regexec(&w->preg, addr, 0, NULL, 0))
while (w) {
if (!cli_regexec(&w->preg, addr, 0, NULL, 0))
return 1;
w = w->next;
}
return 0;
}
int smtpauth_init(const char *r) {
int smtpauth_init(const char *r)
{
char *regex = NULL;
if(!strncmp(r, "file:", 5)) {
if (!strncmp(r, "file:", 5)) {
char buf[2048];
FILE *f = fopen(r+5, "r");
int rxsize = 0, rxavail = 0, rxused=0;
FILE *f = fopen(r + 5, "r");
int rxsize = 0, rxavail = 0, rxused = 0;
if(!f) {
logg("!Cannot open whitelist file '%s'\n", r+5);
if (!f) {
logg("!Cannot open whitelist file '%s'\n", r + 5);
return 1;
}
while(fgets(buf, sizeof(buf), f) != NULL) {
while (fgets(buf, sizeof(buf), f) != NULL) {
int len;
char *ptr;
if(*buf == '#' || *buf == ':' || *buf == '!')
if (*buf == '#' || *buf == ':' || *buf == '!')
continue;
len = strlen(buf) - 1;
for(;len>=0; len--) {
if(buf[len] != '\n' && buf[len] != '\r') break;
for (; len >= 0; len--) {
if (buf[len] != '\n' && buf[len] != '\r') break;
buf[len] = '\0';
}
if(len<=0) continue;
if(len*3+1 > rxavail) {
if (len <= 0) continue;
if (len * 3 + 1 > rxavail) {
ptr = regex;
regex = realloc(regex, rxsize + 2048);
if(!regex) {
if (!regex) {
logg("!Cannot allocate memory for SkipAuthenticated file\n");
fclose(f);
return 1;
}
rxavail = 2048;
rxsize += 2048;
if(!ptr) {
if (!ptr) {
regex[0] = '^';
regex[1] = '(';
rxavail -= 2;
@ -165,15 +169,15 @@ int smtpauth_init(const char *r) {
}
}
ptr = buf;
while(*ptr) {
if((*ptr>='A' && *ptr<='Z') || (*ptr>='a' && *ptr<='z') || (*ptr>='0' && *ptr<='9') || *ptr=='@') {
while (*ptr) {
if ((*ptr >= 'A' && *ptr <= 'Z') || (*ptr >= 'a' && *ptr <= 'z') || (*ptr >= '0' && *ptr <= '9') || *ptr == '@') {
regex[rxused] = *ptr;
rxused++;
rxavail--;
} else {
regex[rxused] = '[';
regex[rxused+1] = *ptr;
regex[rxused+2] = ']';
regex[rxused + 1] = *ptr;
regex[rxused + 2] = ']';
rxused += 3;
rxavail -= 3;
}
@ -182,36 +186,35 @@ int smtpauth_init(const char *r) {
regex[rxused++] = '|';
rxavail--;
}
if(rxavail < 4 && !(regex = realloc(regex, rxsize + 4))) {
if (rxavail < 4 && !(regex = realloc(regex, rxsize + 4))) {
logg("!Cannot allocate memory for SkipAuthenticated file\n");
fclose(f);
return 1;
}
regex[rxused-1] = ')';
regex[rxused - 1] = ')';
regex[rxused] = '$';
regex[rxused+1] = '\0';
regex[rxused + 1] = '\0';
r = regex;
fclose(f);
}
if(cli_regcomp(&authreg, r, REG_ICASE|REG_NOSUB|REG_EXTENDED)) {
if (cli_regcomp(&authreg, r, REG_ICASE | REG_NOSUB | REG_EXTENDED)) {
logg("!Failed to compile regex '%s' for SkipAuthenticated\n", r);
if(regex) free(regex);
if (regex) free(regex);
return 1;
}
if(regex) free(regex);
if (regex) free(regex);
skipauth = 1;
return 0;
}
int smtpauthed(const char *login) {
if(skipauth && !cli_regexec(&authreg, login, 0, NULL, 0))
int smtpauthed(const char *login)
{
if (skipauth && !cli_regexec(&authreg, login, 0, NULL, 0))
return 1;
return 0;
}
/*
* Local Variables:
* mode: c

View file

@ -143,19 +143,19 @@ static void print_src(const char *file)
int nread, i, found = 0, lcnt = 0;
FILE *f = fopen(file, "r");
if (!f) {
fprintf(stderr,"Unable to reopen %s\n", file);
fprintf(stderr, "Unable to reopen %s\n", file);
return;
}
do {
nread = fread(buf, 1, sizeof(buf), f);
for (i=0;i<nread-1;i++) {
for (i = 0; i < nread - 1; i++) {
if (buf[i] == '\n') {
lcnt++;
}
/* skip over the logical trigger */
if (lcnt >= 2 && buf[i] == '\n' && buf[i+1] == 'S') {
if (lcnt >= 2 && buf[i] == '\n' && buf[i + 1] == 'S') {
found = 1;
i+=2;
i += 2;
break;
}
}
@ -163,17 +163,17 @@ static void print_src(const char *file)
if (debug_flag)
printf("[clambc] Source code:");
do {
for (;i+1<nread;i++) {
for (; i + 1 < nread; i++) {
if (buf[i] == 'S' || buf[i] == '\n') {
putc('\n', stdout);
continue;
}
putc(((buf[i]&0xf) | ((buf[i+1]&0xf)<<4)), stdout);
putc(((buf[i] & 0xf) | ((buf[i + 1] & 0xf) << 4)), stdout);
i++;
}
if (i == nread-1 && nread != 1)
if (i == nread - 1 && nread != 1)
fseek(f, -1, SEEK_CUR);
i=0;
i = 0;
nread = fread(buf, 1, sizeof(buf), f);
} while (nread > 0);
fclose(f);
@ -249,15 +249,15 @@ int main(int argc, char *argv[])
FILE *f;
struct cli_bc *bc;
struct cli_bc_ctx *ctx;
int rc, dbgargc, bc_stats=0;
int rc, dbgargc, bc_stats = 0;
struct optstruct *opts;
const struct optstruct *opt;
unsigned funcid=0, i;
unsigned funcid = 0, i;
struct cli_all_bc bcs;
int fd = -1;
unsigned tracelevel;
if(check_flevel())
if (check_flevel())
exit(1);
opts = optparse(NULL, argc, argv, 1, OPT_CLAMBC, 0, NULL);
@ -265,14 +265,14 @@ int main(int argc, char *argv[])
fprintf(stderr, "ERROR: Can't parse command line options\n");
exit(1);
}
if(optget(opts, "version")->enabled) {
if (optget(opts, "version")->enabled) {
printf("Clam AntiVirus Bytecode Testing Tool %s\n", get_version());
cl_init(CL_INIT_DEFAULT);
cli_bytecode_printversion();
optfree(opts);
exit(0);
}
if(optget(opts, "help")->enabled || !opts->filename) {
if (optget(opts, "help")->enabled || !opts->filename) {
optfree(opts);
help();
exit(0);
@ -291,18 +291,18 @@ int main(int argc, char *argv[])
exit(3);
}
if (optget(opts,"debug")->enabled) {
if (optget(opts, "debug")->enabled) {
cl_debug();
debug_flag=1;
debug_flag = 1;
}
rc = cl_init(CL_INIT_DEFAULT);
if (rc != CL_SUCCESS) {
fprintf(stderr,"Unable to init libclamav: %s\n", cl_strerror(rc));
fprintf(stderr, "Unable to init libclamav: %s\n", cl_strerror(rc));
optfree(opts);
exit(4);
}
dbgargc=1;
dbgargc = 1;
while (opts->filename[dbgargc]) dbgargc++;
if (dbgargc > 1)
@ -313,7 +313,7 @@ int main(int argc, char *argv[])
} else {
rc = cli_bytecode_init(&bcs);
if (rc != CL_SUCCESS) {
fprintf(stderr,"Unable to init bytecode engine: %s\n", cl_strerror(rc));
fprintf(stderr, "Unable to init bytecode engine: %s\n", cl_strerror(rc));
optfree(opts);
exit(4);
}
@ -322,23 +322,23 @@ int main(int argc, char *argv[])
bcs.all_bcs = bc;
bcs.count = 1;
if((opt = optget(opts, "statistics"))->enabled) {
while(opt) {
if ((opt = optget(opts, "statistics"))->enabled) {
while (opt) {
if (!strcasecmp(opt->strarg, "bytecode"))
bc_stats=1;
bc_stats = 1;
opt = opt->nextarg;
}
}
rc = cli_bytecode_load(bc, f, NULL, optget(opts, "trust-bytecode")->enabled, bc_stats);
if (rc != CL_SUCCESS) {
fprintf(stderr,"Unable to load bytecode: %s\n", cl_strerror(rc));
fprintf(stderr, "Unable to load bytecode: %s\n", cl_strerror(rc));
optfree(opts);
exit(4);
}
fclose(f);
if (bc->state == bc_skip) {
fprintf(stderr,"bytecode load skipped\n");
fprintf(stderr, "bytecode load skipped\n");
exit(0);
}
if (debug_flag)
@ -357,19 +357,19 @@ int main(int argc, char *argv[])
fmap_t *map = NULL;
memset(&cctx, 0, sizeof(cctx));
if (!engine) {
fprintf(stderr,"Unable to create engine\n");
fprintf(stderr, "Unable to create engine\n");
optfree(opts);
exit(3);
}
rc = cl_engine_compile(engine);
if (rc) {
fprintf(stderr,"Unable to compile engine: %s\n", cl_strerror(rc));
fprintf(stderr, "Unable to compile engine: %s\n", cl_strerror(rc));
optfree(opts);
exit(4);
}
rc = cli_bytecode_prepare2(engine, &bcs, BYTECODE_ENGINE_MASK);
if (rc != CL_SUCCESS) {
fprintf(stderr,"Unable to prepare bytecode: %s\n", cl_strerror(rc));
fprintf(stderr, "Unable to prepare bytecode: %s\n", cl_strerror(rc));
optfree(opts);
exit(4);
}
@ -378,14 +378,14 @@ int main(int argc, char *argv[])
ctx = cli_bytecode_context_alloc();
if (!ctx) {
fprintf(stderr,"Out of memory\n");
fprintf(stderr, "Out of memory\n");
exit(3);
}
ctx->ctx = &cctx;
cctx.engine = engine;
cctx.fmap = cli_calloc(sizeof(fmap_t*), engine->maxreclevel+2);
cctx.fmap = cli_calloc(sizeof(fmap_t *), engine->maxreclevel + 2);
if (!cctx.fmap) {
fprintf(stderr,"Out of memory\n");
fprintf(stderr, "Out of memory\n");
exit(3);
}
memset(&dbg_state, 0, sizeof(dbg_state));
@ -408,17 +408,17 @@ int main(int argc, char *argv[])
printf("[clambc] Running bytecode function :%u\n", funcid);
if (opts->filename[1]) {
i=2;
i = 2;
while (opts->filename[i]) {
rc = cli_bytecode_context_setparam_int(ctx, i-2, atoi(opts->filename[i]));
rc = cli_bytecode_context_setparam_int(ctx, i - 2, atoi(opts->filename[i]));
if (rc != CL_SUCCESS) {
fprintf(stderr,"Unable to set param %u: %s\n", i-2, cl_strerror(rc));
fprintf(stderr, "Unable to set param %u: %s\n", i - 2, cl_strerror(rc));
}
i++;
}
}
if ((opt = optget(opts,"input"))->enabled) {
if ((opt = optget(opts, "input"))->enabled) {
fd = open(opt->strarg, O_RDONLY);
if (fd == -1) {
fprintf(stderr, "Unable to open input file %s: %s\n", opt->strarg, strerror(errno));
@ -442,7 +442,7 @@ int main(int argc, char *argv[])
ctx->hooks.match_offsets = deadbeefcounts;
rc = cli_bytecode_run(&bcs, bc, ctx);
if (rc != CL_SUCCESS) {
fprintf(stderr,"Unable to run bytecode: %s\n", cl_strerror(rc));
fprintf(stderr, "Unable to run bytecode: %s\n", cl_strerror(rc));
} else {
uint64_t v;
if (debug_flag)

View file

@ -59,38 +59,38 @@ static struct _cfgfile {
const char *name;
int tool;
} cfgfile[] = {
{ "clamd.conf", OPT_CLAMD },
{ "freshclam.conf", OPT_FRESHCLAM },
{ "clamav-milter.conf", OPT_MILTER },
{ NULL, 0 }
};
{"clamd.conf", OPT_CLAMD},
{"freshclam.conf", OPT_FRESHCLAM},
{"clamav-milter.conf", OPT_MILTER},
{NULL, 0}};
static void printopts(struct optstruct *opts, int nondef)
{
const struct optstruct *opt;
while(opts) {
if(!opts->name) {
while (opts) {
if (!opts->name) {
opts = opts->next;
continue;
}
if(clam_options[opts->idx].owner & OPT_DEPRECATED) {
if(opts->active)
if (clam_options[opts->idx].owner & OPT_DEPRECATED) {
if (opts->active)
printf("*** %s is DEPRECATED ***\n", opts->name);
opts = opts->next;
continue;
}
if(nondef && (opts->numarg == clam_options[opts->idx].numarg) && ((opts->strarg == clam_options[opts->idx].strarg) || (opts->strarg && clam_options[opts->idx].strarg && !strcmp(opts->strarg, clam_options[opts->idx].strarg)))) {
if (nondef && (opts->numarg == clam_options[opts->idx].numarg) && ((opts->strarg == clam_options[opts->idx].strarg) || (opts->strarg && clam_options[opts->idx].strarg && !strcmp(opts->strarg, clam_options[opts->idx].strarg)))) {
opts = opts->next;
continue;
}
if(!opts->enabled)
if (!opts->enabled)
printf("%s disabled\n", opts->name);
else switch(clam_options[opts->idx].argtype) {
else
switch (clam_options[opts->idx].argtype) {
case CLOPT_TYPE_STRING:
printf("%s = \"%s\"", opts->name, opts->strarg);
opt = opts;
while((opt = opt->nextarg))
while ((opt = opt->nextarg))
printf(", \"%s\"", opt->strarg);
printf("\n");
break;
@ -99,7 +99,7 @@ static void printopts(struct optstruct *opts, int nondef)
case CLOPT_TYPE_SIZE:
printf("%s = \"%lld\"", opts->name, opts->numarg);
opt = opts;
while((opt = opt->nextarg))
while ((opt = opt->nextarg))
printf(", \"%lld\"", opt->numarg);
printf("\n");
break;
@ -122,43 +122,43 @@ static int printconf(const char *name)
const char *tokens[128];
const struct clam_option *cpt;
for(i = 0; cfgfile[i].name; i++) {
if(!strcmp(name, cfgfile[i].name)) {
for (i = 0; cfgfile[i].name; i++) {
if (!strcmp(name, cfgfile[i].name)) {
tool = cfgfile[i].tool;
break;
}
}
if(!tool) {
if (!tool) {
printf("ERROR: Unknown config file\nAvailable options:");
for(i = 0; cfgfile[i].name; i++)
for (i = 0; cfgfile[i].name; i++)
printf(" %s", cfgfile[i].name);
printf("\n");
return 1;
}
printf("##\n## %s - automatically generated by clamconf "VERSION"\n##\n", name);
printf("##\n## %s - automatically generated by clamconf " VERSION "\n##\n", name);
printf("\n# Comment out or remove the line below.\nExample\n");
for(i = 0; clam_options[i].owner; i++) {
for (i = 0; clam_options[i].owner; i++) {
cpt = &clam_options[i];
if(cpt->name && (cpt->owner & tool) && !(cpt->owner & OPT_DEPRECATED) && !(cpt->flags & 4)) {
strncpy(buffer, cpt->description, sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = 0;
if (cpt->name && (cpt->owner & tool) && !(cpt->owner & OPT_DEPRECATED) && !(cpt->flags & 4)) {
strncpy(buffer, cpt->description, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = 0;
tokens_count = cli_strtokenize(buffer, '\n', 128, tokens);
printf("\n");
for(j = 0; j < tokens_count; j++)
for (j = 0; j < tokens_count; j++)
printf("# %s\n", tokens[j]);
switch(cpt->argtype) {
switch (cpt->argtype) {
case CLOPT_TYPE_STRING:
if(cpt->strarg)
if (cpt->strarg)
printf("# Default: %s\n", cpt->strarg);
else
printf("# Default: disabled\n");
break;
case CLOPT_TYPE_NUMBER:
if(cpt->numarg != -1)
if (cpt->numarg != -1)
printf("# Default: %lld\n", cpt->numarg);
else
printf("# Default: disabled\n");
@ -166,14 +166,14 @@ static int printconf(const char *name)
case CLOPT_TYPE_SIZE:
printf("# You may use 'M' or 'm' for megabytes (1M = 1m = 1048576 bytes)\n# and 'K' or 'k' for kilobytes (1K = 1k = 1024 bytes). To specify the size\n# in bytes just don't use modifiers.\n");
if(cpt->numarg != -1)
if (cpt->numarg != -1)
printf("# Default: %lld\n", cpt->numarg);
else
printf("# Default: disabled\n");
break;
case CLOPT_TYPE_BOOL:
if(cpt->numarg != -1)
if (cpt->numarg != -1)
printf("# Default: %s\n", cpt->numarg ? "yes" : "no");
else
printf("# Default: disabled\n");
@ -183,11 +183,11 @@ static int printconf(const char *name)
printf("!!! %s: UNKNOWN INTERNAL TYPE !!!\n", cpt->name);
}
if(cpt->suggested && strchr(cpt->suggested, '\n')) {
strncpy(buffer, cpt->suggested, sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = 0;
if (cpt->suggested && strchr(cpt->suggested, '\n')) {
strncpy(buffer, cpt->suggested, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = 0;
tokens_count = cli_strtokenize(buffer, '\n', 128, tokens);
for(j = 0; j < tokens_count; j++)
for (j = 0; j < tokens_count; j++)
printf("#%s %s\n", cpt->name, tokens[j]);
} else {
printf("#%s %s\n", cpt->name, cpt->suggested ? cpt->suggested : "ARG");
@ -220,7 +220,7 @@ static void print_platform(struct cli_environment *env)
printf("uname: %s %s %s %s\n",
env->sysname, env->release, env->version, env->machine);
printf("OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE"\n");
printf("OS: " TARGET_OS_TYPE ", ARCH: " TARGET_ARCH_TYPE ", CPU: " TARGET_CPU_TYPE "\n");
#ifdef C_LINUX
if (!access("/usr/bin/lsb_release", X_OK)) {
@ -301,8 +301,8 @@ static void print_build(struct cli_environment *env)
version ? version : "",
version ? " " : "",
env->c_version >> 16,
(env->c_version >> 8)&0xff,
(env->c_version)&0xff);
(env->c_version >> 8) & 0xff,
(env->c_version) & 0xff);
cli_printcxxver();
#if defined(BUILD_CPPFLAGS) && defined(BUILD_CFLAGS) && defined(BUILD_CXXFLAGS) && defined(BUILD_LDFLAGS) && defined(BUILD_CONFIGURE_FLAGS)
printf("CPPFLAGS: %s\nCFLAGS: %s\nCXXFLAGS: %s\nLDFLAGS: %s\nConfigure: %s\n",
@ -323,34 +323,34 @@ static void print_dbs(const char *dir)
unsigned int flevel = cl_retflevel(), cnt, sigs = 0;
struct cl_cvd *cvd;
if((dd = opendir(dir)) == NULL) {
if ((dd = opendir(dir)) == NULL) {
printf("print_dbs: Can't open directory %s\n", dir);
return;
}
while((dent = readdir(dd))) {
if(dent->d_ino) {
if(CLI_DBEXT(dent->d_name)) {
dbfile = (char *) malloc(strlen(dent->d_name) + strlen(dir) + 2);
if(!dbfile) {
while ((dent = readdir(dd))) {
if (dent->d_ino) {
if (CLI_DBEXT(dent->d_name)) {
dbfile = (char *)malloc(strlen(dent->d_name) + strlen(dir) + 2);
if (!dbfile) {
printf("print_dbs: Can't allocate memory for dbfile\n");
closedir(dd);
return;
}
sprintf(dbfile, "%s"PATHSEP"%s", dir, dent->d_name);
if(cli_strbcasestr(dbfile, ".cvd") || cli_strbcasestr(dbfile, ".cld")) {
sprintf(dbfile, "%s" PATHSEP "%s", dir, dent->d_name);
if (cli_strbcasestr(dbfile, ".cvd") || cli_strbcasestr(dbfile, ".cld")) {
cvd = cl_cvdhead(dbfile);
if(!cvd) {
if (!cvd) {
printf("%s: Can't get information about the database\n", dbfile);
} else {
const time_t t = cvd->stime;
printf("%s: version %u, sigs: %u, built on %s", dent->d_name, cvd->version, cvd->sigs, ctime(&t));
sigs += cvd->sigs;
if(cvd->fl > flevel)
if (cvd->fl > flevel)
printf("%s: WARNING: This database requires f-level %u (current f-level: %u)\n", dent->d_name, cvd->fl, flevel);
cl_cvdfree(cvd);
}
} else if(cli_strbcasestr(dbfile, ".cbc")) {
} else if (cli_strbcasestr(dbfile, ".cbc")) {
printf("[3rd Party] %s: bytecode\n", dent->d_name);
sigs++;
} else {
@ -376,24 +376,24 @@ int main(int argc, char **argv)
struct cli_environment env;
opts = optparse(NULL, argc, argv, 1, OPT_CLAMCONF, 0, NULL);
if(!opts) {
if (!opts) {
printf("ERROR: Can't parse command line options\n");
return 1;
}
if(optget(opts, "help")->enabled) {
if (optget(opts, "help")->enabled) {
help();
optfree(opts);
return 0;
}
if(optget(opts, "version")->enabled) {
if (optget(opts, "version")->enabled) {
printf("Clam AntiVirus Configuration Tool %s\n", get_version());
optfree(opts);
return 0;
}
if((opt = optget(opts, "generate-config"))->enabled) {
if ((opt = optget(opts, "generate-config"))->enabled) {
printconf(opt->strarg);
optfree(opts);
return 0;
@ -403,26 +403,26 @@ int main(int argc, char **argv)
clamd_dbdir[0] = 0;
dir = optget(opts, "config-dir")->strarg;
printf("Checking configuration files in %s\n", dir);
for(i = 0; cfgfile[i].name; i++) {
snprintf(path, sizeof(path), "%s"PATHSEP"%s", dir, cfgfile[i].name);
for (i = 0; cfgfile[i].name; i++) {
snprintf(path, sizeof(path), "%s" PATHSEP "%s", dir, cfgfile[i].name);
path[511] = 0;
if(access(path, R_OK)) {
if (access(path, R_OK)) {
printf("\n%s not found\n", cfgfile[i].name);
continue;
}
printf("\nConfig file: %s\n", cfgfile[i].name);
for(j = 0; j < strlen(cfgfile[i].name) + 13; j++)
for (j = 0; j < strlen(cfgfile[i].name) + 13; j++)
printf("-");
printf("\n");
toolopts = optparse(path, 0, NULL, 1, cfgfile[i].tool | OPT_DEPRECATED, 0, NULL);
if(!toolopts)
if (!toolopts)
continue;
printopts(toolopts, optget(opts, "non-default")->enabled);
if(cfgfile[i].tool == OPT_FRESHCLAM) {
if (cfgfile[i].tool == OPT_FRESHCLAM) {
opt = optget(toolopts, "DatabaseDirectory");
strncpy(dbdir, opt->strarg, sizeof(dbdir));
dbdir[sizeof(dbdir) - 1] = 0;
} else if(cfgfile[i].tool == OPT_CLAMD) {
} else if (cfgfile[i].tool == OPT_CLAMD) {
opt = optget(toolopts, "DatabaseDirectory");
strncpy(clamd_dbdir, opt->strarg, sizeof(clamd_dbdir));
clamd_dbdir[sizeof(clamd_dbdir) - 1] = 0;
@ -433,7 +433,7 @@ int main(int argc, char **argv)
printf("\nSoftware settings\n-----------------\n");
printf("Version: %s\n", cl_retver());
if(strcmp(cl_retver(), get_version()))
if (strcmp(cl_retver(), get_version()))
printf("WARNING: Version mismatch: libclamav=%s, clamconf=%s\n", cl_retver(), get_version());
cl_init(CL_INIT_DEFAULT);
printf("Optional features supported: ");
@ -476,15 +476,15 @@ int main(int argc, char **argv)
#ifdef HAVE_JSON
printf("JSON ");
#endif
if(have_rar)
if (have_rar)
printf("RAR ");
if (have_clamjit)
printf("JIT");
printf("\n");
if(!strlen(dbdir)) {
if (!strlen(dbdir)) {
pt = freshdbdir();
if(pt) {
if (pt) {
strncpy(dbdir, pt, sizeof(dbdir));
free(pt);
} else {
@ -495,7 +495,7 @@ int main(int argc, char **argv)
printf("\nDatabase information\n--------------------\n");
printf("Database directory: %s\n", dbdir);
if(strcmp(dbdir, clamd_dbdir))
if (strcmp(dbdir, clamd_dbdir))
printf("WARNING: freshclam.conf and clamd.conf point to different database directories\n");
print_dbs(dbdir);

View file

@ -128,7 +128,7 @@ int main(int argc, char **argv)
char *pua_cats = NULL, *pt;
int ret, tcpsock = 0, localsock = 0, min_port, max_port;
unsigned int sigs = 0;
int *lsockets=NULL;
int *lsockets = NULL;
unsigned int nlsockets = 0;
unsigned int dboptions = 0;
unsigned int i;
@ -138,7 +138,7 @@ int main(int argc, char **argv)
STATBUF sb;
#endif
if(check_flevel())
if (check_flevel())
exit(1);
#ifndef _WIN32
@ -148,45 +148,39 @@ int main(int argc, char **argv)
sigaction(SIGUSR2, &sa, NULL);
#endif
if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMD, 0, NULL)) == NULL) {
if ((opts = optparse(NULL, argc, argv, 1, OPT_CLAMD, 0, NULL)) == NULL) {
mprintf("!Can't parse command line options\n");
return 1;
}
if(optget(opts, "help")->enabled) {
if (optget(opts, "help")->enabled) {
help();
optfree(opts);
return 0;
}
if(optget(opts, "debug")->enabled) {
if (optget(opts, "debug")->enabled) {
#if defined(C_LINUX)
/* njh@bandsman.co.uk: create a dump if needed */
rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
if(setrlimit(RLIMIT_CORE, &rlim) < 0)
if (setrlimit(RLIMIT_CORE, &rlim) < 0)
perror("setrlimit");
#endif
debug_mode = 1;
}
/* check foreground option from command line to override config file */
for(j = 0; j < argc; j += 1)
{
if ((memcmp(argv[j], "--foreground", 12) == 0) || (memcmp(argv[j], "-F", 2) == 0))
{
for (j = 0; j < argc; j += 1) {
if ((memcmp(argv[j], "--foreground", 12) == 0) || (memcmp(argv[j], "-F", 2) == 0)) {
/* found */
break;
}
}
if (j < argc)
{
if(optget(opts, "Foreground")->enabled)
{
if (j < argc) {
if (optget(opts, "Foreground")->enabled) {
foreground = 1;
}
else
{
} else {
foreground = 0;
}
}
@ -200,14 +194,14 @@ int main(int argc, char **argv)
fprintf(stderr, "ERROR: Unable to allocate memory for config file\n");
return 1;
}
if((opts = optparse(cfgfile, 0, NULL, 1, OPT_CLAMD, 0, opts)) == NULL) {
if ((opts = optparse(cfgfile, 0, NULL, 1, OPT_CLAMD, 0, opts)) == NULL) {
fprintf(stderr, "ERROR: Can't open/parse the config file %s\n", pt);
free(pt);
return 1;
}
free(pt);
if(optget(opts, "version")->enabled) {
if (optget(opts, "version")->enabled) {
print_version(optget(opts, "DatabaseDirectory")->strarg);
optfree(opts);
return 0;
@ -215,35 +209,35 @@ int main(int argc, char **argv)
/* drop privileges */
#ifndef _WIN32
if(geteuid() == 0 && (opt = optget(opts, "User"))->enabled) {
if((user = getpwnam(opt->strarg)) == NULL) {
if (geteuid() == 0 && (opt = optget(opts, "User"))->enabled) {
if ((user = getpwnam(opt->strarg)) == NULL) {
fprintf(stderr, "ERROR: Can't get information about user %s.\n", opt->strarg);
optfree(opts);
return 1;
}
#ifdef HAVE_INITGROUPS
if(initgroups(opt->strarg, user->pw_gid)) {
if (initgroups(opt->strarg, user->pw_gid)) {
fprintf(stderr, "ERROR: initgroups() failed.\n");
optfree(opts);
return 1;
}
#elif HAVE_SETGROUPS
if(setgroups(1, &user->pw_gid)) {
if (setgroups(1, &user->pw_gid)) {
fprintf(stderr, "ERROR: setgroups() failed.\n");
optfree(opts);
return 1;
}
#endif
if(setgid(user->pw_gid)) {
fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid);
if (setgid(user->pw_gid)) {
fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int)user->pw_gid);
optfree(opts);
return 1;
}
if(setuid(user->pw_uid)) {
fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid);
if (setuid(user->pw_uid)) {
fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int)user->pw_uid);
optfree(opts);
return 1;
}
@ -261,16 +255,16 @@ int main(int argc, char **argv)
mprintf_send_timeout = optget(opts, "SendBufTimeout")->numarg;
do { /* logger initialized */
if((opt = optget(opts, "LogFile"))->enabled) {
if ((opt = optget(opts, "LogFile"))->enabled) {
char timestr[32];
logg_file = opt->strarg;
if(!cli_is_abspath(logg_file)) {
if (!cli_is_abspath(logg_file)) {
fprintf(stderr, "ERROR: LogFile requires full path.\n");
ret = 1;
break;
}
time(&currtime);
if(logg("#+++ Started at %s", cli_ctime(&currtime, timestr, sizeof(timestr)))) {
if (logg("#+++ Started at %s", cli_ctime(&currtime, timestr, sizeof(timestr)))) {
fprintf(stderr, "ERROR: Can't initialize the internal logger\n");
ret = 1;
break;
@ -279,27 +273,27 @@ int main(int argc, char **argv)
logg_file = NULL;
}
if (optget(opts,"DevLiblog")->enabled)
if (optget(opts, "DevLiblog")->enabled)
cl_set_clcb_msg(msg_callback);
if((ret = cl_init(CL_INIT_DEFAULT))) {
if ((ret = cl_init(CL_INIT_DEFAULT))) {
logg("!Can't initialize libclamav: %s\n", cl_strerror(ret));
ret = 1;
break;
}
if(optget(opts, "Debug")->enabled) {
if (optget(opts, "Debug")->enabled) {
/* enable debug messages in libclamav */
cl_debug();
logg_verbose = 2;
}
#if defined(USE_SYSLOG) && !defined(C_AIX)
if(optget(opts, "LogSyslog")->enabled) {
if (optget(opts, "LogSyslog")->enabled) {
int fac = LOG_LOCAL6;
opt = optget(opts, "LogFacility");
if((fac = logg_facility(opt->strarg)) == -1) {
if ((fac = logg_facility(opt->strarg)) == -1) {
logg("!LogFacility: %s: No such facility.\n", opt->strarg);
ret = 1;
break;
@ -312,30 +306,30 @@ int main(int argc, char **argv)
#ifdef C_LINUX
procdev = 0;
if(CLAMSTAT("/proc", &sb) != -1 && !sb.st_size)
if (CLAMSTAT("/proc", &sb) != -1 && !sb.st_size)
procdev = sb.st_dev;
#endif
/* check socket type */
if(optget(opts, "TCPSocket")->enabled)
if (optget(opts, "TCPSocket")->enabled)
tcpsock = 1;
if(optget(opts, "LocalSocket")->enabled)
if (optget(opts, "LocalSocket")->enabled)
localsock = 1;
logg("#Received %d file descriptor(s) from systemd.\n", num_fd);
if(!tcpsock && !localsock && num_fd == 0) {
if (!tcpsock && !localsock && num_fd == 0) {
logg("!Please define server type (local and/or TCP).\n");
ret = 1;
break;
}
logg("#clamd daemon %s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")\n", get_version());
logg("#clamd daemon %s (OS: " TARGET_OS_TYPE ", ARCH: " TARGET_ARCH_TYPE ", CPU: " TARGET_CPU_TYPE ")\n", get_version());
#ifndef _WIN32
if(user)
if (user)
logg("#Running as user %s (UID %u, GID %u)\n", user->pw_name, user->pw_uid, user->pw_gid);
#endif
@ -346,7 +340,7 @@ int main(int argc, char **argv)
* too soon (after ~120 MB).
* Set limit lower than 2G if on 32-bit */
uint64_t lim = rlim.rlim_cur;
if (sizeof(void*) == 4 &&
if (sizeof(void *) == 4 &&
lim > (1ULL << 31)) {
rlim.rlim_cur = 1ULL << 31;
if (setrlimit(RLIMIT_DATA, &rlim) < 0)
@ -357,8 +351,7 @@ int main(int argc, char **argv)
}
#endif
if(logg_size)
if (logg_size)
logg("#Log file size limited to %lld bytes.\n", (long long int)logg_size);
else
logg("#Log file size limit disabled.\n");
@ -372,7 +365,7 @@ int main(int argc, char **argv)
}
/* TODO: Re-enable OnAccessExtraScanning once the thread resource consumption issue is resolved. */
if(optget(opts, "OnAccessExtraScanning")->enabled) {
if (optget(opts, "OnAccessExtraScanning")->enabled) {
logg("*ScanOnAccess: OnAccessExtraScanning was requested, but has "
"been disabled due to a known issue with thread resource "
"cleanup. The OnAccessExtraScanning feature will be "
@ -380,7 +373,7 @@ int main(int argc, char **argv)
"For details, see: https://bugzilla.clamav.net/show_bug.cgi?id=12048\n");
}
if(!(engine = cl_engine_new())) {
if (!(engine = cl_engine_new())) {
logg("!Can't initialize antivirus engine\n");
ret = 1;
break;
@ -393,16 +386,16 @@ int main(int argc, char **argv)
dbdir = optget(opts, "DatabaseDirectory")->strarg;
logg("#Reading databases from %s\n", dbdir);
if(optget(opts, "DetectPUA")->enabled) {
if (optget(opts, "DetectPUA")->enabled) {
dboptions |= CL_DB_PUA;
if((opt = optget(opts, "ExcludePUA"))->enabled) {
if ((opt = optget(opts, "ExcludePUA"))->enabled) {
dboptions |= CL_DB_PUA_EXCLUDE;
i = 0;
logg("#Excluded PUA categories:");
while(opt) {
if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) {
while (opt) {
if (!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) {
logg("!Can't allocate memory for pua_cats\n");
cl_engine_free(engine);
ret = 1;
@ -425,8 +418,8 @@ int main(int argc, char **argv)
pua_cats[i + 1] = 0;
}
if((opt = optget(opts, "IncludePUA"))->enabled) {
if(pua_cats) {
if ((opt = optget(opts, "IncludePUA"))->enabled) {
if (pua_cats) {
logg("!ExcludePUA and IncludePUA cannot be used at the same time\n");
free(pua_cats);
ret = 1;
@ -436,8 +429,8 @@ int main(int argc, char **argv)
dboptions |= CL_DB_PUA_INCLUDE;
i = 0;
logg("#Included PUA categories:");
while(opt) {
if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) {
while (opt) {
if (!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) {
logg("!Can't allocate memory for pua_cats\n");
ret = 1;
break;
@ -459,8 +452,8 @@ int main(int argc, char **argv)
pua_cats[i + 1] = 0;
}
if(pua_cats) {
if((ret = cl_engine_set_str(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))) {
if (pua_cats) {
if ((ret = cl_engine_set_str(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))) {
logg("!cli_engine_set_str(CL_ENGINE_PUA_CATEGORIES) failed: %s\n", cl_strerror(ret));
free(pua_cats);
ret = 1;
@ -472,14 +465,14 @@ int main(int argc, char **argv)
logg("#Not loading PUA signatures.\n");
}
if(optget(opts, "OfficialDatabaseOnly")->enabled) {
if (optget(opts, "OfficialDatabaseOnly")->enabled) {
dboptions |= CL_DB_OFFICIAL_ONLY;
logg("#Only loading official signatures.\n");
}
/* set the temporary dir */
if((opt = optget(opts, "TemporaryDirectory"))->enabled) {
if((ret = cl_engine_set_str(engine, CL_ENGINE_TMPDIR, opt->strarg))) {
if ((opt = optget(opts, "TemporaryDirectory"))->enabled) {
if ((ret = cl_engine_set_str(engine, CL_ENGINE_TMPDIR, opt->strarg))) {
logg("!cli_engine_set_str(CL_ENGINE_TMPDIR) failed: %s\n", cl_strerror(ret));
ret = 1;
break;
@ -490,20 +483,20 @@ int main(int argc, char **argv)
cl_engine_set_clcb_virus_found(engine, clamd_virus_found_cb);
if(optget(opts, "LeaveTemporaryFiles")->enabled)
if (optget(opts, "LeaveTemporaryFiles")->enabled)
cl_engine_set_num(engine, CL_ENGINE_KEEPTMP, 1);
if(optget(opts, "ForceToDisk")->enabled)
if (optget(opts, "ForceToDisk")->enabled)
cl_engine_set_num(engine, CL_ENGINE_FORCETODISK, 1);
if(optget(opts, "PhishingSignatures")->enabled)
if (optget(opts, "PhishingSignatures")->enabled)
dboptions |= CL_DB_PHISHING;
else
logg("#Not loading phishing signatures.\n");
if(optget(opts,"Bytecode")->enabled) {
if (optget(opts, "Bytecode")->enabled) {
dboptions |= CL_DB_BYTECODE;
if((opt = optget(opts,"BytecodeSecurity"))->enabled) {
if ((opt = optget(opts, "BytecodeSecurity"))->enabled) {
enum bytecode_security s;
if (!strcmp(opt->strarg, "TrustSigned")) {
@ -525,54 +518,54 @@ int main(int argc, char **argv)
break;
}
}
if((opt = optget(opts,"BytecodeUnsigned"))->enabled) {
if ((opt = optget(opts, "BytecodeUnsigned"))->enabled) {
dboptions |= CL_DB_BYTECODE_UNSIGNED;
logg("#Bytecode: Enabled support for unsigned bytecode.\n");
}
if((opt = optget(opts,"BytecodeMode"))->enabled) {
if ((opt = optget(opts, "BytecodeMode"))->enabled) {
enum bytecode_mode mode;
if (!strcmp(opt->strarg, "ForceJIT"))
mode = CL_BYTECODE_MODE_JIT;
else if(!strcmp(opt->strarg, "ForceInterpreter"))
else if (!strcmp(opt->strarg, "ForceInterpreter"))
mode = CL_BYTECODE_MODE_INTERPRETER;
else if(!strcmp(opt->strarg, "Test"))
else if (!strcmp(opt->strarg, "Test"))
mode = CL_BYTECODE_MODE_TEST;
else
mode = CL_BYTECODE_MODE_AUTO;
cl_engine_set_num(engine, CL_ENGINE_BYTECODE_MODE, mode);
}
if((opt = optget(opts,"BytecodeTimeout"))->enabled) {
if ((opt = optget(opts, "BytecodeTimeout"))->enabled) {
cl_engine_set_num(engine, CL_ENGINE_BYTECODE_TIMEOUT, opt->numarg);
}
} else {
logg("#Bytecode support disabled.\n");
}
if(optget(opts,"PhishingScanURLs")->enabled)
if (optget(opts, "PhishingScanURLs")->enabled)
dboptions |= CL_DB_PHISHING_URLS;
else
logg("#Disabling URL based phishing detection.\n");
if(optget(opts,"DevACOnly")->enabled) {
if (optget(opts, "DevACOnly")->enabled) {
logg("#Only using the A-C matcher.\n");
cl_engine_set_num(engine, CL_ENGINE_AC_ONLY, 1);
}
if((opt = optget(opts, "DevACDepth"))->enabled) {
if ((opt = optget(opts, "DevACDepth"))->enabled) {
cl_engine_set_num(engine, CL_ENGINE_AC_MAXDEPTH, opt->numarg);
logg("#Max A-C depth set to %u\n", (unsigned int) opt->numarg);
logg("#Max A-C depth set to %u\n", (unsigned int)opt->numarg);
}
if((ret = cl_load(dbdir, engine, &sigs, dboptions))) {
if ((ret = cl_load(dbdir, engine, &sigs, dboptions))) {
logg("!%s\n", cl_strerror(ret));
ret = 1;
break;
}
if((ret = statinidir_th(dbdir))) {
if ((ret = statinidir_th(dbdir))) {
logg("!%s\n", cl_strerror(ret));
ret = 1;
break;
@ -584,29 +577,29 @@ int main(int argc, char **argv)
logg("#Loaded %u signatures.\n", sigs);
/* pcre engine limits - required for cl_engine_compile */
if((opt = optget(opts, "PCREMatchLimit"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_PCRE_MATCH_LIMIT, opt->numarg))) {
if ((opt = optget(opts, "PCREMatchLimit"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_PCRE_MATCH_LIMIT, opt->numarg))) {
logg("!cli_engine_set_num(PCREMatchLimit) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
}
}
if((opt = optget(opts, "PCRERecMatchLimit"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_PCRE_RECMATCH_LIMIT, opt->numarg))) {
if ((opt = optget(opts, "PCRERecMatchLimit"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_PCRE_RECMATCH_LIMIT, opt->numarg))) {
logg("!cli_engine_set_num(PCRERecMatchLimit) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
}
}
if((ret = cl_engine_compile(engine)) != 0) {
if ((ret = cl_engine_compile(engine)) != 0) {
logg("!Database initialization error: %s\n", cl_strerror(ret));
ret = 1;
break;
}
if(tcpsock || num_fd > 0) {
if (tcpsock || num_fd > 0) {
int *t;
opt = optget(opts, "TCPAddr");
@ -635,7 +628,7 @@ int main(int argc, char **argv)
}
}
#ifndef _WIN32
if(localsock && num_fd == 0) {
if (localsock && num_fd == 0) {
int *t;
mode_t sock_mode, umsk = umask(0777); /* socket is created with 000 to avoid races */
@ -653,14 +646,14 @@ int main(int argc, char **argv)
}
umask(umsk); /* restore umask */
if(optget(opts, "LocalSocketGroup")->enabled) {
if (optget(opts, "LocalSocketGroup")->enabled) {
char *gname = optget(opts, "LocalSocketGroup")->strarg, *end;
gid_t sock_gid = strtol(gname, &end, 10);
if(*end) {
if (*end) {
struct group *pgrp = getgrnam(gname);
if(!pgrp) {
if (!pgrp) {
logg("!Unknown group %s\n", gname);
ret = 1;
break;
@ -668,18 +661,18 @@ int main(int argc, char **argv)
sock_gid = pgrp->gr_gid;
}
if(chown(optget(opts, "LocalSocket")->strarg, -1, sock_gid)) {
if (chown(optget(opts, "LocalSocket")->strarg, -1, sock_gid)) {
logg("!Failed to change socket ownership to group %s\n", gname);
ret = 1;
break;
}
}
if(optget(opts, "LocalSocketMode")->enabled) {
if (optget(opts, "LocalSocketMode")->enabled) {
char *end;
sock_mode = strtol(optget(opts, "LocalSocketMode")->strarg, &end, 8);
if(*end) {
if (*end) {
logg("!Invalid LocalSocketMode %s\n", optget(opts, "LocalSocketMode")->strarg);
ret = 1;
break;
@ -688,7 +681,7 @@ int main(int argc, char **argv)
sock_mode = 0777 /* & ~umsk*/; /* conservative default: umask was 0 in clamd < 0.96 */
}
if(chmod(optget(opts, "LocalSocket")->strarg, sock_mode & 0666)) {
if (chmod(optget(opts, "LocalSocket")->strarg, sock_mode & 0666)) {
logg("!Cannot set socket permission to %s\n", optget(opts, "LocalSocketMode")->strarg);
ret = 1;
break;
@ -698,8 +691,7 @@ int main(int argc, char **argv)
}
/* check for local sockets passed by systemd */
if (num_fd > 0)
{
if (num_fd > 0) {
int *t;
t = realloc(lsockets, sizeof(int) * (nlsockets + 1));
if (!(t)) {
@ -709,34 +701,26 @@ int main(int argc, char **argv)
lsockets = t;
lsockets[nlsockets] = localserver(opts);
if (lsockets[nlsockets] == -1)
{
if (lsockets[nlsockets] == -1) {
ret = 1;
break;
}
else if (lsockets[nlsockets] > 0)
{
} else if (lsockets[nlsockets] > 0) {
nlsockets++;
}
}
/* fork into background */
if (foreground == -1)
{
if (optget(opts, "Foreground")->enabled)
{
if (foreground == -1) {
if (optget(opts, "Foreground")->enabled) {
foreground = 1;
}
else
{
} else {
foreground = 0;
}
}
if(foreground == 0)
{
if (foreground == 0) {
#ifdef C_BSD
/* workaround for OpenBSD bug, see https://wwws.clamav.net/bugzilla/show_bug.cgi?id=885 */
for(ret=0;(unsigned int)ret<nlsockets;ret++) {
for (ret = 0; (unsigned int)ret < nlsockets; ret++) {
if (fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) | O_NONBLOCK) == -1) {
logg("!fcntl for lsockets[] failed\n");
close(lsockets[ret]);
@ -747,14 +731,14 @@ int main(int argc, char **argv)
#endif
gengine = engine;
atexit(free_engine);
if(daemonize() == -1) {
if (daemonize() == -1) {
logg("!daemonize() failed: %s\n", strerror(errno));
ret = 1;
break;
}
gengine = NULL;
#ifdef C_BSD
for(ret=0;(unsigned int)ret<nlsockets;ret++) {
for (ret = 0; (unsigned int)ret < nlsockets; ret++) {
if (fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) & ~O_NONBLOCK) == -1) {
logg("!fcntl for lsockets[] failed\n");
close(lsockets[ret]);
@ -763,10 +747,9 @@ int main(int argc, char **argv)
}
}
#endif
if(!debug_mode)
if(chdir("/") == -1)
if (!debug_mode)
if (chdir("/") == -1)
logg("^Can't change current working directory to root\n");
}
#endif
@ -780,18 +763,17 @@ int main(int argc, char **argv)
} while (0);
if (num_fd == 0)
{
if (num_fd == 0) {
logg("*Closing the main socket%s.\n", (nlsockets > 1) ? "s" : "");
for (i = 0; i < nlsockets; i++) {
closesocket(lsockets[i]);
}
#ifndef _WIN32
if(nlsockets && localsock) {
if (nlsockets && localsock) {
opt = optget(opts, "LocalSocket");
if(unlink(opt->strarg) == -1)
if (unlink(opt->strarg) == -1)
logg("!Can't unlink the socket file %s\n", opt->strarg);
else
logg("Socket file removed.\n");
@ -816,8 +798,8 @@ int is_valid_hostid(void)
if (strlen(hostid) != 36)
return 0;
count=0;
for (i=0; i < 36; i++)
count = 0;
for (i = 0; i < 36; i++)
if (hostid[i] == '-')
count++;

View file

@ -68,31 +68,23 @@ int localserver(const struct optstruct *opts)
int cnt;
int num_fd = sd_listen_fds(0);
if (num_fd > 2)
{
if (num_fd > 2) {
logg("!LOCAL: Received more than two file descriptors from systemd.\n");
return -1;
}
else if (num_fd > 0)
{
} else if (num_fd > 0) {
/* use socket passed by systemd */
int i;
for(i = 0; i < num_fd; i += 1)
{
for (i = 0; i < num_fd; i += 1) {
sockfd = SD_LISTEN_FDS_START + i;
if (sd_is_socket(sockfd, AF_UNIX, SOCK_STREAM, 1) == 1)
{
if (sd_is_socket(sockfd, AF_UNIX, SOCK_STREAM, 1) == 1) {
/* correct socket */
break;
}
else
{
} else {
/* wrong socket */
sockfd = -2;
}
}
if (sockfd == -2)
{
if (sockfd == -2) {
logg("#LOCAL: No local AF_UNIX SOCK_STREAM socket received from systemd.\n");
return -2;
}
@ -100,13 +92,13 @@ int localserver(const struct optstruct *opts)
return sockfd;
}
/* create socket */
memset((char *) &server, 0, sizeof(server));
memset((char *)&server, 0, sizeof(server));
server.sun_family = AF_UNIX;
strncpy(server.sun_path, optget(opts, "LocalSocket")->strarg, sizeof(server.sun_path));
server.sun_path[sizeof(server.sun_path)-1]='\0';
server.sun_path[sizeof(server.sun_path) - 1] = '\0';
pos = NULL;
if ((pos = strstr(server.sun_path, "/")) && (pos = strstr(((char*) pos + 1), "/"))) {
if ((pos = strstr(server.sun_path, "/")) && (pos = strstr(((char *)pos + 1), "/"))) {
cnt = 0;
sockdir = NULL;
pos = server.sun_path + strlen(server.sun_path);
@ -114,8 +106,7 @@ int localserver(const struct optstruct *opts)
if (*pos == '/') {
sockdir = cli_strndup(server.sun_path, strlen(server.sun_path) - cnt);
break;
}
else {
} else {
pos--;
cnt++;
}
@ -124,11 +115,11 @@ int localserver(const struct optstruct *opts)
if (stat(sockdir, &sb)) {
if (errno == ENOENT) {
mode_t sock_mode;
if(optget(opts, "LocalSocketMode")->enabled) {
if (optget(opts, "LocalSocketMode")->enabled) {
char *end;
sock_mode = strtol(optget(opts, "LocalSocketMode")->strarg, &end, 8);
if(*end) {
if (*end) {
logg("!Invalid LocalSocketMode %s\n", optget(opts, "LocalSocketMode")->strarg);
free(sockdir);
return -1;
@ -142,8 +133,7 @@ int localserver(const struct optstruct *opts)
if (errno == ENOENT) {
logg("!LOCAL: Ensure parent directory exists.\n");
}
}
else {
} else {
logg("Localserver: Creating socket directory: %s\n", sockdir);
}
}
@ -151,34 +141,34 @@ int localserver(const struct optstruct *opts)
free(sockdir);
}
if((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
estr = strerror(errno);
logg("!LOCAL: Socket allocation error: %s\n", estr);
return -1;
}
if(bind(sockfd, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) == -1) {
if(errno == EADDRINUSE) {
if(connect(sockfd, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) >= 0) {
if (bind(sockfd, (struct sockaddr *)&server, sizeof(struct sockaddr_un)) == -1) {
if (errno == EADDRINUSE) {
if (connect(sockfd, (struct sockaddr *)&server, sizeof(struct sockaddr_un)) >= 0) {
logg("!LOCAL: Socket file %s is in use by another process.\n", server.sun_path);
close(sockfd);
return -1;
}
if(optget(opts, "FixStaleSocket")->enabled) {
if (optget(opts, "FixStaleSocket")->enabled) {
logg("#LOCAL: Removing stale socket file %s\n", server.sun_path);
if(unlink(server.sun_path) == -1) {
if (unlink(server.sun_path) == -1) {
estr = strerror(errno);
logg("!LOCAL: Socket file %s could not be removed: %s\n", server.sun_path, estr);
close(sockfd);
return -1;
}
if(bind(sockfd, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) == -1) {
if (bind(sockfd, (struct sockaddr *)&server, sizeof(struct sockaddr_un)) == -1) {
estr = strerror(errno);
logg("!LOCAL: Socket file %s could not be bound: %s (unlink tried)\n", server.sun_path, estr);
close(sockfd);
return -1;
}
} else if(CLAMSTAT(server.sun_path, &foo) != -1) {
} else if (CLAMSTAT(server.sun_path, &foo) != -1) {
logg("!LOCAL: Socket file %s exists. Either remove it, or configure a different one.\n", server.sun_path);
close(sockfd);
return -1;
@ -196,7 +186,7 @@ int localserver(const struct optstruct *opts)
backlog = optget(opts, "MaxConnectionQueueLength")->numarg;
logg("#LOCAL: Setting connection queue length to %d\n", backlog);
if(listen(sockfd, backlog) == -1) {
if (listen(sockfd, backlog) == -1) {
estr = strerror(errno);
logg("!LOCAL: listen() error: %s\n", estr);
close(sockfd);

View file

@ -60,9 +60,9 @@ static int onas_ddd_init_wdlt(uint64_t nwatches);
static int onas_ddd_grow_wdlt();
static int onas_ddd_watch(const char *pathname, int fan_fd, uint64_t fan_mask, int in_fd, uint64_t in_mask);
static int onas_ddd_watch_hierarchy(const char* pathname, size_t len, int fd, uint64_t mask, uint32_t type);
static int onas_ddd_watch_hierarchy(const char *pathname, size_t len, int fd, uint64_t mask, uint32_t type);
static int onas_ddd_unwatch(const char *pathname, int fan_fd, int in_fd);
static int onas_ddd_unwatch_hierarchy(const char* pathname, size_t len, int fd, uint32_t type);
static int onas_ddd_unwatch_hierarchy(const char *pathname, size_t len, int fd, uint32_t type);
static void onas_ddd_handle_in_moved_to(struct ddd_thrarg *tharg, const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask);
static void onas_ddd_handle_in_create(struct ddd_thrarg *tharg, const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask);
@ -78,7 +78,8 @@ static char **wdlt;
static uint32_t wdlt_len;
static int onas_in_fd;
static int onas_ddd_init_ht(uint32_t ht_size) {
static int onas_ddd_init_ht(uint32_t ht_size)
{
if (ht_size <= 0)
ht_size = ONAS_DEFAULT_HT_SIZE;
@ -86,11 +87,12 @@ static int onas_ddd_init_ht(uint32_t ht_size) {
return onas_ht_init(&ddd_ht, ht_size);
}
static int onas_ddd_init_wdlt(uint64_t nwatches) {
static int onas_ddd_init_wdlt(uint64_t nwatches)
{
if (nwatches <= 0) return CL_EARG;
wdlt = (char **) cli_calloc(nwatches << 1, sizeof(char*));
wdlt = (char **)cli_calloc(nwatches << 1, sizeof(char *));
if (!wdlt) return CL_EMEM;
wdlt_len = nwatches << 1;
@ -98,11 +100,12 @@ static int onas_ddd_init_wdlt(uint64_t nwatches) {
return CL_SUCCESS;
}
static int onas_ddd_grow_wdlt() {
static int onas_ddd_grow_wdlt()
{
char **ptr = NULL;
ptr = (char **) cli_realloc(wdlt, wdlt_len << 1);
ptr = (char **)cli_realloc(wdlt, wdlt_len << 1);
if (ptr) {
wdlt = ptr;
memset(&ptr[wdlt_len], 0, sizeof(char *) * (wdlt_len - 1));
@ -115,11 +118,11 @@ static int onas_ddd_grow_wdlt() {
return CL_SUCCESS;
}
/* TODO: Support configuration for changing/setting number of inotify watches. */
int onas_ddd_init(uint64_t nwatches, size_t ht_size) {
int onas_ddd_init(uint64_t nwatches, size_t ht_size)
{
const char* nwatch_file = "/proc/sys/fs/inotify/max_user_watches";
const char *nwatch_file = "/proc/sys/fs/inotify/max_user_watches";
int nwfd = 0;
int ret = 0;
char nwatch_str[MAX_WATCH_LEN];
@ -144,7 +147,8 @@ int onas_ddd_init(uint64_t nwatches, size_t ht_size) {
return CL_SUCCESS;
}
static int onas_ddd_watch(const char *pathname, int fan_fd, uint64_t fan_mask, int in_fd, uint64_t in_mask) {
static int onas_ddd_watch(const char *pathname, int fan_fd, uint64_t fan_mask, int in_fd, uint64_t in_mask)
{
if (!pathname || fan_fd <= 0 || in_fd <= 0) return CL_ENULLARG;
int ret = CL_SUCCESS;
@ -159,7 +163,8 @@ static int onas_ddd_watch(const char *pathname, int fan_fd, uint64_t fan_mask, i
return CL_SUCCESS;
}
static int onas_ddd_watch_hierarchy(const char* pathname, size_t len, int fd, uint64_t mask, uint32_t type) {
static int onas_ddd_watch_hierarchy(const char *pathname, size_t len, int fd, uint64_t mask, uint32_t type)
{
if (!pathname || fd <= 0 || !type) return CL_ENULLARG;
@ -169,16 +174,16 @@ static int onas_ddd_watch_hierarchy(const char* pathname, size_t len, int fd, ui
struct onas_element *elem = NULL;
int wd = 0;
if(onas_ht_get(ddd_ht, pathname, len, &elem) != CL_SUCCESS) return CL_EARG;
if (onas_ht_get(ddd_ht, pathname, len, &elem) != CL_SUCCESS) return CL_EARG;
hnode = elem->data;
if (type & ONAS_IN) {
wd = inotify_add_watch(fd, pathname, (uint32_t) mask);
wd = inotify_add_watch(fd, pathname, (uint32_t)mask);
if (wd < 0) return CL_EARG;
if ((uint32_t) wd >= wdlt_len) {
if ((uint32_t)wd >= wdlt_len) {
onas_ddd_grow_wdlt();
}
@ -188,7 +193,7 @@ static int onas_ddd_watch_hierarchy(const char* pathname, size_t len, int fd, ui
hnode->watched |= ONAS_INWATCH;
} else if (type & ONAS_FAN) {
if(fanotify_mark(fd, FAN_MARK_ADD, mask, AT_FDCWD, hnode->pathname) < 0) return CL_EARG;
if (fanotify_mark(fd, FAN_MARK_ADD, mask, AT_FDCWD, hnode->pathname) < 0) return CL_EARG;
hnode->watched |= ONAS_FANWATCH;
} else {
return CL_EARG;
@ -200,15 +205,15 @@ static int onas_ddd_watch_hierarchy(const char* pathname, size_t len, int fd, ui
curr = curr->next;
size_t size = len + strlen(curr->dirname) + 2;
char *child_path = (char *) cli_malloc(size);
char *child_path = (char *)cli_malloc(size);
if (child_path == NULL)
return CL_EMEM;
if (hnode->pathname[len-1] == '/')
if (hnode->pathname[len - 1] == '/')
snprintf(child_path, --size, "%s%s", hnode->pathname, curr->dirname);
else
snprintf(child_path, size, "%s/%s", hnode->pathname, curr->dirname);
if(onas_ddd_watch_hierarchy(child_path, strlen(child_path), fd, mask, type)) {
if (onas_ddd_watch_hierarchy(child_path, strlen(child_path), fd, mask, type)) {
return CL_EARG;
}
free(child_path);
@ -217,7 +222,8 @@ static int onas_ddd_watch_hierarchy(const char* pathname, size_t len, int fd, ui
return CL_SUCCESS;
}
static int onas_ddd_unwatch(const char *pathname, int fan_fd, int in_fd) {
static int onas_ddd_unwatch(const char *pathname, int fan_fd, int in_fd)
{
if (!pathname || fan_fd <= 0 || in_fd <= 0) return CL_ENULLARG;
int ret = CL_SUCCESS;
@ -226,13 +232,14 @@ static int onas_ddd_unwatch(const char *pathname, int fan_fd, int in_fd) {
ret = onas_ddd_unwatch_hierarchy(pathname, len, in_fd, ONAS_IN);
if (ret) return ret;
ret = onas_ddd_unwatch_hierarchy(pathname, len,fan_fd, ONAS_FAN);
ret = onas_ddd_unwatch_hierarchy(pathname, len, fan_fd, ONAS_FAN);
if (ret) return ret;
return CL_SUCCESS;
}
static int onas_ddd_unwatch_hierarchy(const char* pathname, size_t len, int fd, uint32_t type) {
static int onas_ddd_unwatch_hierarchy(const char *pathname, size_t len, int fd, uint32_t type)
{
if (!pathname || fd <= 0 || !type) return CL_ENULLARG;
@ -242,14 +249,14 @@ static int onas_ddd_unwatch_hierarchy(const char* pathname, size_t len, int fd,
struct onas_element *elem = NULL;
int wd = 0;
if(onas_ht_get(ddd_ht, pathname, len, &elem)) return CL_EARG;
if (onas_ht_get(ddd_ht, pathname, len, &elem)) return CL_EARG;
hnode = elem->data;
if (type & ONAS_IN) {
wd = hnode->wd;
if(!inotify_rm_watch(fd, wd)) return CL_EARG;
if (!inotify_rm_watch(fd, wd)) return CL_EARG;
/* Unlink the hash node from the watch descriptor lookup table */
hnode->wd = 0;
@ -257,7 +264,7 @@ static int onas_ddd_unwatch_hierarchy(const char* pathname, size_t len, int fd,
hnode->watched = ONAS_STOPWATCH;
} else if (type & ONAS_FAN) {
if(fanotify_mark(fd, FAN_MARK_REMOVE, 0, AT_FDCWD, hnode->pathname) < 0) return CL_EARG;
if (fanotify_mark(fd, FAN_MARK_REMOVE, 0, AT_FDCWD, hnode->pathname) < 0) return CL_EARG;
hnode->watched = ONAS_STOPWATCH;
} else {
return CL_EARG;
@ -269,10 +276,10 @@ static int onas_ddd_unwatch_hierarchy(const char* pathname, size_t len, int fd,
curr = curr->next;
size_t size = len + strlen(curr->dirname) + 2;
char *child_path = (char *) cli_malloc(size);
char *child_path = (char *)cli_malloc(size);
if (child_path == NULL)
return CL_EMEM;
if (hnode->pathname[len-1] == '/')
if (hnode->pathname[len - 1] == '/')
snprintf(child_path, --size, "%s%s", hnode->pathname, curr->dirname);
else
snprintf(child_path, size, "%s/%s", hnode->pathname, curr->dirname);
@ -284,8 +291,9 @@ static int onas_ddd_unwatch_hierarchy(const char* pathname, size_t len, int fd,
return CL_SUCCESS;
}
void *onas_ddd_th(void *arg) {
struct ddd_thrarg *tharg = (struct ddd_thrarg *) arg;
void *onas_ddd_th(void *arg)
{
struct ddd_thrarg *tharg = (struct ddd_thrarg *)arg;
sigset_t sigset;
struct sigaction act;
const struct optstruct *pt;
@ -327,23 +335,23 @@ void *onas_ddd_th(void *arg) {
}
/* Add provided paths recursively. */
if((pt = optget(tharg->opts, "OnAccessIncludePath"))->enabled) {
while(pt) {
if ((pt = optget(tharg->opts, "OnAccessIncludePath"))->enabled) {
while (pt) {
if (!strcmp(pt->strarg, "/")) {
logg("!ScanOnAccess: Not including path '%s' while DDD is enabled\n", pt->strarg);
logg("!ScanOnAccess: Please use the OnAccessMountPath option to watch '%s'\n", pt->strarg);
pt = (struct optstruct *) pt->nextarg;
pt = (struct optstruct *)pt->nextarg;
continue;
}
if(onas_ht_get(ddd_ht, pt->strarg, strlen(pt->strarg), NULL) != CL_SUCCESS) {
if(onas_ht_add_hierarchy(ddd_ht, pt->strarg)) {
if (onas_ht_get(ddd_ht, pt->strarg, strlen(pt->strarg), NULL) != CL_SUCCESS) {
if (onas_ht_add_hierarchy(ddd_ht, pt->strarg)) {
logg("!ScanOnAccess: Can't include path '%s'\n", pt->strarg);
return NULL;
} else
logg("ScanOnAccess: Protecting directory '%s' (and all sub-directories)\n", pt->strarg);
}
pt = (struct optstruct *) pt->nextarg;
pt = (struct optstruct *)pt->nextarg;
}
} else {
logg("!ScanOnAccess: Please specify at least one path with OnAccessIncludePath\n");
@ -351,29 +359,29 @@ void *onas_ddd_th(void *arg) {
}
/* Remove provided paths recursively. */
if((pt = optget(tharg->opts, "OnAccessExcludePath"))->enabled) {
while(pt) {
if ((pt = optget(tharg->opts, "OnAccessExcludePath"))->enabled) {
while (pt) {
size_t ptlen = strlen(pt->strarg);
if(onas_ht_get(ddd_ht, pt->strarg, ptlen, NULL) == CL_SUCCESS) {
if(onas_ht_rm_hierarchy(ddd_ht, pt->strarg, ptlen, 0)) {
if (onas_ht_get(ddd_ht, pt->strarg, ptlen, NULL) == CL_SUCCESS) {
if (onas_ht_rm_hierarchy(ddd_ht, pt->strarg, ptlen, 0)) {
logg("!ScanOnAccess: Can't exclude path '%s'\n", pt->strarg);
return NULL;
} else
logg("ScanOnAccess: Excluding directory '%s' (and all sub-directories)\n", pt->strarg);
}
pt = (struct optstruct *) pt->nextarg;
pt = (struct optstruct *)pt->nextarg;
}
}
/* Watch provided paths recursively */
if((pt = optget(tharg->opts, "OnAccessIncludePath"))->enabled) {
while(pt) {
if ((pt = optget(tharg->opts, "OnAccessIncludePath"))->enabled) {
while (pt) {
size_t ptlen = strlen(pt->strarg);
if(onas_ht_get(ddd_ht, pt->strarg, ptlen, NULL) == CL_SUCCESS) {
if(onas_ddd_watch(pt->strarg, tharg->fan_fd, tharg->fan_mask, onas_in_fd, in_mask)) {
if (onas_ht_get(ddd_ht, pt->strarg, ptlen, NULL) == CL_SUCCESS) {
if (onas_ddd_watch(pt->strarg, tharg->fan_fd, tharg->fan_mask, onas_in_fd, in_mask)) {
logg("!ScanOnAccess: Could not watch path '%s', %s\n", pt->strarg, strerror(errno));
if(errno == EINVAL && optget(tharg->opts, "OnAccessPrevention")->enabled) {
if (errno == EINVAL && optget(tharg->opts, "OnAccessPrevention")->enabled) {
logg("!ScanOnAccess: When using the OnAccessPrevention option, please ensure your kernel\n\t\t\twas compiled with CONFIG_FANOTIFY_ACCESS_PERMISSIONS set to Y\n");
kill(getpid(), SIGTERM);
@ -381,7 +389,7 @@ void *onas_ddd_th(void *arg) {
return NULL;
}
}
pt = (struct optstruct *) pt->nextarg;
pt = (struct optstruct *)pt->nextarg;
}
}
@ -390,8 +398,7 @@ void *onas_ddd_th(void *arg) {
if(optget(tharg->opts, "OnAccessExtraScanning")->enabled) {
logg("ScanOnAccess: Extra scanning and notifications enabled.\n");
}
#endif
#endif
FD_ZERO(&rfds);
FD_SET(onas_in_fd, &rfds);
@ -399,29 +406,29 @@ void *onas_ddd_th(void *arg) {
while (1) {
do {
ret = select(onas_in_fd + 1, &rfds, NULL, NULL, NULL);
} while(ret == -1 && errno == EINTR);
} while (ret == -1 && errno == EINTR);
while((bread = read(onas_in_fd, buf, sizeof(buf))) > 0) {
while ((bread = read(onas_in_fd, buf, sizeof(buf))) > 0) {
/* Handle events. */
int wd;
char *p = buf;
const char *path = NULL;
const char *child = NULL;
for(; p < buf + bread; p += sizeof(struct inotify_event) + event->len) {
for (; p < buf + bread; p += sizeof(struct inotify_event) + event->len) {
event = (const struct inotify_event *) p;
event = (const struct inotify_event *)p;
wd = event->wd;
path = wdlt[wd];
child = event->name;
len = strlen(path);
size_t size = strlen(child) + len + 2;
char *child_path = (char *) cli_malloc(size);
char *child_path = (char *)cli_malloc(size);
if (child_path == NULL)
return NULL;
if (path[len-1] == '/')
if (path[len - 1] == '/')
snprintf(child_path, --size, "%s%s", path, child);
else
snprintf(child_path, size, "%s/%s", path, child);
@ -446,11 +453,12 @@ void *onas_ddd_th(void *arg) {
}
static void onas_ddd_handle_in_delete(struct ddd_thrarg *tharg,
const char *path, const char *child_path, const struct inotify_event *event, int wd) {
const char *path, const char *child_path, const struct inotify_event *event, int wd)
{
struct stat s;
if(stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return;
if(!(event->mask & IN_ISDIR)) return;
if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return;
if (!(event->mask & IN_ISDIR)) return;
logg("*ddd: DELETE - Removing %s from %s with wd:%d\n", child_path, path, wd);
onas_ddd_unwatch(child_path, tharg->fan_fd, onas_in_fd);
@ -459,13 +467,13 @@ static void onas_ddd_handle_in_delete(struct ddd_thrarg *tharg,
return;
}
static void onas_ddd_handle_in_moved_from(struct ddd_thrarg *tharg,
const char *path, const char *child_path, const struct inotify_event *event, int wd) {
const char *path, const char *child_path, const struct inotify_event *event, int wd)
{
struct stat s;
if(stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return;
if(!(event->mask & IN_ISDIR)) return;
if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return;
if (!(event->mask & IN_ISDIR)) return;
logg("*ddd: MOVED_FROM - Removing %s from %s with wd:%d\n", child_path, path, wd);
onas_ddd_unwatch(child_path, tharg->fan_fd, onas_in_fd);
@ -474,9 +482,9 @@ static void onas_ddd_handle_in_moved_from(struct ddd_thrarg *tharg,
return;
}
static void onas_ddd_handle_in_create(struct ddd_thrarg *tharg,
const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask) {
const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask)
{
struct stat s;
@ -497,8 +505,8 @@ static void onas_ddd_handle_in_create(struct ddd_thrarg *tharg,
else
#endif
{
if(stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return;
if(!(event->mask & IN_ISDIR)) return;
if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return;
if (!(event->mask & IN_ISDIR)) return;
logg("*ddd: MOVED_TO - Adding %s to %s with wd:%d\n", child_path, path, wd);
onas_ht_add_hierarchy(ddd_ht, child_path);
@ -509,7 +517,8 @@ static void onas_ddd_handle_in_create(struct ddd_thrarg *tharg,
}
static void onas_ddd_handle_in_moved_to(struct ddd_thrarg *tharg,
const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask) {
const char *path, const char *child_path, const struct inotify_event *event, int wd, uint64_t in_mask)
{
struct stat s;
/* TODO: Re-enable OnAccessExtraScanning once the thread resource consumption issue is resolved. */
@ -529,8 +538,8 @@ static void onas_ddd_handle_in_moved_to(struct ddd_thrarg *tharg,
else
#endif
{
if(stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return;
if(!(event->mask & IN_ISDIR)) return;
if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return;
if (!(event->mask & IN_ISDIR)) return;
logg("*ddd: MOVED_TO - Adding %s to %s with wd:%d\n", child_path, path, wd);
onas_ht_add_hierarchy(ddd_ht, child_path);
@ -540,7 +549,8 @@ static void onas_ddd_handle_in_moved_to(struct ddd_thrarg *tharg,
return;
}
static void onas_ddd_handle_extra_scanning(struct ddd_thrarg *tharg, const char *pathname, int extra_options) {
static void onas_ddd_handle_extra_scanning(struct ddd_thrarg *tharg, const char *pathname, int extra_options)
{
int thread_started = 1;
struct scth_thrarg *scth_tharg = NULL;
@ -552,10 +562,10 @@ static void onas_ddd_handle_extra_scanning(struct ddd_thrarg *tharg, const char
pthread_attr_setdetachstate(&scth_attr, PTHREAD_CREATE_JOINABLE);
/* Allocate memory for arguments. Thread is responsible for freeing it. */
if (!(scth_tharg = (struct scth_thrarg *) calloc(sizeof(struct scth_thrarg), 1))) break;
if (!(scth_tharg->options = (struct cl_scan_options *) calloc(sizeof(struct cl_scan_options), 1))) break;
if (!(scth_tharg = (struct scth_thrarg *)calloc(sizeof(struct scth_thrarg), 1))) break;
if (!(scth_tharg->options = (struct cl_scan_options *)calloc(sizeof(struct cl_scan_options), 1))) break;
(void) memcpy(scth_tharg->options, tharg->options, sizeof(struct cl_scan_options));
(void)memcpy(scth_tharg->options, tharg->options, sizeof(struct cl_scan_options));
scth_tharg->extra_options = extra_options;
scth_tharg->opts = tharg->opts;
@ -563,13 +573,13 @@ static void onas_ddd_handle_extra_scanning(struct ddd_thrarg *tharg, const char
scth_tharg->engine = tharg->engine;
thread_started = pthread_create(&scth_pid, &scth_attr, onas_scan_th, scth_tharg);
} while(0);
} while (0);
if (0 != thread_started) {
/* Failed to create thread. Free anything we may have allocated. */
logg("!ScanOnAccess: Unable to kick off extra scanning.\n");
if (NULL != scth_tharg) {
if (NULL != scth_tharg->pathname){
if (NULL != scth_tharg->pathname) {
free(scth_tharg->pathname);
scth_tharg->pathname = NULL;
}
@ -585,8 +595,8 @@ static void onas_ddd_handle_extra_scanning(struct ddd_thrarg *tharg, const char
return;
}
static void onas_ddd_exit(int sig) {
static void onas_ddd_exit(int sig)
{
logg("*ScanOnAccess: onas_ddd_exit(), signal %d\n", sig);
close(onas_in_fd);

View file

@ -42,9 +42,7 @@ struct ddd_thrarg {
const struct cl_engine *engine;
};
int onas_ddd_init(uint64_t nwatches, size_t ht_size);
void *onas_ddd_th(void *arg);
#endif

View file

@ -87,9 +87,9 @@ static int onas_fan_scanfile(int fan_fd, const char *fname, struct fanotify_even
}
}
if(fmd->mask & FAN_ALL_PERM_EVENTS) {
if (fmd->mask & FAN_ALL_PERM_EVENTS) {
ret = write(fan_fd, &res, sizeof(res));
if(ret == -1)
if (ret == -1)
logg("!ScanOnAccess: Internal error (can't write to fanotify)\n");
}
@ -98,7 +98,7 @@ static int onas_fan_scanfile(int fan_fd, const char *fname, struct fanotify_even
void *onas_fan_th(void *arg)
{
struct thrarg *tharg = (struct thrarg *) arg;
struct thrarg *tharg = (struct thrarg *)arg;
sigset_t sigset;
struct sigaction act;
const struct optstruct *pt;
@ -139,9 +139,9 @@ void *onas_fan_th(void *arg)
/* Initialize fanotify */
onas_fan_fd = fanotify_init(FAN_CLASS_CONTENT | FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS, O_LARGEFILE | O_RDONLY);
if(onas_fan_fd < 0) {
if (onas_fan_fd < 0) {
logg("!ScanOnAccess: fanotify_init failed: %s\n", cli_strerror(errno, err, sizeof(err)));
if(errno == EPERM)
if (errno == EPERM)
logg("ScanOnAccess: clamd must be started by root\n");
return NULL;
}
@ -151,7 +151,6 @@ void *onas_fan_th(void *arg)
return NULL;
}
if (optget(tharg->opts, "OnAccessPrevention")->enabled && !optget(tharg->opts, "OnAccessMountPath")->enabled) {
logg("ScanOnAccess: preventing access attempts on malicious files.\n");
fan_mask |= FAN_ACCESS_PERM | FAN_OPEN_PERM;
@ -161,33 +160,33 @@ void *onas_fan_th(void *arg)
}
if ((pt = optget(tharg->opts, "OnAccessMountPath"))->enabled) {
while(pt) {
if(fanotify_mark(onas_fan_fd, FAN_MARK_ADD | FAN_MARK_MOUNT, fan_mask, onas_fan_fd, pt->strarg) != 0) {
while (pt) {
if (fanotify_mark(onas_fan_fd, FAN_MARK_ADD | FAN_MARK_MOUNT, fan_mask, onas_fan_fd, pt->strarg) != 0) {
logg("!ScanOnAccess: Can't include mountpoint '%s'\n", pt->strarg);
return NULL;
} else
logg("ScanOnAccess: Protecting '%s' and rest of mount.\n", pt->strarg);
pt = (struct optstruct *) pt->nextarg;
pt = (struct optstruct *)pt->nextarg;
}
} else if (!optget(tharg->opts, "OnAccessDisableDDD")->enabled) {
int thread_started = 1;
do {
if(pthread_attr_init(&ddd_attr)) break;
if (pthread_attr_init(&ddd_attr)) break;
pthread_attr_setdetachstate(&ddd_attr, PTHREAD_CREATE_JOINABLE);
/* Allocate memory for arguments. Thread is responsible for freeing it. */
if (!(ddd_tharg = (struct ddd_thrarg *) calloc(sizeof(struct ddd_thrarg), 1))) break;
if (!(ddd_tharg->options = (struct cl_scan_options *) calloc(sizeof(struct cl_scan_options), 1))) break;
if (!(ddd_tharg = (struct ddd_thrarg *)calloc(sizeof(struct ddd_thrarg), 1))) break;
if (!(ddd_tharg->options = (struct cl_scan_options *)calloc(sizeof(struct cl_scan_options), 1))) break;
(void) memcpy(ddd_tharg->options, tharg->options, sizeof(struct cl_scan_options));
(void)memcpy(ddd_tharg->options, tharg->options, sizeof(struct cl_scan_options));
ddd_tharg->fan_fd = onas_fan_fd;
ddd_tharg->fan_mask = fan_mask;
ddd_tharg->opts = tharg->opts;
ddd_tharg->engine = tharg->engine;
thread_started = pthread_create(&ddd_pid, &ddd_attr, onas_ddd_th, ddd_tharg);
} while(0);
} while (0);
if (0 != thread_started) {
/* Failed to create thread. Free anything we may have allocated. */
@ -203,14 +202,14 @@ void *onas_fan_th(void *arg)
}
} else {
if((pt = optget(tharg->opts, "OnAccessIncludePath"))->enabled) {
while(pt) {
if(fanotify_mark(onas_fan_fd, FAN_MARK_ADD, fan_mask, onas_fan_fd, pt->strarg) != 0) {
if ((pt = optget(tharg->opts, "OnAccessIncludePath"))->enabled) {
while (pt) {
if (fanotify_mark(onas_fan_fd, FAN_MARK_ADD, fan_mask, onas_fan_fd, pt->strarg) != 0) {
logg("!ScanOnAccess: Can't include path '%s'\n", pt->strarg);
return NULL;
} else
logg("ScanOnAccess: Protecting directory '%s'\n", pt->strarg);
pt = (struct optstruct *) pt->nextarg;
pt = (struct optstruct *)pt->nextarg;
}
} else {
logg("!ScanOnAccess: Please specify at least one path with OnAccessIncludePath\n");
@ -220,7 +219,7 @@ void *onas_fan_th(void *arg)
/* Load other options. */
sizelimit = optget(tharg->opts, "OnAccessMaxFileSize")->numarg;
if(sizelimit)
if (sizelimit)
logg("ScanOnAccess: Max file size limited to %u bytes\n", sizelimit);
else
logg("ScanOnAccess: File size limit disabled\n");
@ -232,11 +231,10 @@ void *onas_fan_th(void *arg)
do {
if (reload) sleep(1);
ret = select(onas_fan_fd + 1, &rfds, NULL, NULL, NULL);
} while((ret == -1 && errno == EINTR) || reload);
} while ((ret == -1 && errno == EINTR) || reload);
time_t start = time(NULL) - 30;
while(((bread = read(onas_fan_fd, buf, sizeof(buf))) > 0) || errno == EOVERFLOW) {
while (((bread = read(onas_fan_fd, buf, sizeof(buf))) > 0) || errno == EOVERFLOW) {
if (errno == EOVERFLOW) {
if (time(NULL) - start >= 30) {
@ -249,44 +247,44 @@ void *onas_fan_th(void *arg)
continue;
}
fmd = (struct fanotify_event_metadata *) buf;
while(FAN_EVENT_OK(fmd, bread)) {
fmd = (struct fanotify_event_metadata *)buf;
while (FAN_EVENT_OK(fmd, bread)) {
scan = 1;
if(fmd->fd >= 0) {
if (fmd->fd >= 0) {
sprintf(fname, "/proc/self/fd/%d", fmd->fd);
len = readlink(fname, fname, sizeof(fname) - 1);
if(len == -1) {
if (len == -1) {
close(fmd->fd);
logg("!ScanOnAccess: Internal error (readlink() failed)\n");
return NULL;
}
fname[len] = 0;
if((check = onas_fan_checkowner(fmd->pid, tharg->opts))) {
if ((check = onas_fan_checkowner(fmd->pid, tharg->opts))) {
scan = 0;
/* TODO: Re-enable OnAccessExtraScanning once the thread resource consumption issue is resolved. */
#if 0
/* TODO: Re-enable OnAccessExtraScanning once the thread resource consumption issue is resolved. */
#if 0
if ((check != CHK_SELF) || !(optget(tharg->opts, "OnAccessExtraScanning")->enabled)) {
#else
#else
if (check != CHK_SELF) {
#endif
#endif
logg("*ScanOnAccess: %s skipped (excluded UID)\n", fname);
}
}
if(sizelimit) {
if(FSTAT(fmd->fd, &sb) != 0 || sb.st_size > sizelimit) {
if (sizelimit) {
if (FSTAT(fmd->fd, &sb) != 0 || sb.st_size > sizelimit) {
scan = 0;
/* logg("*ScanOnAccess: %s skipped (size > %d)\n", fname, sizelimit); */
}
}
if(onas_fan_scanfile(onas_fan_fd, fname, fmd, scan, extinfo, tharg) == -1) {
if (onas_fan_scanfile(onas_fan_fd, fname, fmd, scan, extinfo, tharg) == -1) {
close(fmd->fd);
return NULL;
}
if(close(fmd->fd) == -1) {
if (close(fmd->fd) == -1) {
printf("!ScanOnAccess: Internal error (close(%d) failed)\n", fmd->fd);
close(fmd->fd);
return NULL;
@ -297,15 +295,14 @@ void *onas_fan_th(void *arg)
do {
if (reload) sleep(1);
ret = select(onas_fan_fd + 1, &rfds, NULL, NULL, NULL);
} while((ret == -1 && errno == EINTR) || reload);
}
if(bread < 0)
logg("!ScanOnAccess: Internal error (failed to read data) ... %s\n", strerror(errno));
return NULL;
} while ((ret == -1 && errno == EINTR) || reload);
}
if (bread < 0)
logg("!ScanOnAccess: Internal error (failed to read data) ... %s\n", strerror(errno));
return NULL;
}
/* CLAMAUTH is deprecated */
#elif defined(CLAMAUTH)
@ -344,7 +341,7 @@ struct ClamAuthEvent {
static void cauth_exit(int sig)
{
logg("*ScanOnAccess: cauth_exit(), signal %d\n", sig);
if(cauth_fd > 0)
if (cauth_fd > 0)
close(cauth_fd);
pthread_exit(NULL);
logg("ScanOnAccess: stopped\n");
@ -361,11 +358,11 @@ static int cauth_scanfile(const char *fname, int extinfo, struct thrarg *tharg)
context.scandata = NULL;
fd = open(fname, O_RDONLY);
if(fd == -1)
if (fd == -1)
return -1;
if(cl_scandesc_callback(fd, fname, &virname, NULL, tharg->engine, tharg->options, &context) == CL_VIRUS) {
if(extinfo && context.virsize)
if (cl_scandesc_callback(fd, fname, &virname, NULL, tharg->engine, tharg->options, &context) == CL_VIRUS) {
if (extinfo && context.virsize)
logg("ScanOnAccess: %s: %s(%s:%llu) FOUND\n", fname, virname, context.virhash, context.virsize);
else
logg("ScanOnAccess: %s: %s FOUND\n", fname, virname);
@ -377,7 +374,7 @@ static int cauth_scanfile(const char *fname, int extinfo, struct thrarg *tharg)
void *onas_fan_th(void *arg)
{
struct thrarg *tharg = (struct thrarg *) arg;
struct thrarg *tharg = (struct thrarg *)arg;
sigset_t sigset;
struct sigaction act;
int eventcnt = 1, extinfo;
@ -405,11 +402,11 @@ void *onas_fan_th(void *arg)
extinfo = optget(tharg->opts, "ExtendedDetectionInfo")->enabled;
cauth_fd = open("/dev/clamauth", O_RDONLY);
if(cauth_fd == -1) {
if (cauth_fd == -1) {
logg("!ScanOnAccess: Can't open /dev/clamauth\n");
if(errno == ENOENT)
if (errno == ENOENT)
logg("!ScanOnAccess: Please make sure ClamAuth.kext is loaded\n");
else if(errno == EACCES)
else if (errno == EACCES)
logg("!ScanOnAccess: This application requires root privileges\n");
else
logg("!ScanOnAccess: /dev/clamauth: %s\n", cli_strerror(errno, err, sizeof(err)));
@ -417,15 +414,15 @@ void *onas_fan_th(void *arg)
return NULL;
}
while(1) {
if(read(cauth_fd, &event, sizeof(event)) > 0) {
if(eventcnt == 1) {
if(event.action != SUPPORTED_PROTOCOL) {
while (1) {
if (read(cauth_fd, &event, sizeof(event)) > 0) {
if (eventcnt == 1) {
if (event.action != SUPPORTED_PROTOCOL) {
logg("!ScanOnAccess: Protocol version mismatch (tool: %d, driver: %d)\n", SUPPORTED_PROTOCOL, event.action);
close(cauth_fd);
return NULL;
}
if(strncmp(event.path, "ClamAuth", 8)) {
if (strncmp(event.path, "ClamAuth", 8)) {
logg("!ScanOnAccess: Invalid version event\n");
close(cauth_fd);
return NULL;
@ -436,7 +433,7 @@ void *onas_fan_th(void *arg)
}
eventcnt++;
} else {
if(errno == ENODEV) {
if (errno == ENODEV) {
printf("^ScanOnAccess: ClamAuth module deactivated, terminating\n");
close(cauth_fd);
return NULL;

View file

@ -58,13 +58,14 @@ static void onas_free_bucket(struct onas_bucket *bckt);
static int onas_bucket_insert(struct onas_bucket *bckt, struct onas_element *elem);
static int onas_bucket_remove(struct onas_bucket *bckt, struct onas_element *elem);
static int onas_add_hashnode_child(struct onas_hnode *node, const char* dirname);
static int onas_add_hashnode_child(struct onas_hnode *node, const char *dirname);
static struct onas_lnode *onas_listnode_init(void);
static struct onas_hnode *onas_hashnode_init(void);
static inline uint32_t onas_hshift(uint32_t hash) {
static inline uint32_t onas_hshift(uint32_t hash)
{
hash = ~hash;
@ -79,7 +80,8 @@ static inline uint32_t onas_hshift(uint32_t hash) {
return hash;
}
static inline int onas_hash(const char* key, size_t keylen, uint32_t size) {
static inline int onas_hash(const char *key, size_t keylen, uint32_t size)
{
uint32_t hash = 1;
uint32_t i;
@ -92,20 +94,21 @@ static inline int onas_hash(const char* key, size_t keylen, uint32_t size) {
return hash & (size - 1);
}
int onas_ht_init(struct onas_ht **ht, uint32_t size) {
int onas_ht_init(struct onas_ht **ht, uint32_t size)
{
if (size == 0 || (size & (~size + 1)) != size) return CL_EARG;
*ht = (struct onas_ht *) cli_malloc(sizeof(struct onas_ht));
*ht = (struct onas_ht *)cli_malloc(sizeof(struct onas_ht));
if (!(*ht)) return CL_EMEM;
**ht = (struct onas_ht) {
**ht = (struct onas_ht){
.htable = NULL,
.size = size,
.nbckts = 0,
};
if (!((*ht)->htable = (struct onas_bucket **) cli_calloc(size, sizeof(struct onas_bucket *)))) {
if (!((*ht)->htable = (struct onas_bucket **)cli_calloc(size, sizeof(struct onas_bucket *)))) {
onas_free_ht(*ht);
return CL_EMEM;
}
@ -113,7 +116,8 @@ int onas_ht_init(struct onas_ht **ht, uint32_t size) {
return CL_SUCCESS;
}
void onas_free_ht(struct onas_ht *ht) {
void onas_free_ht(struct onas_ht *ht)
{
if (!ht || ht->size == 0) return;
@ -136,21 +140,22 @@ void onas_free_ht(struct onas_ht *ht) {
return;
}
static struct onas_bucket *onas_bucket_init() {
static struct onas_bucket *onas_bucket_init()
{
struct onas_bucket *bckt = (struct onas_bucket*) cli_malloc(sizeof(struct onas_bucket));
struct onas_bucket *bckt = (struct onas_bucket *)cli_malloc(sizeof(struct onas_bucket));
if (!bckt) return NULL;
*bckt = (struct onas_bucket) {
*bckt = (struct onas_bucket){
.size = 0,
.head = NULL,
.tail = NULL
};
.tail = NULL};
return bckt;
}
static void onas_free_bucket(struct onas_bucket *bckt) {
static void onas_free_bucket(struct onas_bucket *bckt)
{
if (!bckt) return;
@ -169,23 +174,24 @@ static void onas_free_bucket(struct onas_bucket *bckt) {
return;
}
struct onas_element *onas_element_init(struct onas_hnode *value, const char *key, size_t klen) {
struct onas_element *onas_element_init(struct onas_hnode *value, const char *key, size_t klen)
{
struct onas_element *elem = (struct onas_element *) cli_malloc(sizeof(struct onas_element));
struct onas_element *elem = (struct onas_element *)cli_malloc(sizeof(struct onas_element));
if (!elem) return NULL;
*elem = (struct onas_element) {
*elem = (struct onas_element){
.key = key,
.klen = klen,
.data = value,
.next = NULL,
.prev = NULL
};
.prev = NULL};
return elem;
}
void onas_free_element(struct onas_element *elem) {
void onas_free_element(struct onas_element *elem)
{
if (!elem) return;
@ -199,7 +205,8 @@ void onas_free_element(struct onas_element *elem) {
return;
}
int onas_ht_insert(struct onas_ht *ht, struct onas_element *elem) {
int onas_ht_insert(struct onas_ht *ht, struct onas_element *elem)
{
if (!ht || !elem || !elem->key) return CL_ENULLARG;
@ -224,7 +231,8 @@ int onas_ht_insert(struct onas_ht *ht, struct onas_element *elem) {
return ret;
}
static int onas_bucket_insert(struct onas_bucket *bckt, struct onas_element *elem) {
static int onas_bucket_insert(struct onas_bucket *bckt, struct onas_element *elem)
{
if (!bckt || !elem) return CL_ENULLARG;
if (bckt->size == 0) {
@ -247,7 +255,8 @@ static int onas_bucket_insert(struct onas_bucket *bckt, struct onas_element *ele
}
/* Checks if key exists and optionally stores address to the element corresponding to the key within elem */
int onas_ht_get(struct onas_ht *ht, const char *key, size_t klen, struct onas_element **elem) {
int onas_ht_get(struct onas_ht *ht, const char *key, size_t klen, struct onas_element **elem)
{
if (elem) *elem = NULL;
@ -271,7 +280,8 @@ int onas_ht_get(struct onas_ht *ht, const char *key, size_t klen, struct onas_el
}
/* Removes the element corresponding to key from the hashtable and optionally returns a pointer to the removed element. */
int onas_ht_remove(struct onas_ht *ht, const char* key, size_t klen, struct onas_element **relem) {
int onas_ht_remove(struct onas_ht *ht, const char *key, size_t klen, struct onas_element **relem)
{
if (!ht || !key || klen <= 0) return CL_ENULLARG;
struct onas_bucket *bckt = ht->htable[onas_hash(key, klen, ht->size)];
@ -290,7 +300,8 @@ int onas_ht_remove(struct onas_ht *ht, const char* key, size_t klen, struct onas
return ret;
}
static int onas_bucket_remove(struct onas_bucket *bckt, struct onas_element *elem) {
static int onas_bucket_remove(struct onas_bucket *bckt, struct onas_element *elem)
{
if (!bckt || !elem) return CL_ENULLARG;
struct onas_element *curr = bckt->head;
@ -330,17 +341,17 @@ static int onas_bucket_remove(struct onas_bucket *bckt, struct onas_element *ele
return CL_SUCCESS;
}
/* Dealing with hash nodes and list nodes */
/* Function to initialize hashnode. */
static struct onas_hnode *onas_hashnode_init(void) {
static struct onas_hnode *onas_hashnode_init(void)
{
struct onas_hnode *hnode = NULL;
if(!(hnode = (struct onas_hnode *) cli_malloc(sizeof(struct onas_hnode)))) {
if (!(hnode = (struct onas_hnode *)cli_malloc(sizeof(struct onas_hnode)))) {
return NULL;
}
*hnode = (struct onas_hnode) {
*hnode = (struct onas_hnode){
.pathlen = 0,
.pathname = NULL,
.prnt_pathlen = 0,
@ -348,43 +359,43 @@ static struct onas_hnode *onas_hashnode_init(void) {
.childhead = NULL,
.childtail = NULL,
.wd = 0,
.watched = 0
};
.watched = 0};
if (!(hnode->childhead = (struct onas_lnode *) onas_listnode_init())) {
if (!(hnode->childhead = (struct onas_lnode *)onas_listnode_init())) {
onas_free_hashnode(hnode);
return NULL;
}
if (!(hnode->childtail = (struct onas_lnode *) onas_listnode_init())) {
if (!(hnode->childtail = (struct onas_lnode *)onas_listnode_init())) {
onas_free_hashnode(hnode);
return NULL;
}
hnode->childhead->next = (struct onas_lnode *) hnode->childtail;
hnode->childtail->prev = (struct onas_lnode *) hnode->childhead;
hnode->childhead->next = (struct onas_lnode *)hnode->childtail;
hnode->childtail->prev = (struct onas_lnode *)hnode->childhead;
return hnode;
}
/* Function to initialize listnode. */
static struct onas_lnode *onas_listnode_init(void) {
static struct onas_lnode *onas_listnode_init(void)
{
struct onas_lnode *lnode = NULL;
if(!(lnode = (struct onas_lnode *) cli_malloc(sizeof(struct onas_lnode)))) {
if (!(lnode = (struct onas_lnode *)cli_malloc(sizeof(struct onas_lnode)))) {
return NULL;
}
*lnode = (struct onas_lnode) {
*lnode = (struct onas_lnode){
.dirname = NULL,
.next = NULL,
.prev = NULL
};
.prev = NULL};
return lnode;
}
/* Function to free hashnode. */
void onas_free_hashnode(struct onas_hnode *hnode) {
void onas_free_hashnode(struct onas_hnode *hnode)
{
if (!hnode) return;
onas_free_dirlist(hnode->childhead);
@ -401,14 +412,14 @@ void onas_free_hashnode(struct onas_hnode *hnode) {
return;
}
/* Function to free list of listnodes. */
void onas_free_dirlist(struct onas_lnode *head) {
void onas_free_dirlist(struct onas_lnode *head)
{
if (!head) return;
struct onas_lnode *curr = head;
struct onas_lnode *tmp = curr;
while(curr) {
while (curr) {
tmp = curr->next;
onas_free_listnode(curr);
curr = tmp;
@ -418,7 +429,8 @@ void onas_free_dirlist(struct onas_lnode *head) {
}
/* Function to free a listnode. */
void onas_free_listnode(struct onas_lnode *lnode) {
void onas_free_listnode(struct onas_lnode *lnode)
{
if (!lnode) return;
lnode->next = NULL;
@ -432,7 +444,8 @@ void onas_free_listnode(struct onas_lnode *lnode) {
return;
}
static int onas_add_hashnode_child(struct onas_hnode *node, const char* dirname) {
static int onas_add_hashnode_child(struct onas_hnode *node, const char *dirname)
{
if (!node || !dirname) return CL_ENULLARG;
struct onas_lnode *child = onas_listnode_init();
@ -447,7 +460,8 @@ static int onas_add_hashnode_child(struct onas_hnode *node, const char* dirname)
}
/* Function to add a dir_listnode to a list */
int onas_add_listnode(struct onas_lnode *tail, struct onas_lnode *node) {
int onas_add_listnode(struct onas_lnode *tail, struct onas_lnode *node)
{
if (!tail || !node) return CL_ENULLARG;
struct onas_lnode *tmp = tail->prev;
@ -462,7 +476,8 @@ int onas_add_listnode(struct onas_lnode *tail, struct onas_lnode *node) {
}
/* Function to remove a listnode based on dirname. */
int onas_rm_listnode(struct onas_lnode *head, const char *dirname) {
int onas_rm_listnode(struct onas_lnode *head, const char *dirname)
{
if (!dirname || !head) return CL_ENULLARG;
struct onas_lnode *curr = head;
@ -487,13 +502,14 @@ int onas_rm_listnode(struct onas_lnode *head, const char *dirname) {
/*** Dealing with parent/child relationships in the table. ***/
/* Determines parent and returns a copy based on full pathname. */
inline static char *onas_get_parent(const char *pathname, size_t len) {
inline static char *onas_get_parent(const char *pathname, size_t len)
{
if (!pathname || len <= 1) return NULL;
int idx = len - 2;
char *ret = NULL;
while(idx >= 0 && pathname[idx] != '/') {
while (idx >= 0 && pathname[idx] != '/') {
idx--;
}
@ -511,12 +527,13 @@ inline static char *onas_get_parent(const char *pathname, size_t len) {
}
/* Gets the index at which the name of directory begins from the full pathname. */
inline static int onas_get_dirname_idx(const char *pathname, size_t len) {
inline static int onas_get_dirname_idx(const char *pathname, size_t len)
{
if (!pathname || len <= 1) return -1;
int idx = len - 2;
while(idx >= 0 && pathname[idx] != '/') {
while (idx >= 0 && pathname[idx] != '/') {
idx--;
}
@ -527,7 +544,8 @@ inline static int onas_get_dirname_idx(const char *pathname, size_t len) {
}
/* Emancipates the specified child from the specified parent. */
int onas_ht_rm_child(struct onas_ht *ht, const char *prntpath, size_t prntlen, const char *childpath, size_t childlen) {
int onas_ht_rm_child(struct onas_ht *ht, const char *prntpath, size_t prntlen, const char *childpath, size_t childlen)
{
if (!ht || !prntpath || prntlen <= 0 || !childpath || childlen <= 1) return CL_ENULLARG;
@ -536,9 +554,9 @@ int onas_ht_rm_child(struct onas_ht *ht, const char *prntpath, size_t prntlen, c
int idx = onas_get_dirname_idx(childpath, childlen);
int ret = 0;
if(idx <= 0) return CL_SUCCESS;
if (idx <= 0) return CL_SUCCESS;
if(onas_ht_get(ht, prntpath, prntlen, &elem) != CL_SUCCESS) return CL_EARG;
if (onas_ht_get(ht, prntpath, prntlen, &elem) != CL_SUCCESS) return CL_EARG;
hnode = elem->data;
@ -548,16 +566,17 @@ int onas_ht_rm_child(struct onas_ht *ht, const char *prntpath, size_t prntlen, c
}
/* The specified parent adds the specified child to its list. */
int onas_ht_add_child(struct onas_ht *ht, const char *prntpath, size_t prntlen, const char *childpath, size_t childlen) {
int onas_ht_add_child(struct onas_ht *ht, const char *prntpath, size_t prntlen, const char *childpath, size_t childlen)
{
if (!ht || !prntpath || prntlen <= 0 || !childpath || childlen <= 1) return CL_ENULLARG;
struct onas_element *elem = NULL;
struct onas_hnode *hnode = NULL;
int idx = onas_get_dirname_idx(childpath, childlen);
if(idx <= 0) return CL_SUCCESS;
if (idx <= 0) return CL_SUCCESS;
if(onas_ht_get(ht, prntpath, prntlen, &elem)) return CL_EARG;
if (onas_ht_get(ht, prntpath, prntlen, &elem)) return CL_EARG;
hnode = elem->data;
return onas_add_hashnode_child(hnode, &(childpath[idx]));
@ -566,7 +585,8 @@ int onas_ht_add_child(struct onas_ht *ht, const char *prntpath, size_t prntlen,
/*** Dealing with hierarchy changes. ***/
/* Adds the hierarchy under pathname to the tree and allocates all necessary memory. */
int onas_ht_add_hierarchy(struct onas_ht *ht, const char *pathname) {
int onas_ht_add_hierarchy(struct onas_ht *ht, const char *pathname)
{
if (!ht || !pathname) return CL_ENULLARG;
@ -580,13 +600,13 @@ int onas_ht_add_hierarchy(struct onas_ht *ht, const char *pathname) {
if (prnt) onas_ht_add_child(ht, prnt, strlen(prnt), pathname, len);
free(prnt);
char * const pathargv[] = { (char*) pathname, NULL };
char *const pathargv[] = {(char *)pathname, NULL};
if (!(ftsp = _priv_fts_open(pathargv, ftspopts, NULL))) {
logg("!ScanOnAccess: Could not open '%s'\n", pathname);
return CL_EARG;
}
while((curr = _priv_fts_read(ftsp))) {
while ((curr = _priv_fts_read(ftsp))) {
struct onas_hnode *hnode = NULL;
@ -609,10 +629,10 @@ int onas_ht_add_hierarchy(struct onas_ht *ht, const char *pathname) {
continue;
}
if((childlist = _priv_fts_children(ftsp, 0))) {
if ((childlist = _priv_fts_children(ftsp, 0))) {
do {
if (childlist->fts_info == FTS_D) {
if(CL_EMEM == onas_add_hashnode_child(hnode, childlist->fts_name))
if (CL_EMEM == onas_add_hashnode_child(hnode, childlist->fts_name))
return CL_EMEM;
}
@ -630,7 +650,8 @@ int onas_ht_add_hierarchy(struct onas_ht *ht, const char *pathname) {
}
/* Removes the underlying hierarchy from the tree and frees all associated memory. */
int onas_ht_rm_hierarchy(struct onas_ht *ht, const char* pathname, size_t len, int level) {
int onas_ht_rm_hierarchy(struct onas_ht *ht, const char *pathname, size_t len, int level)
{
if (!ht || !pathname || len <= 0) return CL_ENULLARG;
struct onas_hnode *hnode = NULL;
@ -638,17 +659,17 @@ int onas_ht_rm_hierarchy(struct onas_ht *ht, const char* pathname, size_t len, i
char *prntname = NULL;
size_t prntlen = 0;
if(onas_ht_get(ht, pathname, len, &elem)) return CL_EARG;
if (onas_ht_get(ht, pathname, len, &elem)) return CL_EARG;
hnode = elem->data;
struct onas_lnode *curr = hnode->childhead;
if(level == 0) {
if(!(prntname = onas_get_parent(pathname, len))) return CL_EARG;
if (level == 0) {
if (!(prntname = onas_get_parent(pathname, len))) return CL_EARG;
prntlen = strlen(prntname);
if(onas_ht_rm_child(ht, prntname, prntlen, pathname, len)) return CL_EARG;
if (onas_ht_rm_child(ht, prntname, prntlen, pathname, len)) return CL_EARG;
free(prntname);
}
@ -657,10 +678,10 @@ int onas_ht_rm_hierarchy(struct onas_ht *ht, const char* pathname, size_t len, i
curr = curr->next;
size_t size = len + strlen(curr->dirname) + 2;
char *child_path = (char *) cli_malloc(size);
char *child_path = (char *)cli_malloc(size);
if (child_path == NULL)
return CL_EMEM;
if (hnode->pathname[len-1] == '/')
if (hnode->pathname[len - 1] == '/')
snprintf(child_path, size, "%s%s", hnode->pathname, curr->dirname);
else
snprintf(child_path, size, "%s/%s", hnode->pathname, curr->dirname);

View file

@ -30,7 +30,7 @@
struct onas_element {
const char* key;
const char *key;
size_t klen;
struct onas_hnode *data;
@ -86,7 +86,6 @@ struct onas_hnode {
uint32_t watched;
};
void onas_free_ht(struct onas_ht *ht);
int onas_ht_init(struct onas_ht **ht, uint32_t table_size);
int onas_ht_insert(struct onas_ht *ht, struct onas_element *elem);

View file

@ -55,33 +55,32 @@ int onas_fan_checkowner(int pid, const struct optstruct *opts)
const struct optstruct *opt_root = NULL;
/* always ignore ourselves */
if (pid == (int) getpid()) {
if (pid == (int)getpid()) {
return CHK_SELF;
}
/* look up options */
opt = optget (opts, "OnAccessExcludeUID");
opt_root = optget (opts, "OnAccessExcludeRootUID");
opt = optget(opts, "OnAccessExcludeUID");
opt_root = optget(opts, "OnAccessExcludeRootUID");
/* we can return immediately if no uid exclusions were requested */
if (!(opt->enabled || opt_root->enabled))
return CHK_CLEAN;
/* perform exclusion checks if we can stat OK */
snprintf (path, sizeof (path), "/proc/%u", pid);
if (CLAMSTAT (path, &sb) == 0) {
snprintf(path, sizeof(path), "/proc/%u", pid);
if (CLAMSTAT(path, &sb) == 0) {
/* check all our non-root UIDs first */
if (opt->enabled) {
while (opt)
{
if (opt->numarg == (long long) sb.st_uid)
while (opt) {
if (opt->numarg == (long long)sb.st_uid)
return CHK_FOUND;
opt = opt->nextarg;
}
}
/* finally check root UID */
if (opt_root->enabled) {
if (0 == (long long) sb.st_uid)
if (0 == (long long)sb.st_uid)
return CHK_FOUND;
}
} else if (errno == EACCES) {

View file

@ -42,14 +42,14 @@
#include "libclamav/clamav.h"
static int onas_scth_scanfile(const char *fname, int fd, int extinfo, struct scth_thrarg *tharg);
static int onas_scth_handle_dir(const char *pathname, struct scth_thrarg *tharg);
static int onas_scth_handle_file(const char *pathname, struct scth_thrarg *tharg);
static void onas_scth_exit(int sig);
static void onas_scth_exit(int sig) {
static void onas_scth_exit(int sig)
{
logg("*ScanOnAccess: onas_scth_exit(), signal %d\n", sig);
pthread_exit(NULL);
@ -63,7 +63,8 @@ static int onas_scth_scanfile(const char *fname, int fd, int extinfo, struct sct
return onas_scan(fname, fd, &virname, tharg->engine, tharg->options, extinfo);
}
static int onas_scth_handle_dir(const char *pathname, struct scth_thrarg *tharg) {
static int onas_scth_handle_dir(const char *pathname, struct scth_thrarg *tharg)
{
FTS *ftsp = NULL;
int fd;
int ftspopts = FTS_PHYSICAL | FTS_XDEV;
@ -73,7 +74,7 @@ static int onas_scth_handle_dir(const char *pathname, struct scth_thrarg *tharg)
extinfo = optget(tharg->opts, "ExtendedDetectionInfo")->enabled;
char *const pathargv[] = { (char *) pathname, NULL };
char *const pathargv[] = {(char *)pathname, NULL};
if (!(ftsp = _priv_fts_open(pathargv, ftspopts, NULL))) return CL_EOPEN;
while ((curr = _priv_fts_read(ftsp))) {
@ -81,7 +82,8 @@ static int onas_scth_handle_dir(const char *pathname, struct scth_thrarg *tharg)
if ((fd = safe_open(curr->fts_path, O_RDONLY | O_BINARY)) == -1)
return CL_EOPEN;
if (onas_scth_scanfile(curr->fts_path, fd, extinfo, tharg) == CL_VIRUS);
if (onas_scth_scanfile(curr->fts_path, fd, extinfo, tharg) == CL_VIRUS)
;
ret = CL_VIRUS;
close(fd);
@ -91,8 +93,8 @@ static int onas_scth_handle_dir(const char *pathname, struct scth_thrarg *tharg)
return ret;
}
static int onas_scth_handle_file(const char *pathname, struct scth_thrarg *tharg) {
static int onas_scth_handle_file(const char *pathname, struct scth_thrarg *tharg)
{
int fd;
int extinfo;
int ret;
@ -110,8 +112,9 @@ static int onas_scth_handle_file(const char *pathname, struct scth_thrarg *tharg
return ret;
}
void *onas_scan_th(void *arg) {
struct scth_thrarg *tharg = (struct scth_thrarg *) arg;
void *onas_scan_th(void *arg)
{
struct scth_thrarg *tharg = (struct scth_thrarg *)arg;
sigset_t sigset;
struct sigaction act;
@ -147,7 +150,7 @@ void *onas_scan_th(void *arg) {
}
done:
if (NULL != tharg->pathname){
if (NULL != tharg->pathname) {
free(tharg->pathname);
tharg->pathname = NULL;
}

View file

@ -85,12 +85,11 @@ static void xfree(void *p)
}
#ifdef _WIN32
void
virusaction (const char *filename, const char *virname,
void virusaction(const char *filename, const char *virname,
const struct optstruct *opts)
{
if (optget (opts, "VirusEvent")->enabled)
logg ("^VirusEvent is not supported on this platform"); /* Yet */
if (optget(opts, "VirusEvent")->enabled)
logg("^VirusEvent is not supported on this platform"); /* Yet */
}
#else
@ -98,8 +97,7 @@ virusaction (const char *filename, const char *virname,
#define VE_FILENAME "CLAM_VIRUSEVENT_FILENAME"
#define VE_VIRUSNAME "CLAM_VIRUSEVENT_VIRUSNAME"
void
virusaction (const char *filename, const char *virname,
void virusaction(const char *filename, const char *virname,
const struct optstruct *opts)
{
pid_t pid;
@ -109,132 +107,113 @@ virusaction (const char *filename, const char *virname,
size_t i, j, v = 0, len;
char *env[4];
if (!(opt = optget (opts, "VirusEvent"))->enabled)
if (!(opt = optget(opts, "VirusEvent"))->enabled)
return;
path = getenv ("PATH");
path = getenv("PATH");
env[0] = path ? strdup(path) : NULL;
j = env[0] ? 1 : 0;
/* Allocate env vars.. to be portable env vars should not be freed */
buffer_file =
(char *) malloc (strlen (VE_FILENAME) + strlen (filename) + 2);
if (buffer_file)
{
sprintf (buffer_file, "%s=%s", VE_FILENAME, filename);
(char *)malloc(strlen(VE_FILENAME) + strlen(filename) + 2);
if (buffer_file) {
sprintf(buffer_file, "%s=%s", VE_FILENAME, filename);
env[j++] = buffer_file;
}
buffer_vir =
(char *) malloc (strlen (VE_VIRUSNAME) + strlen (virname) + 2);
if (buffer_vir)
{
sprintf (buffer_vir, "%s=%s", VE_VIRUSNAME, virname);
(char *)malloc(strlen(VE_VIRUSNAME) + strlen(virname) + 2);
if (buffer_vir) {
sprintf(buffer_vir, "%s=%s", VE_VIRUSNAME, virname);
env[j++] = buffer_vir;
}
env[j++] = NULL;
pt = opt->strarg;
while ((pt = strstr (pt, "%v")))
{
while ((pt = strstr(pt, "%v"))) {
pt += 2;
v++;
}
len = strlen (opt->strarg);
len = strlen(opt->strarg);
buffer_cmd =
(char *) calloc (len + v * strlen (virname) + 1, sizeof (char));
if (!buffer_cmd)
{
(char *)calloc(len + v * strlen(virname) + 1, sizeof(char));
if (!buffer_cmd) {
if (path)
xfree(env[0]);
xfree (buffer_file);
xfree (buffer_vir);
xfree(buffer_file);
xfree(buffer_vir);
return;
}
for (i = 0, j = 0; i < len; i++)
{
if (i + 1 < len && opt->strarg[i] == '%' && opt->strarg[i + 1] == 'v')
{
strcat (buffer_cmd, virname);
j += strlen (virname);
for (i = 0, j = 0; i < len; i++) {
if (i + 1 < len && opt->strarg[i] == '%' && opt->strarg[i + 1] == 'v') {
strcat(buffer_cmd, virname);
j += strlen(virname);
i++;
}
else
{
} else {
buffer_cmd[j++] = opt->strarg[i];
}
}
pthread_mutex_lock (&virusaction_lock);
pthread_mutex_lock(&virusaction_lock);
/* We can only call async-signal-safe functions after fork(). */
pid = fork ();
if (pid == 0)
{ /* child */
exit (execle ("/bin/sh", "sh", "-c", buffer_cmd, NULL, env));
}
else if (pid > 0)
{ /* parent */
pthread_mutex_unlock (&virusaction_lock);
while (waitpid (pid, NULL, 0) == -1 && errno == EINTR) continue;
}
else
{
pid = fork();
if (pid == 0) { /* child */
exit(execle("/bin/sh", "sh", "-c", buffer_cmd, NULL, env));
} else if (pid > 0) { /* parent */
pthread_mutex_unlock(&virusaction_lock);
logg ("!VirusEvent: fork failed.\n");
while (waitpid(pid, NULL, 0) == -1 && errno == EINTR) continue;
} else {
pthread_mutex_unlock(&virusaction_lock);
logg("!VirusEvent: fork failed.\n");
}
if (path)
xfree(env[0]);
xfree (buffer_cmd);
xfree (buffer_file);
xfree (buffer_vir);
xfree(buffer_cmd);
xfree(buffer_file);
xfree(buffer_vir);
}
#endif /* _WIN32 */
/* Function: writen
Try hard to write the specified number of bytes
*/
int
writen (int fd, void *buff, unsigned int count)
int writen(int fd, void *buff, unsigned int count)
{
int retval;
unsigned int todo;
unsigned char *current;
todo = count;
current = (unsigned char *) buff;
current = (unsigned char *)buff;
do
{
retval = write (fd, current, todo);
if (retval < 0)
{
if (errno == EINTR)
{
do {
retval = write(fd, current, todo);
if (retval < 0) {
if (errno == EINTR) {
continue;
}
return -1;
}
todo -= retval;
current += retval;
}
while (todo > 0);
} while (todo > 0);
return count;
}
static int
realloc_polldata (struct fd_data *data)
realloc_polldata(struct fd_data *data)
{
#ifdef HAVE_POLL
if (data->poll_data_nfds == data->nfds)
return 0;
if (data->poll_data)
free (data->poll_data);
data->poll_data = malloc (data->nfds * sizeof (*data->poll_data));
if (!data->poll_data)
{
logg ("!realloc_polldata: Memory allocation failed for poll_data\n");
free(data->poll_data);
data->poll_data = malloc(data->nfds * sizeof(*data->poll_data));
if (!data->poll_data) {
logg("!realloc_polldata: Memory allocation failed for poll_data\n");
return -1;
}
data->poll_data_nfds = data->nfds;
@ -242,35 +221,29 @@ realloc_polldata (struct fd_data *data)
return 0;
}
int
poll_fd (int fd, int timeout_sec, int check_signals)
int poll_fd(int fd, int timeout_sec, int check_signals)
{
int ret;
struct fd_data fds = FDS_INIT (NULL);
struct fd_data fds = FDS_INIT(NULL);
if (fds_add (&fds, fd, 1, timeout_sec) == -1)
if (fds_add(&fds, fd, 1, timeout_sec) == -1)
return -1;
do
{
ret = fds_poll_recv (&fds, timeout_sec, check_signals, NULL);
}
while (ret == -1 && errno == EINTR);
fds_free (&fds);
do {
ret = fds_poll_recv(&fds, timeout_sec, check_signals, NULL);
} while (ret == -1 && errno == EINTR);
fds_free(&fds);
return ret;
}
void
fds_cleanup (struct fd_data *data)
void fds_cleanup(struct fd_data *data)
{
struct fd_buf *newbuf;
unsigned i, j;
for (i = 0, j = 0; i < data->nfds; i++)
{
if (data->buf[i].fd < 0)
{
for (i = 0, j = 0; i < data->nfds; i++) {
if (data->buf[i].fd < 0) {
if (data->buf[i].buffer)
free (data->buf[i].buffer);
free(data->buf[i].buffer);
continue;
}
if (i != j)
@ -282,10 +255,10 @@ fds_cleanup (struct fd_data *data)
for (i = j; i < data->nfds; i++)
data->buf[i].fd = -1;
data->nfds = j;
logg ("$Number of file descriptors polled: %u fds\n",
(unsigned) data->nfds);
logg("$Number of file descriptors polled: %u fds\n",
(unsigned)data->nfds);
/* Shrink buffer */
newbuf = realloc (data->buf, j * sizeof (*newbuf));
newbuf = realloc(data->buf, j * sizeof(*newbuf));
if (!j)
data->buf = NULL;
else if (newbuf)
@ -293,7 +266,7 @@ fds_cleanup (struct fd_data *data)
}
static int
read_fd_data (struct fd_buf *buf)
read_fd_data(struct fd_buf *buf)
{
ssize_t n;
@ -312,69 +285,62 @@ read_fd_data (struct fd_buf *buf)
{
struct msghdr msg;
struct cmsghdr *cmsg;
union
{
unsigned char buff[CMSG_SPACE (sizeof (int))];
union {
unsigned char buff[CMSG_SPACE(sizeof(int))];
struct cmsghdr hdr;
} b;
struct iovec iov[1];
if (buf->recvfd != -1)
{
logg ("$Closing unclaimed FD: %d\n", buf->recvfd);
close (buf->recvfd);
if (buf->recvfd != -1) {
logg("$Closing unclaimed FD: %d\n", buf->recvfd);
close(buf->recvfd);
buf->recvfd = -1;
}
memset (&msg, 0, sizeof (msg));
memset(&msg, 0, sizeof(msg));
iov[0].iov_base = buf->buffer + buf->off;
iov[0].iov_len = buf->bufsize - buf->off;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_control = b.buff;
msg.msg_controllen = sizeof (b.buff);
msg.msg_controllen = sizeof(b.buff);
n = recvmsg (buf->fd, &msg, 0);
n = recvmsg(buf->fd, &msg, 0);
if (n < 0)
return -1;
if (msg.msg_flags & MSG_TRUNC)
{
logg ("^Message truncated at %d bytes\n", (int) n);
if (msg.msg_flags & MSG_TRUNC) {
logg("^Message truncated at %d bytes\n", (int)n);
return -1;
}
if (msg.msg_flags & MSG_CTRUNC)
{
if (msg.msg_flags & MSG_CTRUNC) {
if (msg.msg_controllen > 0)
logg ("^Control message truncated at %d bytes, %d data read\n", (int) msg.msg_controllen, (int) n);
logg("^Control message truncated at %d bytes, %d data read\n", (int)msg.msg_controllen, (int)n);
else
logg ("^Control message truncated, no control data received, %d bytes read"
logg("^Control message truncated, no control data received, %d bytes read"
#ifdef C_LINUX
"(Is SELinux/AppArmor enabled, and blocking file descriptor passing?)"
#endif
"\n", (int) n);
"\n",
(int)n);
return -1;
}
if (msg.msg_controllen)
{
for (cmsg = CMSG_FIRSTHDR (&msg); cmsg != NULL;
cmsg = CMSG_NXTHDR (&msg, cmsg))
{
if (cmsg->cmsg_len == CMSG_LEN (sizeof (int)) &&
if (msg.msg_controllen) {
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) &&
cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS)
{
if (buf->recvfd != -1)
{
logg ("$Unclaimed file descriptor received. closing: %d\n", buf->recvfd);
close (buf->recvfd);
cmsg->cmsg_type == SCM_RIGHTS) {
if (buf->recvfd != -1) {
logg("$Unclaimed file descriptor received. closing: %d\n", buf->recvfd);
close(buf->recvfd);
}
buf->recvfd = *(int *) CMSG_DATA (cmsg);
logg ("$Receveived a file descriptor: %d\n", buf->recvfd);
buf->recvfd = *(int *)CMSG_DATA(cmsg);
logg("$Receveived a file descriptor: %d\n", buf->recvfd);
}
}
}
}
#else
n = recv (buf->fd, buf->buffer + buf->off, buf->bufsize - buf->off, 0);
n = recv(buf->fd, buf->buffer + buf->off, buf->bufsize - buf->off, 0);
if (n < 0)
return -1;
#endif
@ -383,7 +349,7 @@ read_fd_data (struct fd_buf *buf)
}
static int
buf_init (struct fd_buf *buf, int listen_only, int timeout)
buf_init(struct fd_buf *buf, int listen_only, int timeout)
{
buf->off = 0;
buf->got_newdata = 0;
@ -396,107 +362,91 @@ buf_init (struct fd_buf *buf, int listen_only, int timeout)
buf->dumpname = NULL;
buf->group = NULL;
buf->term = '\0';
if (!listen_only)
{
if (!buf->buffer)
{
if (!listen_only) {
if (!buf->buffer) {
buf->bufsize = PATH_MAX + 8;
/* plus extra space for a \0 so we can make sure every command is \0
* terminated */
if (!(buf->buffer = malloc (buf->bufsize + 1)))
{
logg ("!add_fd: Memory allocation failed for command buffer\n");
if (!(buf->buffer = malloc(buf->bufsize + 1))) {
logg("!add_fd: Memory allocation failed for command buffer\n");
return -1;
}
}
}
else
{
} else {
if (buf->buffer)
free (buf->buffer);
free(buf->buffer);
buf->bufsize = 0;
buf->buffer = NULL;
}
if (timeout)
{
time (&buf->timeout_at);
if (timeout) {
time(&buf->timeout_at);
buf->timeout_at += timeout;
}
else
{
} else {
buf->timeout_at = 0;
}
return 0;
}
int
fds_add (struct fd_data *data, int fd, int listen_only, int timeout)
int fds_add(struct fd_data *data, int fd, int listen_only, int timeout)
{
struct fd_buf *buf;
unsigned n;
if (fd < 0)
{
logg ("!add_fd: invalid fd passed to add_fd\n");
if (fd < 0) {
logg("!add_fd: invalid fd passed to add_fd\n");
return -1;
}
/* we may already have this fd, if
* the old FD got closed, and the kernel reused the FD */
for (n = 0; n < data->nfds; n++)
if (data->buf[n].fd == fd)
{
if (data->buf[n].fd == fd) {
/* clear stale data in buffer */
if (buf_init (&data->buf[n], listen_only, timeout) < 0)
if (buf_init(&data->buf[n], listen_only, timeout) < 0)
return -1;
return 0;
}
n++;
buf = realloc (data->buf, n * sizeof (*buf));
if (!buf)
{
logg ("!add_fd: Memory allocation failed for fd_buf\n");
buf = realloc(data->buf, n * sizeof(*buf));
if (!buf) {
logg("!add_fd: Memory allocation failed for fd_buf\n");
return -1;
}
data->buf = buf;
data->nfds = n;
data->buf[n - 1].buffer = NULL;
if (buf_init (&data->buf[n - 1], listen_only, timeout) < 0)
if (buf_init(&data->buf[n - 1], listen_only, timeout) < 0)
return -1;
data->buf[n - 1].fd = fd;
return 0;
}
static inline void
fds_lock (struct fd_data *data)
fds_lock(struct fd_data *data)
{
if (data->buf_mutex)
pthread_mutex_lock (data->buf_mutex);
pthread_mutex_lock(data->buf_mutex);
}
static inline void
fds_unlock (struct fd_data *data)
fds_unlock(struct fd_data *data)
{
if (data->buf_mutex)
pthread_mutex_unlock (data->buf_mutex);
pthread_mutex_unlock(data->buf_mutex);
}
void
fds_remove (struct fd_data *data, int fd)
void fds_remove(struct fd_data *data, int fd)
{
size_t i;
fds_lock (data);
if (data->buf)
{
for (i = 0; i < data->nfds; i++)
{
if (data->buf[i].fd == fd)
{
fds_lock(data);
if (data->buf) {
for (i = 0; i < data->nfds; i++) {
if (data->buf[i].fd == fd) {
data->buf[i].fd = -1;
break;
}
}
}
fds_unlock (data);
fds_unlock(data);
}
#define BUFFSIZE 1024
@ -509,8 +459,7 @@ fds_remove (struct fd_data *data, int fd)
* Must be called with buf_mutex lock held.
*/
/* TODO: handle ReadTimeout */
int
fds_poll_recv (struct fd_data *data, int timeout, int check_signals,
int fds_poll_recv(struct fd_data *data, int timeout, int check_signals,
void *event)
{
unsigned fdsok = data->nfds;
@ -521,33 +470,28 @@ fds_poll_recv (struct fd_data *data, int timeout, int check_signals,
UNUSEDPARAM(event);
/* we must have at least one fd, the control fd! */
fds_cleanup (data);
fds_cleanup(data);
#ifndef _WIN32
if (!data->nfds)
return 0;
#endif
for (i = 0; i < data->nfds; i++)
{
for (i = 0; i < data->nfds; i++) {
data->buf[i].got_newdata = 0;
}
time (&now);
time(&now);
if (timeout > 0)
closest_timeout = now + timeout;
else
closest_timeout = 0;
for (i = 0; i < data->nfds; i++)
{
for (i = 0; i < data->nfds; i++) {
time_t timeout_at = data->buf[i].timeout_at;
if (timeout_at && timeout_at < now)
{
if (timeout_at && timeout_at < now) {
/* timed out */
data->buf[i].got_newdata = -2;
/* we must return immediately from poll/select, we have a timeout! */
closest_timeout = now;
}
else
{
} else {
if (!closest_timeout)
closest_timeout = timeout_at;
else if (timeout_at && timeout_at < closest_timeout)
@ -559,7 +503,7 @@ fds_poll_recv (struct fd_data *data, int timeout, int check_signals,
else
timeout = -1;
if (timeout > 0)
logg ("$fds_poll_recv: timeout after %d seconds\n", timeout);
logg("$fds_poll_recv: timeout after %d seconds\n", timeout);
#ifdef HAVE_POLL
/* Use poll() if available, preferred because:
* - can poll any number of FDs
@ -569,65 +513,56 @@ fds_poll_recv (struct fd_data *data, int timeout, int check_signals,
* recv() may still block according to the manpage
*/
if (realloc_polldata (data) == -1)
if (realloc_polldata(data) == -1)
return -1;
if (timeout > 0)
{
if (timeout > 0) {
/* seconds to ms */
timeout *= 1000;
}
for (i = 0; i < data->nfds; i++)
{
for (i = 0; i < data->nfds; i++) {
data->poll_data[i].fd = data->buf[i].fd;
data->poll_data[i].events = POLLIN;
data->poll_data[i].revents = 0;
}
do
{
do {
int n = data->nfds;
fds_unlock (data);
fds_unlock(data);
#ifdef _WIN32
retval = poll_with_event (data->poll_data, n, timeout, event);
retval = poll_with_event(data->poll_data, n, timeout, event);
#else
retval = poll (data->poll_data, n, timeout);
retval = poll(data->poll_data, n, timeout);
#endif
fds_lock (data);
fds_lock(data);
if (retval > 0)
{
if (retval > 0) {
fdsok = 0;
/* nfds may change during poll, but not
* poll_data_nfds */
for (i = 0; i < data->poll_data_nfds; i++)
{
for (i = 0; i < data->poll_data_nfds; i++) {
short revents;
if (data->buf[i].fd < 0)
continue;
if (data->buf[i].fd != data->poll_data[i].fd)
{
if (data->buf[i].fd != data->poll_data[i].fd) {
/* should never happen */
logg ("!poll_recv_fds FD mismatch\n");
logg("!poll_recv_fds FD mismatch\n");
continue;
}
revents = data->poll_data[i].revents;
if (revents & (POLLIN | POLLHUP))
{
logg ("$Received POLLIN|POLLHUP on fd %d\n",
if (revents & (POLLIN | POLLHUP)) {
logg("$Received POLLIN|POLLHUP on fd %d\n",
data->poll_data[i].fd);
}
#ifndef _WIN32
if (revents & POLLHUP)
{
if (revents & POLLHUP) {
/* avoid SHUT_WR problem on Mac OS X */
int ret = send (data->poll_data[i].fd, &n, 0, 0);
int ret = send(data->poll_data[i].fd, &n, 0, 0);
if (!ret || (ret == -1 && errno == EINTR))
revents &= ~POLLHUP;
}
#endif
if (revents & POLLIN)
{
int ret = read_fd_data (&data->buf[i]);
if (revents & POLLIN) {
int ret = read_fd_data(&data->buf[i]);
/* Data available to be read */
if (ret == -1)
revents |= POLLERR;
@ -635,168 +570,139 @@ fds_poll_recv (struct fd_data *data, int timeout, int check_signals,
revents = POLLHUP;
}
if (revents & (POLLHUP | POLLERR | POLLNVAL))
{
if (revents & (POLLHUP | POLLNVAL))
{
if (revents & (POLLHUP | POLLERR | POLLNVAL)) {
if (revents & (POLLHUP | POLLNVAL)) {
/* remote disconnected */
logg ("*Client disconnected (FD %d)\n",
logg("*Client disconnected (FD %d)\n",
data->poll_data[i].fd);
}
else
{
} else {
/* error on file descriptor */
logg ("^Error condition on fd %d\n",
logg("^Error condition on fd %d\n",
data->poll_data[i].fd);
}
data->buf[i].got_newdata = -1;
}
else
{
} else {
fdsok++;
}
}
}
}
while (retval == -1 && !check_signals && errno == EINTR);
} while (retval == -1 && !check_signals && errno == EINTR);
#else
{
fd_set rfds;
struct timeval tv;
int maxfd = -1;
for (i = 0; i < data->nfds; i++)
{
for (i = 0; i < data->nfds; i++) {
int fd = data->buf[i].fd;
if (fd >= FD_SETSIZE)
{
logg ("!File descriptor is too high for FD_SET\n");
if (fd >= FD_SETSIZE) {
logg("!File descriptor is too high for FD_SET\n");
return -1;
}
maxfd = MAX (maxfd, fd);
maxfd = MAX(maxfd, fd);
}
do
{
FD_ZERO (&rfds);
for (i = 0; i < data->nfds; i++)
{
do {
FD_ZERO(&rfds);
for (i = 0; i < data->nfds; i++) {
int fd = data->buf[i].fd;
if (fd >= 0)
FD_SET (fd, &rfds);
FD_SET(fd, &rfds);
}
tv.tv_sec = timeout;
tv.tv_usec = 0;
fds_unlock (data);
fds_unlock(data);
retval =
select (maxfd + 1, &rfds, NULL, NULL,
select(maxfd + 1, &rfds, NULL, NULL,
timeout >= 0 ? &tv : NULL);
fds_lock (data);
if (retval > 0)
{
fds_lock(data);
if (retval > 0) {
fdsok = data->nfds;
for (i = 0; i < data->nfds; i++)
{
if (data->buf[i].fd < 0)
{
for (i = 0; i < data->nfds; i++) {
if (data->buf[i].fd < 0) {
fdsok--;
continue;
}
if (FD_ISSET (data->buf[i].fd, &rfds))
{
int ret = read_fd_data (&data->buf[i]);
if (ret == -1 || !ret)
{
if (FD_ISSET(data->buf[i].fd, &rfds)) {
int ret = read_fd_data(&data->buf[i]);
if (ret == -1 || !ret) {
if (ret == -1)
logg ("!Error condition on fd %d\n",
logg("!Error condition on fd %d\n",
data->buf[i].fd);
else
{
else {
/* avoid SHUT_WR problem on Mac OS X */
int ret = send (data->buf[i].fd, &i, 0, 0);
int ret = send(data->buf[i].fd, &i, 0, 0);
if (!ret || (ret == -1 && errno == EINTR))
continue;
logg ("*Client disconnected\n");
logg("*Client disconnected\n");
}
data->buf[i].got_newdata = -1;
}
}
}
}
if (retval < 0 && errno == EBADF)
{
if (retval < 0 && errno == EBADF) {
/* unlike poll(), select() won't tell us which FD is bad, so
* we have to check them one by one. */
tv.tv_sec = 0;
tv.tv_usec = 0;
/* with tv == 0 it doesn't check for EBADF */
FD_ZERO (&rfds);
for (i = 0; i < data->nfds; i++)
{
FD_ZERO(&rfds);
for (i = 0; i < data->nfds; i++) {
if (data->buf[i].fd == -1)
continue;
FD_SET (data->buf[i].fd, &rfds);
do
{
FD_SET(data->buf[i].fd, &rfds);
do {
retval =
select (data->buf[i].fd + 1, &rfds, NULL, NULL,
select(data->buf[i].fd + 1, &rfds, NULL, NULL,
&tv);
}
while (retval == -1 && errno == EINTR);
if (retval == -1)
{
} while (retval == -1 && errno == EINTR);
if (retval == -1) {
data->buf[i].fd = -1;
}
else
{
FD_CLR (data->buf[i].fd, &rfds);
} else {
FD_CLR(data->buf[i].fd, &rfds);
}
}
retval = -1;
errno = EINTR;
continue;
}
}
while (retval == -1 && !check_signals && errno == EINTR);
} while (retval == -1 && !check_signals && errno == EINTR);
}
#endif
if (retval == -1 && errno != EINTR)
{
if (retval == -1 && errno != EINTR) {
char err[128];
#ifdef HAVE_POLL
logg ("!poll_recv_fds: poll failed: %s\n",
cli_strerror (errno, err, sizeof (err)));
logg("!poll_recv_fds: poll failed: %s\n",
cli_strerror(errno, err, sizeof(err)));
#else
logg ("!poll_recv_fds: select failed: %s\n",
cli_strerror (errno, err, sizeof (err)));
logg("!poll_recv_fds: select failed: %s\n",
cli_strerror(errno, err, sizeof(err)));
#endif
}
return retval;
}
void
fds_free (struct fd_data *data)
void fds_free(struct fd_data *data)
{
unsigned i;
fds_lock (data);
for (i = 0; i < data->nfds; i++)
{
if (data->buf[i].buffer)
{
free (data->buf[i].buffer);
fds_lock(data);
for (i = 0; i < data->nfds; i++) {
if (data->buf[i].buffer) {
free(data->buf[i].buffer);
}
}
if (data->buf)
free (data->buf);
free(data->buf);
#ifdef HAVE_POLL
if (data->poll_data)
free (data->poll_data);
free(data->poll_data);
#endif
data->buf = NULL;
data->nfds = 0;
fds_unlock (data);
fds_unlock(data);
}

View file

@ -69,9 +69,15 @@ struct fd_data {
};
#ifdef HAVE_POLL
#define FDS_INIT(mutex) { (mutex), NULL, 0, NULL, 0}
#define FDS_INIT(mutex) \
{ \
(mutex), NULL, 0, NULL, 0 \
}
#else
#define FDS_INIT(mutex) { (mutex), NULL, 0}
#define FDS_INIT(mutex) \
{ \
(mutex), NULL, 0 \
}
#endif
int poll_fd(int fd, int timeout_sec, int check_signals);

View file

@ -127,7 +127,7 @@ void clamd_virus_found_cb(int fd, const char *virname, void *ctx)
if (virname) {
d->infected++;
conn_reply_virus(d->conn, fname, virname);
if(c->virsize > 0 && optget(d->opts, "ExtendedDetectionInfo")->enabled)
if (c->virsize > 0 && optget(d->opts, "ExtendedDetectionInfo")->enabled)
logg("~%s: %s(%s:%llu) FOUND\n", fname, virname, c->virhash, c->virsize);
logg("~%s: %s FOUND\n", fname, virname);
}
@ -195,13 +195,13 @@ int scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_rea
/* check whether the file is excluded */
#ifdef C_LINUX
if(procdev && sb && (sb->st_dev == procdev)) {
if (procdev && sb && (sb->st_dev == procdev)) {
free(filename);
return CL_SUCCESS;
}
#endif
if(sb && sb->st_size == 0) { /* empty file */
if (sb && sb->st_size == 0) { /* empty file */
if (msg == scandata->toplevel_path)
conn_reply_single(scandata->conn, filename, "Empty file");
free(filename);
@ -209,8 +209,8 @@ int scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_rea
}
if (type == TYPE_MULTISCAN) {
client_conn_t *client_conn = (client_conn_t *) calloc(1, sizeof(struct client_conn_tag));
if(client_conn) {
client_conn_t *client_conn = (client_conn_t *)calloc(1, sizeof(struct client_conn_tag));
if (client_conn) {
client_conn->scanfd = -1;
client_conn->sd = scandata->odesc;
client_conn->filename = filename;
@ -219,7 +219,7 @@ int scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_rea
client_conn->options = scandata->options;
client_conn->opts = scandata->opts;
client_conn->group = scandata->group;
if(cl_engine_addref(scandata->engine)) {
if (cl_engine_addref(scandata->engine)) {
logg("!cl_engine_addref() failed\n");
free(filename);
free(client_conn);
@ -229,7 +229,7 @@ int scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_rea
pthread_mutex_lock(&reload_mutex);
client_conn->engine_timestamp = reloaded_time;
pthread_mutex_unlock(&reload_mutex);
if(!thrmgr_group_dispatch(scandata->thr_pool, scandata->group, client_conn, 1)) {
if (!thrmgr_group_dispatch(scandata->thr_pool, scandata->group, client_conn, 1)) {
logg("!thread dispatch failed\n");
cl_engine_free(scandata->engine);
free(filename);
@ -278,7 +278,7 @@ int scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_rea
if (ret == CL_VIRUS) {
if (scandata->options->general & CL_SCAN_GENERAL_ALLMATCHES || (scandata->infected && scandata->options->general & CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE)) {
if(optget(scandata->opts, "PreludeEnable")->enabled){
if (optget(scandata->opts, "PreludeEnable")->enabled) {
prelude_logging(filename, virname, context.virhash, context.virsize);
}
virusaction(filename, virname, scandata->opts);
@ -288,11 +288,11 @@ int scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_rea
free(filename);
return CL_ETIMEOUT;
}
if(optget(scandata->opts, "PreludeEnable")->enabled){
if (optget(scandata->opts, "PreludeEnable")->enabled) {
prelude_logging(filename, virname, context.virhash, context.virsize);
}
if(context.virsize && optget(scandata->opts, "ExtendedDetectionInfo")->enabled)
if (context.virsize && optget(scandata->opts, "ExtendedDetectionInfo")->enabled)
logg("~%s: %s(%s:%llu) FOUND\n", filename, virname, context.virhash, context.virsize);
else
logg("~%s: %s FOUND\n", filename, virname);
@ -311,7 +311,7 @@ int scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_rea
free(filename);
if(ret == CL_EMEM) /* stop scanning */
if (ret == CL_EMEM) /* stop scanning */
return ret;
if (type == TYPE_SCAN) {
@ -329,21 +329,21 @@ int scan_pathchk(const char *path, struct cli_ftw_cbdata *data)
const struct optstruct *opt;
STATBUF statbuf;
if((opt = optget(scandata->opts, "ExcludePath"))->enabled) {
while(opt) {
if(match_regex(path, opt->strarg) == 1) {
if(scandata->type != TYPE_MULTISCAN)
if ((opt = optget(scandata->opts, "ExcludePath"))->enabled) {
while (opt) {
if (match_regex(path, opt->strarg) == 1) {
if (scandata->type != TYPE_MULTISCAN)
conn_reply_single(scandata->conn, path, "Excluded");
return 1;
}
opt = (const struct optstruct *) opt->nextarg;
opt = (const struct optstruct *)opt->nextarg;
}
}
if(!optget(scandata->opts, "CrossFilesystems")->enabled) {
if(CLAMSTAT(path, &statbuf) == 0) {
if(statbuf.st_dev != scandata->dev) {
if(scandata->type != TYPE_MULTISCAN)
if (!optget(scandata->opts, "CrossFilesystems")->enabled) {
if (CLAMSTAT(path, &statbuf) == 0) {
if (statbuf.st_dev != scandata->dev) {
if (scandata->type != TYPE_MULTISCAN)
conn_reply_single(scandata->conn, path, "Excluded (another filesystem)");
return 1;
}
@ -367,14 +367,14 @@ int scanfd(
STATBUF statbuf;
struct cb_context context;
char fdstr[32];
const char*reply_fdstr;
const char *reply_fdstr;
UNUSEDPARAM(odesc);
if (stream) {
struct sockaddr_in sa;
socklen_t salen = sizeof(sa);
if(getpeername(conn->sd, (struct sockaddr *)&sa, &salen) || salen > sizeof(sa) || sa.sin_family != AF_INET)
if (getpeername(conn->sd, (struct sockaddr *)&sa, &salen) || salen > sizeof(sa) || sa.sin_family != AF_INET)
strncpy(fdstr, "instream(local)", sizeof(fdstr));
else
snprintf(fdstr, sizeof(fdstr), "instream(%s@%u)", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
@ -383,7 +383,7 @@ int scanfd(
snprintf(fdstr, sizeof(fdstr), "fd[%d]", fd);
reply_fdstr = fdstr;
}
if(FSTAT(fd, &statbuf) == -1 || !S_ISREG(statbuf.st_mode)) {
if (FSTAT(fd, &statbuf) == -1 || !S_ISREG(statbuf.st_mode)) {
logg("%s: Not a regular file. ERROR\n", fdstr);
if (conn_reply(conn, reply_fdstr, "Not a regular file", "ERROR") == -1)
return CL_ETIMEOUT;
@ -402,22 +402,22 @@ int scanfd(
return ret == CL_ETIMEOUT ? ret : CL_BREAK;
}
if(ret == CL_VIRUS) {
if (ret == CL_VIRUS) {
if (conn_reply_virus(conn, reply_fdstr, virname) == -1)
ret = CL_ETIMEOUT;
if(context.virsize && optget(opts, "ExtendedDetectionInfo")->enabled)
if (context.virsize && optget(opts, "ExtendedDetectionInfo")->enabled)
logg("%s: %s(%s:%llu) FOUND\n", fdstr, virname, context.virhash, context.virsize);
else
logg("%s: %s FOUND\n", fdstr, virname);
virusaction(reply_fdstr, virname, opts);
} else if(ret != CL_CLEAN) {
} else if (ret != CL_CLEAN) {
if (conn_reply(conn, reply_fdstr, cl_strerror(ret), "ERROR") == -1)
ret = CL_ETIMEOUT;
logg("%s: %s ERROR\n", fdstr, cl_strerror(ret));
} else {
if (conn_reply_single(conn, reply_fdstr, "OK") == CL_ETIMEOUT)
ret = CL_ETIMEOUT;
if(logok)
if (logok)
logg("%s: OK\n", fdstr);
}
return ret;
@ -445,7 +445,6 @@ int scanstream(
socklen_t addrlen;
char *tmpname;
min_port = optget(opts, "StreamMinPort")->numarg;
max_port = optget(opts, "StreamMaxPort")->numarg;
@ -455,15 +454,15 @@ int scanstream(
for (portscan = 0; portscan < 1000; portscan++) {
port = (port - 1) % (max_port - min_port + 1);
memset((char *) &server, 0, sizeof(server));
memset((char *)&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(min_port + port);
server.sin_addr.s_addr = htonl(INADDR_ANY);
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
continue;
if(bind(sockfd, (struct sockaddr *) &server, (socklen_t)sizeof(struct sockaddr_in)) == -1)
if (bind(sockfd, (struct sockaddr *)&server, (socklen_t)sizeof(struct sockaddr_in)) == -1)
closesocket(sockfd);
else {
bound = 1;
@ -475,7 +474,7 @@ int scanstream(
timeout = optget(opts, "ReadTimeout")->numarg;
firsttimeout = optget(opts, "CommandReadTimeout")->numarg;
if(!bound) {
if (!bound) {
logg("!ScanStream: Can't find any free port.\n");
mdprintf(odesc, "Can't find any free port. ERROR%c", term);
return -1;
@ -485,7 +484,7 @@ int scanstream(
closesocket(sockfd);
return -1;
}
if(mdprintf(odesc, "PORT %u%c", port, term) <= 0) {
if (mdprintf(odesc, "PORT %u%c", port, term) <= 0) {
logg("!ScanStream: error transmitting port.\n");
closesocket(sockfd);
return -1;
@ -502,7 +501,7 @@ int scanstream(
}
addrlen = sizeof(peer);
if((acceptd = accept(sockfd, (struct sockaddr *) &peer, (socklen_t *)&addrlen)) == -1) {
if ((acceptd = accept(sockfd, (struct sockaddr *)&peer, (socklen_t *)&addrlen)) == -1) {
closesocket(sockfd);
mdprintf(odesc, "accept() ERROR%c", term);
logg("!ScanStream %u: accept() failed.\n", port);
@ -513,7 +512,7 @@ int scanstream(
inet_ntop(peer.sin_family, &peer.sin_addr, peer_addr, sizeof(peer_addr));
logg("*Accepted connection from %s on port %u, fd %d\n", peer_addr, port, acceptd);
if(cli_gentempfd(optget(opts, "TemporaryDirectory")->strarg, &tmpname, &tmpd)) {
if (cli_gentempfd(optget(opts, "TemporaryDirectory")->strarg, &tmpname, &tmpd)) {
shutdown(sockfd, 2);
closesocket(sockfd);
closesocket(acceptd);
@ -524,7 +523,7 @@ int scanstream(
quota = maxsize = optget(opts, "StreamMaxLength")->numarg;
while((retval = poll_fd(acceptd, timeout, 0)) == 1) {
while ((retval = poll_fd(acceptd, timeout, 0)) == 1) {
/* only read up to max */
btread = (maxsize && (quota < sizeof(buff))) ? quota : sizeof(buff);
if (!btread) {
@ -532,26 +531,26 @@ int scanstream(
break; /* Scan what we have */
}
bread = recv(acceptd, buff, btread, 0);
if(bread <= 0)
if (bread <= 0)
break;
quota -= bread;
if(writen(tmpd, buff, bread) != bread) {
if (writen(tmpd, buff, bread) != bread) {
shutdown(sockfd, 2);
closesocket(sockfd);
closesocket(acceptd);
mdprintf(odesc, "Temporary file -> write ERROR%c", term);
logg("!ScanStream(%s@%u): Can't write to temporary file.\n", peer_addr, port);
close(tmpd);
if(!optget(opts, "LeaveTemporaryFiles")->enabled)
if (!optget(opts, "LeaveTemporaryFiles")->enabled)
unlink(tmpname);
free(tmpname);
return -1;
}
}
switch(retval) {
switch (retval) {
case 0: /* timeout */
mdprintf(odesc, "read timeout ERROR%c", term);
logg("!ScanStream(%s@%u): read timeout.\n", peer_addr, port);
@ -562,7 +561,7 @@ int scanstream(
break;
}
if(retval == 1) {
if (retval == 1) {
lseek(tmpd, 0, SEEK_SET);
thrmgr_setactivetask(peer_addr, NULL);
context.filename = peer_addr;
@ -574,15 +573,15 @@ int scanstream(
ret = -1;
}
close(tmpd);
if(!optget(opts, "LeaveTemporaryFiles")->enabled)
if (!optget(opts, "LeaveTemporaryFiles")->enabled)
unlink(tmpname);
free(tmpname);
closesocket(acceptd);
closesocket(sockfd);
if(ret == CL_VIRUS) {
if(context.virsize && optget(opts, "ExtendedDetectionInfo")->enabled) {
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("stream(%s@%u): %s(%s:%llu) FOUND\n", peer_addr, port, virname, context.virhash, context.virsize);
} else {
@ -590,14 +589,14 @@ int scanstream(
logg("stream(%s@%u): %s FOUND\n", peer_addr, port, virname);
}
virusaction("stream", virname, opts);
} else if(ret != CL_CLEAN) {
if(retval == 1) {
} else if (ret != CL_CLEAN) {
if (retval == 1) {
mdprintf(odesc, "stream: %s ERROR%c", cl_strerror(ret), term);
logg("stream(%s@%u): %s ERROR\n", peer_addr, port, cl_strerror(ret));
}
} else {
mdprintf(odesc, "stream: OK%c", term);
if(logok)
if (logok)
logg("stream(%s@%u): OK\n", peer_addr, port);
}

View file

@ -30,7 +30,10 @@
#include "thrmgr.h"
#include "session.h"
enum scan_type { TYPE_INIT = -1, TYPE_SCAN = 0, TYPE_CONTSCAN = 1, TYPE_MULTISCAN = 2 };
enum scan_type { TYPE_INIT = -1,
TYPE_SCAN = 0,
TYPE_CONTSCAN = 1,
TYPE_MULTISCAN = 2 };
struct scan_cb_data {
int scantype;

View file

@ -79,12 +79,12 @@ void *event_wake_accept = NULL;
static void scanner_thread(void *arg)
{
client_conn_t *conn = (client_conn_t *) arg;
client_conn_t *conn = (client_conn_t *)arg;
#ifndef _WIN32
sigset_t sigset;
#endif
int ret;
int virus=0, errors = 0;
int virus = 0, errors = 0;
#ifndef _WIN32
/* ignore all signals */
@ -116,8 +116,7 @@ static void scanner_thread(void *arg)
if (conn->filename)
free(conn->filename);
logg("$Finished scanthread\n");
if (thrmgr_group_finished(conn->group, virus ? EXIT_OTHER :
errors ? EXIT_ERROR : EXIT_OK)) {
if (thrmgr_group_finished(conn->group, virus ? EXIT_OTHER : errors ? EXIT_ERROR : EXIT_OK)) {
logg("$Scanthread: connection shut down (FD %d)\n", conn->sd);
/* close connection if we were last in group */
shutdown(conn->sd, 2);
@ -133,7 +132,7 @@ static int syncpipe_wake_recv_w = -1;
void sighandler_th(int sig)
{
int action = 0;
switch(sig) {
switch (sig) {
case SIGINT:
case SIGTERM:
progexit = 1;
@ -171,13 +170,13 @@ static struct cl_engine *reload_db(struct cl_engine *engine, unsigned int dbopti
struct cl_settings *settings = NULL;
*ret = 0;
if(do_check) {
if(!dbstat.entries) {
if (do_check) {
if (!dbstat.entries) {
logg("No stats for Database check - forcing reload\n");
return engine;
}
if(cl_statchkdir(&dbstat) == 1) {
if (cl_statchkdir(&dbstat) == 1) {
logg("SelfCheck: Database modification detected. Forcing reload.\n");
return engine;
} else {
@ -187,10 +186,10 @@ static struct cl_engine *reload_db(struct cl_engine *engine, unsigned int dbopti
}
/* release old structure */
if(engine) {
if (engine) {
/* copy current settings */
settings = cl_engine_settings_copy(engine);
if(!settings)
if (!settings)
logg("^Can't make a copy of the current engine settings\n");
thrmgr_setactiveengine(NULL);
@ -200,43 +199,43 @@ static struct cl_engine *reload_db(struct cl_engine *engine, unsigned int dbopti
dbdir = optget(opts, "DatabaseDirectory")->strarg;
logg("Reading databases from %s\n", dbdir);
if(dbstat.entries)
if (dbstat.entries)
cl_statfree(&dbstat);
memset(&dbstat, 0, sizeof(struct cl_stat));
if((retval = cl_statinidir(dbdir, &dbstat))) {
if ((retval = cl_statinidir(dbdir, &dbstat))) {
logg("!cl_statinidir() failed: %s\n", cl_strerror(retval));
*ret = 1;
if(settings)
if (settings)
cl_engine_settings_free(settings);
return NULL;
}
if(!(engine = cl_engine_new())) {
if (!(engine = cl_engine_new())) {
logg("!Can't initialize antivirus engine\n");
*ret = 1;
if(settings)
if (settings)
cl_engine_settings_free(settings);
return NULL;
}
if(settings) {
if (settings) {
retval = cl_engine_settings_apply(engine, settings);
if(retval != CL_SUCCESS) {
if (retval != CL_SUCCESS) {
logg("^Can't apply previous engine settings: %s\n", cl_strerror(retval));
logg("^Using default engine settings\n");
}
cl_engine_settings_free(settings);
}
if((retval = cl_load(dbdir, engine, &sigs, dboptions))) {
if ((retval = cl_load(dbdir, engine, &sigs, dboptions))) {
logg("!reload db failed: %s\n", cl_strerror(retval));
cl_engine_free(engine);
*ret = 1;
return NULL;
}
if((retval = cl_engine_compile(engine)) != 0) {
if ((retval = cl_engine_compile(engine)) != 0) {
logg("!Database initialization error: can't compile engine: %s\n", cl_strerror(retval));
cl_engine_free(engine);
*ret = 1;
@ -300,7 +299,7 @@ static const char *get_cmd(struct fd_buf *buf, size_t off, size_t *len, char *te
}
}
int statinidir_th(const char* dirname)
int statinidir_th(const char *dirname)
{
if (!dbstat.entries) {
memset(&dbstat, 0, sizeof(dbstat));
@ -319,13 +318,19 @@ struct acceptdata {
int syncpipe_wake_accept[2];
};
#define ACCEPTDATA_INIT(mutex1, mutex2) { FDS_INIT(mutex1), FDS_INIT(mutex2), PTHREAD_COND_INITIALIZER, 0, 0, {-1, -1}, {-1, -1}}
#define ACCEPTDATA_INIT(mutex1, mutex2) \
{ \
FDS_INIT(mutex1), FDS_INIT(mutex2), PTHREAD_COND_INITIALIZER, 0, 0, {-1, -1}, \
{ \
-1, -1 \
} \
}
static void *acceptloop_th(void *arg)
{
char buff[BUFFSIZE + 1];
size_t i;
struct acceptdata *data = (struct acceptdata*)arg;
struct acceptdata *data = (struct acceptdata *)arg;
struct fd_data *fds = &data->fds;
struct fd_data *recv_fds = &data->recv_fds;
int max_queue = data->max_queue;
@ -354,7 +359,7 @@ static void *acceptloop_th(void *arg)
}
/* accept() loop */
for (i=0;i < fds->nfds && new_sd >= 0; i++) {
for (i = 0; i < fds->nfds && new_sd >= 0; i++) {
struct fd_buf *buf = &fds->buf[i];
if (!buf->got_newdata)
continue;
@ -380,7 +385,7 @@ static void *acceptloop_th(void *arg)
pthread_mutex_lock(recv_fds->buf_mutex);
while (recv_fds->nfds > (unsigned)max_queue) {
pthread_mutex_lock(&exit_mutex);
if(progexit) {
if (progexit) {
pthread_mutex_unlock(&exit_mutex);
break;
}
@ -390,7 +395,7 @@ static void *acceptloop_th(void *arg)
pthread_mutex_unlock(recv_fds->buf_mutex);
pthread_mutex_lock(&exit_mutex);
if(progexit) {
if (progexit) {
pthread_mutex_unlock(&exit_mutex);
break;
}
@ -445,7 +450,6 @@ static void *acceptloop_th(void *arg)
/* give the poll loop a chance to close disconnected FDs */
break;
}
}
/* handle progexit */
@ -458,11 +462,9 @@ static void *acceptloop_th(void *arg)
}
pthread_mutex_unlock(fds->buf_mutex);
if (sd_listen_fds(0) == 0)
{
if (sd_listen_fds(0) == 0) {
/* only close the sockets, when not using systemd socket activation */
for (i=0;i < fds->nfds; i++)
{
for (i = 0; i < fds->nfds; i++) {
if (fds->buf[i].fd == -1)
continue;
logg("$Shutdown: closed fd %d\n", fds->buf[i].fd);
@ -486,7 +488,7 @@ static void *acceptloop_th(void *arg)
return NULL;
}
static const char* parse_dispatch_cmd(client_conn_t *conn, struct fd_buf *buf, size_t *ppos, int *error, const struct optstruct *opts, int readtimeout)
static const char *parse_dispatch_cmd(client_conn_t *conn, struct fd_buf *buf, size_t *ppos, int *error, const struct optstruct *opts, int readtimeout)
{
const char *cmd = NULL;
int rc;
@ -528,7 +530,7 @@ static const char* parse_dispatch_cmd(client_conn_t *conn, struct fd_buf *buf, s
if ((rc = execute_or_dispatch_command(conn, cmdtype, argument)) < 0) {
logg("!Command dispatch failed\n");
if(rc == -1 && optget(opts, "ExitOnOOM")->enabled) {
if (rc == -1 && optget(opts, "ExitOnOOM")->enabled) {
pthread_mutex_lock(&exit_mutex);
progexit = 1;
pthread_mutex_unlock(&exit_mutex);
@ -582,7 +584,7 @@ static const char* parse_dispatch_cmd(client_conn_t *conn, struct fd_buf *buf, s
/* we received a command, set readtimeout */
time(&buf->timeout_at);
buf->timeout_at += readtimeout;
pos += cmdlen+1;
pos += cmdlen + 1;
if (conn->mode == MODE_STREAM) {
/* TODO: this doesn't belong here */
buf->dumpname = conn->filename;
@ -611,7 +613,7 @@ static const char* parse_dispatch_cmd(client_conn_t *conn, struct fd_buf *buf, s
if (!*error) {
/* move partial command to beginning of buffer */
if (pos < buf->off) {
memmove (buf->buffer, &buf->buffer[pos], buf->off - pos);
memmove(buf->buffer, &buf->buffer[pos], buf->off - pos);
buf->off -= pos;
} else
buf->off = 0;
@ -640,7 +642,7 @@ static int handle_stream(client_conn_t *conn, struct fd_buf *buf, const struct o
while (pos <= buf->off) {
if (!buf->chunksize) {
/* read chunksize */
if (buf->off-pos >= 4) {
if (buf->off - pos >= 4) {
uint32_t cs;
memmove(&cs, buf->buffer + pos, 4);
pos += 4;
@ -658,14 +660,14 @@ static int handle_stream(client_conn_t *conn, struct fd_buf *buf, const struct o
buf->dumpname = NULL;
if ((rc = execute_or_dispatch_command(conn, COMMAND_INSTREAMSCAN, NULL)) < 0) {
logg("!Command dispatch failed\n");
if(rc == -1 && optget(opts, "ExitOnOOM")->enabled) {
if (rc == -1 && optget(opts, "ExitOnOOM")->enabled) {
pthread_mutex_lock(&exit_mutex);
progexit = 1;
pthread_mutex_unlock(&exit_mutex);
}
*error = 1;
} else {
memmove (buf->buffer, &buf->buffer[pos], buf->off - pos);
memmove(buf->buffer, &buf->buffer[pos], buf->off - pos);
buf->off -= pos;
*ppos = 0;
buf->id++;
@ -685,7 +687,7 @@ static int handle_stream(client_conn_t *conn, struct fd_buf *buf, const struct o
logg("$Quota Remaining: %lu\n", buf->quota);
} else {
/* need more data, so return and wait for some */
memmove (buf->buffer, &buf->buffer[pos], buf->off - pos);
memmove(buf->buffer, &buf->buffer[pos], buf->off - pos);
buf->off -= pos;
*ppos = 0;
return -1;
@ -755,66 +757,66 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
memset(&options, 0, sizeof(struct cl_scan_options));
/* set up limits */
if((opt = optget(opts, "MaxScanSize"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_SCANSIZE, opt->numarg))) {
if ((opt = optget(opts, "MaxScanSize"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_SCANSIZE, opt->numarg))) {
logg("!cl_engine_set_num(CL_ENGINE_MAX_SCANSIZE) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
}
}
val = cl_engine_get_num(engine, CL_ENGINE_MAX_SCANSIZE, NULL);
if(val)
if (val)
logg("Limits: Global size limit set to %llu bytes.\n", val);
else
logg("^Limits: Global size limit protection disabled.\n");
if((opt = optget(opts, "MaxFileSize"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_FILESIZE, opt->numarg))) {
if ((opt = optget(opts, "MaxFileSize"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_FILESIZE, opt->numarg))) {
logg("!cl_engine_set_num(CL_ENGINE_MAX_FILESIZE) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
}
}
val = cl_engine_get_num(engine, CL_ENGINE_MAX_FILESIZE, NULL);
if(val)
if (val)
logg("Limits: File size limit set to %llu bytes.\n", val);
else
logg("^Limits: File size limit protection disabled.\n");
#ifndef _WIN32
if(getrlimit(RLIMIT_FSIZE, &rlim) == 0) {
if(rlim.rlim_cur < (rlim_t) cl_engine_get_num(engine, CL_ENGINE_MAX_FILESIZE, NULL))
if (getrlimit(RLIMIT_FSIZE, &rlim) == 0) {
if (rlim.rlim_cur < (rlim_t)cl_engine_get_num(engine, CL_ENGINE_MAX_FILESIZE, NULL))
logg("^System limit for file size is lower than engine->maxfilesize\n");
if(rlim.rlim_cur < (rlim_t) cl_engine_get_num(engine, CL_ENGINE_MAX_SCANSIZE, NULL))
if (rlim.rlim_cur < (rlim_t)cl_engine_get_num(engine, CL_ENGINE_MAX_SCANSIZE, NULL))
logg("^System limit for file size is lower than engine->maxscansize\n");
} else {
logg("^Cannot obtain resource limits for file size\n");
}
#endif
if((opt = optget(opts, "MaxRecursion"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_RECURSION, opt->numarg))) {
if ((opt = optget(opts, "MaxRecursion"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_RECURSION, opt->numarg))) {
logg("!cl_engine_set_num(CL_ENGINE_MAX_RECURSION) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
}
}
val = cl_engine_get_num(engine, CL_ENGINE_MAX_RECURSION, NULL);
if(val)
logg("Limits: Recursion level limit set to %u.\n", (unsigned int) val);
if (val)
logg("Limits: Recursion level limit set to %u.\n", (unsigned int)val);
else
logg("^Limits: Recursion level limit protection disabled.\n");
if((opt = optget(opts, "MaxFiles"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_FILES, opt->numarg))) {
if ((opt = optget(opts, "MaxFiles"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_FILES, opt->numarg))) {
logg("!cl_engine_set_num(CL_ENGINE_MAX_FILES) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
}
}
val = cl_engine_get_num(engine, CL_ENGINE_MAX_FILES, NULL);
if(val)
logg("Limits: Files limit set to %u.\n", (unsigned int) val);
if (val)
logg("Limits: Files limit set to %u.\n", (unsigned int)val);
else
logg("^Limits: Files limit protection disabled.\n");
@ -826,8 +828,8 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
/* Engine max sizes */
if((opt = optget(opts, "MaxEmbeddedPE"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_EMBEDDEDPE, opt->numarg))) {
if ((opt = optget(opts, "MaxEmbeddedPE"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_EMBEDDEDPE, opt->numarg))) {
logg("!cli_engine_set_num(CL_ENGINE_MAX_EMBEDDEDPE) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
@ -836,8 +838,8 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
val = cl_engine_get_num(engine, CL_ENGINE_MAX_EMBEDDEDPE, NULL);
logg("Limits: MaxEmbeddedPE limit set to %llu bytes.\n", val);
if((opt = optget(opts, "MaxHTMLNormalize"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_HTMLNORMALIZE, opt->numarg))) {
if ((opt = optget(opts, "MaxHTMLNormalize"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_HTMLNORMALIZE, opt->numarg))) {
logg("!cli_engine_set_num(CL_ENGINE_MAX_HTMLNORMALIZE) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
@ -846,8 +848,8 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
val = cl_engine_get_num(engine, CL_ENGINE_MAX_HTMLNORMALIZE, NULL);
logg("Limits: MaxHTMLNormalize limit set to %llu bytes.\n", val);
if((opt = optget(opts, "MaxHTMLNoTags"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_HTMLNOTAGS, opt->numarg))) {
if ((opt = optget(opts, "MaxHTMLNoTags"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_HTMLNOTAGS, opt->numarg))) {
logg("!cli_engine_set_num(CL_ENGINE_MAX_HTMLNOTAGS) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
@ -856,8 +858,8 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
val = cl_engine_get_num(engine, CL_ENGINE_MAX_HTMLNOTAGS, NULL);
logg("Limits: MaxHTMLNoTags limit set to %llu bytes.\n", val);
if((opt = optget(opts, "MaxScriptNormalize"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_SCRIPTNORMALIZE, opt->numarg))) {
if ((opt = optget(opts, "MaxScriptNormalize"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_SCRIPTNORMALIZE, opt->numarg))) {
logg("!cli_engine_set_num(CL_ENGINE_MAX_SCRIPTNORMALIZE) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
@ -866,8 +868,8 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
val = cl_engine_get_num(engine, CL_ENGINE_MAX_SCRIPTNORMALIZE, NULL);
logg("Limits: MaxScriptNormalize limit set to %llu bytes.\n", val);
if((opt = optget(opts, "MaxZipTypeRcg"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_ZIPTYPERCG, opt->numarg))) {
if ((opt = optget(opts, "MaxZipTypeRcg"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_ZIPTYPERCG, opt->numarg))) {
logg("!cli_engine_set_num(CL_ENGINE_MAX_ZIPTYPERCG) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
@ -876,8 +878,8 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
val = cl_engine_get_num(engine, CL_ENGINE_MAX_ZIPTYPERCG, NULL);
logg("Limits: MaxZipTypeRcg limit set to %llu bytes.\n", val);
if((opt = optget(opts, "MaxPartitions"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_PARTITIONS, opt->numarg))) {
if ((opt = optget(opts, "MaxPartitions"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_PARTITIONS, opt->numarg))) {
logg("!cli_engine_set_num(MaxPartitions) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
@ -886,8 +888,8 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
val = cl_engine_get_num(engine, CL_ENGINE_MAX_PARTITIONS, NULL);
logg("Limits: MaxPartitions limit set to %llu.\n", val);
if((opt = optget(opts, "MaxIconsPE"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_ICONSPE, opt->numarg))) {
if ((opt = optget(opts, "MaxIconsPE"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_ICONSPE, opt->numarg))) {
logg("!cli_engine_set_num(MaxIconsPE) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
@ -896,8 +898,8 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
val = cl_engine_get_num(engine, CL_ENGINE_MAX_ICONSPE, NULL);
logg("Limits: MaxIconsPE limit set to %llu.\n", val);
if((opt = optget(opts, "MaxRecHWP3"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_RECHWP3, opt->numarg))) {
if ((opt = optget(opts, "MaxRecHWP3"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_RECHWP3, opt->numarg))) {
logg("!cli_engine_set_num(MaxRecHWP3) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
@ -913,8 +915,8 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
val = cl_engine_get_num(engine, CL_ENGINE_PCRE_RECMATCH_LIMIT, NULL);
logg("Limits: PCRERecMatchLimit limit set to %llu.\n", val);
if((opt = optget(opts, "PCREMaxFileSize"))->active) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_PCRE_MAX_FILESIZE, opt->numarg))) {
if ((opt = optget(opts, "PCREMaxFileSize"))->active) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_PCRE_MAX_FILESIZE, opt->numarg))) {
logg("!cli_engine_set_num(PCREMaxFileSize) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
@ -1001,14 +1003,14 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
options.general |= CL_SCAN_GENERAL_HEURISTICS;
}
if(optget(opts, "ScanPE")->enabled) {
if (optget(opts, "ScanPE")->enabled) {
logg("Portable Executable support enabled.\n");
options.parse |= CL_SCAN_PARSE_PE;
} else {
logg("Portable Executable support disabled.\n");
}
if(optget(opts, "ScanELF")->enabled) {
if (optget(opts, "ScanELF")->enabled) {
logg("ELF support enabled.\n");
options.parse |= CL_SCAN_PARSE_ELF;
} else {
@ -1024,11 +1026,11 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
}
}
if(optget(opts, "ScanMail")->enabled) {
if (optget(opts, "ScanMail")->enabled) {
logg("Mail files support enabled.\n");
options.parse |= CL_SCAN_PARSE_MAIL;
if(optget(opts, "ScanPartialMessages")->enabled) {
if (optget(opts, "ScanPartialMessages")->enabled) {
logg("Mail: RFC1341 handling enabled.\n");
options.mail |= CL_SCAN_MAIL_PARTIAL_MESSAGE;
}
@ -1051,35 +1053,35 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
logg("OLE2 support disabled.\n");
}
if(optget(opts, "ScanPDF")->enabled) {
if (optget(opts, "ScanPDF")->enabled) {
logg("PDF support enabled.\n");
options.parse |= CL_SCAN_PARSE_PDF;
} else {
logg("PDF support disabled.\n");
}
if(optget(opts, "ScanSWF")->enabled) {
if (optget(opts, "ScanSWF")->enabled) {
logg("SWF support enabled.\n");
options.parse |= CL_SCAN_PARSE_SWF;
} else {
logg("SWF support disabled.\n");
}
if(optget(opts, "ScanHTML")->enabled) {
if (optget(opts, "ScanHTML")->enabled) {
logg("HTML support enabled.\n");
options.parse |= CL_SCAN_PARSE_HTML;
} else {
logg("HTML support disabled.\n");
}
if(optget(opts, "ScanXMLDOCS")->enabled) {
if (optget(opts, "ScanXMLDOCS")->enabled) {
logg("XMLDOCS support enabled.\n");
options.parse |= CL_SCAN_PARSE_XMLDOCS;
} else {
logg("XMLDOCS support disabled.\n");
}
if(optget(opts, "ScanHWP3")->enabled) {
if (optget(opts, "ScanHWP3")->enabled) {
logg("HWP3 support enabled.\n");
options.parse |= CL_SCAN_PARSE_HWP3;
} else {
@ -1102,54 +1104,54 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
}
/* TODO: Remove deprecated option in a future feature release */
if ((optget(opts,"PartitionIntersection")->enabled) ||
(optget(opts,"AlertPartitionIntersection")->enabled)) {
if ((optget(opts, "PartitionIntersection")->enabled) ||
(optget(opts, "AlertPartitionIntersection")->enabled)) {
options.heuristic |= CL_SCAN_HEURISTIC_PARTITION_INTXN;
logg("Raw DMG: Alert on partitions intersections\n");
}
if(optget(opts,"HeuristicScanPrecedence")->enabled) {
if (optget(opts, "HeuristicScanPrecedence")->enabled) {
options.general |= CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE;
logg("Heuristic: precedence enabled\n");
}
if(optget(opts, "StructuredDataDetection")->enabled) {
if (optget(opts, "StructuredDataDetection")->enabled) {
options.heuristic |= CL_SCAN_HEURISTIC_STRUCTURED;
if((opt = optget(opts, "StructuredMinCreditCardCount"))->enabled) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MIN_CC_COUNT, opt->numarg))) {
if ((opt = optget(opts, "StructuredMinCreditCardCount"))->enabled) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_MIN_CC_COUNT, opt->numarg))) {
logg("!cl_engine_set_num(CL_ENGINE_MIN_CC_COUNT) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
}
}
val = cl_engine_get_num(engine, CL_ENGINE_MIN_CC_COUNT, NULL);
logg("Structured: Minimum Credit Card Number Count set to %u\n", (unsigned int) val);
logg("Structured: Minimum Credit Card Number Count set to %u\n", (unsigned int)val);
if((opt = optget(opts, "StructuredMinSSNCount"))->enabled) {
if((ret = cl_engine_set_num(engine, CL_ENGINE_MIN_SSN_COUNT, opt->numarg))) {
if ((opt = optget(opts, "StructuredMinSSNCount"))->enabled) {
if ((ret = cl_engine_set_num(engine, CL_ENGINE_MIN_SSN_COUNT, opt->numarg))) {
logg("!cl_engine_set_num(CL_ENGINE_MIN_SSN_COUNT) failed: %s\n", cl_strerror(ret));
cl_engine_free(engine);
return 1;
}
}
val = cl_engine_get_num(engine, CL_ENGINE_MIN_SSN_COUNT, NULL);
logg("Structured: Minimum Social Security Number Count set to %u\n", (unsigned int) val);
logg("Structured: Minimum Social Security Number Count set to %u\n", (unsigned int)val);
if(optget(opts, "StructuredSSNFormatNormal")->enabled)
if (optget(opts, "StructuredSSNFormatNormal")->enabled)
options.heuristic |= CL_SCAN_HEURISTIC_STRUCTURED_SSN_NORMAL;
if(optget(opts, "StructuredSSNFormatStripped")->enabled)
if (optget(opts, "StructuredSSNFormatStripped")->enabled)
options.heuristic |= CL_SCAN_HEURISTIC_STRUCTURED_SSN_STRIPPED;
}
#ifdef HAVE__INTERNAL__SHA_COLLECT
if(optget(opts, "DevCollectHashes")->enabled)
if (optget(opts, "DevCollectHashes")->enabled)
options.dev |= CL_SCAN_DEV_COLLECT_SHA;
#endif
selfchk = optget(opts, "SelfCheck")->numarg;
if(!selfchk) {
if (!selfchk) {
logg("Self checking disabled.\n");
} else {
logg("Self checking every %u seconds.\n", selfchk);
@ -1157,13 +1159,13 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
/* save the PID */
mainpid = getpid();
if((opt = optget(opts, "PidFile"))->enabled) {
if ((opt = optget(opts, "PidFile"))->enabled) {
FILE *fd;
old_umask = umask(0002);
if((fd = fopen(opt->strarg, "w")) == NULL) {
if ((fd = fopen(opt->strarg, "w")) == NULL) {
logg("!Can't save PID in file %s\n", opt->strarg);
} else {
if (fprintf(fd, "%u\n", (unsigned int) mainpid)<0) {
if (fprintf(fd, "%u\n", (unsigned int)mainpid) < 0) {
logg("!Can't save PID in file %s\n", opt->strarg);
}
fclose(fd);
@ -1171,7 +1173,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
umask(old_umask);
}
logg("*Listening daemon: PID: %u\n", (unsigned int) mainpid);
logg("*Listening daemon: PID: %u\n", (unsigned int)mainpid);
max_threads = optget(opts, "MaxThreads")->numarg;
max_queue = optget(opts, "MaxQueue")->numarg;
acceptdata.commandtimeout = optget(opts, "CommandReadTimeout")->numarg;
@ -1206,9 +1208,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
if (enable_extended_FILE_stdio(-1, -1) == -1) {
logg("^Unable to set extended FILE stdio, clamd will be limited to max 256 open files\n");
rlim.rlim_cur = rlim.rlim_cur > 255 ? 255 : rlim.rlim_cur;
}
else
{
} else {
solaris_has_extended_stdio++;
}
@ -1225,21 +1225,19 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
** as the default is usually 256
*/
if (solaris_has_extended_stdio)
{
if (solaris_has_extended_stdio) {
rlim_t saved_soft_limit = rlim.rlim_cur;
rlim.rlim_cur = rlim.rlim_max;
if (setrlimit (RLIMIT_NOFILE, &rlim) < 0)
{
if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
logg("!setrlimit() for RLIMIT_NOFILE to %lu failed: %s\n",
(unsigned long) rlim.rlim_cur, strerror (errno));
(unsigned long)rlim.rlim_cur, strerror(errno));
rlim.rlim_cur = saved_soft_limit;
}
} /* If 64bit or has extended stdio */
#endif
opt = optget(opts,"MaxRecursion");
opt = optget(opts, "MaxRecursion");
maxrec = opt->numarg;
max_max_queue = rlim.rlim_cur - maxrec * max_threads - clamdfiles + max_threads;
if (max_queue < max_threads) {
@ -1249,15 +1247,15 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
}
if (max_max_queue < max_threads) {
logg("^MaxThreads * MaxRecursion is too high: %d, open file descriptor limit is: %lu\n",
maxrec*max_threads, (unsigned long)rlim.rlim_cur);
maxrec * max_threads, (unsigned long)rlim.rlim_cur);
max_max_queue = max_threads;
}
if (max_queue > max_max_queue) {
max_queue = max_max_queue;
if (warn)
logg("^MaxQueue value too high, lowering to: %d\n", max_queue);
} else if (max_queue < 2*max_threads && max_queue < max_max_queue) {
max_queue = 2*max_threads;
} else if (max_queue < 2 * max_threads && max_queue < max_max_queue) {
max_queue = 2 * max_threads;
if (max_queue > max_max_queue)
max_queue = max_max_queue;
/* always warn here */
@ -1268,25 +1266,25 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
logg("*MaxQueue set to: %d\n", max_queue);
acceptdata.max_queue = max_queue;
if(optget(opts, "ScanOnAccess")->enabled)
if (optget(opts, "ScanOnAccess")->enabled)
#if defined(FANOTIFY) || defined(CLAMAUTH)
{
int thread_started = 1;
do {
if(pthread_attr_init(&fan_attr)) break;
if (pthread_attr_init(&fan_attr)) break;
pthread_attr_setdetachstate(&fan_attr, PTHREAD_CREATE_JOINABLE);
/* Allocate memory for arguments. Thread is responsible for freeing it. */
if (!(tharg = (struct thrarg *) calloc(sizeof(struct thrarg), 1))) break;
if (!(tharg->options = (struct cl_scan_options *) calloc(sizeof(struct cl_scan_options), 1))) break;
if (!(tharg = (struct thrarg *)calloc(sizeof(struct thrarg), 1))) break;
if (!(tharg->options = (struct cl_scan_options *)calloc(sizeof(struct cl_scan_options), 1))) break;
(void) memcpy(tharg->options, &options, sizeof(struct cl_scan_options));
(void)memcpy(tharg->options, &options, sizeof(struct cl_scan_options));
tharg->opts = opts;
tharg->engine = engine;
thread_started = pthread_create(&fan_pid, &fan_attr, onas_fan_th, tharg);
} while(0);
} while (0);
if (0 != thread_started) {
/* Failed to create thread. Free anything we may have allocated. */
@ -1305,7 +1303,6 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
logg("!On-access scan is not available\n");
#endif
#ifndef _WIN32
/* set up signal handling */
sigfillset(&sigset);
@ -1344,7 +1341,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
idletimeout = optget(opts, "IdleTimeout")->numarg;
for (i=0;i < nsockets;i++)
for (i = 0; i < nsockets; i++)
if (fds_add(&acceptdata.fds, socketds[i], 1, 0) == -1) {
logg("!fds_add failed\n");
cl_engine_free(engine);
@ -1380,7 +1377,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
}
time(&start_time);
for(;;) {
for (;;) {
int new_sd;
/* Block waiting for connection on any of the sockets */
@ -1410,9 +1407,8 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
pthread_mutex_unlock(&exit_mutex);
}
if(fds->nfds) i = (rr_last + 1) % fds->nfds;
for (j = 0; j < fds->nfds && new_sd >= 0; j++, i = (i+1) % fds->nfds) {
if (fds->nfds) i = (rr_last + 1) % fds->nfds;
for (j = 0; j < fds->nfds && new_sd >= 0; j++, i = (i + 1) % fds->nfds) {
size_t pos = 0;
int error = 0;
struct fd_buf *buf = &fds->buf[i];
@ -1511,8 +1507,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
if (thrmgr_group_finished(buf->group, EXIT_ERROR)) {
if (buf->fd < 0) {
logg("$Skipping shutdown of bad socket after error (FD %d)\n", buf->fd);
}
else {
} else {
logg("$Shutting down socket after error (FD %d)\n", buf->fd);
shutdown(buf->fd, 2);
closesocket(buf->fd);
@ -1529,16 +1524,13 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
if (progexit) {
pthread_mutex_unlock(&exit_mutex);
pthread_mutex_lock(fds->buf_mutex);
if (sd_listen_fds(0) == 0)
{
if (sd_listen_fds(0) == 0) {
/* only close the sockets, when not using systemd socket activation */
for (i=0;i < fds->nfds; i++)
{
for (i = 0; i < fds->nfds; i++) {
if (fds->buf[i].fd == -1)
continue;
thrmgr_group_terminate(fds->buf[i].group);
if (thrmgr_group_finished(fds->buf[i].group, EXIT_ERROR))
{
if (thrmgr_group_finished(fds->buf[i].group, EXIT_ERROR)) {
logg("$Shutdown closed fd %d\n", fds->buf[i].fd);
shutdown(fds->buf[i].fd, 2);
closesocket(fds->buf[i].fd);
@ -1556,15 +1548,15 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
logg("SIGHUP caught: re-opening log file.\n");
logg_close();
sighup = 0;
if(!logg_file && (opt = optget(opts, "LogFile"))->enabled)
if (!logg_file && (opt = optget(opts, "LogFile"))->enabled)
logg_file = opt->strarg;
}
/* SelfCheck */
if(selfchk) {
if (selfchk) {
time(&current_time);
if((current_time - start_time) >= (time_t)selfchk) {
if(reload_db(engine, dboptions, opts, TRUE, &ret)) {
if ((current_time - start_time) >= (time_t)selfchk) {
if (reload_db(engine, dboptions, opts, TRUE, &ret)) {
pthread_mutex_lock(&reload_mutex);
reload = 1;
pthread_mutex_unlock(&reload_mutex);
@ -1575,13 +1567,13 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
/* DB reload */
pthread_mutex_lock(&reload_mutex);
if(reload) {
if (reload) {
pthread_mutex_unlock(&reload_mutex);
engine = reload_db(engine, dboptions, opts, FALSE, &ret);
if(ret) {
if (ret) {
logg("Terminating because of a fatal error.\n");
if(new_sd >= 0)
if (new_sd >= 0)
closesocket(new_sd);
break;
}
@ -1592,7 +1584,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
pthread_mutex_unlock(&reload_mutex);
#if defined(FANOTIFY) || defined(CLAMAUTH)
if(optget(opts, "ScanOnAccess")->enabled && tharg) {
if (optget(opts, "ScanOnAccess")->enabled && tharg) {
tharg->engine = engine;
}
#endif
@ -1618,7 +1610,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
logg("*Waiting for all threads to finish\n");
thrmgr_destroy(thr_pool);
#if defined(FANOTIFY) || defined(CLAMAUTH)
if(optget(opts, "ScanOnAccess")->enabled && tharg) {
if (optget(opts, "ScanOnAccess")->enabled && tharg) {
logg("Stopping on-access scan\n");
pthread_mutex_lock(&logg_mutex);
pthread_kill(fan_pid, SIGUSR1);
@ -1627,7 +1619,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
free(tharg);
}
#endif
if(engine) {
if (engine) {
thrmgr_setactiveengine(NULL);
cl_engine_free(engine);
}
@ -1643,18 +1635,17 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
close(acceptdata.syncpipe_wake_accept[1]);
close(acceptdata.syncpipe_wake_recv[1]);
#endif
if(dbstat.entries)
if (dbstat.entries)
cl_statfree(&dbstat);
if (sd_listen_fds(0) == 0)
{
if (sd_listen_fds(0) == 0) {
/* only close the sockets, when not using systemd socket activation */
logg("*Shutting down the main socket%s.\n", (nsockets > 1) ? "s" : "");
for (i = 0; i < nsockets; i++)
shutdown(socketds[i], 2);
}
if((opt = optget(opts, "PidFile"))->enabled) {
if(unlink(opt->strarg) == -1)
if ((opt = optget(opts, "PidFile"))->enabled) {
if (unlink(opt->strarg) == -1)
logg("!Can't unlink the pid file %s\n", opt->strarg);
else
logg("Pid file removed.\n");

View file

@ -38,7 +38,7 @@ struct thrarg {
};
int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsigned int dboptions, const struct optstruct *opts);
int statinidir_th(const char* dirname);
int statinidir_th(const char *dirname);
void sighandler(int sig);
void sighandler_th(int sig);
void sigsegv(int sig);

View file

@ -78,43 +78,42 @@ static struct {
int support_old;
int enabled;
} commands[] = {
{CMD1, sizeof(CMD1)-1, COMMAND_SCAN, 1, 1, 0},
{CMD3, sizeof(CMD3)-1, COMMAND_SHUTDOWN, 0, 1, 0},
{CMD4, sizeof(CMD4)-1, COMMAND_RELOAD, 0, 1, 0},
{CMD5, sizeof(CMD5)-1, COMMAND_PING, 0, 1, 0},
{CMD6, sizeof(CMD6)-1, COMMAND_CONTSCAN, 1, 1, 0},
{CMD1, sizeof(CMD1) - 1, COMMAND_SCAN, 1, 1, 0},
{CMD3, sizeof(CMD3) - 1, COMMAND_SHUTDOWN, 0, 1, 0},
{CMD4, sizeof(CMD4) - 1, COMMAND_RELOAD, 0, 1, 0},
{CMD5, sizeof(CMD5) - 1, COMMAND_PING, 0, 1, 0},
{CMD6, sizeof(CMD6) - 1, COMMAND_CONTSCAN, 1, 1, 0},
/* must be before VERSION, because they share common prefix! */
{CMD18, sizeof(CMD18)-1, COMMAND_COMMANDS, 0, 0, 1},
{CMD7, sizeof(CMD7)-1, COMMAND_VERSION, 0, 1, 1},
{CMD8, sizeof(CMD8)-1, COMMAND_STREAM, 0, 1, 1},
{CMD10, sizeof(CMD10)-1, COMMAND_END, 0, 0, 1},
{CMD11, sizeof(CMD11)-1, COMMAND_SHUTDOWN, 0, 1, 1},
{CMD13, sizeof(CMD13)-1, COMMAND_MULTISCAN, 1, 1, 1},
{CMD14, sizeof(CMD14)-1, COMMAND_FILDES, 0, 1, FEATURE_FDPASSING},
{CMD15, sizeof(CMD15)-1, COMMAND_STATS, 0, 0, 1},
{CMD16, sizeof(CMD16)-1, COMMAND_IDSESSION, 0, 0, 1},
{CMD17, sizeof(CMD17)-1, COMMAND_INSTREAM, 0, 0, 1},
{CMD19, sizeof(CMD19)-1, COMMAND_DETSTATSCLEAR, 0, 1, 1},
{CMD20, sizeof(CMD20)-1, COMMAND_DETSTATS, 0, 1, 1},
{CMD21, sizeof(CMD21)-1, COMMAND_ALLMATCHSCAN, 1, 0, 1}
};
{CMD18, sizeof(CMD18) - 1, COMMAND_COMMANDS, 0, 0, 1},
{CMD7, sizeof(CMD7) - 1, COMMAND_VERSION, 0, 1, 1},
{CMD8, sizeof(CMD8) - 1, COMMAND_STREAM, 0, 1, 1},
{CMD10, sizeof(CMD10) - 1, COMMAND_END, 0, 0, 1},
{CMD11, sizeof(CMD11) - 1, COMMAND_SHUTDOWN, 0, 1, 1},
{CMD13, sizeof(CMD13) - 1, COMMAND_MULTISCAN, 1, 1, 1},
{CMD14, sizeof(CMD14) - 1, COMMAND_FILDES, 0, 1, FEATURE_FDPASSING},
{CMD15, sizeof(CMD15) - 1, COMMAND_STATS, 0, 0, 1},
{CMD16, sizeof(CMD16) - 1, COMMAND_IDSESSION, 0, 0, 1},
{CMD17, sizeof(CMD17) - 1, COMMAND_INSTREAM, 0, 0, 1},
{CMD19, sizeof(CMD19) - 1, COMMAND_DETSTATSCLEAR, 0, 1, 1},
{CMD20, sizeof(CMD20) - 1, COMMAND_DETSTATS, 0, 1, 1},
{CMD21, sizeof(CMD21) - 1, COMMAND_ALLMATCHSCAN, 1, 0, 1}};
enum commands parse_command(const char *cmd, const char **argument, int oldstyle)
{
size_t i;
*argument = NULL;
for (i=0; i < sizeof(commands)/sizeof(commands[0]); i++) {
for (i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) {
const size_t len = commands[i].len;
if (!strncmp(cmd, commands[i].cmd, len)) {
const char *arg = cmd + len;
if (commands[i].need_arg) {
if (!*arg) {/* missing argument */
if (!*arg) { /* missing argument */
logg("$Command %s missing argument!\n", commands[i].cmd);
return COMMAND_UNKNOWN;
}
*argument = arg+1;
*argument = arg + 1;
} else {
if (*arg) {/* extra stuff after command */
if (*arg) { /* extra stuff after command */
logg("$Command %s has trailing garbage!\n", commands[i].cmd);
return COMMAND_UNKNOWN;
}
@ -177,7 +176,7 @@ int conn_reply_errno(const client_conn_t *conn, const char *path,
const char *msg)
{
char err[BUFFSIZE + sizeof(". ERROR")];
cli_strerror(errno, err, BUFFSIZE-1);
cli_strerror(errno, err, BUFFSIZE - 1);
strcat(err, ". ERROR");
return conn_reply(conn, path, msg, err);
}
@ -247,8 +246,8 @@ int command(client_conn_t *conn, int *virus)
pthread_mutex_lock(&conn->thrpool->pool_mutex);
multiscan = conn->thrpool->thr_multiscan;
max = conn->thrpool->thr_max;
if (multiscan+1 < max)
conn->thrpool->thr_multiscan = multiscan+1;
if (multiscan + 1 < max)
conn->thrpool->thr_multiscan = multiscan + 1;
else {
alive = conn->thrpool->thr_alive;
ret = -1;
@ -268,7 +267,7 @@ int command(client_conn_t *conn, int *virus)
type = TYPE_MULTISCAN;
scandata.group = group = thrmgr_group_new();
if (!group) {
if(optget(opts, "ExitOnOOM")->enabled)
if (optget(opts, "ExitOnOOM")->enabled)
return -1;
else
return 1;
@ -295,14 +294,13 @@ int command(client_conn_t *conn, int *virus)
if (conn->scanfd == -1) {
conn_reply_error(conn, "FILDES: didn't receive file descriptor.");
return 1;
}
else {
} else {
ret = scanfd(conn, NULL, engine, options, opts, desc, 0);
if (ret == CL_VIRUS) {
*virus = 1;
ret = 0;
} else if (ret == CL_EMEM) {
if(optget(opts, "ExitOnOOM")->enabled)
if (optget(opts, "ExitOnOOM")->enabled)
ret = -1;
else
ret = 1;
@ -319,7 +317,7 @@ int command(client_conn_t *conn, int *virus)
conn_reply_error(conn, "FILDES support not compiled in.");
close(conn->scanfd);
return 0;
#endif
#endif
case COMMAND_STATS:
thrmgr_setactivetask(NULL, "STATS");
if (conn->group)
@ -332,7 +330,7 @@ int command(client_conn_t *conn, int *virus)
if (ret == CL_VIRUS)
*virus = 1;
if (ret == CL_EMEM) {
if(optget(opts, "ExitOnOOM")->enabled)
if (optget(opts, "ExitOnOOM")->enabled)
return -1;
else
return 1;
@ -345,7 +343,7 @@ int command(client_conn_t *conn, int *virus)
*virus = 1;
ret = 0;
} else if (ret == CL_EMEM) {
if(optget(opts, "ExitOnOOM")->enabled)
if (optget(opts, "ExitOnOOM")->enabled)
ret = -1;
else
ret = 1;
@ -384,13 +382,13 @@ int command(client_conn_t *conn, int *virus)
if (optget(opts, "FollowFileSymlinks")->enabled)
flags |= CLI_FTW_FOLLOW_FILE_SYMLINK;
if(!optget(opts, "CrossFilesystems")->enabled)
if(CLAMSTAT(conn->filename, &sb) == 0)
if (!optget(opts, "CrossFilesystems")->enabled)
if (CLAMSTAT(conn->filename, &sb) == 0)
scandata.dev = sb.st_dev;
ret = cli_ftw(conn->filename, flags, maxdirrec ? maxdirrec : INT_MAX, scan_callback, &data, scan_pathchk);
if (ret == CL_EMEM) {
if(optget(opts, "ExitOnOOM")->enabled)
if (optget(opts, "ExitOnOOM")->enabled)
return -1;
else
return 1;
@ -415,21 +413,21 @@ int command(client_conn_t *conn, int *virus)
if (ret == CL_ETIMEOUT)
thrmgr_group_terminate(conn->group);
return error;
}
}
static int dispatch_command(client_conn_t *conn, enum commands cmd, const char *argument)
{
static int dispatch_command(client_conn_t *conn, enum commands cmd, const char *argument)
{
int ret = 0;
int bulk;
client_conn_t *dup_conn = (client_conn_t *) malloc(sizeof(struct client_conn_tag));
client_conn_t *dup_conn = (client_conn_t *)malloc(sizeof(struct client_conn_tag));
if(!dup_conn) {
if (!dup_conn) {
logg("!Can't allocate memory for client_conn\n");
return -1;
}
memcpy(dup_conn, conn, sizeof(*conn));
dup_conn->cmdtype = cmd;
if(cl_engine_addref(dup_conn->engine)) {
if (cl_engine_addref(dup_conn->engine)) {
logg("!cl_engine_addref() failed\n");
free(dup_conn);
return -1;
@ -473,7 +471,7 @@ int command(client_conn_t *conn, int *virus)
}
if (!dup_conn->group)
bulk = 0;
if(!ret && !thrmgr_group_dispatch(dup_conn->thrpool, dup_conn->group, dup_conn, bulk)) {
if (!ret && !thrmgr_group_dispatch(dup_conn->thrpool, dup_conn->group, dup_conn, bulk)) {
logg("!thread dispatch failed\n");
ret = -2;
}
@ -489,15 +487,15 @@ static int print_ver(int desc, char term, const struct cl_engine *engine)
uint32_t ver;
ver = cl_engine_get_num(engine, CL_ENGINE_DB_VERSION, NULL);
if(ver) {
if (ver) {
char timestr[32];
const char *tstr;
time_t t;
t = cl_engine_get_num(engine, CL_ENGINE_DB_TIME, NULL);
tstr = cli_ctime(&t, timestr, sizeof(timestr));
/* cut trailing \n */
timestr[strlen(tstr)-1] = '\0';
return mdprintf(desc, "ClamAV %s/%u/%s%c", get_version(), (unsigned int) ver, tstr, term);
timestr[strlen(tstr) - 1] = '\0';
return mdprintf(desc, "ClamAV %s/%u/%s%c", get_version(), (unsigned int)ver, tstr, term);
}
return mdprintf(desc, "ClamAV %s%c", get_version(), term);
}
@ -514,8 +512,8 @@ static void print_commands(int desc, char term, const struct cl_engine *engine)
}
print_ver(desc, '|', engine);
mdprintf(desc, " COMMANDS:");
n = sizeof(commands)/sizeof(commands[0]);
for (i=0;i<n;i++) {
n = sizeof(commands) / sizeof(commands[0]);
for (i = 0; i < n; i++) {
mdprintf(desc, " %s", commands[i].cmd);
}
mdprintf(desc, "%c", term);
@ -581,32 +579,27 @@ int execute_or_dispatch_command(client_conn_t *conn, enum commands cmd, const ch
else
mdprintf(desc, "PONG%c", term);
return conn->group ? 0 : 1;
case COMMAND_VERSION:
{
case COMMAND_VERSION: {
if (conn->group)
mdprintf(desc, "%u: ", conn->id);
print_ver(desc, conn->term, engine);
return conn->group ? 0 : 1;
}
case COMMAND_COMMANDS:
{
case COMMAND_COMMANDS: {
if (conn->group)
mdprintf(desc, "%u: ", conn->id);
print_commands(desc, conn->term, engine);
return conn->group ? 0 : 1;
}
case COMMAND_DETSTATSCLEAR:
{
case COMMAND_DETSTATSCLEAR: {
/* TODO: tell client this command has been removed */
return 1;
}
case COMMAND_DETSTATS:
{
case COMMAND_DETSTATS: {
/* TODO: tell client this command has been removed */
return 1;
}
case COMMAND_INSTREAM:
{
case COMMAND_INSTREAM: {
int rc = cli_gentempfd(optget(conn->opts, "TemporaryDirectory")->strarg, &conn->filename, &conn->scanfd);
if (rc != CL_SUCCESS)
return rc;

View file

@ -22,7 +22,6 @@
#ifndef __SESSION_H
#define __SESSION_H
#define CMD1 "SCAN"
/* #define CMD2 "RAWSCAN" */
#define CMD3 "QUIT" /* deprecated */

View file

@ -57,44 +57,34 @@ int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struc
char *estr, port[10];
int yes = 1;
int res;
unsigned int i=0;
unsigned int i = 0;
int num_fd;
sockets = *lsockets;
num_fd = sd_listen_fds(0);
if (num_fd > 2)
{
if (num_fd > 2) {
logg("!TCP: Received more than two file descriptors from systemd.\n");
return -1;
}
else if (num_fd > 0)
{
} else if (num_fd > 0) {
/* use socket passed by systemd */
int i;
for(i = 0; i < num_fd; i += 1)
{
for (i = 0; i < num_fd; i += 1) {
sockfd = SD_LISTEN_FDS_START + i;
if (sd_is_socket(sockfd, AF_INET, SOCK_STREAM, 1) == 1)
{
if (sd_is_socket(sockfd, AF_INET, SOCK_STREAM, 1) == 1) {
/* correct socket */
logg("#TCP: Received AF_INET SOCK_STREAM socket from systemd.\n");
break;
}
else if (sd_is_socket(sockfd, AF_INET6, SOCK_STREAM, 1) == 1)
{
} else if (sd_is_socket(sockfd, AF_INET6, SOCK_STREAM, 1) == 1) {
/* correct socket */
logg("#TCP: Received AF_INET6 SOCK_STREAM socket from systemd.\n");
break;
}
else
{
} else {
/* wrong socket */
sockfd = -2;
}
}
if (sockfd == -2)
{
if (sockfd == -2) {
logg("#TCP: No tcp AF_INET/AF_INET6 SOCK_STREAM socket received from systemd.\n");
return -2;
}
@ -131,7 +121,7 @@ int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struc
for (p = info; p != NULL; p = p->ai_next, i++) {
t = realloc(sockets, sizeof(int) * (*nlsockets + 1));
if (!(t)) {
for (i=0; i < *nlsockets; i++)
for (i = 0; i < *nlsockets; i++)
close(sockets[i]);
return -1;
@ -144,7 +134,7 @@ int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struc
continue;
}
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *) &yes, sizeof(yes)) == -1) {
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes)) == -1) {
logg("!TCP: setsocktopt(SO_REUSEADDR) error: %s\n", strerror(errno));
}
@ -158,7 +148,7 @@ int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struc
#ifdef HAVE_GETNAMEINFO
if ((res = getnameinfo(p->ai_addr, p->ai_addrlen, host, sizeof(host),
serv, sizeof(serv), NI_NUMERICHOST|NI_NUMERICSERV))) {
serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV))) {
logg("!TCP: getnameinfo failed: %s\n", gai_strerror(res));
host[0] = '\0';
serv[0] = '\0';
@ -166,12 +156,12 @@ int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struc
#else
if (ipaddr) {
strncpy(host, ipaddr, sizeof(host));
host[sizeof(host)-1] = '\0';
host[sizeof(host) - 1] = '\0';
} else
host[0] = '\0';
snprintf(serv, sizeof(serv), "%u", (unsigned int)(optget(opts, "TCPSocket")->numarg));
#endif
if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
estr = strerror(errno);
logg("!TCP: Cannot bind to [%s]:%s: %s\n", host, serv, estr);
closesocket(sockfd);
@ -183,7 +173,7 @@ int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struc
backlog = optget(opts, "MaxConnectionQueueLength")->numarg;
logg("#TCP: Setting connection queue length to %d\n", backlog);
if(listen(sockfd, backlog) == -1) {
if (listen(sockfd, backlog) == -1) {
estr = strerror(errno);
logg("!TCP: Cannot listen on [%s]:%s: %s\n", host, serv, estr);
closesocket(sockfd);

View file

@ -44,7 +44,7 @@
#endif
/* BSD and HP-UX need a bigger stacksize than the system default */
#if defined (C_BSD) || defined (C_HPUX) || defined(C_AIX) || (defined(C_LINUX) && !defined(__GLIBC__))
#if defined(C_BSD) || defined(C_HPUX) || defined(C_AIX) || (defined(C_LINUX) && !defined(__GLIBC__))
#define C_BIGSTACK 1
#endif
@ -52,7 +52,7 @@ static work_queue_t *work_queue_new(void)
{
work_queue_t *work_q;
work_q = (work_queue_t *) malloc(sizeof(work_queue_t));
work_q = (work_queue_t *)malloc(sizeof(work_queue_t));
if (!work_q) {
return NULL;
}
@ -70,7 +70,7 @@ static int work_queue_add(work_queue_t *work_q, void *data)
if (!work_q) {
return FALSE;
}
work_item = (work_item_t *) malloc(sizeof(work_item_t));
work_item = (work_item_t *)malloc(sizeof(work_item_t));
if (!work_item) {
return FALSE;
}
@ -118,7 +118,7 @@ static pthread_mutex_t pools_lock = PTHREAD_MUTEX_INITIALIZER;
static void add_topools(threadpool_t *t)
{
struct threadpool_list *new = malloc(sizeof(*new));
if(!new) {
if (!new) {
logg("!Unable to add threadpool to list\n");
return;
}
@ -136,21 +136,21 @@ static void remove_frompools(threadpool_t *t)
pthread_mutex_lock(&pools_lock);
prev = NULL;
l = pools;
while(l && l->pool != t) {
while (l && l->pool != t) {
prev = l;
l = l->nxt;
}
if(!l) {
if (!l) {
pthread_mutex_unlock(&pools_lock);
return;
}
if(prev)
if (prev)
prev->nxt = l->nxt;
if(l == pools)
if (l == pools)
pools = l->nxt;
free(l);
desc = t->tasks;
while(desc) {
while (desc) {
struct task_desc *q = desc;
desc = desc->nxt;
free(q);
@ -161,33 +161,33 @@ static void remove_frompools(threadpool_t *t)
static void print_queue(int f, work_queue_t *queue, struct timeval *tv_now)
{
long umin=LONG_MAX, umax=0, usum=0;
long umin = LONG_MAX, umax = 0, usum = 0;
unsigned invalids = 0, cnt = 0;
work_item_t *q;
if(!queue->head)
if (!queue->head)
return;
for(q=queue->head;q;q=q->next) {
for (q = queue->head; q; q = q->next) {
long delta;
delta = tv_now->tv_usec - q->time_queued.tv_usec;
delta += (tv_now->tv_sec - q->time_queued.tv_sec)*1000000;
if(delta < 0) {
delta += (tv_now->tv_sec - q->time_queued.tv_sec) * 1000000;
if (delta < 0) {
invalids++;
continue;
}
if(delta > umax)
if (delta > umax)
umax = delta;
if(delta < umin)
if (delta < umin)
umin = delta;
usum += delta;
++cnt;
}
mdprintf(f," min_wait: %.6f max_wait: %.6f avg_wait: %.6f",
umin/1e6, umax/1e6, usum /(1e6*cnt));
if(invalids)
mdprintf(f," (INVALID timestamps: %u)", invalids);
if(cnt + invalids != (unsigned)queue->item_count)
mdprintf(f," (ERROR: %u != %u)", cnt + invalids,
mdprintf(f, " min_wait: %.6f max_wait: %.6f avg_wait: %.6f",
umin / 1e6, umax / 1e6, usum / (1e6 * cnt));
if (invalids)
mdprintf(f, " (INVALID timestamps: %u)", invalids);
if (cnt + invalids != (unsigned)queue->item_count)
mdprintf(f, " (ERROR: %u != %u)", cnt + invalids,
(unsigned)queue->item_count);
}
@ -201,23 +201,23 @@ int thrmgr_printstats(int f, char term)
int has_libc_memstats = 0;
pthread_mutex_lock(&pools_lock);
for(cnt=0,l=pools;l;l=l->nxt) cnt++;
mdprintf(f,"POOLS: %u\n\n", cnt);
for(l= pools;l && !error_flag;l = l->nxt) {
for (cnt = 0, l = pools; l; l = l->nxt) cnt++;
mdprintf(f, "POOLS: %u\n\n", cnt);
for (l = pools; l && !error_flag; l = l->nxt) {
threadpool_t *pool = l->pool;
const char *state;
struct timeval tv_now;
struct task_desc *task;
cnt = 0;
if(!pool) {
mdprintf(f,"NULL\n\n");
if (!pool) {
mdprintf(f, "NULL\n\n");
continue;
}
/* now we can access desc->, knowing that they won't get freed
* because the other tasks can't quit while pool_mutex is taken
*/
switch(pool->state) {
switch (pool->state) {
case POOL_INVALID:
state = "INVALID";
break;
@ -232,30 +232,29 @@ int thrmgr_printstats(int f, char term)
break;
}
mdprintf(f, "STATE: %s %s\n", state, l->nxt ? "" : "PRIMARY");
mdprintf(f, "THREADS: live %u idle %u max %u idle-timeout %u\n"
,pool->thr_alive, pool->thr_idle, pool->thr_max,
mdprintf(f, "THREADS: live %u idle %u max %u idle-timeout %u\n", pool->thr_alive, pool->thr_idle, pool->thr_max,
pool->idle_timeout);
/* TODO: show both queues */
mdprintf(f,"QUEUE: %u items", pool->single_queue->item_count + pool->bulk_queue->item_count);
mdprintf(f, "QUEUE: %u items", pool->single_queue->item_count + pool->bulk_queue->item_count);
gettimeofday(&tv_now, NULL);
print_queue(f, pool->bulk_queue, &tv_now);
print_queue(f, pool->single_queue, &tv_now);
mdprintf(f, "\n");
for(task = pool->tasks; task; task = task->nxt) {
for (task = pool->tasks; task; task = task->nxt) {
double delta;
size_t used, total;
delta = tv_now.tv_usec - task->tv.tv_usec;
delta += (tv_now.tv_sec - task->tv.tv_sec)*1000000.0;
mdprintf(f,"\t%s %f %s\n",
delta += (tv_now.tv_sec - task->tv.tv_sec) * 1000000.0;
mdprintf(f, "\t%s %f %s\n",
task->command ? task->command : "N/A",
delta/1e6,
task->filename ? task->filename:"");
delta / 1e6,
task->filename ? task->filename : "");
if (task->engine) {
/* we usually have at most 2 engines so a linear
* search is good enough */
size_t i;
for (i=0;i<seen_cnt;i++) {
for (i = 0; i < seen_cnt; i++) {
if (seen[i] == task->engine)
break;
}
@ -281,32 +280,32 @@ int thrmgr_printstats(int f, char term)
}
}
}
mdprintf(f,"\n");
mdprintf(f, "\n");
}
free(seen);
#ifdef HAVE_MALLINFO
{
struct mallinfo inf = mallinfo();
mem_heap = inf.arena/(1024*1024.0);
mem_mmap = inf.hblkhd/(1024*1024.0);
mem_used = (inf.usmblks + inf.uordblks)/(1024*1024.0);
mem_free = (inf.fsmblks + inf.fordblks)/(1024*1024.0);
mem_releasable = inf.keepcost/(1024*1024.0);
has_libc_memstats=1;
mem_heap = inf.arena / (1024 * 1024.0);
mem_mmap = inf.hblkhd / (1024 * 1024.0);
mem_used = (inf.usmblks + inf.uordblks) / (1024 * 1024.0);
mem_free = (inf.fsmblks + inf.fordblks) / (1024 * 1024.0);
mem_releasable = inf.keepcost / (1024 * 1024.0);
has_libc_memstats = 1;
}
#endif
if (error_flag) {
mdprintf(f, "ERROR: error encountered while formatting statistics\n");
} else {
if (has_libc_memstats)
mdprintf(f,"MEMSTATS: heap %.3fM mmap %.3fM used %.3fM free %.3fM releasable %.3fM pools %u pools_used %.3fM pools_total %.3fM\n",
mdprintf(f, "MEMSTATS: heap %.3fM mmap %.3fM used %.3fM free %.3fM releasable %.3fM pools %u pools_used %.3fM pools_total %.3fM\n",
mem_heap, mem_mmap, mem_used, mem_free, mem_releasable, pool_cnt,
pool_used/(1024*1024.0), pool_total/(1024*1024.0));
pool_used / (1024 * 1024.0), pool_total / (1024 * 1024.0));
else
mdprintf(f,"MEMSTATS: heap N/A mmap N/A used N/A free N/A releasable N/A pools %u pools_used %.3fM pools_total %.3fM\n",
pool_cnt, pool_used/(1024*1024.0), pool_total/(1024*1024.0));
mdprintf(f, "MEMSTATS: heap N/A mmap N/A used N/A free N/A releasable N/A pools %u pools_used %.3fM pools_total %.3fM\n",
pool_cnt, pool_used / (1024 * 1024.0), pool_total / (1024 * 1024.0));
}
mdprintf(f,"END%c", term);
mdprintf(f, "END%c", term);
pthread_mutex_unlock(&pools_lock);
return 0;
}
@ -320,7 +319,7 @@ void thrmgr_destroy(threadpool_t *threadpool)
logg("!Mutex lock failed\n");
exit(-1);
}
if(threadpool->state != POOL_VALID) {
if (threadpool->state != POOL_VALID) {
if (pthread_mutex_unlock(&threadpool->pool_mutex) != 0) {
logg("!Mutex unlock failed\n");
exit(-1);
@ -337,7 +336,7 @@ void thrmgr_destroy(threadpool_t *threadpool)
}
}
while (threadpool->thr_alive > 0) {
if (pthread_cond_wait (&threadpool->pool_cond, &threadpool->pool_mutex) != 0) {
if (pthread_cond_wait(&threadpool->pool_cond, &threadpool->pool_mutex) != 0) {
pthread_mutex_unlock(&threadpool->pool_mutex);
return;
}
@ -371,7 +370,7 @@ threadpool_t *thrmgr_new(int max_threads, int idle_timeout, int max_queue, void
return NULL;
}
threadpool = (threadpool_t *) malloc(sizeof(threadpool_t));
threadpool = (threadpool_t *)malloc(sizeof(threadpool_t));
if (!threadpool) {
return NULL;
}
@ -398,7 +397,7 @@ threadpool_t *thrmgr_new(int max_threads, int idle_timeout, int max_queue, void
threadpool->handler = handler;
threadpool->tasks = NULL;
if(pthread_mutex_init(&(threadpool->pool_mutex), NULL)) {
if (pthread_mutex_init(&(threadpool->pool_mutex), NULL)) {
free(threadpool->single_queue);
free(threadpool->bulk_queue);
free(threadpool);
@ -432,8 +431,7 @@ threadpool_t *thrmgr_new(int max_threads, int idle_timeout, int max_queue, void
return NULL;
}
if (pthread_cond_init(&(threadpool->idle_cond),NULL) != 0) {
if (pthread_cond_init(&(threadpool->idle_cond), NULL) != 0) {
pthread_cond_destroy(&(threadpool->queueable_single_cond));
pthread_cond_destroy(&(threadpool->queueable_bulk_cond));
pthread_cond_destroy(&(threadpool->pool_cond));
@ -476,12 +474,12 @@ threadpool_t *thrmgr_new(int max_threads, int idle_timeout, int max_queue, void
#if defined(C_HPUX) && defined(USE_MPOOL)
/* Set aside one cli_pagesize() for the stack's pthread header,
* giving a 1M region to fit a 1M large-page */
if(cli_getpagesize() < 1048576)
if (cli_getpagesize() < 1048576)
stacksize = 1048576 - cli_getpagesize();
else
#endif
stacksize = 1048576;
logg("Set stacksize to %lu\n", (unsigned long int) stacksize);
logg("Set stacksize to %lu\n", (unsigned long int)stacksize);
pthread_attr_setstacksize(&(threadpool->pool_attr), stacksize);
#endif
threadpool->state = POOL_VALID;
@ -501,16 +499,16 @@ static void stats_tls_key_alloc(void)
static const char *IDLE_TASK = "IDLE";
/* no mutex is needed, we are using thread local variable */
void thrmgr_setactivetask(const char *filename, const char* cmd)
void thrmgr_setactivetask(const char *filename, const char *cmd)
{
struct task_desc *desc;
pthread_once(&stats_tls_key_once, stats_tls_key_alloc);
desc = pthread_getspecific(stats_tls_key);
if(!desc)
if (!desc)
return;
desc->filename = filename;
if(cmd) {
if(cmd == IDLE_TASK && desc->command == cmd)
if (cmd) {
if (cmd == IDLE_TASK && desc->command == cmd)
return;
desc->command = cmd;
gettimeofday(&desc->tv, NULL);
@ -522,7 +520,7 @@ void thrmgr_setactiveengine(const struct cl_engine *engine)
struct task_desc *desc;
pthread_once(&stats_tls_key_once, stats_tls_key_alloc);
desc = pthread_getspecific(stats_tls_key);
if(!desc)
if (!desc)
return;
desc->engine = engine;
}
@ -531,11 +529,11 @@ void thrmgr_setactiveengine(const struct cl_engine *engine)
static void stats_init(threadpool_t *pool)
{
struct task_desc *desc = calloc(1, sizeof(*desc));
if(!desc)
if (!desc)
return;
pthread_once(&stats_tls_key_once, stats_tls_key_alloc);
pthread_setspecific(stats_tls_key, desc);
if(!pool->tasks)
if (!pool->tasks)
pool->tasks = desc;
else {
desc->nxt = pool->tasks;
@ -548,14 +546,14 @@ static void stats_init(threadpool_t *pool)
static void stats_destroy(threadpool_t *pool)
{
struct task_desc *desc = pthread_getspecific(stats_tls_key);
if(!desc)
if (!desc)
return;
pthread_mutex_lock(&pools_lock);
if(desc->prv)
if (desc->prv)
desc->prv->nxt = desc->nxt;
if(desc->nxt)
if (desc->nxt)
desc->nxt->prv = desc->prv;
if(pool->tasks == desc)
if (pool->tasks == desc)
pool->tasks = desc->nxt;
free(desc);
pthread_setspecific(stats_tls_key, NULL);
@ -566,10 +564,9 @@ static inline int thrmgr_contended(threadpool_t *pool, int bulk)
{
/* don't allow bulk items to exceed 50% of queue, so that
* non-bulk items get a chance to be in the queue */
if (bulk && pool->bulk_queue->item_count >= pool->queue_max/2)
if (bulk && pool->bulk_queue->item_count >= pool->queue_max / 2)
return 1;
return pool->bulk_queue->item_count + pool->single_queue->item_count
+ pool->thr_alive - pool->thr_idle >= pool->queue_max;
return pool->bulk_queue->item_count + pool->single_queue->item_count + pool->thr_alive - pool->thr_idle >= pool->queue_max;
}
/* when both queues have tasks, it will pick 4 items from the single queue,
@ -619,10 +616,9 @@ static void *thrmgr_pop(threadpool_t *pool)
return task;
}
static void *thrmgr_worker(void *arg)
{
threadpool_t *threadpool = (threadpool_t *) arg;
threadpool_t *threadpool = (threadpool_t *)arg;
void *job_data;
int retval, must_exit = FALSE, stats_inited = FALSE;
struct timespec timeout;
@ -633,7 +629,7 @@ static void *thrmgr_worker(void *arg)
logg("!Fatal: mutex lock failed\n");
exit(-2);
}
if(!stats_inited) {
if (!stats_inited) {
stats_init(threadpool);
stats_inited = TRUE;
}
@ -642,8 +638,7 @@ static void *thrmgr_worker(void *arg)
timeout.tv_sec = time(NULL) + threadpool->idle_timeout;
timeout.tv_nsec = 0;
threadpool->thr_idle++;
while (((job_data=thrmgr_pop(threadpool)) == NULL)
&& (threadpool->state != POOL_EXIT)) {
while (((job_data = thrmgr_pop(threadpool)) == NULL) && (threadpool->state != POOL_EXIT)) {
/* Sleep, awaiting wakeup */
pthread_cond_signal(&threadpool->idle_cond);
retval = pthread_cond_timedwait(&(threadpool->pool_cond),
@ -837,7 +832,7 @@ void thrmgr_group_waitforall(jobgroup_t *group, unsigned *ok, unsigned *error, u
*ok = group->exit_ok;
*error = group->exit_error + needexit;
*total = group->exit_total;
if(!--group->jobs)
if (!--group->jobs)
needfree = 1;
else
logg("$THRMGR: active jobs for %p: %d\n", group, group->jobs);

View file

@ -107,7 +107,7 @@ int thrmgr_group_need_terminate(jobgroup_t *group);
void thrmgr_group_terminate(jobgroup_t *group);
jobgroup_t *thrmgr_group_new(void);
int thrmgr_printstats(int outfd, char term);
void thrmgr_setactivetask(const char *filename, const char* command);
void thrmgr_setactivetask(const char *filename, const char *command);
void thrmgr_setactiveengine(const struct cl_engine *engine);
#endif

View file

@ -52,7 +52,7 @@ struct optstruct *clamdopts = NULL;
static void print_server_version(const struct optstruct *opt)
{
if(get_clamd_version(opt)) {
if (get_clamd_version(opt)) {
/* can't get version from server, fallback */
printf("ClamAV %s\n", get_version());
}
@ -69,48 +69,48 @@ int main(int argc, char **argv)
struct sigaction sigact;
#endif
if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMDSCAN, OPT_CLAMSCAN, NULL)) == NULL) {
if ((opts = optparse(NULL, argc, argv, 1, OPT_CLAMDSCAN, OPT_CLAMSCAN, NULL)) == NULL) {
mprintf("!Can't parse command line options\n");
return 2;
}
if((clamdopts = optparse(optget(opts, "config-file")->strarg, 0, NULL, 1, OPT_CLAMD, 0, NULL)) == NULL) {
if ((clamdopts = optparse(optget(opts, "config-file")->strarg, 0, NULL, 1, OPT_CLAMD, 0, NULL)) == NULL) {
logg("!Can't parse clamd configuration file %s\n", optget(opts, "config-file")->strarg);
return 2;
}
if(optget(opts, "verbose")->enabled) {
if (optget(opts, "verbose")->enabled) {
mprintf_verbose = 1;
logg_verbose = 1;
}
if(optget(opts, "quiet")->enabled)
if (optget(opts, "quiet")->enabled)
mprintf_quiet = 1;
if(optget(opts, "stdout")->enabled)
if (optget(opts, "stdout")->enabled)
mprintf_stdout = 1;
if(optget(opts, "version")->enabled) {
if (optget(opts, "version")->enabled) {
print_server_version(opts);
optfree(opts);
optfree(clamdopts);
exit(0);
}
if(optget(opts, "help")->enabled) {
if (optget(opts, "help")->enabled) {
optfree(opts);
optfree(clamdopts);
help();
}
if(optget(opts, "infected")->enabled)
if (optget(opts, "infected")->enabled)
printinfected = 1;
/* initialize logger */
if((opt = optget(opts, "log"))->enabled) {
if ((opt = optget(opts, "log"))->enabled) {
logg_file = opt->strarg;
if(logg("--------------------------------------\n")) {
if (logg("--------------------------------------\n")) {
mprintf("!Problem with internal logger.\n");
optfree(opts);
optfree(clamdopts);
@ -119,8 +119,7 @@ int main(int argc, char **argv)
} else
logg_file = NULL;
if(optget(opts, "reload")->enabled) {
if (optget(opts, "reload")->enabled) {
ret = reload_clamd_database(opts);
optfree(opts);
optfree(clamdopts);
@ -128,7 +127,7 @@ int main(int argc, char **argv)
exit(ret);
}
if(actsetup(opts)) {
if (actsetup(opts)) {
optfree(opts);
optfree(clamdopts);
logg_close();
@ -152,23 +151,23 @@ int main(int argc, char **argv)
optfree(clamdopts);
/* TODO: Implement STATUS in clamd */
if(!optget(opts, "no-summary")->enabled) {
if (!optget(opts, "no-summary")->enabled) {
gettimeofday(&t2, NULL);
ds = t2.tv_sec - t1.tv_sec;
dms = t2.tv_usec - t1.tv_usec;
ds -= (dms < 0) ? (1):(0);
dms += (dms < 0) ? (1000000):(0);
ds -= (dms < 0) ? (1) : (0);
dms += (dms < 0) ? (1000000) : (0);
logg("\n----------- SCAN SUMMARY -----------\n");
logg("Infected files: %d\n", infected);
if(err)
if (err)
logg("Total errors: %d\n", err);
if(notremoved) {
if (notremoved) {
logg("Not removed: %d\n", notremoved);
}
if(notmoved) {
if (notmoved) {
logg("Not moved: %d\n", notmoved);
}
logg("Time: %d.%3.3d sec (%d m %d s)\n", ds, dms/1000, ds/60, ds%60);
logg("Time: %d.%3.3d sec (%d m %d s)\n", ds, dms / 1000, ds / 60, ds % 60);
}
logg_close();

View file

@ -74,7 +74,8 @@ extern struct optstruct *clamdopts;
/* Inits the communication layer
* Returns 0 if clamd is local, non zero if clamd is remote */
static int isremote(const struct optstruct *opts) {
static int isremote(const struct optstruct *opts)
{
int s, ret;
const struct optstruct *opt;
char *ipaddr, port[10];
@ -84,15 +85,15 @@ static int isremote(const struct optstruct *opts) {
UNUSEDPARAM(opts);
#ifndef _WIN32
if((opt = optget(clamdopts, "LocalSocket"))->enabled) {
if ((opt = optget(clamdopts, "LocalSocket"))->enabled) {
memset((void *)&nixsock, 0, sizeof(nixsock));
nixsock.sun_family = AF_UNIX;
strncpy(nixsock.sun_path, opt->strarg, sizeof(nixsock.sun_path));
nixsock.sun_path[sizeof(nixsock.sun_path)-1]='\0';
nixsock.sun_path[sizeof(nixsock.sun_path) - 1] = '\0';
return 0;
}
#endif
if(!(opt = optget(clamdopts, "TCPSocket"))->enabled)
if (!(opt = optget(clamdopts, "TCPSocket"))->enabled)
return 0;
snprintf(port, sizeof(port), "%lld", optget(clamdopts, "TCPSocket")->numarg);
@ -115,7 +116,7 @@ static int isremote(const struct optstruct *opts) {
}
for (p = info; p != NULL; p = p->ai_next) {
if((s = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
if ((s = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
logg("isremote: socket() returning: %s.\n", strerror(errno));
continue;
}
@ -159,32 +160,32 @@ static int isremote(const struct optstruct *opts) {
return 0;
}
/* Turns a relative path into an absolute one
* Returns a pointer to the path (which must be
* freed by the caller) or NULL on error */
static char *makeabs(const char *basepath) {
static char *makeabs(const char *basepath)
{
int namelen;
char *ret;
if(!(ret = malloc(PATH_MAX + 1))) {
if (!(ret = malloc(PATH_MAX + 1))) {
logg("^Can't make room for fullpath.\n");
return NULL;
}
if(!cli_is_abspath(basepath)) {
if(!getcwd(ret, PATH_MAX)) {
if (!cli_is_abspath(basepath)) {
if (!getcwd(ret, PATH_MAX)) {
logg("^Can't get absolute pathname of current working directory.\n");
free(ret);
return NULL;
}
#ifdef _WIN32
if(*basepath == '\\') {
if (*basepath == '\\') {
namelen = 2;
basepath++;
} else
#endif
namelen = strlen(ret);
snprintf(&ret[namelen], PATH_MAX - namelen, PATHSEP"%s", basepath);
snprintf(&ret[namelen], PATH_MAX - namelen, PATHSEP "%s", basepath);
} else {
strncpy(ret, basepath, PATH_MAX);
}
@ -194,11 +195,12 @@ static char *makeabs(const char *basepath) {
/* Recursively scans a path with the given scantype
* Returns non zero for serious errors, zero otherwise */
static int client_scan(const char *file, int scantype, int *infected, int *err, int maxlevel, int session, int flags) {
static int client_scan(const char *file, int scantype, int *infected, int *err, int maxlevel, int session, int flags)
{
int ret;
char *fullpath = makeabs(file);
if(!fullpath)
if (!fullpath)
return 0;
if (!session)
ret = serial_client_scan(fullpath, scantype, infected, err, maxlevel, flags);
@ -215,16 +217,16 @@ int get_clamd_version(const struct optstruct *opts)
struct RCVLN rcv;
isremote(opts);
if((sockd = dconnect()) < 0) return 2;
if ((sockd = dconnect()) < 0) return 2;
recvlninit(&rcv, sockd);
if(sendln(sockd, "zVERSION", 9)) {
if (sendln(sockd, "zVERSION", 9)) {
closesocket(sockd);
return 2;
}
while((len = recvln(&rcv, &buff, NULL))) {
if(len == -1) {
while ((len = recvln(&rcv, &buff, NULL))) {
if (len == -1) {
logg("!Error occurred while receiving version information.\n");
break;
}
@ -242,15 +244,15 @@ int reload_clamd_database(const struct optstruct *opts)
struct RCVLN rcv;
isremote(opts);
if((sockd = dconnect()) < 0) return 2;
if ((sockd = dconnect()) < 0) return 2;
recvlninit(&rcv, sockd);
if(sendln(sockd, "zRELOAD", 8)) {
if (sendln(sockd, "zRELOAD", 8)) {
closesocket(sockd);
return 2;
}
if(!(len = recvln(&rcv, &buff, NULL)) || len < 10 || memcmp(buff, "RELOADING", 9)) {
if (!(len = recvln(&rcv, &buff, NULL)) || len < 10 || memcmp(buff, "RELOADING", 9)) {
logg("!Clamd did not reload the database\n");
closesocket(sockd);
return 2;
@ -267,18 +269,20 @@ int client(const struct optstruct *opts, int *infected, int *err)
scandash = (opts->filename && opts->filename[0] && !strcmp(opts->filename[0], "-") && !optget(opts, "file-list")->enabled && !opts->filename[1]);
remote = isremote(opts) | optget(opts, "stream")->enabled;
#ifdef HAVE_FD_PASSING
if(!remote && optget(clamdopts, "LocalSocket")->enabled && (optget(opts, "fdpass")->enabled || scandash)) {
if (!remote && optget(clamdopts, "LocalSocket")->enabled && (optget(opts, "fdpass")->enabled || scandash)) {
scantype = FILDES;
session = optget(opts, "multiscan")->enabled;
} else
#endif
if(remote || scandash) {
if (remote || scandash) {
scantype = STREAM;
session = optget(opts, "multiscan")->enabled;
}
else if(optget(opts, "multiscan")->enabled) scantype = MULTI;
else if(optget(opts, "allmatch")->enabled) scantype = ALLMATCH;
else scantype = CONT;
} else if (optget(opts, "multiscan")->enabled)
scantype = MULTI;
else if (optget(opts, "allmatch")->enabled)
scantype = ALLMATCH;
else
scantype = CONT;
maxrec = optget(clamdopts, "MaxDirectoryRecursion")->numarg;
maxstream = optget(clamdopts, "StreamMaxLength")->numarg;
@ -290,26 +294,26 @@ int client(const struct optstruct *opts, int *infected, int *err)
*infected = 0;
if(scandash) {
if (scandash) {
int sockd, ret;
STATBUF sb;
if(FSTAT(0, &sb) < 0) {
if (FSTAT(0, &sb) < 0) {
logg("client.c: fstat failed for file name \"%s\", with %s\n.",
opts->filename[0], strerror(errno));
return 2;
}
if((sb.st_mode & S_IFMT) != S_IFREG) scantype = STREAM;
if((sockd = dconnect()) >= 0 && (ret = dsresult(sockd, scantype, NULL, &ret, NULL)) >= 0)
if ((sb.st_mode & S_IFMT) != S_IFREG) scantype = STREAM;
if ((sockd = dconnect()) >= 0 && (ret = dsresult(sockd, scantype, NULL, &ret, NULL)) >= 0)
*infected = ret;
else
errors = 1;
if(sockd >= 0) closesocket(sockd);
} else if(opts->filename || optget(opts, "file-list")->enabled) {
if(opts->filename && optget(opts, "file-list")->enabled)
if (sockd >= 0) closesocket(sockd);
} else if (opts->filename || optget(opts, "file-list")->enabled) {
if (opts->filename && optget(opts, "file-list")->enabled)
logg("^Only scanning files from --file-list (files passed at cmdline are ignored)\n");
while((fname = filelist(opts, NULL))) {
if(!strcmp(fname, "-")) {
while ((fname = filelist(opts, NULL))) {
if (!strcmp(fname, "-")) {
logg("!Scanning from standard input requires \"-\" to be the only file argument\n");
continue;
}

View file

@ -69,11 +69,12 @@ extern struct optstruct *clamdopts;
extern struct sockaddr_un nixsock;
#endif
static const char *scancmd[] = { "CONTSCAN", "MULTISCAN", "INSTREAM", "FILDES", "ALLMATCHSCAN" };
static const char *scancmd[] = {"CONTSCAN", "MULTISCAN", "INSTREAM", "FILDES", "ALLMATCHSCAN"};
/* Connects to clamd
* Returns a FD or -1 on error */
int dconnect() {
int dconnect()
{
int sockd, res;
const struct optstruct *opt;
struct addrinfo hints, *info, *p;
@ -114,12 +115,12 @@ int dconnect() {
}
for (p = info; p != NULL; p = p->ai_next) {
if((sockd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
if ((sockd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
logg("!Can't create the socket: %s\n", strerror(errno));
continue;
}
if(connect(sockd, p->ai_addr, p->ai_addrlen) < 0) {
if (connect(sockd, p->ai_addr, p->ai_addrlen) < 0) {
logg("!Could not connect to clamd on %s: %s\n", opt->strarg, strerror(errno));
closesocket(sockd);
continue;
@ -139,42 +140,44 @@ int dconnect() {
/* Issues an INSTREAM command to clamd and streams the given file
* Returns >0 on success, 0 soft fail, -1 hard fail */
static int send_stream(int sockd, const char *filename) {
uint32_t buf[BUFSIZ/sizeof(uint32_t)];
static int send_stream(int sockd, const char *filename)
{
uint32_t buf[BUFSIZ / sizeof(uint32_t)];
int fd, len;
unsigned long int todo = maxstream;
if(filename) {
if((fd = safe_open(filename, O_RDONLY | O_BINARY))<0) {
if (filename) {
if ((fd = safe_open(filename, O_RDONLY | O_BINARY)) < 0) {
logg("~%s: Access denied. ERROR\n", filename);
return 0;
}
} else fd = 0;
} else
fd = 0;
if(sendln(sockd, "zINSTREAM", 10)) {
if (sendln(sockd, "zINSTREAM", 10)) {
close(fd);
return -1;
}
while((len = read(fd, &buf[1], sizeof(buf) - sizeof(uint32_t))) > 0) {
if((unsigned int)len > todo) len = todo;
while ((len = read(fd, &buf[1], sizeof(buf) - sizeof(uint32_t))) > 0) {
if ((unsigned int)len > todo) len = todo;
buf[0] = htonl(len);
if(sendln(sockd, (const char *)buf, len+sizeof(uint32_t))) {
if (sendln(sockd, (const char *)buf, len + sizeof(uint32_t))) {
close(fd);
return -1;
}
todo -= len;
if(!todo) {
if (!todo) {
len = 0;
break;
}
}
close(fd);
if(len) {
if (len) {
logg("!Failed to read from %s.\n", filename ? filename : "STDIN");
return 0;
}
*buf=0;
*buf = 0;
sendln(sockd, (const char *)buf, 4);
return 1;
}
@ -182,21 +185,23 @@ static int send_stream(int sockd, const char *filename) {
#ifdef HAVE_FD_PASSING
/* Issues a FILDES command and pass a FD to clamd
* Returns >0 on success, 0 soft fail, -1 hard fail */
static int send_fdpass(int sockd, const char *filename) {
static int send_fdpass(int sockd, const char *filename)
{
struct iovec iov[1];
struct msghdr msg;
struct cmsghdr *cmsg;
unsigned char fdbuf[CMSG_SPACE(sizeof(int))];
char dummy[]="";
char dummy[] = "";
int fd;
if(filename) {
if((fd = open(filename, O_RDONLY))<0) {
if (filename) {
if ((fd = open(filename, O_RDONLY)) < 0) {
logg("~%s: Access denied. ERROR\n", filename);
return 0;
}
} else fd = 0;
if(sendln(sockd, "zFILDES", 8)) {
} else
fd = 0;
if (sendln(sockd, "zFILDES", 8)) {
close(fd);
return -1;
}
@ -213,7 +218,7 @@ static int send_fdpass(int sockd, const char *filename) {
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
*(int *)CMSG_DATA(cmsg) = fd;
if(sendmsg(sockd, &msg, 0) == -1) {
if (sendmsg(sockd, &msg, 0) == -1) {
logg("!FD send failed: %s\n", strerror(errno));
close(fd);
return -1;
@ -228,9 +233,9 @@ static int chkpath(const char *path)
{
const struct optstruct *opt;
if((opt = optget(clamdopts, "ExcludePath"))->enabled) {
while(opt) {
if(match_regex(path, opt->strarg) == 1) {
if ((opt = optget(clamdopts, "ExcludePath"))->enabled) {
while (opt) {
if (match_regex(path, opt->strarg) == 1) {
if (printinfected != 1)
logg("~%s: Excluded\n", path);
return 1;
@ -251,17 +256,18 @@ static int ftw_chkpath(const char *path, struct cli_ftw_cbdata *data)
* This is used only in non IDSESSION mode
* Returns the number of infected files or -1 on error
* NOTE: filename may be NULL for STREAM scantype. */
int dsresult(int sockd, int scantype, const char *filename, int *printok, int *errors) {
int dsresult(int sockd, int scantype, const char *filename, int *printok, int *errors)
{
int infected = 0, len = 0, beenthere = 0;
char *bol, *eol;
struct RCVLN rcv;
STATBUF sb;
if(filename && chkpath(filename))
if (filename && chkpath(filename))
return 0;
recvlninit(&rcv, sockd);
switch(scantype) {
switch (scantype) {
case MULTI:
case CONT:
case ALLMATCH:
@ -275,7 +281,7 @@ int dsresult(int sockd, int scantype, const char *filename, int *printok, int *e
return -1;
}
sprintf(bol, "z%s %s", scancmd[scantype], filename);
if(sendln(sockd, bol, len)) {
if (sendln(sockd, bol, len)) {
free(bol);
return -1;
}
@ -294,38 +300,37 @@ int dsresult(int sockd, int scantype, const char *filename, int *printok, int *e
#endif
}
if(len <=0) {
if (len <= 0) {
*printok = 0;
if(errors)
if (errors)
(*errors)++;
return len;
}
while((len = recvln(&rcv, &bol, &eol))) {
if(len == -1) return -1;
while ((len = recvln(&rcv, &bol, &eol))) {
if (len == -1) return -1;
beenthere = 1;
if(!filename) logg("~%s\n", bol);
if(len > 7) {
if (!filename) logg("~%s\n", bol);
if (len > 7) {
char *colon = strrchr(bol, ':');
if(colon && colon[1] != ' ') {
if (colon && colon[1] != ' ') {
char *br;
*colon = 0;
br = strrchr(bol, '(');
if(br)
if (br)
*br = 0;
colon = strrchr(bol, ':');
}
if(!colon) {
char * unkco = "UNKNOWN COMMAND";
if (!colon) {
char *unkco = "UNKNOWN COMMAND";
if (!strncmp(bol, unkco, sizeof(unkco) - 1))
logg("clamd replied \"UNKNOWN COMMAND\". Command was %s\n",
(scantype < 0 || scantype > MAX_SCANTYPE) ? "unidentified" :
scancmd[scantype]);
(scantype < 0 || scantype > MAX_SCANTYPE) ? "unidentified" : scancmd[scantype]);
else
logg("Failed to parse reply: \"%s\"\n", bol);
return -1;
} else if(!memcmp(eol - 7, " FOUND", 6)) {
static char last_filename[PATH_MAX+1] = {'\0'};
} else if (!memcmp(eol - 7, " FOUND", 6)) {
static char last_filename[PATH_MAX + 1] = {'\0'};
*(eol - 7) = 0;
*printok = 0;
if (scantype != ALLMATCH) {
@ -337,23 +342,23 @@ int dsresult(int sockd, int scantype, const char *filename, int *printok, int *e
last_filename[PATH_MAX] = '\0';
}
}
if(filename) {
if(scantype >= STREAM) {
if (filename) {
if (scantype >= STREAM) {
logg("~%s%s FOUND\n", filename, colon);
if(action) action(filename);
if (action) action(filename);
} else {
logg("~%s FOUND\n", bol);
*colon = '\0';
if(action)
if (action)
action(bol);
}
}
} else if(!memcmp(eol-7, " ERROR", 6)) {
if(errors)
} else if (!memcmp(eol - 7, " ERROR", 6)) {
if (errors)
(*errors)++;
*printok = 0;
if(filename) {
if(scantype >= STREAM)
if (filename) {
if (scantype >= STREAM)
logg("~%s%s\n", filename, colon);
else
logg("~%s\n", bol);
@ -361,17 +366,17 @@ int dsresult(int sockd, int scantype, const char *filename, int *printok, int *e
}
}
}
if(!beenthere) {
if (!beenthere) {
if (!filename) {
logg("STDIN: noreply from clamd\n.");
return -1;
}
if(CLAMSTAT(filename, &sb) == -1) {
if (CLAMSTAT(filename, &sb) == -1) {
logg("~%s: stat() failed with %s, clamd may not be responding\n",
filename, strerror(errno));
return -1;
}
if(!S_ISDIR(sb.st_mode)) {
if (!S_ISDIR(sb.st_mode)) {
logg("~%s: no reply from clamd\n", filename);
return -1;
}
@ -390,17 +395,18 @@ struct client_serial_data {
/* FTW callback for scanning in non IDSESSION mode
* Returns SUCCESS or BREAK on success, CL_EXXX on error */
static int serial_callback(STATBUF *sb, char *filename, const char *path, enum cli_ftw_reason reason, struct cli_ftw_cbdata *data) {
static int serial_callback(STATBUF *sb, char *filename, const char *path, enum cli_ftw_reason reason, struct cli_ftw_cbdata *data)
{
struct client_serial_data *c = (struct client_serial_data *)data->data;
int sockd, ret;
const char *f = filename;
UNUSEDPARAM(sb);
if(chkpath(path))
if (chkpath(path))
return CL_SUCCESS;
c->files++;
switch(reason) {
switch (reason) {
case error_stat:
logg("!Can't access file %s\n", path);
c->errors++;
@ -418,7 +424,7 @@ static int serial_callback(STATBUF *sb, char *filename, const char *path, enum c
c->errors++;
return CL_SUCCESS;
case visit_directory_toplev:
if(c->scantype >= STREAM)
if (c->scantype >= STREAM)
return CL_SUCCESS;
f = path;
filename = NULL;
@ -426,27 +432,28 @@ static int serial_callback(STATBUF *sb, char *filename, const char *path, enum c
break;
}
if((sockd = dconnect()) < 0) {
if(filename) free(filename);
if ((sockd = dconnect()) < 0) {
if (filename) free(filename);
c->errors++;
return CL_EOPEN;
}
ret = dsresult(sockd, c->scantype, f, &c->printok, &c->errors);
if(filename) free(filename);
if (filename) free(filename);
closesocket(sockd);
if(ret < 0) {
if (ret < 0) {
c->errors++;
return CL_EOPEN;
}
c->infected += ret;
if(reason == visit_directory_toplev)
if (reason == visit_directory_toplev)
return CL_BREAK;
return CL_SUCCESS;
}
/* Non-IDSESSION handler
* Returns non zero for serious errors, zero otherwise */
int serial_client_scan(char *file, int scantype, int *infected, int *err, int maxlevel, int flags) {
int serial_client_scan(char *file, int scantype, int *infected, int *err, int maxlevel, int flags)
{
struct cli_ftw_cbdata data;
struct client_serial_data cdata;
int ftw;
@ -454,7 +461,7 @@ int serial_client_scan(char *file, int scantype, int *infected, int *err, int ma
cdata.infected = 0;
cdata.files = 0;
cdata.errors = 0;
cdata.printok = printinfected^1;
cdata.printok = printinfected ^ 1;
cdata.scantype = scantype;
data.data = &cdata;
@ -462,11 +469,11 @@ int serial_client_scan(char *file, int scantype, int *infected, int *err, int ma
*infected += cdata.infected;
*err += cdata.errors;
if(!cdata.errors && (ftw == CL_SUCCESS || ftw == CL_BREAK)) {
if(cdata.printok)
if (!cdata.errors && (ftw == CL_SUCCESS || ftw == CL_BREAK)) {
if (cdata.printok)
logg("~%s: OK\n", file);
return 0;
} else if(!cdata.files) {
} else if (!cdata.files) {
logg("~%s: No files scanned\n", file);
return 0;
}
@ -486,13 +493,14 @@ struct client_parallel_data {
unsigned int id;
const char *file;
struct SCANID *next;
} *ids;
} * ids;
};
/* Sends a proper scan request to clamd and parses its replies
* This is used only in IDSESSION mode
* Returns 0 on success, 1 on hard failures, 2 on len == 0 (bb#1717) */
static int dspresult(struct client_parallel_data *c) {
static int dspresult(struct client_parallel_data *c)
{
const char *filename;
char *bol, *eol;
unsigned int rid;
@ -503,33 +511,33 @@ static int dspresult(struct client_parallel_data *c) {
recvlninit(&rcv, c->sockd);
do {
len = recvln(&rcv, &bol, &eol);
if(len < 0) return 1;
if(!len) return 2;
if((rid = atoi(bol))) {
if (len < 0) return 1;
if (!len) return 2;
if ((rid = atoi(bol))) {
id = &c->ids;
while(*id) {
if((*id)->id == rid) break;
while (*id) {
if ((*id)->id == rid) break;
id = &((*id)->next);
}
if(!*id) id = NULL;
if (!*id) id = NULL;
}
if(!id) {
if (!id) {
logg("!Bogus session id from clamd\n");
return 1;
}
filename = (*id)->file;
if(len > 7) {
if (len > 7) {
char *colon = strrchr(bol, ':');
if(!colon) {
if (!colon) {
logg("!Failed to parse reply\n");
free((void *)filename);
return 1;
} else if(!memcmp(eol - 7, " FOUND", 6)) {
} else if (!memcmp(eol - 7, " FOUND", 6)) {
c->infected++;
c->printok = 0;
logg("~%s%s\n", filename, colon);
if(action) action(filename);
} else if(!memcmp(eol-7, " ERROR", 6)) {
if (action) action(filename);
} else if (!memcmp(eol - 7, " ERROR", 6)) {
c->errors++;
c->printok = 0;
logg("~%s%s\n", filename, colon);
@ -539,24 +547,25 @@ static int dspresult(struct client_parallel_data *c) {
bol = (char *)*id;
*id = (*id)->next;
free(bol);
} while(rcv.cur != rcv.buf); /* clamd sends whole lines, so, on partial lines, we just assume
} while (rcv.cur != rcv.buf); /* clamd sends whole lines, so, on partial lines, we just assume
more data can be recv()'d with close to zero latency */
return 0;
}
/* FTW callback for scanning in IDSESSION mode
* Returns SUCCESS on success, CL_EXXX or BREAK on error */
static int parallel_callback(STATBUF *sb, char *filename, const char *path, enum cli_ftw_reason reason, struct cli_ftw_cbdata *data) {
static int parallel_callback(STATBUF *sb, char *filename, const char *path, enum cli_ftw_reason reason, struct cli_ftw_cbdata *data)
{
struct client_parallel_data *c = (struct client_parallel_data *)data->data;
struct SCANID *cid;
int res = CL_CLEAN;
UNUSEDPARAM(sb);
if(chkpath(path))
if (chkpath(path))
return CL_SUCCESS;
c->files++;
switch(reason) {
switch (reason) {
case error_stat:
logg("!Can't access file %s\n", path);
c->errors++;
@ -578,7 +587,7 @@ static int parallel_callback(STATBUF *sb, char *filename, const char *path, enum
break;
}
while(1) {
while (1) {
/* consume all the available input to let some of the clamd
* threads blocked on send() to be dead.
* by doing so we shouldn't deadlock on the next recv() */
@ -587,23 +596,24 @@ static int parallel_callback(STATBUF *sb, char *filename, const char *path, enum
FD_SET(c->sockd, &rfds);
FD_ZERO(&wfds);
FD_SET(c->sockd, &wfds);
if(select(c->sockd + 1, &rfds, &wfds, NULL, NULL) < 0) {
if(errno == EINTR) continue;
if (select(c->sockd + 1, &rfds, &wfds, NULL, NULL) < 0) {
if (errno == EINTR) continue;
free(filename);
logg("!select() failed during session: %s\n", strerror(errno));
return CL_BREAK;
}
if(FD_ISSET(c->sockd, &rfds)) {
if(dspresult(c)) {
if (FD_ISSET(c->sockd, &rfds)) {
if (dspresult(c)) {
free(filename);
return CL_BREAK;
} else continue;
} else
continue;
}
if(FD_ISSET(c->sockd, &wfds)) break;
if (FD_ISSET(c->sockd, &wfds)) break;
}
cid = (struct SCANID *)malloc(sizeof(struct SCANID));
if(!cid) {
if (!cid) {
free(filename);
logg("!Failed to allocate scanid entry: %s\n", strerror(errno));
return CL_BREAK;
@ -613,7 +623,7 @@ static int parallel_callback(STATBUF *sb, char *filename, const char *path, enum
cid->next = c->ids;
c->ids = cid;
switch(c->scantype) {
switch (c->scantype) {
#ifdef HAVE_FD_PASSING
case FILDES:
res = send_fdpass(c->sockd, filename);
@ -623,7 +633,7 @@ static int parallel_callback(STATBUF *sb, char *filename, const char *path, enum
res = send_stream(c->sockd, filename);
break;
}
if(res <= 0) {
if (res <= 0) {
c->printok = 0;
c->errors++;
c->ids = cid->next;
@ -637,15 +647,16 @@ static int parallel_callback(STATBUF *sb, char *filename, const char *path, enum
/* IDSESSION handler
* Returns non zero for serious errors, zero otherwise */
int parallel_client_scan(char *file, int scantype, int *infected, int *err, int maxlevel, int flags) {
int parallel_client_scan(char *file, int scantype, int *infected, int *err, int maxlevel, int flags)
{
struct cli_ftw_cbdata data;
struct client_parallel_data cdata;
int ftw;
if((cdata.sockd = dconnect()) < 0)
if ((cdata.sockd = dconnect()) < 0)
return 1;
if(sendln(cdata.sockd, "zIDSESSION", 11)) {
if (sendln(cdata.sockd, "zIDSESSION", 11)) {
closesocket(cdata.sockd);
return 1;
}
@ -656,12 +667,12 @@ int parallel_client_scan(char *file, int scantype, int *infected, int *err, int
cdata.scantype = scantype;
cdata.lastid = 0;
cdata.ids = NULL;
cdata.printok = printinfected^1;
cdata.printok = printinfected ^ 1;
data.data = &cdata;
ftw = cli_ftw(file, flags, maxlevel ? maxlevel : INT_MAX, parallel_callback, &data, ftw_chkpath);
if(ftw != CL_SUCCESS) {
if (ftw != CL_SUCCESS) {
*err += cdata.errors;
*infected += cdata.infected;
closesocket(cdata.sockd);
@ -675,17 +686,17 @@ int parallel_client_scan(char *file, int scantype, int *infected, int *err, int
*infected += cdata.infected;
*err += cdata.errors;
if(cdata.ids) {
if (cdata.ids) {
logg("!Clamd closed the connection before scanning all files.\n");
return 1;
}
if(cdata.errors)
if (cdata.errors)
return 1;
if(!cdata.files)
if (!cdata.files)
return 0;
if(cdata.printok)
if (cdata.printok)
logg("~%s: OK\n", file);
return 0;
}

View file

@ -94,7 +94,7 @@ struct stats {
unsigned live, idle, max;
/* queue */
unsigned biggest_queue, current_q;
double mem;/* in megabytes */
double mem; /* in megabytes */
unsigned long lheapu, lmmapu, ltotalu, ltotalf, lreleasable, lpoolu, lpoolt;
unsigned pools_cnt;
};
@ -108,7 +108,7 @@ char *get_port(const char *ip);
char *make_ip(const char *host, const char *port);
enum exit_reason {
FAIL_CMDLINE=1,
FAIL_CMDLINE = 1,
FAIL_INITIAL_CONN,
OUT_OF_MEMORY,
RECONNECT_FAIL,
@ -121,12 +121,14 @@ static void exit_program(enum exit_reason reason, const char *func, unsigned lin
#else
#define EXIT_PROGRAM(r) exit_program(r, "<unknown>", __LINE__);
#endif
#define OOM_CHECK(p) do { if (!p) EXIT_PROGRAM(OUT_OF_MEMORY); } while (0)
#define OOM_CHECK(p) \
do { \
if (!p) EXIT_PROGRAM(OUT_OF_MEMORY); \
} while (0)
static struct global_stats global;
static int curses_inited = 1;
static int maxystats=0;
static int maxystats = 0;
static int detail_selected = -1;
static int detail_exists(void)
@ -143,10 +145,9 @@ static int detail_is_selected(int idx)
return idx == detail_selected;
}
/* ---------------------- NCurses routines -----------------*/
enum colors {
header_color=1,
header_color = 1,
version_color,
error_color,
value_color,
@ -175,7 +176,7 @@ static WINDOW *status_bar_window = NULL;
static WINDOW *mem_window = NULL;
static const char *status_bar_keys[10];
static unsigned maxy=0, maxx=0;
static unsigned maxy = 0, maxx = 0;
static char *queue_header = NULL;
static char *clamd_header = NULL;
@ -197,7 +198,7 @@ static void resize(void)
char *p;
unsigned new_maxy, new_maxx;
getmaxyx(stdscr, new_maxy, new_maxx);
if(new_maxy == maxy && new_maxx == maxx)
if (new_maxy == maxy && new_maxx == maxx)
return;
maxx = new_maxx;
maxy = new_maxy;
@ -208,43 +209,42 @@ static void resize(void)
clamd_header = malloc(maxx + 1);
OOM_CHECK(clamd_header);
assert(clamd_header && queue_header);
strncpy(queue_header, global.num_clamd>1 ? CMDHEAD2 : CMDHEAD, maxx);
strncpy(queue_header, global.num_clamd > 1 ? CMDHEAD2 : CMDHEAD, maxx);
strncpy(clamd_header, SUMHEAD, maxx);
queue_header[maxx] = '\0';
clamd_header[maxx] = '\0';
p = queue_header + strlen(queue_header);
while(p < queue_header+maxx)
while (p < queue_header + maxx)
*p++ = ' ';
p = clamd_header + strlen(clamd_header);
while(p < clamd_header+maxx)
while (p < clamd_header + maxx)
*p++ = ' ';
}
static void rm_windows(void)
{
if(header_window) {
if (header_window) {
delwin(header_window);
header_window = NULL;
}
if(mem_window) {
if (mem_window) {
delwin(mem_window);
mem_window = NULL;
}
if(stats_window) {
if (stats_window) {
delwin(stats_window);
stats_window = NULL;
}
if(stats_head_window) {
if (stats_head_window) {
delwin(stats_head_window);
stats_head_window = NULL;
}
if(status_bar_window) {
if (status_bar_window) {
delwin(status_bar_window);
status_bar_window = NULL;
}
}
static void init_windows(int num_clamd)
{
resize();
@ -252,12 +252,12 @@ static void init_windows(int num_clamd)
rm_windows();
/* non-overlapping windows */
header_window = subwin(stdscr, 1, maxx, 0, 0);
stats_head_window = subwin(stdscr, num_clamd+1, maxx, 1, 0);
maxystats = maxy-num_clamd-3;
stats_window = subwin(stdscr, maxystats, maxx, num_clamd+2, 0);
status_bar_window = subwin(stdscr, 1, maxx, maxy-1, 0);
stats_head_window = subwin(stdscr, num_clamd + 1, maxx, 1, 0);
maxystats = maxy - num_clamd - 3;
stats_window = subwin(stdscr, maxystats, maxx, num_clamd + 2, 0);
status_bar_window = subwin(stdscr, 1, maxx, maxy - 1, 0);
/* memwindow overlaps, used only in details mode */
mem_window = derwin(stats_window, 6, 41, 1, maxx-41);
mem_window = derwin(stats_window, 6, 41, 1, maxx - 41);
touchwin(stdscr);
werase(stdscr);
refresh();
@ -281,7 +281,7 @@ static void init_ncurses(int num_clamd, int use_default)
start_color();
keypad(stdscr, TRUE); /* enable keyboard mapping */
nonl(); /* tell curses not to do NL->CR/NL on output */
halfdelay(UPDATE_INTERVAL*10); /* timeout of 2s when waiting for input*/
halfdelay(UPDATE_INTERVAL * 10); /* timeout of 2s when waiting for input*/
noecho(); /* dont echo input */
curs_set(0); /* turn off cursor */
if (use_default)
@ -308,16 +308,15 @@ static void win_start(WINDOW *win, enum colors col)
werase(win);
}
static void print_colored(WINDOW *win, const char *p)
{
while(*p) {
while (*p) {
wattron(win, DESCR_ATTR);
while(*p && !isdigit(*p))
while (*p && !isdigit(*p))
waddch(win, *p++);
wattroff(win, DESCR_ATTR);
wattron(win, VALUE_ATTR);
while(*p && isdigit(*p))
while (*p && isdigit(*p))
waddch(win, *p++);
wattroff(win, VALUE_ATTR);
}
@ -325,25 +324,24 @@ static void print_colored(WINDOW *win, const char *p)
static void header(void)
{
size_t i, x=0;
size_t i, x = 0;
time_t t;
win_start(header_window, header_color);
mvwprintw(header_window, 0, 0, " ClamdTOP version %s ", get_version());
time(&t);
wprintw(header_window, "%s", ctime(&t));
wrefresh(header_window);
/* win_start(version_window, version_color);
/* win_start(version_window, version_color);
mvwprintw(version_window, 0, 0, "Connected to: ");
print_colored(version_window, clamd_version ? clamd_version : "Unknown");
wrefresh(version_window);*/
werase(status_bar_window);
for(i=0;i<sizeof(status_bar_keys)/sizeof(status_bar_keys[0]);i++) {
for (i = 0; i < sizeof(status_bar_keys) / sizeof(status_bar_keys[0]); i++) {
const char *s = status_bar_keys[i];
if(!s)
if (!s)
continue;
wattron(status_bar_window, A_REVERSE);
if (s[0] == '^') {
@ -355,7 +353,7 @@ static void header(void)
s++;
x++;
}
mvwprintw(status_bar_window, 0, x, "%s",s);
mvwprintw(status_bar_window, 0, x, "%s", s);
wattroff(status_bar_window, A_REVERSE);
x += strlen(status_bar_keys[i]) + 1;
}
@ -365,27 +363,27 @@ static void header(void)
static void show_bar(WINDOW *win, size_t i, unsigned live, unsigned idle,
unsigned max, int blink)
{
int y,x,z = 0;
int y, x, z = 0;
unsigned len = 39;
unsigned start = 1;
unsigned activ = max ? ((live-idle)*(len - start - 2) + (max/2)) / max : 0;
unsigned dim = max ? idle*(len - start - 2) / max : 0;
unsigned rem = len - activ - dim - start-2;
unsigned activ = max ? ((live - idle) * (len - start - 2) + (max / 2)) / max : 0;
unsigned dim = max ? idle * (len - start - 2) / max : 0;
unsigned rem = len - activ - dim - start - 2;
assert(activ + 2 < len && activ+dim + 2 < len && activ+dim+rem + 2 < len && "Invalid values");
assert(activ + 2 < len && activ + dim + 2 < len && activ + dim + rem + 2 < len && "Invalid values");
mvwaddch(win, i, start, '[' | A_BOLD);
wattron(win, A_BOLD | COLOR_PAIR(activ_color));
for(i=0;i<activ;i++)
for (i = 0; i < activ; i++)
waddch(win, '|');
wattroff(win, A_BOLD | COLOR_PAIR(activ_color));
wattron(win, A_DIM | COLOR_PAIR(dim_color));
for(i=0;i<dim;i++)
for (i = 0; i < dim; i++)
waddch(win, '|');
wattroff(win, A_DIM | COLOR_PAIR(dim_color));
for(i=0;i<rem;i++)
for (i = 0; i < rem; i++)
waddch(win, ' ');
waddch(win, ']' | A_BOLD);
if(blink) {
if (blink) {
getyx(win, y, x);
if ((x < 0) || (y < 0)) {
return; /* if getyx() failed, nevermind the blinking */
@ -416,7 +414,7 @@ static void cleanup(void)
endwin();
}
curses_inited = 0;
for (i=0;i<global.num_clamd;i++) {
for (i = 0; i < global.num_clamd; i++) {
if (global.conn[i].sd && global.conn[i].sd != -1) {
send_string_noreconn(&global.conn[i], "nEND\n");
close(global.conn[i].sd);
@ -428,12 +426,12 @@ static void cleanup(void)
free(global.conn);
free(queue_header);
free(clamd_header);
if(!normal_exit) {
if (!normal_exit) {
fprintf(stderr, "Abnormal program termination");
if (exit_reason) fprintf(stderr, ": %s",exit_reason);
if (exit_reason) fprintf(stderr, ": %s", exit_reason);
if (exit_func) fprintf(stderr, " in %s", exit_func);
if (exit_line) fprintf(stderr, " at line %u", exit_line);
fputc('\n',stderr);
fputc('\n', stderr);
}
}
@ -445,7 +443,7 @@ static void cleanup(void)
static void __noreturn exit_program(enum exit_reason reason, const char *func, unsigned line)
{
switch(reason) {
switch (reason) {
case FAIL_CMDLINE:
exit_reason = "Invalid command-line arguments";
break;
@ -480,9 +478,9 @@ static int tasks_compare(const void *a, const void *b)
{
const struct task *ta = a;
const struct task *tb = b;
if(ta->tim < tb->tim)
if (ta->tim < tb->tim)
return 1;
if(ta->tim > tb->tim)
if (ta->tim > tb->tim)
return -1;
return 0;
}
@ -499,9 +497,9 @@ static void print_con_info(conn_t *conn, const char *fmt, ...)
char *buf = malloc(maxx);
OOM_CHECK(buf);
memset(buf, ' ', maxx);
vsnprintf(buf, maxx-1, fmt, ap);
vsnprintf(buf, maxx - 1, fmt, ap);
buf[strlen(buf)] = ' ';
buf[maxx-1] = '\0';
buf[maxx - 1] = '\0';
wattron(stats_head_window, ERROR_ATTR);
mvwprintw(stats_head_window, conn->line, 0, "%s", buf);
wattroff(stats_head_window, ERROR_ATTR);
@ -541,13 +539,13 @@ char *get_ip(const char *ip)
*p1 = '\0';
p1 = strdup(dupip+1);
p1 = strdup(dupip + 1);
free(dupip);
return p1;
}
p1 = dupip;
i=0;
i = 0;
while ((p1 = strchr(p1, ':'))) {
i++;
p1++;
@ -568,7 +566,7 @@ char *get_ip(const char *ip)
char *get_port(const char *ip)
{
char *dupip, *p;
unsigned int offset=0;
unsigned int offset = 0;
dupip = get_ip(ip);
if (!(dupip))
@ -579,7 +577,7 @@ char *get_port(const char *ip)
p = (char *)ip + strlen(dupip) + offset;
if (*p == ':') {
p = strdup(p+1);
p = strdup(p + 1);
free(dupip);
return p;
}
@ -612,21 +610,21 @@ static int make_connection_real(const char *soname, conn_t *conn)
{
int s = -1;
struct timeval tv;
char *port=NULL;
char *port = NULL;
char *pt = strdup(soname);
const char *host = pt;
struct addrinfo hints, *res=NULL, *p;
struct addrinfo hints, *res = NULL, *p;
int err;
OOM_CHECK(pt);
conn->tcp = 0;
#ifndef _WIN32
if(cli_is_abspath(soname) || (access(soname, F_OK) == 0)) {
if (cli_is_abspath(soname) || (access(soname, F_OK) == 0)) {
struct sockaddr_un addr;
s = socket(AF_UNIX, SOCK_STREAM, 0);
if(s < 0) {
if (s < 0) {
perror("socket");
return -1;
}
@ -658,7 +656,7 @@ static int make_connection_real(const char *soname, conn_t *conn)
port = get_port(soname);
conn->tcp=1;
conn->tcp = 1;
print_con_info(conn, "Looking up: %s:%s\n", host, port ? port : "3310");
if ((err = getaddrinfo(host, (port != NULL) ? port : "3310", &hints, &res))) {
@ -744,7 +742,7 @@ static int send_string_noreconn(conn_t *conn, const char *cmd)
static void send_string(conn_t *conn, const char *cmd)
{
while(send_string_noreconn(conn, cmd) == -1) {
while (send_string_noreconn(conn, cmd) == -1) {
reconnect(conn);
}
}
@ -752,7 +750,7 @@ static void send_string(conn_t *conn, const char *cmd)
static int tries = 0;
static void reconnect(conn_t *conn)
{
if(++tries > 3) {
if (++tries > 3) {
EXIT_PROGRAM(RECONNECT_FAIL);
}
if (conn->sd != -1)
@ -795,7 +793,7 @@ static int recv_line(conn_t *conn, char *buf, size_t len)
if (nread == -1)
reconnect(conn);
else {
assert(nread >0 && (size_t)nread == len);
assert(nread > 0 && (size_t)nread == len);
buf += nread;
}
if (p)
@ -812,8 +810,8 @@ static void output_queue(size_t line, ssize_t max)
struct task *tasks = global.tasks;
struct task *filtered_tasks = calloc(global.n, sizeof(*filtered_tasks));
OOM_CHECK(filtered_tasks);
for (i=0,j=0;i<global.n;i++) {
if (detail_selected == -1 || detail_is_selected(tasks[i].clamd_no-1)) {
for (i = 0, j = 0; i < global.n; i++) {
if (detail_selected == -1 || detail_is_selected(tasks[i].clamd_no - 1)) {
filtered_tasks[j++] = tasks[i];
}
}
@ -826,32 +824,32 @@ static void output_queue(size_t line, ssize_t max)
else
--max;
if (max < 0) max = 0;
for(i=0;i<max;i++) {
for (i = 0; i < max; i++) {
char *cmde;
assert(tasks);
cmde = strchr(filtered_tasks[i].line, ' ');
if(cmde) {
if (cmde) {
char cmd[16];
const char *filstart = strchr(cmde + 1, ' ');
strncpy(cmd, filtered_tasks[i].line, sizeof(cmd)-1);
cmd[15]='\0';
if (filtered_tasks[i].line+15 > cmde)
strncpy(cmd, filtered_tasks[i].line, sizeof(cmd) - 1);
cmd[15] = '\0';
if (filtered_tasks[i].line + 15 > cmde)
cmd[cmde - filtered_tasks[i].line] = '\0';
if(filstart) {
if (filstart) {
++filstart;
if (detail_selected == -1 && global.num_clamd > 1)
mvwprintw(stats_window, line + i, 0, "%2u %s", filtered_tasks[i].clamd_no, cmd + 1);
else
mvwprintw(stats_window, line + i, 0, " %s", cmd + 1);
mvwprintw(stats_window, line + i, 15, "%10.03fs", filtered_tasks[i].tim);
mvwprintw(stats_window, line + i, 30, "%s",filstart);
mvwprintw(stats_window, line + i, 30, "%s", filstart);
}
}
}
if (max < j) {
/* in summary mode we can only show a max amount of tasks */
wattron(stats_window, A_DIM | COLOR_PAIR(header_color));
mvwprintw(stats_window, line+i, 0, "*** %u more task(s) not shown ***", (unsigned)(j - max));
mvwprintw(stats_window, line + i, 0, "*** %u more task(s) not shown ***", (unsigned)(j - max));
wattroff(stats_window, A_DIM | COLOR_PAIR(header_color));
}
free(filtered_tasks);
@ -859,23 +857,22 @@ static void output_queue(size_t line, ssize_t max)
/* ---------------------- stats parsing routines ------------------- */
static void parse_queue(conn_t *conn, char* buf, size_t len, unsigned idx)
static void parse_queue(conn_t *conn, char *buf, size_t len, unsigned idx)
{
do {
double tim;
const char *t = strchr(buf, ' ');
if(!t)
if (!t)
continue;
if(sscanf(t,"%lf", &tim) != 1)
if (sscanf(t, "%lf", &tim) != 1)
continue;
++global.n;
global.tasks = realloc(global.tasks, sizeof(*global.tasks)*global.n);
global.tasks = realloc(global.tasks, sizeof(*global.tasks) * global.n);
OOM_CHECK(global.tasks);
global.tasks[global.n-1].line = strdup(buf);
OOM_CHECK(global.tasks[global.n-1].line);
global.tasks[global.n-1].tim = tim;
global.tasks[global.n-1].clamd_no = idx + 1;
global.tasks[global.n - 1].line = strdup(buf);
OOM_CHECK(global.tasks[global.n - 1].line);
global.tasks[global.n - 1].tim = tim;
global.tasks[global.n - 1].clamd_no = idx + 1;
} while (recv_line(conn, buf, len) && buf[0] == '\t' && strcmp("END\n", buf) != 0);
}
@ -888,12 +885,12 @@ static void output_memstats(struct stats *stats)
int blink = 0;
werase(mem_window);
if (stats->mem > 0 || (stats->mem >=0 && (stats->lpoolt > 0))) {
if (stats->mem > 0 || (stats->mem >= 0 && (stats->lpoolt > 0))) {
box(mem_window, 0, 0);
if (stats->mem > 0)
snprintf(buf, sizeof(buf),"heap %4luM mmap %4luM unused %3luM",
stats->lheapu/1000, stats->lmmapu/1000, stats->lreleasable/1000);
snprintf(buf, sizeof(buf), "heap %4luM mmap %4luM unused %3luM",
stats->lheapu / 1000, stats->lmmapu / 1000, stats->lreleasable / 1000);
else
snprintf(buf, sizeof(buf), "heap N/A mmap N/A unused N/A");
mvwprintw(mem_window, 1, 1, "Mem: ");
@ -901,19 +898,19 @@ static void output_memstats(struct stats *stats)
mvwprintw(mem_window, 2, 1, "Libc: ");
if (stats->mem > 0)
snprintf(buf, sizeof(buf),"used %4luM free %4luM total %4luM",
stats->ltotalu/1000, stats->ltotalf/1000, (stats->ltotalu+stats->ltotalf)/1000);
snprintf(buf, sizeof(buf), "used %4luM free %4luM total %4luM",
stats->ltotalu / 1000, stats->ltotalf / 1000, (stats->ltotalu + stats->ltotalf) / 1000);
else
snprintf(buf, sizeof(buf), "used N/A free N/A total N/A");
print_colored(mem_window, buf);
mvwprintw(mem_window, 3, 1, "Pool: ");
snprintf(buf, sizeof(buf), "count %4u used %4luM total %4luM",
stats->pools_cnt, stats->lpoolu/1000, stats->lpoolt/1000);
stats->pools_cnt, stats->lpoolu / 1000, stats->lpoolt / 1000);
print_colored(mem_window, buf);
totalmem = stats->lheapu + stats->lmmapu + stats->lpoolt;
if(totalmem > biggest_mem) {
if (totalmem > biggest_mem) {
biggest_mem = totalmem;
blink = 1;
}
@ -927,25 +924,25 @@ static void parse_memstats(const char *line, struct stats *stats)
{
double heapu, mmapu, totalu, totalf, releasable, pools_used, pools_total;
if(sscanf(line, " heap %lfM mmap %lfM used %lfM free %lfM releasable %lfM pools %u pools_used %lfM pools_total %lfM",
if (sscanf(line, " heap %lfM mmap %lfM used %lfM free %lfM releasable %lfM pools %u pools_used %lfM pools_total %lfM",
&heapu, &mmapu, &totalu, &totalf, &releasable, &stats->pools_cnt, &pools_used, &pools_total) != 8) {
if (sscanf(line , " heap N/A mmap N/A used N/A free N/A releasable N/A pools %u pools_used %lfM pools_total %lfM",
if (sscanf(line, " heap N/A mmap N/A used N/A free N/A releasable N/A pools %u pools_used %lfM pools_total %lfM",
&stats->pools_cnt, &pools_used, &pools_total) != 3) {
stats->mem = -1;
return;
}
stats->lpoolu = pools_used*1000;
stats->lpoolt = pools_total*1000;
stats->lpoolu = pools_used * 1000;
stats->lpoolt = pools_total * 1000;
stats->mem = 0;
return;
}
stats->lheapu = heapu*1000;
stats->lmmapu = mmapu*1000;
stats->ltotalu = totalu*1000;
stats->ltotalf = totalf*1000;
stats->lreleasable = releasable*1000;
stats->lpoolu = pools_used*1000;
stats->lpoolt = pools_total*1000;
stats->lheapu = heapu * 1000;
stats->lmmapu = mmapu * 1000;
stats->ltotalu = totalu * 1000;
stats->ltotalf = totalf * 1000;
stats->lreleasable = releasable * 1000;
stats->lpoolu = pools_used * 1000;
stats->lpoolt = pools_total * 1000;
stats->mem = heapu + mmapu + pools_total;
}
@ -954,19 +951,18 @@ static int output_stats(struct stats *stats, unsigned idx)
char buf[128];
char timbuf[15];
int blink = 0;
size_t i= 0;
size_t i = 0;
char mem[6];
WINDOW *win = stats_head_window;
int sel = detail_is_selected(idx);
char *line = malloc(maxx+1);
char *line = malloc(maxx + 1);
OOM_CHECK(line);
if (stats->mem <= 0 || stats->stats_unsupp) {
strncpy(mem, "N/A", sizeof(mem));
mem[sizeof(mem)-1]='\0';
}
else {
mem[sizeof(mem) - 1] = '\0';
} else {
char c;
double s;
if (stats->mem > 999.0) {
@ -978,32 +974,31 @@ static int output_stats(struct stats *stats, unsigned idx)
}
snprintf(mem, sizeof(mem), "%7.3f", s);
i = 4;
if (mem[i-1] == '.') i--;
if (mem[i - 1] == '.') i--;
mem[i++] = c;
mem[i] = '\0';
}
i = idx+1;
i = idx + 1;
if (!stats->db_time.tm_year) {
strncpy(timbuf,"N/A",sizeof(timbuf));
timbuf[sizeof(timbuf)-1]='\0';
}
else
strncpy(timbuf, "N/A", sizeof(timbuf));
timbuf[sizeof(timbuf) - 1] = '\0';
} else
snprintf(timbuf, sizeof(timbuf), "%04u-%02u-%02u %02uh",
1900 + stats->db_time.tm_year,
stats->db_time.tm_mon+1,
stats->db_time.tm_mon + 1,
stats->db_time.tm_mday,
stats->db_time.tm_hour);
memset(line, ' ', maxx+1);
memset(line, ' ', maxx + 1);
if (!stats->stats_unsupp) {
snprintf(line, maxx-1, "%2u %02u:%02u:%02u %3u %3u %5u %5u %5s %-14s %-6s %5s %s", idx+1, stats->conn_hr, stats->conn_min, stats->conn_sec,
snprintf(line, maxx - 1, "%2u %02u:%02u:%02u %3u %3u %5u %5u %5s %-14s %-6s %5s %s", idx + 1, stats->conn_hr, stats->conn_min, stats->conn_sec,
stats->live, stats->idle,
stats->current_q, stats->biggest_queue,
mem,
stats->remote, stats->engine_version, stats->db_version, timbuf);
} else {
snprintf(line, maxx-1, "%2u %02u:%02u:%02u N/A N/A N/A N/A N/A %-14s %-6s %5s %s", idx+1, stats->conn_hr, stats->conn_min, stats->conn_sec,
snprintf(line, maxx - 1, "%2u %02u:%02u:%02u N/A N/A N/A N/A N/A %-14s %-6s %5s %s", idx + 1, stats->conn_hr, stats->conn_min, stats->conn_sec,
stats->remote, stats->engine_version, stats->db_version, timbuf);
}
line[maxx] = '\0';
@ -1018,10 +1013,10 @@ static int output_stats(struct stats *stats, unsigned idx)
win = stats_window;
i = 0;
if (sel && !stats->stats_unsupp) {
memset(line, ' ', maxx+1);
snprintf(line, maxx-1, "Details for Clamd version: %s", stats->version);
memset(line, ' ', maxx + 1);
snprintf(line, maxx - 1, "Details for Clamd version: %s", stats->version);
line[maxx] = '\0';
line[strlen(line)]= ' ';
line[strlen(line)] = ' ';
wattron(win, COLOR_PAIR(queue_header_color));
mvwprintw(win, i++, 0, "%s", line);
wattroff(win, COLOR_PAIR(queue_header_color));
@ -1029,13 +1024,13 @@ static int output_stats(struct stats *stats, unsigned idx)
snprintf(buf, sizeof(buf), "live %3u idle %3u max %3u", stats->prim_live, stats->prim_idle, stats->prim_max);
print_colored(win, buf);
show_bar(win, i++, stats->prim_live, stats->prim_idle, stats->prim_max, 0);
/* mvwprintw(win, i++, 0, "Multiscan pool : ");
/* mvwprintw(win, i++, 0, "Multiscan pool : ");
snprintf(buf, sizeof(buf), "live %3u idle %3u max %3u", stats->live, stats->idle, stats->max);
print_colored(win, buf);
show_bar(win, i++, stats->live, stats->idle, stats->max, 0);*/
blink = 0;
if(stats->current_q > stats->biggest_queue) {
if (stats->current_q > stats->biggest_queue) {
stats->biggest_queue = stats->current_q;
blink = 1;
}
@ -1053,18 +1048,18 @@ static int output_stats(struct stats *stats, unsigned idx)
static void output_all(void)
{
unsigned i, stats_line=0;
unsigned i, stats_line = 0;
werase(stats_head_window);
werase(stats_window);
wattron(stats_head_window, COLOR_PAIR(queue_header_color));
mvwprintw(stats_head_window, 0, 0, "%s", clamd_header);
wattroff(stats_head_window, COLOR_PAIR(queue_header_color));
for (i=0;i<global.num_clamd;i++) {
for (i = 0; i < global.num_clamd; i++) {
unsigned j = output_stats(&global.all_stats[i], i);
if (j > stats_line)
stats_line = j;
}
output_queue(stats_line, maxystats - stats_line-1);
output_queue(stats_line, maxystats - stats_line - 1);
wrefresh(stats_head_window);
wrefresh(stats_window);
if (detail_exists()) {
@ -1110,11 +1105,11 @@ static void parse_stats(conn_t *conn, struct stats *stats, unsigned idx)
while (*p && *p != '-' && *p != '/')
p++;
stats->engine_version = malloc(p - pstart+1);
stats->engine_version = malloc(p - pstart + 1);
OOM_CHECK(stats->engine_version);
memcpy(stats->engine_version, pstart, p-pstart);
stats->engine_version[p-pstart] = '\0';
memcpy(stats->engine_version, pstart, p - pstart);
stats->engine_version[p - pstart] = '\0';
pstart = strchr(p, '/');
if (!pstart) {
@ -1127,46 +1122,46 @@ static void parse_stats(conn_t *conn, struct stats *stats, unsigned idx)
p = pstart + strlen(pstart);
stats->db_version = malloc(p - pstart + 1);
OOM_CHECK(stats->db_version);
memcpy(stats->db_version, pstart, p-pstart);
stats->db_version[p-pstart] = '\0';
if(*p) p++;
if (!*p || !strptime(p,"%a %b %d %H:%M:%S %Y", &stats->db_time)) {
memcpy(stats->db_version, pstart, p - pstart);
stats->db_version[p - pstart] = '\0';
if (*p) p++;
if (!*p || !strptime(p, "%a %b %d %H:%M:%S %Y", &stats->db_time)) {
memset(&stats->db_time, 0, sizeof(stats->db_time));
}
}
if (maxx > 61 && strlen(stats->db_version) > (maxx-61)) {
stats->db_version[maxx-61] = '\0';
if (maxx > 61 && strlen(stats->db_version) > (maxx - 61)) {
stats->db_version[maxx - 61] = '\0';
}
stats->version = vstart; /* for details view */
gettimeofday(&tv, NULL);
tv.tv_sec -= conn->tv_conn.tv_sec;
tv.tv_usec -= conn->tv_conn.tv_usec;
conn_dt = tv.tv_sec + tv.tv_usec/1e6;
conn_dt = tv.tv_sec + tv.tv_usec / 1e6;
stats->live = stats->idle = stats->max = 0;
stats->conn_hr = conn_dt/3600;
stats->conn_min = (conn_dt/60)%60;
stats->conn_sec = conn_dt%60;
stats->conn_hr = conn_dt / 3600;
stats->conn_min = (conn_dt / 60) % 60;
stats->conn_sec = conn_dt % 60;
stats->current_q = 0;
buf[sizeof(buf) - 1] = 0x0;
while(recv_line(conn, buf, sizeof(buf)-1) && strcmp("END\n",buf) != 0) {
while (recv_line(conn, buf, sizeof(buf) - 1) && strcmp("END\n", buf) != 0) {
char *val = strchr(buf, ':');
if(buf[0] == '\t') {
parse_queue(conn, buf, sizeof(buf)-1, idx);
if (buf[0] == '\t') {
parse_queue(conn, buf, sizeof(buf) - 1, idx);
continue;
} else if(val)
} else if (val)
*val++ = '\0';
if(!strcmp("MEMSTATS", buf)) {
if (!strcmp("MEMSTATS", buf)) {
parse_memstats(val, stats);
continue;
}
if(!strncmp("UNKNOWN COMMAND", buf, 15)) {
if (!strncmp("UNKNOWN COMMAND", buf, 15)) {
stats->stats_unsupp = 1;
break;
}
for(j=1;j<strlen(buf);j++)
for (j = 1; j < strlen(buf); j++)
buf[j] = tolower(buf[j]);
/* mvwprintw(win, i, 0, "%s", buf);
if(!val) {
@ -1176,8 +1171,8 @@ static void parse_stats(conn_t *conn, struct stats *stats, unsigned idx)
waddch(win, ':');
print_colored(win, val);
i++;*/
if(!strncmp("State",buf,5)) {
if(strstr(val, "PRIMARY")) {
if (!strncmp("State", buf, 5)) {
if (strstr(val, "PRIMARY")) {
/* primary thread pool */
primary = 1;
} else {
@ -1185,9 +1180,9 @@ static void parse_stats(conn_t *conn, struct stats *stats, unsigned idx)
primary = 0;
}
}
if(!strcmp("Threads",buf)) {
if (!strcmp("Threads", buf)) {
unsigned live, idle, max;
if(sscanf(val, " live %u idle %u max %u", &live, &idle, &max) != 3)
if (sscanf(val, " live %u idle %u max %u", &live, &idle, &max) != 3)
continue;
if (primary) {
stats->prim_live = live;
@ -1198,9 +1193,9 @@ static void parse_stats(conn_t *conn, struct stats *stats, unsigned idx)
stats->live += live;
stats->idle += idle;
stats->max += max;
} else if (!strcmp("Queue",buf)) {
} else if (!strcmp("Queue", buf)) {
unsigned len;
if(sscanf(val, "%u", &len) != 1)
if (sscanf(val, "%u", &len) != 1)
continue;
stats->current_q += len;
}
@ -1211,14 +1206,14 @@ static int read_version(conn_t *conn)
{
char buf[1024];
unsigned i;
if(!recv_line(conn, buf, sizeof(buf)))
if (!recv_line(conn, buf, sizeof(buf)))
return -1;
if (!strcmp(buf, "UNKNOWN COMMAND\n"))
return -2;
conn->version = strdup(buf);
OOM_CHECK(conn->version);
for (i=0;i<strlen(conn->version);i++)
for (i = 0; i < strlen(conn->version); i++)
if (conn->version[i] == '\n')
conn->version[i] = ' ';
return 0;
@ -1248,7 +1243,7 @@ static void help(void)
printf("\n");
return;
}
static int default_colors=0;
static int default_colors = 0;
/* -------------------------- Initialization ---------------- */
static void setup_connections(int argc, char *argv[])
{
@ -1263,21 +1258,21 @@ static void setup_connections(int argc, char *argv[])
EXIT_PROGRAM(FAIL_CMDLINE);
}
if(optget(opts, "help")->enabled) {
if (optget(opts, "help")->enabled) {
optfree(opts);
help();
normal_exit = 1;
exit(0);
}
if(optget(opts, "version")->enabled) {
if (optget(opts, "version")->enabled) {
printf("Clam AntiVirus Monitoring Tool %s\n", get_version());
optfree(opts);
normal_exit = 1;
exit(0);
}
if(optget(opts, "defaultcolors")->enabled)
if (optget(opts, "defaultcolors")->enabled)
default_colors = 1;
memset(&global, 0, sizeof(global));
@ -1290,7 +1285,7 @@ static void setup_connections(int argc, char *argv[])
EXIT_PROGRAM(FAIL_CMDLINE);
}
if((opt = optget(clamd_opts, "LocalSocket"))->enabled) {
if ((opt = optget(clamd_opts, "LocalSocket"))->enabled) {
conn = strdup(opt->strarg);
if (!conn) {
fprintf(stderr, "Can't strdup LocalSocket value\n");
@ -1314,19 +1309,21 @@ static void setup_connections(int argc, char *argv[])
global.num_clamd = 1;
} else {
unsigned i = 0;
while (opts->filename[i]) { i++; }
while (opts->filename[i]) {
i++;
}
global.num_clamd = i;
}
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) {
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) {
fprintf(stderr, "Error at WSAStartup(): %d\n", WSAGetLastError());
EXIT_PROGRAM(FAIL_INITIAL_CONN);
}
#endif
/* clamdtop */
puts( " __ ____");
puts(" __ ____");
puts(" _____/ /___ _____ ___ ____/ / /_____ ____");
puts(" / ___/ / __ `/ __ `__ \\/ __ / __/ __ \\/ __ \\");
puts("/ /__/ / /_/ / / / / / / /_/ / /_/ /_/ / /_/ /");
@ -1338,9 +1335,9 @@ static void setup_connections(int argc, char *argv[])
global.conn = calloc(global.num_clamd, sizeof(*global.conn));
OOM_CHECK(global.conn);
for (i=0;i < global.num_clamd;i++) {
for (i = 0; i < global.num_clamd; i++) {
const char *soname = conn ? conn : opts->filename[i];
global.conn[i].line = i+1;
global.conn[i].line = i + 1;
if (make_connection(soname, &global.conn[i]) < 0) {
EXIT_PROGRAM(FAIL_INITIAL_CONN);
}
@ -1357,16 +1354,16 @@ static void setup_connections(int argc, char *argv[])
static void free_global_stats(void)
{
unsigned i;
for (i=0;i<(unsigned)global.n;i++) {
for (i = 0; i < (unsigned)global.n; i++) {
free(global.tasks[i].line);
}
for (i=0;i<global.num_clamd;i++) {
for (i = 0; i < global.num_clamd; i++) {
free(global.all_stats[i].engine_version);
free(global.all_stats[i].db_version);
}
free(global.tasks);
global.tasks = NULL;
global.n=0;
global.n = 0;
}
static int help_line;
@ -1375,7 +1372,7 @@ static void explain(const char *abbrev, const char *msg)
wattron(stdscr, A_BOLD);
mvwprintw(stdscr, help_line++, 0, "%-15s", abbrev);
wattroff(stdscr, A_BOLD);
wprintw(stdscr," %s", msg);
wprintw(stdscr, " %s", msg);
}
static int show_help(void)
@ -1384,29 +1381,29 @@ static int show_help(void)
werase(stdscr);
help_line = 0;
explain("NO","Unique clamd number");
explain("NO", "Unique clamd number");
explain("CONNTIME", "How long it is connected");
explain("LIV", "Total number of live threads");
explain("IDL", "Total number of idle threads");
explain("QUEUE", "Number of items in queue");
explain("MAXQ","Maximum number of items observed in queue");
explain("MAXQ", "Maximum number of items observed in queue");
explain("MEM", "Total memory usage (if available)");
explain("HOST", "Which clamd, local means unix socket");
explain("ENGINE", "Engine version");
explain("DBVER", "Database version");
explain("DBTIME", "Database publish time");
explain("Primary threads", "Threadpool used to receive commands");
explain("Multiscan pool","Threadpool used for multiscan");
explain("live","Executing commands, or scanning");
explain("idle","Waiting for commands, will exit after idle_timeout");
explain("Multiscan pool", "Threadpool used for multiscan");
explain("live", "Executing commands, or scanning");
explain("idle", "Waiting for commands, will exit after idle_timeout");
explain("max", "Maximum number of threads configured for this pool");
explain("Queue","Tasks queued for processing, but not yet picked up by a thread");
explain("COMMAND","Command this thread is executing");
explain("QUEUEDSINCE","How long this task is executing");
explain("FILE","Which file it is processing (if applicable)");
explain("Mem","Memory usage reported by libc");
explain("Libc","Used/free memory reported by libc");
explain("Pool","Memory usage reported by libclamav's pool");
explain("Queue", "Tasks queued for processing, but not yet picked up by a thread");
explain("COMMAND", "Command this thread is executing");
explain("QUEUEDSINCE", "How long this task is executing");
explain("FILE", "Which file it is processing (if applicable)");
explain("Mem", "Memory usage reported by libc");
explain("Libc", "Used/free memory reported by libc");
explain("Pool", "Memory usage reported by libclamav's pool");
wrefresh(stdscr);
werase(status_bar_window);
@ -1438,7 +1435,7 @@ int main(int argc, char *argv[])
if (toupper(ch) == 'H') {
ch = show_help();
}
switch(ch) {
switch (ch) {
case KEY_RESIZE:
resize();
endwin();
@ -1447,14 +1444,14 @@ int main(int argc, char *argv[])
break;
case 'R':
case 'r':
for (i=0;i<global.num_clamd;i++)
for (i = 0; i < global.num_clamd; i++)
global.all_stats[i].biggest_queue = 1;
biggest_mem = 0;
break;
case KEY_UP:
if (global.num_clamd > 1) {
if (detail_selected == -1)
detail_selected = global.num_clamd-1;
detail_selected = global.num_clamd - 1;
else
--detail_selected;
}
@ -1464,7 +1461,7 @@ int main(int argc, char *argv[])
if (detail_selected == -1)
detail_selected = 0;
else {
if((unsigned)++detail_selected >= global.num_clamd)
if ((unsigned)++detail_selected >= global.num_clamd)
detail_selected = -1;
}
}
@ -1472,9 +1469,9 @@ int main(int argc, char *argv[])
}
gettimeofday(&tv, NULL);
header();
if(tv.tv_sec - tv_last.tv_sec >= MIN_INTERVAL) {
if (tv.tv_sec - tv_last.tv_sec >= MIN_INTERVAL) {
free_global_stats();
for(i=0;i<global.num_clamd;i++) {
for (i = 0; i < global.num_clamd; i++) {
unsigned biggest_q;
struct stats *stats = &global.all_stats[i];
if (global.conn[i].sd != -1)
@ -1490,11 +1487,11 @@ int main(int argc, char *argv[])
}
/* always show, so that screen resizes take effect instantly*/
output_all();
for(i=0;i<global.num_clamd;i++) {
for (i = 0; i < global.num_clamd; i++) {
if (global.conn[i].sd == -1)
reconnect(&global.conn[i]);
}
} while(toupper(ch = getch()) != 'Q');
} while (toupper(ch = getch()) != 'Q');
free_global_stats();
normal_exit = 1;
return 0;

View file

@ -79,31 +79,29 @@ int main(int argc, char **argv)
cl_initialize_crypto();
if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMSCAN, 0, NULL)) == NULL) {
if ((opts = optparse(NULL, argc, argv, 1, OPT_CLAMSCAN, 0, NULL)) == NULL) {
mprintf("!Can't parse command line options\n");
return 2;
}
if(optget(opts, "verbose")->enabled) {
if (optget(opts, "verbose")->enabled) {
mprintf_verbose = 1;
logg_verbose = 1;
}
if(optget(opts, "quiet")->enabled)
if (optget(opts, "quiet")->enabled)
mprintf_quiet = 1;
if(optget(opts, "stdout")->enabled)
if (optget(opts, "stdout")->enabled)
mprintf_stdout = 1;
if(optget(opts, "debug")->enabled) {
if (optget(opts, "debug")->enabled) {
#if defined(C_LINUX)
/* njh@bandsman.co.uk: create a dump if needed */
struct rlimit rlim;
rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
if(setrlimit(RLIMIT_CORE, &rlim) < 0)
if (setrlimit(RLIMIT_CORE, &rlim) < 0)
perror("setrlimit");
#endif
cl_debug(); /* enable debug messages */
@ -113,34 +111,34 @@ int main(int argc, char **argv)
cl_always_gen_section_hash();
}
if(optget(opts, "version")->enabled) {
if (optget(opts, "version")->enabled) {
print_version(optget(opts, "database")->strarg);
optfree(opts);
return 0;
}
if(optget(opts, "help")->enabled) {
if (optget(opts, "help")->enabled) {
optfree(opts);
help();
return 0;
}
if(optget(opts, "recursive")->enabled)
if (optget(opts, "recursive")->enabled)
recursion = 1;
if(optget(opts, "infected")->enabled)
if (optget(opts, "infected")->enabled)
printinfected = 1;
if(optget(opts, "suppress-ok-results")->enabled)
if (optget(opts, "suppress-ok-results")->enabled)
printclean = 0;
if(optget(opts, "bell")->enabled)
if (optget(opts, "bell")->enabled)
bell = 1;
/* initialize logger */
if((opt = optget(opts, "log"))->enabled) {
if ((opt = optget(opts, "log"))->enabled) {
logg_file = opt->strarg;
if(logg("#\n-------------------------------------------------------------------------------\n\n")) {
if (logg("#\n-------------------------------------------------------------------------------\n\n")) {
mprintf("!Problem with internal logger.\n");
optfree(opts);
return 2;
@ -148,7 +146,7 @@ int main(int argc, char **argv)
} else
logg_file = NULL;
if(actsetup(opts)) {
if (actsetup(opts)) {
optfree(opts);
logg_close();
exit(2);
@ -160,32 +158,32 @@ int main(int argc, char **argv)
ret = scanmanager(opts);
if(!optget(opts, "no-summary")->enabled) {
if (!optget(opts, "no-summary")->enabled) {
gettimeofday(&t2, NULL);
ds = t2.tv_sec - t1.tv_sec;
dms = t2.tv_usec - t1.tv_usec;
ds -= (dms < 0) ? (1):(0);
dms += (dms < 0) ? (1000000):(0);
ds -= (dms < 0) ? (1) : (0);
dms += (dms < 0) ? (1000000) : (0);
logg("\n----------- SCAN SUMMARY -----------\n");
logg("Known viruses: %u\n", info.sigs);
logg("Engine version: %s\n", get_version());
logg("Scanned directories: %u\n", info.dirs);
logg("Scanned files: %u\n", info.files);
logg("Infected files: %u\n", info.ifiles);
if(info.errors)
if (info.errors)
logg("Total errors: %u\n", info.errors);
if(notremoved) {
if (notremoved) {
logg("Not removed: %u\n", notremoved);
}
if(notmoved) {
if (notmoved) {
logg("Not %s: %u\n", optget(opts, "copy")->enabled ? "moved" : "copied", notmoved);
}
mb = info.blocks * (CL_COUNT_PRECISION / 1024) / 1024.0;
logg("Data scanned: %2.2lf MB\n", mb);
rmb = info.rblocks * (CL_COUNT_PRECISION / 1024) / 1024.0;
logg("Data read: %2.2lf MB (ratio %.2f:1)\n", rmb, info.rblocks ? (double)info.blocks/(double)info.rblocks : 0);
logg("Time: %u.%3.3u sec (%u m %u s)\n", ds, dms/1000, ds/60, ds%60);
logg("Data read: %2.2lf MB (ratio %.2f:1)\n", rmb, info.rblocks ? (double)info.blocks / (double)info.rblocks : 0);
logg("Time: %u.%3.3u sec (%u m %u s)\n", ds, dms / 1000, ds / 60, ds % 60);
}
optfree(opts);

File diff suppressed because it is too large Load diff

View file

@ -18,13 +18,13 @@ void version(void);
typedef struct _header_data {
int len;
char * cfduid;
char * session;
char *cfduid;
char *session;
} header_data;
typedef struct _write_data {
int len;
char * str;
char *str;
} write_data;
void usage(char *name)
@ -56,9 +56,9 @@ void version(void)
size_t header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
{
int len = size*nmemb;
int len = size * nmemb;
char *sp, *ep, *mem;
header_data *hd = (header_data *) userdata;
header_data *hd = (header_data *)userdata;
const char *set_cookie = "Set-Cookie:";
int clen = strlen(set_cookie);
@ -71,13 +71,13 @@ size_t header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
fprintf(stderr, "header_cb(): malformed cookie\n");
return 0;
}
mem = malloc(ep-sp+1);
mem = malloc(ep - sp + 1);
if (mem == NULL) {
fprintf(stderr, "header_cb(): malloc failed\n");
return 0;
}
memcpy(mem, sp, ep-sp);
mem[ep-sp] = '\0';
memcpy(mem, sp, ep - sp);
mem[ep - sp] = '\0';
if (!strncmp(mem, "__cfduid", 8))
hd->cfduid = mem;
else if (!strncmp(mem, "_clamav-net_session", strlen("_clamav-net_session")))
@ -90,14 +90,14 @@ size_t header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
{
int len = size*nmemb;
char * str;
write_data *wd = (write_data *) userdata;
int len = size * nmemb;
char *str;
write_data *wd = (write_data *)userdata;
if (len) {
str = realloc(wd->str, wd->len + len + 1);
if (str == NULL) {
fprintf (stderr, "write_cb() realloc failure\n");
fprintf(stderr, "write_cb() realloc failure\n");
return 0;
}
memcpy(str + wd->len, ptr, len);
@ -115,10 +115,10 @@ size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
* @param key The Key
* @return const char* The Value on Success, NULL on Failure.
*/
const char* presigned_get_string(json_object * ps_json_obj, char * key)
const char *presigned_get_string(json_object *ps_json_obj, char *key)
{
json_object * json_obj = NULL;
const char * json_str = NULL;
json_object *json_obj = NULL;
const char *json_str = NULL;
if (json_object_object_get_ex(ps_json_obj, key, &json_obj)) {
json_str = json_object_get_string(json_obj);
@ -137,23 +137,23 @@ int main(int argc, char *argv[])
CURL *clam_curl = NULL, *aws_curl = NULL;
CURLcode res;
int ch;
struct curl_httppost *post=NULL, *last=NULL;
struct curl_httppost *post = NULL, *last = NULL;
struct curl_slist *slist = NULL;
char *name=NULL, *email=NULL, *filename=NULL;
int setURL=0, fromStream=0;
const char * json_str;
char *name = NULL, *email = NULL, *filename = NULL;
int setURL = 0, fromStream = 0;
const char *json_str;
write_data wd = {0, NULL};
header_data hd_malware = {0, NULL, NULL};
header_data hd_presigned = {0, NULL, NULL};
json_object * ps_json_obj = NULL;
json_object * json_obj = NULL;
json_object *ps_json_obj = NULL;
json_object *json_obj = NULL;
int malware = 0;
int len = 0;
char * submissionID = NULL;
char * fpvname = NULL;
char *submissionID = NULL;
char *fpvname = NULL;
char *sp, *ep, *str;
char * authenticity_token = NULL;
char * urlp;
char *authenticity_token = NULL;
char *urlp;
curl_global_init(CURL_GLOBAL_ALL);
@ -208,10 +208,9 @@ int main(int argc, char *argv[])
fprintf(stderr, "ERROR: Unable to read stream\n");
goto cleanup;
}
fromStream=1;
fromStream = 1;
}
/*** The GET malware|fp ***/
if (malware == 1)
urlp = "https://www.clamav.net/reports/malware";
@ -225,40 +224,39 @@ int main(int argc, char *argv[])
curl_easy_setopt(clam_curl, CURLOPT_HEADERFUNCTION, header_cb);
res = curl_easy_perform(clam_curl);
if (res != CURLE_OK) {
fprintf(stderr, "Error in GET %s: %s\n", urlp , curl_easy_strerror(res));
fprintf(stderr, "Error in GET %s: %s\n", urlp, curl_easy_strerror(res));
goto cleanup;
}
if (wd.str != NULL) {
sp = strstr(wd.str, "name=\"authenticity_token\"");
if (sp == NULL) {
fprintf (stderr, "Authenticity token element not found.\n");
fprintf(stderr, "Authenticity token element not found.\n");
goto cleanup;
}
sp = strstr(sp, "value=");
if (sp == NULL) {
fprintf (stderr, "Authenticity token value not found.\n");
fprintf(stderr, "Authenticity token value not found.\n");
goto cleanup;
}
sp += 7;
ep = strchr(sp, '"');
if (ep == NULL) {
fprintf (stderr, "Authenticity token malformed.\n");
fprintf(stderr, "Authenticity token malformed.\n");
goto cleanup;
}
authenticity_token = malloc(ep-sp+1);
authenticity_token = malloc(ep - sp + 1);
if (authenticity_token == NULL) {
fprintf (stderr, "no memory for authenticity token.\n");
fprintf(stderr, "no memory for authenticity token.\n");
goto cleanup;
}
memcpy(authenticity_token, sp, ep-sp);
authenticity_token[ep-sp] = '\0';
free (wd.str);
memcpy(authenticity_token, sp, ep - sp);
authenticity_token[ep - sp] = '\0';
free(wd.str);
wd.str = NULL;
}
wd.len = 0;
urlp = NULL;
/*** The GET presigned ***/
if (malware == 1)
curl_easy_setopt(clam_curl, CURLOPT_URL, "https://www.clamav.net/presigned?type=malware");
@ -267,7 +265,7 @@ int main(int argc, char *argv[])
curl_easy_setopt(clam_curl, CURLOPT_HTTPGET, 1);
if (NULL == hd_malware.cfduid || NULL == hd_malware.session) {
fprintf (stderr, "invalid cfduid and/or session id values provided by clamav.net/presigned. Unable to continue submission.");
fprintf(stderr, "invalid cfduid and/or session id values provided by clamav.net/presigned. Unable to continue submission.");
goto cleanup;
}
@ -300,7 +298,7 @@ int main(int argc, char *argv[])
curl_easy_setopt(clam_curl, CURLOPT_HTTPHEADER, slist);
curl_easy_setopt(clam_curl, CURLOPT_HEADERDATA, &hd_presigned);
curl_easy_setopt(clam_curl, CURLOPT_HEADERFUNCTION, header_cb);
if (malware ==1)
if (malware == 1)
curl_easy_setopt(clam_curl, CURLOPT_REFERER, "https://www.clamav.net/reports/malware");
else
curl_easy_setopt(clam_curl, CURLOPT_REFERER, "https://www.clamav.net/reports/fp");
@ -313,7 +311,6 @@ int main(int argc, char *argv[])
curl_slist_free_all(slist);
slist = NULL;
/*** The POST to AWS ***/
ps_json_obj = json_tokener_parse(wd.str);
if (ps_json_obj == NULL) {
@ -336,19 +333,19 @@ int main(int argc, char *argv[])
fprintf(stderr, "Error: malformed 'key' string in GET presigned response (missing '-'.\n");
goto cleanup;
}
submissionID = malloc(ep-sp+1);
submissionID = malloc(ep - sp + 1);
if (submissionID == NULL) {
fprintf(stderr, "Error: malloc submissionID.\n");
goto cleanup;
}
memcpy(submissionID, sp, ep-sp);
submissionID[ep-sp] = '\0';
memcpy(submissionID, sp, ep - sp);
submissionID[ep - sp] = '\0';
aws_curl = curl_easy_init();
if (!(aws_curl)) {
fprintf(stderr, "ERROR: Could not initialize libcurl POST presigned\n");
goto cleanup;
}
submissionID[ep-sp] = '\0';
submissionID[ep - sp] = '\0';
curl_formadd(&post, &last, CURLFORM_COPYNAME, "key", CURLFORM_COPYCONTENTS, json_str, CURLFORM_END);
json_str = presigned_get_string(ps_json_obj, "acl");
@ -424,7 +421,6 @@ int main(int argc, char *argv[])
wd.str = NULL;
wd.len = 0;
/*** The POST submit to clamav.net ***/
slist = curl_slist_append(slist, "Expect:");
len = strlen(hd_malware.cfduid) + strlen(hd_malware.session) + 3;
@ -443,7 +439,7 @@ int main(int argc, char *argv[])
curl_formadd(&post, &last, CURLFORM_COPYNAME, "utf8", CURLFORM_COPYCONTENTS, "\x27\x13", CURLFORM_END);
curl_formadd(&post, &last, CURLFORM_COPYNAME, "authenticity_token", CURLFORM_COPYCONTENTS, authenticity_token, CURLFORM_END);
curl_formadd(&post, &last, CURLFORM_COPYNAME, "submissionID", CURLFORM_COPYCONTENTS, submissionID, CURLFORM_END);
curl_formadd(&post, &last, CURLFORM_COPYNAME, "type", CURLFORM_COPYCONTENTS, malware?"malware":"fp", CURLFORM_END);
curl_formadd(&post, &last, CURLFORM_COPYNAME, "type", CURLFORM_COPYCONTENTS, malware ? "malware" : "fp", CURLFORM_END);
curl_formadd(&post, &last, CURLFORM_COPYNAME, "sendername", CURLFORM_COPYCONTENTS, name, CURLFORM_END);
curl_formadd(&post, &last, CURLFORM_COPYNAME, "email", CURLFORM_COPYCONTENTS, email, CURLFORM_END);
if (malware == 0) {
@ -466,7 +462,7 @@ int main(int argc, char *argv[])
} else {
long response_code;
curl_easy_getinfo(clam_curl, CURLINFO_RESPONSE_CODE, &response_code);
if (response_code/100 == 3) {
if (response_code / 100 == 3) {
curl_easy_getinfo(clam_curl, CURLINFO_REDIRECT_URL, &urlp);
if (urlp == NULL) {
fprintf(stderr, "POST submit Location URL is NULL.\n");
@ -475,19 +471,15 @@ int main(int argc, char *argv[])
sp = strstr(urlp, "/reports/");
if (sp == NULL) {
fprintf(stderr, "POST submit Location URL is malformed.\n");
}
else if (!strcmp(sp, "/reports/success")) {
} else if (!strcmp(sp, "/reports/success")) {
fprintf(stdout, "Submission success!\n");
status = 0;
}
else if (!strcmp(sp, "/reports/failure")) {
} else if (!strcmp(sp, "/reports/failure")) {
fprintf(stdout, "Submission failed\n");
}
else {
} else {
fprintf(stdout, "Unknown submission status %s\n", sp);
}
}
else {
} else {
fprintf(stderr, "Unexpected POST submit response code: %li\n", response_code);
}
}
@ -541,7 +533,6 @@ cleanup:
return status;
}
char *read_stream(void)
{
char *filename;

View file

@ -48,30 +48,30 @@ int main(int argc, char **argv)
struct cl_engine *engine;
struct cl_scan_options options;
if(argc != 2) {
if (argc != 2) {
printf("Usage: %s file\n", argv[0]);
return 2;
}
filename = argv[1];
if((fd = open(argv[1], O_RDONLY)) == -1) {
if ((fd = open(argv[1], O_RDONLY)) == -1) {
printf("Can't open file %s\n", argv[1]);
return 2;
}
if((ret = cl_init(CL_INIT_DEFAULT)) != CL_SUCCESS) {
if ((ret = cl_init(CL_INIT_DEFAULT)) != CL_SUCCESS) {
printf("Can't initialize libclamav: %s\n", cl_strerror(ret));
return 2;
}
if(!(engine = cl_engine_new())) {
if (!(engine = cl_engine_new())) {
printf("Can't create new engine\n");
return 2;
}
/* load all available databases from default directory */
if((ret = cl_load(cl_retdbdir(), engine, &sigs, CL_DB_STDOPT)) != CL_SUCCESS) {
if ((ret = cl_load(cl_retdbdir(), engine, &sigs, CL_DB_STDOPT)) != CL_SUCCESS) {
printf("cl_load: %s\n", cl_strerror(ret));
close(fd);
cl_engine_free(engine);
@ -81,7 +81,7 @@ int main(int argc, char **argv)
printf("Loaded %u signatures.\n", sigs);
/* build engine */
if((ret = cl_engine_compile(engine)) != CL_SUCCESS) {
if ((ret = cl_engine_compile(engine)) != CL_SUCCESS) {
printf("Database initialization error: %s\n", cl_strerror(ret));
cl_engine_free(engine);
close(fd);
@ -93,10 +93,10 @@ int main(int argc, char **argv)
options.parse |= ~0; /* enable all parsers */
options.general |= CL_SCAN_GENERAL_HEURISTICS; /* enable heuristic alert options */
if((ret = cl_scandesc(fd, filename, &virname, &size, engine, &options)) == CL_VIRUS) {
if ((ret = cl_scandesc(fd, filename, &virname, &size, engine, &options)) == CL_VIRUS) {
printf("Virus detected: %s\n", virname);
} else {
if(ret == CL_CLEAN) {
if (ret == CL_CLEAN) {
printf("No virus detected.\n");
} else {
printf("Error: %s\n", cl_strerror(ret));

View file

@ -13,7 +13,7 @@ FUNCTIONALITY_LEVEL_MIN(FUNC_LEVEL_098_7)
#define STR_MAXLEN 256
int entrypoint ()
int entrypoint()
{
int i;
int32_t type, obj, objarr, objit, arrlen, strlen;
@ -49,14 +49,14 @@ int entrypoint ()
type = json_get_type(obj);
if (type == JSON_TYPE_STRING) {
/* acquire string length, note +1 is for the NULL terminator */
strlen = json_get_string_length(obj)+1;
strlen = json_get_string_length(obj) + 1;
/* prevent buffer overflow */
if (strlen > STR_MAXLEN)
strlen = STR_MAXLEN;
/* acquire string data, note strlen includes NULL terminator */
if (json_get_string(str, strlen, obj)) {
/* debug print str (with '\n' and prepended message */
debug_print_str(str,strlen);
debug_print_str(str, strlen);
/* check the contained object's type */
if (strlen == 14 && !memcmp(str, "CL_TYPE_MSEXE", 14)) {

View file

@ -15,7 +15,7 @@ FUNCTIONALITY_LEVEL_MIN(FUNC_LEVEL_098_7)
#define STR_MAXLEN 256
int entrypoint ()
int entrypoint()
{
int32_t objid, type, strlen;
char str[STR_MAXLEN];
@ -37,7 +37,7 @@ int entrypoint ()
}
/* acquire string length, note +1 is for the NULL terminator */
strlen = json_get_string_length(objid)+1;
strlen = json_get_string_length(objid) + 1;
/* prevent buffer overflow */
if (strlen > STR_MAXLEN)
strlen = STR_MAXLEN;
@ -45,7 +45,7 @@ int entrypoint ()
/* acquire string data, note strlen includes NULL terminator */
if (json_get_string(str, strlen, objid)) {
/* debug print str (with '\n' and prepended message */
debug_print_str(str,strlen);
debug_print_str(str, strlen);
/* check the contained object's filetype */
if (strlen == 14 && !memcmp(str, "CL_TYPE_MSEXE", 14)) {

View file

@ -13,7 +13,7 @@ FUNCTIONALITY_LEVEL_MIN(FUNC_LEVEL_098_7)
#define STR_MAXLEN 256
int entrypoint ()
int entrypoint()
{
int32_t type, obj, strlen;
char str[STR_MAXLEN];
@ -31,14 +31,14 @@ int entrypoint ()
type = json_get_type(obj);
if (type == JSON_TYPE_STRING) {
/* acquire string length, note +1 is for the NULL terminator */
strlen = json_get_string_length(obj)+1;
strlen = json_get_string_length(obj) + 1;
/* prevent buffer overflow */
if (strlen > STR_MAXLEN)
strlen = STR_MAXLEN;
/* acquire string data, note strlen includes NULL terminator */
if (json_get_string(str, strlen, obj)) {
/* debug print str (with '\n' and prepended message */
debug_print_str(str,strlen);
debug_print_str(str, strlen);
/* check the contained object's type */
if (!(strlen == 12) || !memcmp(str, "CL_TYPE_PDF", 12)) {

View file

@ -24,7 +24,7 @@ bool logical_trigger(void)
#define STR_MAXLEN 256
int entrypoint ()
int entrypoint()
{
int i;
int32_t type, obj, objarr, objit, arrlen, strlen;
@ -60,14 +60,14 @@ int entrypoint ()
type = json_get_type(obj);
if (type == JSON_TYPE_STRING) {
/* acquire string length, note +1 is for the NULL terminator */
strlen = json_get_string_length(obj)+1;
strlen = json_get_string_length(obj) + 1;
/* prevent buffer overflow */
if (strlen > STR_MAXLEN)
strlen = STR_MAXLEN;
/* acquire string data, note strlen includes NULL terminator */
if (json_get_string(str, strlen, obj)) {
/* debug print str (with '\n' and prepended message */
debug_print_str(str,strlen);
debug_print_str(str, strlen);
/* check the contained object's type */
if (strlen == 14 && !memcmp(str, "CL_TYPE_MSEXE", 14)) {

View file

@ -26,7 +26,7 @@ bool logical_trigger(void)
#define STR_MAXLEN 256
int entrypoint ()
int entrypoint()
{
int32_t objid, type, strlen;
char str[STR_MAXLEN];
@ -48,7 +48,7 @@ int entrypoint ()
}
/* acquire string length, note +1 is for the NULL terminator */
strlen = json_get_string_length(objid)+1;
strlen = json_get_string_length(objid) + 1;
/* prevent buffer overflow */
if (strlen > STR_MAXLEN)
strlen = STR_MAXLEN;
@ -56,7 +56,7 @@ int entrypoint ()
/* acquire string data, note strlen includes NULL terminator */
if (json_get_string(str, strlen, objid)) {
/* debug print str (with '\n' and prepended message */
debug_print_str(str,strlen);
debug_print_str(str, strlen);
/* check the contained object's filetype */
if (strlen == 14 && !memcmp(str, "CL_TYPE_MSEXE", 14)) {

View file

@ -27,7 +27,7 @@ bool logical_trigger(void)
#define STR_MAXLEN 256
int entrypoint ()
int entrypoint()
{
foundVirus("Submit");
return 0;

View file

@ -27,7 +27,7 @@ bool logical_trigger(void)
#define STR_MAXLEN 256
int entrypoint ()
int entrypoint()
{
int32_t i, root = 0, embedded = 0;
int32_t type, obj, strlen, objarr, objit, arrlen;
@ -46,14 +46,14 @@ int entrypoint ()
type = json_get_type(obj);
if (type == JSON_TYPE_STRING) {
/* acquire string length, note +1 is for the NULL terminator */
strlen = json_get_string_length(obj)+1;
strlen = json_get_string_length(obj) + 1;
/* prevent buffer overflow */
if (strlen > STR_MAXLEN)
strlen = STR_MAXLEN;
/* acquire string data, note strlen includes NULL terminator */
if (json_get_string(str, strlen, obj)) {
/* debug print str (with '\n' and prepended message */
debug_print_str(str,strlen);
debug_print_str(str, strlen);
/* check the contained object's type */
if (strlen == 14 && !memcmp(str, "CL_TYPE_MSEXE", 14)) {
@ -97,14 +97,14 @@ int entrypoint ()
type = json_get_type(obj);
if (type == JSON_TYPE_STRING) {
/* acquire string length, note +1 is for the NULL terminator */
strlen = json_get_string_length(obj)+1;
strlen = json_get_string_length(obj) + 1;
/* prevent buffer overflow */
if (strlen > STR_MAXLEN)
strlen = STR_MAXLEN;
/* acquire string data, note strlen includes NULL terminator */
if (json_get_string(str, strlen, obj)) {
/* debug print str (with '\n' and prepended message */
debug_print_str(str,strlen);
debug_print_str(str, strlen);
/* check the contained object's type */
if (strlen == 14 && !memcmp(str, "CL_TYPE_MSEXE", 14)) {
@ -122,11 +122,9 @@ int entrypoint ()
if (root && embedded) {
foundVirus("RootEmbedded");
}
else if (root) {
} else if (root) {
foundVirus("Root");
}
else if (embedded) {
} else if (embedded) {
foundVirus("Embedded");
}

View file

@ -22,7 +22,7 @@ bool logical_trigger(void)
return matches(Signatures.sig1);
}
int entrypoint ()
int entrypoint()
{
return 0;
}

View file

@ -13,7 +13,7 @@ FUNCTIONALITY_LEVEL_MIN(FUNC_LEVEL_098_7)
#define STR_MAXLEN 256
int entrypoint ()
int entrypoint()
{
int32_t i, root = 0, embedded = 0;
int32_t type, obj, strlen, objarr, objit, arrlen;
@ -32,14 +32,14 @@ int entrypoint ()
type = json_get_type(obj);
if (type == JSON_TYPE_STRING) {
/* acquire string length, note +1 is for the NULL terminator */
strlen = json_get_string_length(obj)+1;
strlen = json_get_string_length(obj) + 1;
/* prevent buffer overflow */
if (strlen > STR_MAXLEN)
strlen = STR_MAXLEN;
/* acquire string data, note strlen includes NULL terminator */
if (json_get_string(str, strlen, obj)) {
/* debug print str (with '\n' and prepended message */
debug_print_str(str,strlen);
debug_print_str(str, strlen);
/* check the contained object's type */
if (strlen == 14 && !memcmp(str, "CL_TYPE_MSEXE", 14)) {
@ -83,14 +83,14 @@ int entrypoint ()
type = json_get_type(obj);
if (type == JSON_TYPE_STRING) {
/* acquire string length, note +1 is for the NULL terminator */
strlen = json_get_string_length(obj)+1;
strlen = json_get_string_length(obj) + 1;
/* prevent buffer overflow */
if (strlen > STR_MAXLEN)
strlen = STR_MAXLEN;
/* acquire string data, note strlen includes NULL terminator */
if (json_get_string(str, strlen, obj)) {
/* debug print str (with '\n' and prepended message */
debug_print_str(str,strlen);
debug_print_str(str, strlen);
/* check the contained object's type */
if (strlen == 14 && !memcmp(str, "CL_TYPE_MSEXE", 14)) {
@ -108,11 +108,9 @@ int entrypoint ()
if (root && embedded) {
foundVirus("RootEmbedded");
}
else if (root) {
} else if (root) {
foundVirus("Root");
}
else if (embedded) {
} else if (embedded) {
foundVirus("Embedded");
}

View file

@ -11,7 +11,7 @@ PRECLASS_HOOK_DECLARE
/* PRECLASS_HOOK_DECLARE will require FUNC_LEVEL_098_7 = 80 */
FUNCTIONALITY_LEVEL_MIN(FUNC_LEVEL_098_7)
int entrypoint ()
int entrypoint()
{
return 0;
}

View file

@ -36,128 +36,111 @@
#include "shared/output.h"
#ifndef PACKETSZ
#define PACKETSZ 512
#endif
char *
dnsquery (const char *domain, int qtype, unsigned int *ttl)
dnsquery(const char *domain, int qtype, unsigned int *ttl)
{
unsigned char answer[PACKETSZ], *answend, *pt;
char *txt, host[128];
int len, type;
unsigned int cttl, size, txtlen = 0;
if (ttl)
*ttl = 0;
if (res_init () < 0)
{
logg ("^res_init failed\n");
if (res_init() < 0) {
logg("^res_init failed\n");
return NULL;
}
logg ("*Querying %s\n", domain);
logg("*Querying %s\n", domain);
memset (answer, 0, PACKETSZ);
if ((len = res_query (domain, C_IN, qtype, answer, PACKETSZ)) < 0
|| len > PACKETSZ)
{
memset(answer, 0, PACKETSZ);
if ((len = res_query(domain, C_IN, qtype, answer, PACKETSZ)) < 0 || len > PACKETSZ) {
#ifdef FRESHCLAM_DNS_FIX
/* The DNS server in the SpeedTouch Alcatel 510 modem can't
* handle a TXT-query, but it can resolve an ANY-query to a
* TXT-record, so we try an ANY-query now. The thing we try
* to resolve normally only has a TXT-record anyway.
*/
memset (answer, 0, PACKETSZ);
memset(answer, 0, PACKETSZ);
if (qtype == T_TXT)
qtype = T_ANY;
if ((len = res_query (domain, C_IN, qtype, answer, PACKETSZ)) < 0)
{
logg ("%cCan't query %s\n",
if ((len = res_query(domain, C_IN, qtype, answer, PACKETSZ)) < 0) {
logg("%cCan't query %s\n",
(qtype == T_TXT || qtype == T_ANY) ? '^' : '*', domain);
return NULL;
}
#else
logg ("%cCan't query %s\n", (qtype == T_TXT) ? '^' : '*', domain);
logg("%cCan't query %s\n", (qtype == T_TXT) ? '^' : '*', domain);
return NULL;
#endif
}
if (qtype != T_TXT && qtype != T_ANY)
{
if (qtype != T_TXT && qtype != T_ANY) {
if (ttl)
*ttl = 2;
return NULL;
}
answend = answer + len;
pt = answer + sizeof (HEADER);
pt = answer + sizeof(HEADER);
if ((len = dn_expand (answer, answend, pt, host, sizeof (host))) < 0)
{
logg ("^dn_expand failed\n");
if ((len = dn_expand(answer, answend, pt, host, sizeof(host))) < 0) {
logg("^dn_expand failed\n");
return NULL;
}
pt += len;
if (pt > answend - 4)
{
logg ("^Bad (too short) DNS reply\n");
if (pt > answend - 4) {
logg("^Bad (too short) DNS reply\n");
return NULL;
}
GETSHORT (type, pt);
if (type != qtype)
{
logg ("^Broken DNS reply.\n");
GETSHORT(type, pt);
if (type != qtype) {
logg("^Broken DNS reply.\n");
return NULL;
}
pt += INT16SZ; /* class */
size = 0;
do
{ /* recurse through CNAME rr's */
do { /* recurse through CNAME rr's */
pt += size;
if ((len = dn_expand (answer, answend, pt, host, sizeof (host))) < 0)
{
logg ("^second dn_expand failed\n");
if ((len = dn_expand(answer, answend, pt, host, sizeof(host))) < 0) {
logg("^second dn_expand failed\n");
return NULL;
}
pt += len;
if (pt > answend - 10)
{
logg ("^Bad (too short) DNS reply\n");
if (pt > answend - 10) {
logg("^Bad (too short) DNS reply\n");
return NULL;
}
GETSHORT (type, pt);
GETSHORT(type, pt);
pt += INT16SZ; /* class */
GETLONG (cttl, pt);
GETSHORT (size, pt);
if (pt + size < answer || pt + size > answend)
{
logg ("^DNS rr overflow\n");
GETLONG(cttl, pt);
GETSHORT(size, pt);
if (pt + size < answer || pt + size > answend) {
logg("^DNS rr overflow\n");
return NULL;
}
}
while (type == T_CNAME);
} while (type == T_CNAME);
if (type != T_TXT)
{
logg ("^Not a TXT record\n");
if (type != T_TXT) {
logg("^Not a TXT record\n");
return NULL;
}
if (!size || (txtlen = *pt) >= size || !txtlen)
{
logg ("^Broken TXT record (txtlen = %d, size = %d)\n", txtlen, size);
if (!size || (txtlen = *pt) >= size || !txtlen) {
logg("^Broken TXT record (txtlen = %d, size = %d)\n", txtlen, size);
return NULL;
}
if (!(txt = (char *) malloc (txtlen + 1)))
if (!(txt = (char *)malloc(txtlen + 1)))
return NULL;
memcpy (txt, pt + 1, txtlen);
memcpy(txt, pt + 1, txtlen);
txt[txtlen] = 0;
if (ttl)
*ttl = cttl;
@ -168,7 +151,7 @@ dnsquery (const char *domain, int qtype, unsigned int *ttl)
#else
char *
dnsquery (const char *domain, int qtype, unsigned int *ttl)
dnsquery(const char *domain, int qtype, unsigned int *ttl)
{
if (ttl)
*ttl = 1; /* ttl of 1 combined with a NULL return distinguishes a failed lookup from DNS queries not being available */

View file

@ -32,6 +32,6 @@
#include <resolv.h>
#endif
char *dnsquery (const char *domain, int qtype, unsigned int *ttl);
char *dnsquery(const char *domain, int qtype, unsigned int *ttl);
#endif

View file

@ -37,52 +37,43 @@
int active_children;
void
execute (const char *type, const char *text, const struct optstruct *opts)
void execute(const char *type, const char *text, const struct optstruct *opts)
{
int ret;
if (!optget (opts, "daemon")->enabled)
{
if (sscanf (text, "EXIT_%d", &ret) == 1)
{
logg ("*%s: EXIT_%d\n", type, ret);
exit (ret);
if (!optget(opts, "daemon")->enabled) {
if (sscanf(text, "EXIT_%d", &ret) == 1) {
logg("*%s: EXIT_%d\n", type, ret);
exit(ret);
}
if (system (text) == -1)
logg ("%s: system(%s) failed\n", type, text);
if (system(text) == -1)
logg("%s: system(%s) failed\n", type, text);
return;
}
#ifdef _WIN32
if (spawnlp (_P_NOWAIT, text, text, NULL) == -1)
{
logg ("^%s: couldn't execute \"%s\".\n", type, text);
if (spawnlp(_P_NOWAIT, text, text, NULL) == -1) {
logg("^%s: couldn't execute \"%s\".\n", type, text);
return;
}
#else
if (active_children < MAX_CHILDREN)
{
if (active_children < MAX_CHILDREN) {
pid_t pid;
switch (pid = fork ())
{
switch (pid = fork()) {
case 0:
if (-1 == system (text))
{
logg ("^%s: couldn't execute \"%s\".\n", type, text);
if (-1 == system(text)) {
logg("^%s: couldn't execute \"%s\".\n", type, text);
}
exit (0);
exit(0);
case -1:
logg ("^%s::fork() failed, %s.\n", type, strerror (errno));
logg("^%s::fork() failed, %s.\n", type, strerror(errno));
break;
default:
active_children++;
}
}
else
{
logg ("^%s: already %d processes active.\n", type, active_children);
} else {
logg("^%s: already %d processes active.\n", type, active_children);
}
#endif
}

View file

@ -17,13 +17,12 @@
* MA 02110-1301, USA.
*/
#ifndef __EXECUTE_H
#define __EXECUTE_H
#include "shared/optparser.h"
void execute (const char *type, const char *text,
void execute(const char *type, const char *text,
const struct optstruct *opts);
#endif

View file

@ -74,15 +74,14 @@ char *get_hostid(void *cbdata);
int is_valid_hostid(void);
static void
sighandler (int sig)
sighandler(int sig)
{
switch (sig)
{
switch (sig) {
#ifdef SIGCHLD
case SIGCHLD:
if (sigchld_wait)
waitpid (-1, NULL, WNOHANG);
waitpid(-1, NULL, WNOHANG);
active_children--;
break;
#endif
@ -112,36 +111,33 @@ sighandler (int sig)
default:
if (*updtmpdir)
cli_rmdirs (updtmpdir);
cli_rmdirs(updtmpdir);
if (pidfile)
unlink (pidfile);
logg ("Update process terminated\n");
exit (0);
unlink(pidfile);
logg("Update process terminated\n");
exit(0);
}
return;
}
static void
writepid (const char *pidfile)
writepid(const char *pidfile)
{
FILE *fd;
int old_umask;
old_umask = umask (0006);
if ((fd = fopen (pidfile, "w")) == NULL)
{
logg ("!Can't save PID to file %s: %s\n", pidfile, strerror (errno));
old_umask = umask(0006);
if ((fd = fopen(pidfile, "w")) == NULL) {
logg("!Can't save PID to file %s: %s\n", pidfile, strerror(errno));
} else {
fprintf(fd, "%d\n", (int)getpid());
fclose(fd);
}
else
{
fprintf (fd, "%d\n", (int) getpid ());
fclose (fd);
}
umask (old_umask);
umask(old_umask);
}
static void
help (void)
help(void)
{
mprintf_stdout = 1;
@ -180,11 +176,11 @@ help (void)
mprintf(" --on-outdated-execute=COMMAND Execute COMMAND when software is outdated\n");
mprintf(" --list-mirrors Print mirrors from mirrors.dat\n");
mprintf(" --update-db=DBNAME Only update database DBNAME\n");
mprintf ("\n");
mprintf("\n");
}
static int
download (const struct optstruct *opts, const char *cfgfile)
download(const struct optstruct *opts, const char *cfgfile)
{
time_t currtime;
int ret = 0, attempt = 1, maxattempts = 0;
@ -194,47 +190,35 @@ download (const struct optstruct *opts, const char *cfgfile)
logg("ClamAV update process started at %s", ctime(&currtime));
logg("*Using IPv6 aware code\n");
maxattempts = optget (opts, "MaxAttempts")->numarg;
logg ("*Max retries == %d\n", maxattempts);
maxattempts = optget(opts, "MaxAttempts")->numarg;
logg("*Max retries == %d\n", maxattempts);
if (!(opt = optget (opts, "DatabaseMirror"))->enabled)
{
logg ("^You must specify at least one database mirror in %s\n",
if (!(opt = optget(opts, "DatabaseMirror"))->enabled) {
logg("^You must specify at least one database mirror in %s\n",
cfgfile);
return FCE_CONFIG;
}
else
{
while (opt)
{
ret = downloadmanager (opts, opt->strarg, attempt);
} else {
while (opt) {
ret = downloadmanager(opts, opt->strarg, attempt);
#ifndef _WIN32
alarm (0);
alarm(0);
#endif
if (ret == FCE_CONNECTION || ret == FCE_BADCVD
|| ret == FCE_FAILEDGET || ret == FCE_MIRRORNOTSYNC)
{
if (attempt < maxattempts)
{
logg ("Trying again in 5 secs...\n");
if (ret == FCE_CONNECTION || ret == FCE_BADCVD || ret == FCE_FAILEDGET || ret == FCE_MIRRORNOTSYNC) {
if (attempt < maxattempts) {
logg("Trying again in 5 secs...\n");
attempt++;
sleep (5);
sleep(5);
continue;
}
else
{
logg ("Giving up on %s...\n", opt->strarg);
opt = (struct optstruct *) opt->nextarg;
if (!opt)
{
logg ("Update failed. Your network may be down or none of the mirrors listed in %s is working. Check https://www.clamav.net/documents/official-mirror-faq for possible reasons.\n", cfgfile);
} else {
logg("Giving up on %s...\n", opt->strarg);
opt = (struct optstruct *)opt->nextarg;
if (!opt) {
logg("Update failed. Your network may be down or none of the mirrors listed in %s is working. Check https://www.clamav.net/documents/official-mirror-faq for possible reasons.\n", cfgfile);
}
attempt = 1;
}
}
else
{
} else {
return ret;
}
}
@ -244,28 +228,26 @@ download (const struct optstruct *opts, const char *cfgfile)
}
static void
msg_callback (enum cl_msg severity, const char *fullmsg, const char *msg,
msg_callback(enum cl_msg severity, const char *fullmsg, const char *msg,
void *ctx)
{
UNUSEDPARAM(fullmsg);
UNUSEDPARAM(ctx);
switch (severity)
{
switch (severity) {
case CL_MSG_ERROR:
logg ("^[LibClamAV] %s", msg);
logg("^[LibClamAV] %s", msg);
break;
case CL_MSG_WARN:
logg ("~[LibClamAV] %s", msg);
logg("~[LibClamAV] %s", msg);
break;
default:
logg ("*[LibClamAV] %s", msg);
logg("*[LibClamAV] %s", msg);
break;
}
}
int
main (int argc, char **argv)
int main(int argc, char **argv)
{
int ret = FCE_CONNECTION, retcl;
const char *cfgfile, *arg = NULL;
@ -284,83 +266,71 @@ main (int argc, char **argv)
struct mirdat mdat;
int j;
if (check_flevel ())
exit (FCE_INIT);
if (check_flevel())
exit(FCE_INIT);
if ((retcl = cl_init (CL_INIT_DEFAULT)))
{
mprintf ("!Can't initialize libclamav: %s\n", cl_strerror (retcl));
if ((retcl = cl_init(CL_INIT_DEFAULT))) {
mprintf("!Can't initialize libclamav: %s\n", cl_strerror(retcl));
return FCE_INIT;
}
if ((opts =
optparse (NULL, argc, argv, 1, OPT_FRESHCLAM, 0, NULL)) == NULL)
{
mprintf ("!Can't parse command line options\n");
optparse(NULL, argc, argv, 1, OPT_FRESHCLAM, 0, NULL)) == NULL) {
mprintf("!Can't parse command line options\n");
return FCE_INIT;
}
if (optget (opts, "help")->enabled)
{
help ();
optfree (opts);
if (optget(opts, "help")->enabled) {
help();
optfree(opts);
return FC_SUCCESS;
}
/* check foreground option from command line to override config file */
for(j = 0; j < argc; j += 1)
{
if ((memcmp(argv[j], "--foreground", 12) == 0) || (memcmp(argv[j], "-F", 2) == 0))
{
for (j = 0; j < argc; j += 1) {
if ((memcmp(argv[j], "--foreground", 12) == 0) || (memcmp(argv[j], "-F", 2) == 0)) {
/* found */
break;
}
}
if (j < argc) {
if(optget(opts, "Foreground")->enabled) {
if (optget(opts, "Foreground")->enabled) {
foreground = 1;
}
else {
} else {
foreground = 0;
}
}
/* parse the config file */
cfgfile = optget (opts, "config-file")->strarg;
pt = strdup (cfgfile);
cfgfile = optget(opts, "config-file")->strarg;
pt = strdup(cfgfile);
if ((opts =
optparse (cfgfile, 0, NULL, 1, OPT_FRESHCLAM, 0, opts)) == NULL)
{
fprintf (stderr, "ERROR: Can't open/parse the config file %s\n", pt);
free (pt);
optparse(cfgfile, 0, NULL, 1, OPT_FRESHCLAM, 0, opts)) == NULL) {
fprintf(stderr, "ERROR: Can't open/parse the config file %s\n", pt);
free(pt);
return FCE_INIT;
}
free (pt);
free(pt);
if (optget (opts, "version")->enabled)
{
print_version (optget (opts, "DatabaseDirectory")->strarg);
optfree (opts);
if (optget(opts, "version")->enabled) {
print_version(optget(opts, "DatabaseDirectory")->strarg);
optfree(opts);
return FC_SUCCESS;
}
if (optget (opts, "HTTPProxyPassword")->enabled)
{
if (CLAMSTAT (cfgfile, &statbuf) == -1)
{
logg ("^Can't stat %s (critical error)\n", cfgfile);
optfree (opts);
if (optget(opts, "HTTPProxyPassword")->enabled) {
if (CLAMSTAT(cfgfile, &statbuf) == -1) {
logg("^Can't stat %s (critical error)\n", cfgfile);
optfree(opts);
return FCE_CONFIG;
}
#ifndef _WIN32
if (statbuf.
st_mode & (S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH |
S_IXOTH))
{
logg ("^Insecure permissions (for HTTPProxyPassword): %s must have no more than 0700 permissions.\n", cfgfile);
optfree (opts);
if (statbuf.st_mode & (S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH |
S_IXOTH)) {
logg("^Insecure permissions (for HTTPProxyPassword): %s must have no more than 0700 permissions.\n", cfgfile);
optfree(opts);
return FCE_CONFIG;
}
#endif
@ -368,42 +338,38 @@ main (int argc, char **argv)
#ifdef HAVE_PWD_H
/* freshclam shouldn't work with root privileges */
dbowner = optget (opts, "DatabaseOwner")->strarg;
dbowner = optget(opts, "DatabaseOwner")->strarg;
if (!geteuid ())
{
if ((user = getpwnam (dbowner)) == NULL)
{
logg ("^Can't get information about user %s.\n", dbowner);
optfree (opts);
if (!geteuid()) {
if ((user = getpwnam(dbowner)) == NULL) {
logg("^Can't get information about user %s.\n", dbowner);
optfree(opts);
return FCE_USERINFO;
}
#ifdef HAVE_INITGROUPS
if (initgroups(dbowner, user->pw_gid)) {
logg ("^initgroups() failed.\n");
optfree (opts);
logg("^initgroups() failed.\n");
optfree(opts);
return FCE_USERORGROUP;
}
#elif HAVE_SETGROUPS
if (setgroups(1, &user->pw_gid)) {
logg ("^setgroups() failed.\n");
optfree (opts);
logg("^setgroups() failed.\n");
optfree(opts);
return FCE_USERORGROUP;
}
#endif
if (setgid (user->pw_gid))
{
logg ("^setgid(%d) failed.\n", (int) user->pw_gid);
optfree (opts);
if (setgid(user->pw_gid)) {
logg("^setgid(%d) failed.\n", (int)user->pw_gid);
optfree(opts);
return FCE_USERORGROUP;
}
if (setuid (user->pw_uid))
{
logg ("^setuid(%d) failed.\n", (int) user->pw_uid);
optfree (opts);
if (setuid(user->pw_uid)) {
logg("^setuid(%d) failed.\n", (int)user->pw_uid);
optfree(opts);
return FCE_USERORGROUP;
}
}
@ -411,202 +377,175 @@ main (int argc, char **argv)
/* initialize some important variables */
if (optget (opts, "Debug")->enabled || optget (opts, "debug")->enabled)
cl_debug ();
if (optget(opts, "Debug")->enabled || optget(opts, "debug")->enabled)
cl_debug();
if (optget (opts, "verbose")->enabled)
if (optget(opts, "verbose")->enabled)
mprintf_verbose = 1;
if (optget (opts, "quiet")->enabled)
if (optget(opts, "quiet")->enabled)
mprintf_quiet = 1;
if (optget (opts, "no-warnings")->enabled)
{
if (optget(opts, "no-warnings")->enabled) {
mprintf_nowarn = 1;
logg_nowarn = 1;
}
if (optget (opts, "stdout")->enabled)
if (optget(opts, "stdout")->enabled)
mprintf_stdout = 1;
if (optget (opts, "show-progress")->enabled)
if (optget(opts, "show-progress")->enabled)
mprintf_progress = 1;
/* initialize logger */
logg_verbose = mprintf_verbose ? 1 : optget (opts, "LogVerbose")->enabled;
logg_time = optget (opts, "LogTime")->enabled;
logg_size = optget (opts, "LogFileMaxSize")->numarg;
logg_verbose = mprintf_verbose ? 1 : optget(opts, "LogVerbose")->enabled;
logg_time = optget(opts, "LogTime")->enabled;
logg_size = optget(opts, "LogFileMaxSize")->numarg;
if (logg_size)
logg_rotate = optget(opts, "LogRotate")->enabled;
if ((opt = optget (opts, "UpdateLogFile"))->enabled)
{
if ((opt = optget(opts, "UpdateLogFile"))->enabled) {
logg_file = opt->strarg;
if (logg ("#--------------------------------------\n"))
{
mprintf ("!Problem with internal logger (UpdateLogFile = %s).\n",
if (logg("#--------------------------------------\n")) {
mprintf("!Problem with internal logger (UpdateLogFile = %s).\n",
logg_file);
optfree (opts);
optfree(opts);
return FCE_LOGGING;
}
}
else
} else
logg_file = NULL;
#if defined(USE_SYSLOG) && !defined(C_AIX)
if (optget (opts, "LogSyslog")->enabled)
{
if (optget(opts, "LogSyslog")->enabled) {
int fac = LOG_LOCAL6;
if ((opt = optget (opts, "LogFacility"))->enabled)
{
if ((fac = logg_facility (opt->strarg)) == -1)
{
mprintf ("!LogFacility: %s: No such facility.\n",
if ((opt = optget(opts, "LogFacility"))->enabled) {
if ((fac = logg_facility(opt->strarg)) == -1) {
mprintf("!LogFacility: %s: No such facility.\n",
opt->strarg);
optfree (opts);
optfree(opts);
return FCE_LOGGING;
}
}
openlog ("freshclam", LOG_PID, fac);
openlog("freshclam", LOG_PID, fac);
logg_syslog = 1;
}
#endif
cl_set_clcb_msg (msg_callback);
cl_set_clcb_msg(msg_callback);
/* change the current working directory */
if (chdir (optget (opts, "DatabaseDirectory")->strarg))
{
logg ("!Can't change dir to %s\n",
optget (opts, "DatabaseDirectory")->strarg);
optfree (opts);
if (chdir(optget(opts, "DatabaseDirectory")->strarg)) {
logg("!Can't change dir to %s\n",
optget(opts, "DatabaseDirectory")->strarg);
optfree(opts);
return FCE_DIRECTORY;
} else {
if (!getcwd(dbdir, sizeof(dbdir))) {
logg("!getcwd() failed\n");
optfree(opts);
return FCE_DIRECTORY;
}
else
{
if (!getcwd (dbdir, sizeof (dbdir)))
{
logg ("!getcwd() failed\n");
optfree (opts);
return FCE_DIRECTORY;
}
logg ("*Current working dir is %s\n", dbdir);
logg("*Current working dir is %s\n", dbdir);
}
if (optget (opts, "list-mirrors")->enabled)
{
if (mirman_read("mirrors.dat", &mdat, 1) != FC_SUCCESS)
{
printf ("Can't read mirrors.dat\n");
optfree (opts);
if (optget(opts, "list-mirrors")->enabled) {
if (mirman_read("mirrors.dat", &mdat, 1) != FC_SUCCESS) {
printf("Can't read mirrors.dat\n");
optfree(opts);
return FCE_FILE;
}
mirman_list (&mdat);
mirman_free (&mdat);
optfree (opts);
mirman_list(&mdat);
mirman_free(&mdat);
optfree(opts);
return FC_SUCCESS;
}
if ((opt = optget (opts, "PrivateMirror"))->enabled)
{
if ((opt = optget(opts, "PrivateMirror"))->enabled) {
struct optstruct *dbm, *opth;
dbm = (struct optstruct *) optget (opts, "DatabaseMirror");
dbm = (struct optstruct *)optget(opts, "DatabaseMirror");
dbm->active = dbm->enabled = 1;
do
{
if (cli_strbcasestr (opt->strarg, ".clamav.net"))
{
logg ("!PrivateMirror: *.clamav.net is not allowed in this mode\n");
optfree (opts);
do {
if (cli_strbcasestr(opt->strarg, ".clamav.net")) {
logg("!PrivateMirror: *.clamav.net is not allowed in this mode\n");
optfree(opts);
return FCE_PRIVATEMIRROR;
}
if (dbm->strarg)
free (dbm->strarg);
dbm->strarg = strdup (opt->strarg);
if (!dbm->strarg)
{
logg ("!strdup() failed\n");
optfree (opts);
free(dbm->strarg);
dbm->strarg = strdup(opt->strarg);
if (!dbm->strarg) {
logg("!strdup() failed\n");
optfree(opts);
return FCE_MEM;
}
if (!dbm->nextarg)
{
if (!dbm->nextarg) {
dbm->nextarg =
(struct optstruct *) calloc (1,
sizeof (struct optstruct));
if (!dbm->nextarg)
{
logg ("!calloc() failed\n");
optfree (opts);
(struct optstruct *)calloc(1,
sizeof(struct optstruct));
if (!dbm->nextarg) {
logg("!calloc() failed\n");
optfree(opts);
return FCE_MEM;
}
}
opth = dbm;
dbm = dbm->nextarg;
}
while ((opt = opt->nextarg));
} while ((opt = opt->nextarg));
opth->nextarg = NULL;
while (dbm)
{
free (dbm->name);
free (dbm->cmd);
free (dbm->strarg);
while (dbm) {
free(dbm->name);
free(dbm->cmd);
free(dbm->strarg);
opth = dbm;
dbm = dbm->nextarg;
free (opth);
free(opth);
}
/* disable DNS db checks */
opth = (struct optstruct *) optget (opts, "no-dns");
opth = (struct optstruct *)optget(opts, "no-dns");
opth->active = opth->enabled = 1;
/* disable scripted updates */
opth = (struct optstruct *) optget (opts, "ScriptedUpdates");
opth = (struct optstruct *)optget(opts, "ScriptedUpdates");
opth->active = opth->enabled = 0;
}
*updtmpdir = 0;
#ifdef _WIN32
signal (SIGINT, sighandler);
signal(SIGINT, sighandler);
#else
memset (&sigact, 0, sizeof (struct sigaction));
memset(&sigact, 0, sizeof(struct sigaction));
sigact.sa_handler = sighandler;
sigaction (SIGINT, &sigact, NULL);
sigaction (SIGPIPE, &sigact, NULL);
sigaction(SIGINT, &sigact, NULL);
sigaction(SIGPIPE, &sigact, NULL);
#endif
if (optget (opts, "daemon")->enabled)
{
if (optget(opts, "daemon")->enabled) {
int bigsleep, checks;
#ifndef _WIN32
time_t now, wakeup;
sigaction (SIGTERM, &sigact, NULL);
sigaction (SIGHUP, &sigact, NULL);
sigaction (SIGCHLD, &sigact, NULL);
sigaction(SIGTERM, &sigact, NULL);
sigaction(SIGHUP, &sigact, NULL);
sigaction(SIGCHLD, &sigact, NULL);
#endif
checks = optget (opts, "Checks")->numarg;
checks = optget(opts, "Checks")->numarg;
if (checks <= 0)
{
logg ("^Number of checks must be a positive integer.\n");
optfree (opts);
if (checks <= 0) {
logg("^Number of checks must be a positive integer.\n");
optfree(opts);
return FCE_CHECKS;
}
if (!optget (opts, "DNSDatabaseInfo")->enabled
|| optget (opts, "no-dns")->enabled)
{
if (checks > 50)
{
logg ("^Number of checks must be between 1 and 50.\n");
optfree (opts);
if (!optget(opts, "DNSDatabaseInfo")->enabled || optget(opts, "no-dns")->enabled) {
if (checks > 50) {
logg("^Number of checks must be between 1 and 50.\n");
optfree(opts);
return FCE_CHECKS;
}
}
@ -615,116 +554,97 @@ main (int argc, char **argv)
#ifndef _WIN32
/* fork into background */
if (foreground == -1)
{
if (optget(opts, "Foreground")->enabled)
{
if (foreground == -1) {
if (optget(opts, "Foreground")->enabled) {
foreground = 1;
}
else
{
} else {
foreground = 0;
}
}
if(foreground == 0)
{
if (daemonize () == -1)
{
logg ("!daemonize() failed\n");
optfree (opts);
if (foreground == 0) {
if (daemonize() == -1) {
logg("!daemonize() failed\n");
optfree(opts);
return FCE_FAILEDUPDATE;
}
mprintf_disabled = 1;
}
#endif
if ((opt = optget (opts, "PidFile"))->enabled)
{
if ((opt = optget(opts, "PidFile"))->enabled) {
pidfile = opt->strarg;
writepid (pidfile);
writepid(pidfile);
}
active_children = 0;
logg ("#freshclam daemon %s (OS: " TARGET_OS_TYPE ", ARCH: "
TARGET_ARCH_TYPE ", CPU: " TARGET_CPU_TYPE ")\n",
get_version ());
logg("#freshclam daemon %s (OS: " TARGET_OS_TYPE ", ARCH: " TARGET_ARCH_TYPE ", CPU: " TARGET_CPU_TYPE ")\n",
get_version());
while (!terminate)
{
ret = download (opts, cfgfile);
while (!terminate) {
ret = download(opts, cfgfile);
if (ret > 1)
{
if ((opt = optget (opts, "OnErrorExecute"))->enabled)
if (ret > 1) {
if ((opt = optget(opts, "OnErrorExecute"))->enabled)
arg = opt->strarg;
if (arg)
execute ("OnErrorExecute", arg, opts);
execute("OnErrorExecute", arg, opts);
arg = NULL;
}
logg ("#--------------------------------------\n");
logg("#--------------------------------------\n");
#ifdef SIGALRM
sigaction (SIGALRM, &sigact, &oldact);
sigaction(SIGALRM, &sigact, &oldact);
#endif
#ifdef SIGUSR1
sigaction (SIGUSR1, &sigact, &oldact);
sigaction(SIGUSR1, &sigact, &oldact);
#endif
#ifdef _WIN32
sleep (bigsleep);
sleep(bigsleep);
#else
time (&wakeup);
time(&wakeup);
wakeup += bigsleep;
alarm (bigsleep);
do
{
pause ();
time (&now);
}
while (!terminate && now < wakeup);
alarm(bigsleep);
do {
pause();
time(&now);
} while (!terminate && now < wakeup);
if (terminate == -1)
{
logg ("Received signal: wake up\n");
if (terminate == -1) {
logg("Received signal: wake up\n");
terminate = 0;
}
else if (terminate == -2)
{
logg ("Received signal: re-opening log file\n");
} else if (terminate == -2) {
logg("Received signal: re-opening log file\n");
terminate = 0;
logg_close ();
logg_close();
}
#endif
#ifdef SIGALRM
sigaction (SIGALRM, &oldact, NULL);
sigaction(SIGALRM, &oldact, NULL);
#endif
#ifdef SIGUSR1
sigaction (SIGUSR1, &oldact, NULL);
sigaction(SIGUSR1, &oldact, NULL);
#endif
}
}
else
{
ret = download (opts, cfgfile);
} else {
ret = download(opts, cfgfile);
}
if (ret > 1)
{
if ((opt = optget (opts, "OnErrorExecute"))->enabled)
execute ("OnErrorExecute", opt->strarg, opts);
if (ret > 1) {
if ((opt = optget(opts, "OnErrorExecute"))->enabled)
execute("OnErrorExecute", opt->strarg, opts);
}
if (pidfile)
{
unlink (pidfile);
if (pidfile) {
unlink(pidfile);
}
optfree (opts);
optfree(opts);
cl_cleanup_crypto();
@ -738,8 +658,8 @@ int is_valid_hostid(void)
if (strlen(hostid) != 36)
return 0;
count=0;
for (i=0; i < 36; i++)
count = 0;
for (i = 0; i < 36; i++)
if (hostid[i] == '-')
count++;

View file

@ -33,7 +33,7 @@ typedef enum fc_error_tag {
FCE_EMPTYFILE = 53,
FCE_BADCVD = 54,
FCE_FILE = 55,
/* TESTFAIL is also 55, consider moving to new value */
/* TESTFAIL is also 55, consider moving to new value */
FCE_TESTFAIL = 55,
FCE_CONFIG = 56,
FCE_DBDIRACCESS = 57,

File diff suppressed because it is too large Load diff

View file

@ -25,7 +25,7 @@
#include "shared/optparser.h"
int downloadmanager (const struct optstruct *opts, const char *hostname,
int downloadmanager(const struct optstruct *opts, const char *hostname,
unsigned int attempt);
#endif

View file

@ -53,12 +53,10 @@
#define IGNORE_SHORT (3600) /* 1 hour */
#define IGNORE_LONG (6 * IGNORE_SHORT) /* 6 hours */
void
mirman_free(struct mirdat *mdat)
void mirman_free(struct mirdat *mdat)
{
if (mdat && mdat->num)
{
free (mdat->mirtab);
if (mdat && mdat->num) {
free(mdat->mirtab);
mdat->num = 0;
}
}
@ -68,49 +66,46 @@ fc_error_t mirman_read(const char *file, struct mirdat *mdat, uint8_t active)
struct mirdat_ip mip;
int fd, bread;
memset (mdat, 0, sizeof(struct mirdat));
memset(mdat, 0, sizeof(struct mirdat));
if (!(mdat->active = active))
return FC_SUCCESS;
if ((fd = open (file, O_RDONLY | O_BINARY)) == -1)
if ((fd = open(file, O_RDONLY | O_BINARY)) == -1)
return FCE_OPEN;
while ((bread = read (fd, &mip, sizeof(mip))) == sizeof(mip))
{
while ((bread = read(fd, &mip, sizeof(mip))) == sizeof(mip)) {
mdat->mirtab =
(struct mirdat_ip *) realloc (mdat->mirtab,
(struct mirdat_ip *)realloc(mdat->mirtab,
(mdat->num + 1) * sizeof(mip));
if (!mdat->mirtab)
{
if (!mdat->mirtab) {
logg("!Can't allocate memory for mdat->mirtab\n");
mirman_free (mdat);
close (fd);
mirman_free(mdat);
close(fd);
return FCE_MEM;
}
memcpy (&mdat->mirtab[mdat->num], &mip, sizeof(mip));
memcpy(&mdat->mirtab[mdat->num], &mip, sizeof(mip));
mdat->num++;
}
close (fd);
close(fd);
if (bread)
{
if (bread) {
logg("^Removing broken %s file.\n", file);
unlink (file);
mirman_free (mdat);
unlink(file);
mirman_free(mdat);
return FCE_FILE;
}
return FC_SUCCESS;
}
fc_error_t mirman_check(uint32_t * ip, int af, struct mirdat *mdat,
fc_error_t mirman_check(uint32_t *ip, int af, struct mirdat *mdat,
struct mirdat_ip **md, mir_status_t *mirror_status)
{
fc_error_t status = FC_SUCCESS;
unsigned int i;
unsigned int flevel = cl_retflevel ();
unsigned int flevel = cl_retflevel();
if (NULL == md || NULL == mdat || NULL == ip) {
logg("!mirman_check: Invalid arguments.\n");
@ -120,54 +115,43 @@ fc_error_t mirman_check(uint32_t * ip, int af, struct mirdat *mdat,
*md = NULL;
if (!mdat->active)
{
if (!mdat->active) {
*mirror_status = MIRROR_OK;
goto done;
}
for (i = 0; i < mdat->num; i++)
{
for (i = 0; i < mdat->num; i++) {
if ((af == AF_INET && mdat->mirtab[i].ip4 == *ip) ||
((af == AF_INET6) && (!memcmp (mdat->mirtab[i].ip6, ip, 4 * sizeof(uint32_t)))))
{
((af == AF_INET6) && (!memcmp(mdat->mirtab[i].ip6, ip, 4 * sizeof(uint32_t))))) {
/*
* Mirror found in mirror table.
*/
if (mdat->dbflevel && (mdat->dbflevel > flevel) && (mdat->dbflevel - flevel > 3))
{
if (mdat->dbflevel && (mdat->dbflevel > flevel) && (mdat->dbflevel - flevel > 3)) {
/* Functionality level of database is lower than
* level of the database we already have */
if (difftime(time(NULL), mdat->mirtab[i].atime) < (mdat->dbflevel - flevel) * 3600)
{
if (difftime(time(NULL), mdat->mirtab[i].atime) < (mdat->dbflevel - flevel) * 3600) {
*mirror_status = MIRROR_IGNORE__OUTDATED_VERSION;
goto done;
}
}
if ((mdat->mirtab[i].atime > 0) &&
(IGNORE_NO != mdat->mirtab[i].ignore))
{
(IGNORE_NO != mdat->mirtab[i].ignore)) {
/*
* Found, but the ignore flag is set.
*/
if (difftime(time(NULL), mdat->mirtab[i].atime) > IGNORE_LONG)
{
if (difftime(time(NULL), mdat->mirtab[i].atime) > IGNORE_LONG) {
/* Long-Ignore timeout expired,
* the mirror can be attempted again */
mdat->mirtab[i].ignore = IGNORE_NO;
}
else if ((mdat->mirtab[i].ignore == IGNORE_SHORTTERM) &&
(difftime(time(NULL), mdat->mirtab[i].atime) > IGNORE_SHORT))
{
} else if ((mdat->mirtab[i].ignore == IGNORE_SHORTTERM) &&
(difftime(time(NULL), mdat->mirtab[i].atime) > IGNORE_SHORT)) {
/* Mirror was only set to Short-Term ignore...
* the Short-Ignore timeout expired,
* the mirror can be attempted again */
mdat->mirtab[i].ignore = IGNORE_NO;
}
else
{
} else {
*mirror_status = MIRROR_IGNORE__PREV_ERRS;
goto done;
}
@ -188,7 +172,7 @@ done:
return status;
}
fc_error_t mirman_update(uint32_t * ip, int af, struct mirdat *mdat, fc_error_t error)
fc_error_t mirman_update(uint32_t *ip, int af, struct mirdat *mdat, fc_error_t error)
{
fc_error_t status = FCE_ARG;
unsigned int i = 0;
@ -202,38 +186,31 @@ fc_error_t mirman_update(uint32_t * ip, int af, struct mirdat *mdat, fc_error_t
/*
* Attempt to find the ip in the mirror table.
*/
for (i = 0; i < mdat->num; i++)
{
for (i = 0; i < mdat->num; i++) {
if (((af == AF_INET) && (mdat->mirtab[i].ip4 == *ip)) ||
((af == AF_INET6) && (!memcmp(mdat->mirtab[i].ip6, ip, 4 * sizeof(uint32_t)))))
{
((af == AF_INET6) && (!memcmp(mdat->mirtab[i].ip6, ip, 4 * sizeof(uint32_t))))) {
mirror = &mdat->mirtab[i];
break;
}
}
if (NULL == mirror)
{
if (NULL == mirror) {
/*
* Allocate space in the mirror table for the new mirror IP
*/
mdat->mirtab =
(struct mirdat_ip *) realloc(mdat->mirtab,
(struct mirdat_ip *)realloc(mdat->mirtab,
(mdat->num + 1) * sizeof(struct mirdat_ip));
if (!mdat->mirtab)
{
if (!mdat->mirtab) {
logg("!Can't allocate memory for new element in mdat->mirtab\n");
return FCE_MEM;
}
memset (&mdat->mirtab[mdat->num], 0, sizeof(struct mirdat_ip));
if (af == AF_INET)
{
memset(&mdat->mirtab[mdat->num], 0, sizeof(struct mirdat_ip));
if (af == AF_INET) {
mdat->mirtab[mdat->num].ip4 = *ip;
}
else
{
} else {
mdat->mirtab[mdat->num].ip4 = 0;
memcpy (mdat->mirtab[mdat->num].ip6, ip, 4 * sizeof(uint32_t));
memcpy(mdat->mirtab[mdat->num].ip6, ip, 4 * sizeof(uint32_t));
}
mdat->mirtab[mdat->num].atime = 0;
mdat->mirtab[mdat->num].succ = 0;
@ -249,23 +226,16 @@ fc_error_t mirman_update(uint32_t * ip, int af, struct mirdat *mdat, fc_error_t
if (FC_SUCCESS == error) {
mirror->succ++;
mirror->fail = 0;
}
else
{
} else {
mirror->succ = 0;
mirror->fail++;
}
if (mirror->fail >= 6)
{
if (mirror->fail >= 6) {
mirror->ignore = IGNORE_LONGTERM;
}
else if (mirror->fail >= 3)
{
} else if (mirror->fail >= 3) {
mirror->ignore = IGNORE_SHORTTERM;
}
else
{
} else {
mirror->ignore = IGNORE_NO;
}
@ -278,8 +248,7 @@ void mirman_list(const struct mirdat *mdat)
time_t tm;
char ip[46];
for (i = 0; i < mdat->num; i++)
{
for (i = 0; i < mdat->num; i++) {
printf("Mirror #%u\n", i + 1);
#ifdef HAVE_GETADDRINFO
if (mdat->mirtab[i].ip4)
@ -296,7 +265,7 @@ void mirman_list(const struct mirdat *mdat)
printf("Successes: %u\n", mdat->mirtab[i].succ);
printf("Failures: %u\n", mdat->mirtab[i].fail);
tm = mdat->mirtab[i].atime;
printf("Last access: %s", ctime((const time_t *) &tm));
printf("Last access: %s", ctime((const time_t *)&tm));
if (mdat->mirtab[i].ignore) {
time_t ignore_expires = tm + ((mdat->mirtab[i].ignore == IGNORE_LONGTERM) ? IGNORE_LONG
: IGNORE_SHORT);
@ -332,8 +301,7 @@ void mirman_whitelist(struct mirdat *mdat, unsigned int mode)
return;
}
switch (mode)
{
switch (mode) {
case 1:
logg("*Whitelisting all blacklisted mirrors\n");
break;
@ -345,14 +313,10 @@ void mirman_whitelist(struct mirdat *mdat, unsigned int mode)
return;
}
for (i = 0; i < mdat->num; i++)
{
if (mode == 1)
{
for (i = 0; i < mdat->num; i++) {
if (mode == 1) {
mdat->mirtab[i].ignore = IGNORE_NO;
}
else if ((mode == 2) && (IGNORE_SHORTTERM == mdat->mirtab[i].ignore))
{
} else if ((mode == 2) && (IGNORE_SHORTTERM == mdat->mirtab[i].ignore)) {
mdat->mirtab[i].ignore = IGNORE_NO;
}
}
@ -373,18 +337,16 @@ fc_error_t mirman_write(const char *file, const char *dir, struct mirdat *mdat)
return FC_SUCCESS;
if ((fd =
open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600)) == -1)
{
open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600)) == -1) {
logg("!Can't open %s for writing\n", path);
return FCE_OPEN;
}
for (i = 0; i < mdat->num; i++)
if (!mdat->mirtab[i].atime)
mdat->mirtab[i].atime = (uint32_t) time(NULL);
mdat->mirtab[i].atime = (uint32_t)time(NULL);
if (write(fd, mdat->mirtab, mdat->num * sizeof(struct mirdat_ip)) == -1)
{
if (write(fd, mdat->mirtab, mdat->num * sizeof(struct mirdat_ip)) == -1) {
logg("!Can't write to %s\n", path);
close(fd);
return FCE_FILE;

View file

@ -23,20 +23,19 @@
#include "freshclamcodes.h"
typedef enum mir_status_tag {
MIRROR_OK=0,
MIRROR_OK = 0,
MIRROR_FAILURE,
MIRROR_IGNORE__PREV_ERRS,
MIRROR_IGNORE__OUTDATED_VERSION
} mir_status_t;
typedef enum mir_ignore_tag {
IGNORE_NO=0,
IGNORE_NO = 0,
IGNORE_LONGTERM,
IGNORE_SHORTTERM
} mir_ignore_t;
struct mirdat_ip
{
struct mirdat_ip {
uint32_t ip4; /* IPv4 address */
time_t atime; /* last access time */
uint32_t succ; /* number of successful downloads from this ip */
@ -46,8 +45,7 @@ struct mirdat_ip
char res[16]; /* reserved */
};
struct mirdat
{
struct mirdat {
uint8_t active; /* 1 if active, 2 if disabled */
unsigned int num; /* number of mirrors */
uint32_t currip[4]; /* IP currently attempting */
@ -80,7 +78,7 @@ fc_error_t mirman_read(const char *file, struct mirdat *mdat, uint8_t active);
* MIRROR_IGNORE__OUTDATED_VERSION
* @return fc_error_t FC_SUCCESS or an FCE error code.
*/
fc_error_t mirman_check(uint32_t * ip, int af, struct mirdat *mdat,
fc_error_t mirman_check(uint32_t *ip, int af, struct mirdat *mdat,
struct mirdat_ip **md, mir_status_t *mirror_status);
/**
@ -92,7 +90,7 @@ fc_error_t mirman_check(uint32_t * ip, int af, struct mirdat *mdat,
* @param error FC_SUCCESS or an FCE error code.
* @return fc_error_t FC_SUCCESS or an FCE error code.
*/
fc_error_t mirman_update(uint32_t * ip, int af, struct mirdat *mdat, fc_error_t mirror_status);
fc_error_t mirman_update(uint32_t *ip, int af, struct mirdat *mdat, fc_error_t mirror_status);
/**
* @brief Print out the mirror info.

View file

@ -49,8 +49,8 @@
#ifndef timercmp
#define timercmp(a, b, cmp) \
(((a)->tv_sec == (b)->tv_sec) \
? ((a)->tv_usec cmp (b)->tv_usec) \
: ((a)->tv_sec cmp (b)->tv_sec))
? ((a)->tv_usec cmp(b)->tv_usec) \
: ((a)->tv_sec cmp(b)->tv_sec))
#endif /* timercmp */
#ifndef timersub
@ -70,25 +70,24 @@
#undef NONBLOCK_DEBUG
static int
connect_error (int sock)
connect_error(int sock)
{
int optval;
socklen_t optlen;
optlen = sizeof (optval);
getsockopt (sock, SOL_SOCKET, SO_ERROR, &optval, (socklen_t *)&optlen);
optlen = sizeof(optval);
getsockopt(sock, SOL_SOCKET, SO_ERROR, &optval, (socklen_t *)&optlen);
if (optval)
{
logg ("connect_error: getsockopt(SO_ERROR): fd=%d error=%d: %s\n",
sock, optval, strerror (optval));
if (optval) {
logg("connect_error: getsockopt(SO_ERROR): fd=%d error=%d: %s\n",
sock, optval, strerror(optval));
}
return optval ? -1 : 0;
}
static int
nonblock_connect (int sock, const struct sockaddr *addr, socklen_t addrlen,
nonblock_connect(int sock, const struct sockaddr *addr, socklen_t addrlen,
int secs)
{
/* Max. of unexpected select() failures */
@ -99,19 +98,17 @@ nonblock_connect (int sock, const struct sockaddr *addr, socklen_t addrlen,
int numfd; /* Highest fdset fd plus 1 */
/* Calculate into 'timeout' when we should time out */
gettimeofday (&timeout, 0);
gettimeofday(&timeout, 0);
timeout.tv_sec += secs;
/* Launch (possibly) non-blocking connect() request */
if (connect (sock, addr, addrlen))
{
if (connect(sock, addr, addrlen)) {
int e = errno;
#ifdef NONBLOCK_DEBUG
logg ("DEBUG nonblock_connect: connect(): fd=%d errno=%d: %s\n",
sock, e, strerror (e));
logg("DEBUG nonblock_connect: connect(): fd=%d errno=%d: %s\n",
sock, e, strerror(e));
#endif
switch (e)
{
switch (e) {
case EALREADY:
case EINPROGRESS:
case EAGAIN:
@ -119,63 +116,56 @@ nonblock_connect (int sock, const struct sockaddr *addr, socklen_t addrlen,
case EISCONN:
return 0; /* connected */
default:
logg ("nonblock_connect: connect(): fd=%d errno=%d: %s\n",
sock, e, strerror (e));
logg("nonblock_connect: connect(): fd=%d errno=%d: %s\n",
sock, e, strerror(e));
return -1; /* failed */
}
}
else
{
return connect_error (sock);
} else {
return connect_error(sock);
}
numfd = sock + 1; /* Highest fdset fd plus 1 */
for (;;)
{
for (;;) {
fd_set fds;
struct timeval now;
struct timeval wait;
int n;
/* Force timeout if we ran out of time */
gettimeofday (&now, 0);
if (timercmp (&now, &timeout, >))
{
logg ("nonblock_connect: connect timing out (%d secs)\n", secs);
gettimeofday(&now, 0);
if (timercmp(&now, &timeout, >)) {
logg("nonblock_connect: connect timing out (%d secs)\n", secs);
break; /* failed */
}
/* Calculate into 'wait' how long to wait */
timersub (&timeout, &now, &wait); /* wait = timeout - now */
timersub(&timeout, &now, &wait); /* wait = timeout - now */
/* Init fds with 'sock' as the only fd */
FD_ZERO (&fds);
FD_SET (sock, &fds);
FD_ZERO(&fds);
FD_SET(sock, &fds);
n = select (numfd, 0, &fds, 0, &wait);
if (n < 0)
{
logg ("nonblock_connect: select() failure %d: errno=%d: %s\n",
select_failures, errno, strerror (errno));
n = select(numfd, 0, &fds, 0, &wait);
if (n < 0) {
logg("nonblock_connect: select() failure %d: errno=%d: %s\n",
select_failures, errno, strerror(errno));
if (--select_failures >= 0)
continue; /* keep waiting */
break; /* failed */
}
#ifdef NONBLOCK_DEBUG
logg ("DEBUG nonblock_connect: select = %d\n", n);
logg("DEBUG nonblock_connect: select = %d\n", n);
#endif
if (n)
{
return connect_error (sock);
if (n) {
return connect_error(sock);
}
/* Select returned, but there is no work to do... */
if (--bogus_loops < 0)
{
logg ("nonblock_connect: giving up due to excessive bogus loops\n");
if (--bogus_loops < 0) {
logg("nonblock_connect: giving up due to excessive bogus loops\n");
break; /* failed */
}
@ -185,7 +175,7 @@ nonblock_connect (int sock, const struct sockaddr *addr, socklen_t addrlen,
}
static ssize_t
nonblock_recv (int sock, void *buf, size_t len, int flags, int secs)
nonblock_recv(int sock, void *buf, size_t len, int flags, int secs)
{
/* Max. of unexpected select() failures */
int select_failures = NONBLOCK_SELECT_MAX_FAILURES;
@ -198,13 +188,12 @@ nonblock_recv (int sock, void *buf, size_t len, int flags, int secs)
memset(buf, 0x00, len);
/* Calculate into 'timeout' when we should time out */
gettimeofday (&timeout, 0);
gettimeofday(&timeout, 0);
timeout.tv_sec += secs;
numfd = sock + 1; /* Highest fdset fd plus 1 */
for (;;)
{
for (;;) {
fd_set fds;
struct timeval now;
struct timeval wait;
@ -212,32 +201,29 @@ nonblock_recv (int sock, void *buf, size_t len, int flags, int secs)
ssize_t recvd;
/* Force timeout if we ran out of time */
gettimeofday (&now, 0);
if (timercmp (&now, &timeout, >))
{
logg ("nonblock_recv: recv timing out (%d secs)\n", secs);
gettimeofday(&now, 0);
if (timercmp(&now, &timeout, >)) {
logg("nonblock_recv: recv timing out (%d secs)\n", secs);
break; /* failed */
}
/* Calculate into 'wait' how long to wait */
timersub (&timeout, &now, &wait); /* wait = timeout - now */
timersub(&timeout, &now, &wait); /* wait = timeout - now */
/* Init fds with 'sock' as the only fd */
FD_ZERO (&fds);
FD_SET (sock, &fds);
FD_ZERO(&fds);
FD_SET(sock, &fds);
n = select (numfd, &fds, 0, 0, &wait);
if (n < 0)
{
logg ("nonblock_recv: select() failure %d: errno=%d: %s\n",
select_failures, errno, strerror (errno));
n = select(numfd, &fds, 0, 0, &wait);
if (n < 0) {
logg("nonblock_recv: select() failure %d: errno=%d: %s\n",
select_failures, errno, strerror(errno));
if (--select_failures >= 0)
continue; /* keep waiting */
break; /* failed */
}
if (FD_ISSET(sock, &fds))
{
if (FD_ISSET(sock, &fds)) {
recvd = recv(sock, buf, len, flags);
if (recvd < 0) {
if (errno == EINTR)
@ -250,9 +236,8 @@ nonblock_recv (int sock, void *buf, size_t len, int flags, int secs)
}
/* Select returned, but there is no work to do... */
if (--bogus_loops < 0)
{
logg ("nonblock_recv: giving up due to excessive bogus loops\n");
if (--bogus_loops < 0) {
logg("nonblock_recv: giving up due to excessive bogus loops\n");
break; /* failed */
}
@ -262,20 +247,17 @@ nonblock_recv (int sock, void *buf, size_t len, int flags, int secs)
}
static long
nonblock_fcntl (int sock)
nonblock_fcntl(int sock)
{
#ifdef F_GETFL
long fcntl_flags; /* Save fcntl() flags */
fcntl_flags = fcntl (sock, F_GETFL, 0);
if (fcntl_flags == -1)
{
logg ("nonblock_fcntl: saving: fcntl(%d, F_GETFL): errno=%d: %s\n",
sock, errno, strerror (errno));
}
else if (fcntl (sock, F_SETFL, fcntl_flags | O_NONBLOCK))
{
logg ("nonblock_fcntl: fcntl(%d, F_SETFL, O_NONBLOCK): errno=%d: %s\n", sock, errno, strerror (errno));
fcntl_flags = fcntl(sock, F_GETFL, 0);
if (fcntl_flags == -1) {
logg("nonblock_fcntl: saving: fcntl(%d, F_GETFL): errno=%d: %s\n",
sock, errno, strerror(errno));
} else if (fcntl(sock, F_SETFL, fcntl_flags | O_NONBLOCK)) {
logg("nonblock_fcntl: fcntl(%d, F_SETFL, O_NONBLOCK): errno=%d: %s\n", sock, errno, strerror(errno));
}
return fcntl_flags;
@ -285,14 +267,12 @@ nonblock_fcntl (int sock)
}
static void
restore_fcntl (int sock, long fcntl_flags)
restore_fcntl(int sock, long fcntl_flags)
{
#ifdef F_SETFL
if (fcntl_flags != -1)
{
if (fcntl (sock, F_SETFL, fcntl_flags))
{
logg ("restore_fcntl: restoring: fcntl(%d, F_SETFL): errno=%d: %s\n", sock, errno, strerror (errno));
if (fcntl_flags != -1) {
if (fcntl(sock, F_SETFL, fcntl_flags)) {
logg("restore_fcntl: restoring: fcntl(%d, F_SETFL): errno=%d: %s\n", sock, errno, strerror(errno));
}
}
#endif
@ -301,20 +281,19 @@ restore_fcntl (int sock, long fcntl_flags)
/*
wait_connect(): wrapper for connect(), with explicit 'secs' timeout
*/
int
wait_connect (int sock, const struct sockaddr *addr, socklen_t addrlen,
int wait_connect(int sock, const struct sockaddr *addr, socklen_t addrlen,
int secs)
{
long fcntl_flags; /* Save fcntl() flags */
int ret;
/* Temporarily set socket to non-blocking mode */
fcntl_flags = nonblock_fcntl (sock);
fcntl_flags = nonblock_fcntl(sock);
ret = nonblock_connect (sock, addr, addrlen, secs);
ret = nonblock_connect(sock, addr, addrlen, secs);
/* Restore socket's default blocking mode */
restore_fcntl (sock, fcntl_flags);
restore_fcntl(sock, fcntl_flags);
return ret;
}
@ -323,18 +302,18 @@ wait_connect (int sock, const struct sockaddr *addr, socklen_t addrlen,
wait_recv(): wrapper for recv(), with explicit 'secs' timeout
*/
ssize_t
wait_recv (int sock, void *buf, size_t len, int flags, int secs)
wait_recv(int sock, void *buf, size_t len, int flags, int secs)
{
long fcntl_flags; /* Save fcntl() flags */
int ret;
/* Temporarily set socket to non-blocking mode */
fcntl_flags = nonblock_fcntl (sock);
fcntl_flags = nonblock_fcntl(sock);
ret = nonblock_recv (sock, buf, len, flags, secs);
ret = nonblock_recv(sock, buf, len, flags, secs);
/* Restore socket's default blocking mode */
restore_fcntl (sock, fcntl_flags);
restore_fcntl(sock, fcntl_flags);
return ret;
}

View file

@ -31,12 +31,12 @@
/*
wait_connect(): wrapper for connect(), with explicit 'secs' timeout
*/
int wait_connect (int sock, const struct sockaddr *addr, socklen_t addrlen,
int wait_connect(int sock, const struct sockaddr *addr, socklen_t addrlen,
int secs);
/*
wait_recv(): wrapper for recv(), with explicit 'secs' timeout
*/
ssize_t wait_recv (int sock, void *buf, size_t len, int flags, int secs);
ssize_t wait_recv(int sock, void *buf, size_t len, int flags, int secs);
#endif /* NONBLOCK_H */

View file

@ -44,8 +44,7 @@
#include "notify.h"
int
clamd_connect (const char *cfgfile, const char *option)
int clamd_connect(const char *cfgfile, const char *option)
{
#ifndef _WIN32
struct sockaddr_un server;
@ -59,83 +58,74 @@ clamd_connect (const char *cfgfile, const char *option)
const struct optstruct *opt;
int sockd;
if ((opts = optparse (cfgfile, 0, NULL, 1, OPT_CLAMD, 0, NULL)) == NULL)
{
logg ("!%s: Can't find or parse configuration file %s\n", option,
if ((opts = optparse(cfgfile, 0, NULL, 1, OPT_CLAMD, 0, NULL)) == NULL) {
logg("!%s: Can't find or parse configuration file %s\n", option,
cfgfile);
return -11;
}
#ifndef _WIN32
if ((opt = optget (opts, "LocalSocket"))->enabled)
{
if ((opt = optget(opts, "LocalSocket"))->enabled) {
memset(&server, 0x00, sizeof(server));
server.sun_family = AF_UNIX;
strncpy (server.sun_path, opt->strarg, sizeof (server.sun_path));
server.sun_path[sizeof (server.sun_path) - 1] = '\0';
strncpy(server.sun_path, opt->strarg, sizeof(server.sun_path));
server.sun_path[sizeof(server.sun_path) - 1] = '\0';
if ((sockd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
{
logg ("^Clamd was NOT notified: Can't create socket endpoint for %s: %s\n",
if ((sockd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
logg("^Clamd was NOT notified: Can't create socket endpoint for %s: %s\n",
opt->strarg, strerror(errno));
optfree (opts);
optfree(opts);
return -1;
}
if (connect
(sockd, (struct sockaddr *) &server,
sizeof (struct sockaddr_un)) < 0)
{
logg ("^Clamd was NOT notified: Can't connect to clamd through %s: %s\n",
if (connect(sockd, (struct sockaddr *)&server,
sizeof(struct sockaddr_un)) < 0) {
logg("^Clamd was NOT notified: Can't connect to clamd through %s: %s\n",
opt->strarg, strerror(errno));
closesocket (sockd);
optfree (opts);
closesocket(sockd);
optfree(opts);
return -11;
}
return sockd;
}
else
} else
#endif
if ((opt = optget (opts, "TCPSocket"))->enabled)
{
memset (&hints, 0, sizeof (hints));
if ((opt = optget(opts, "TCPSocket"))->enabled) {
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
snprintf (port, sizeof (port), "%u", (unsigned int) opt->numarg);
snprintf(port, sizeof(port), "%u", (unsigned int)opt->numarg);
port[5] = 0;
opt = optget(opts, "TCPAddr");
while (opt) {
ret = getaddrinfo (opt->strarg, port, &hints, &res);
ret = getaddrinfo(opt->strarg, port, &hints, &res);
if (ret)
{
logg ("!%s: Can't resolve hostname %s (%s)\n", option,
if (ret) {
logg("!%s: Can't resolve hostname %s (%s)\n", option,
opt->strarg ? opt->strarg : "",
(ret ==
EAI_SYSTEM) ? strerror (errno) : gai_strerror (ret));
EAI_SYSTEM)
? strerror(errno)
: gai_strerror(ret));
opt = opt->nextarg;
continue;
}
for (p = res; p != NULL; p = p->ai_next) {
if ((sockd = socket (p->ai_family, p->ai_socktype, p->ai_protocol)) < 0)
{
logg ("!%s: Can't create TCP socket to connect to %s: %s\n",
if ((sockd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
logg("!%s: Can't create TCP socket to connect to %s: %s\n",
option, opt->strarg ? opt->strarg : "localhost", strerror(errno));
continue;
}
if (connect (sockd, p->ai_addr, p->ai_addrlen) == -1)
{
logg ("!%s: Can't connect to clamd on %s:%s: %s\n", option,
if (connect(sockd, p->ai_addr, p->ai_addrlen) == -1) {
logg("!%s: Can't connect to clamd on %s:%s: %s\n", option,
opt->strarg ? opt->strarg : "localhost", port, strerror(errno));
closesocket (sockd);
closesocket(sockd);
continue;
}
@ -145,51 +135,45 @@ clamd_connect (const char *cfgfile, const char *option)
return sockd;
}
freeaddrinfo (res);
freeaddrinfo(res);
opt = opt->nextarg;
}
}
else
{
logg ("!%s: No communication socket specified in %s\n", option,
} else {
logg("!%s: No communication socket specified in %s\n", option,
cfgfile);
optfree (opts);
optfree(opts);
return 1;
}
optfree (opts);
optfree(opts);
return -1;
}
int
notify (const char *cfgfile)
int notify(const char *cfgfile)
{
char buff[20];
int sockd, bread;
if ((sockd = clamd_connect (cfgfile, "NotifyClamd")) < 0)
if ((sockd = clamd_connect(cfgfile, "NotifyClamd")) < 0)
return 1;
if (sendln (sockd, "RELOAD", 7) < 0)
{
logg ("!NotifyClamd: Could not write to clamd socket: %s\n", strerror(errno));
closesocket (sockd);
if (sendln(sockd, "RELOAD", 7) < 0) {
logg("!NotifyClamd: Could not write to clamd socket: %s\n", strerror(errno));
closesocket(sockd);
return 1;
}
memset (buff, 0, sizeof (buff));
if ((bread = recv (sockd, buff, sizeof (buff), 0)) > 0)
{
if (!strstr (buff, "RELOADING"))
{
logg ("!NotifyClamd: Unknown answer from clamd: '%s'\n", buff);
closesocket (sockd);
memset(buff, 0, sizeof(buff));
if ((bread = recv(sockd, buff, sizeof(buff), 0)) > 0) {
if (!strstr(buff, "RELOADING")) {
logg("!NotifyClamd: Unknown answer from clamd: '%s'\n", buff);
closesocket(sockd);
return -1;
}
}
closesocket (sockd);
logg ("Clamd successfully notified about the update.\n");
closesocket(sockd);
logg("Clamd successfully notified about the update.\n");
return 0;
}
#endif

View file

@ -19,7 +19,7 @@
#ifndef __NOTIFY_H
#define __NOTIFY_H
int notify (const char *cfgfile);
int clamd_connect (const char *cfgfile, const char *option);
int notify(const char *cfgfile);
int clamd_connect(const char *cfgfile, const char *option);
#endif

View file

@ -35,10 +35,10 @@
#include "7z/7zAlloc.h"
#include "7z/7zFile.h"
static ISzAlloc allocImp = {__lzma_wrap_alloc, __lzma_wrap_free}, allocTempImp = {__lzma_wrap_alloc, __lzma_wrap_free};
static ISzAlloc allocImp = { __lzma_wrap_alloc, __lzma_wrap_free}, allocTempImp = { __lzma_wrap_alloc, __lzma_wrap_free};
static SRes FileInStream_fmap_Read(void *pp, void *buf, size_t *size) {
static SRes FileInStream_fmap_Read(void *pp, void *buf, size_t *size)
{
CFileInStream *p = (CFileInStream *)pp;
int read_sz;
@ -46,7 +46,7 @@ static SRes FileInStream_fmap_Read(void *pp, void *buf, size_t *size) {
return 0;
read_sz = fmap_readn(p->file.fmap, buf, p->s.curpos, *size);
if(read_sz < 0) {
if (read_sz < 0) {
*size = 0;
return SZ_ERROR_READ;
}
@ -57,7 +57,8 @@ static SRes FileInStream_fmap_Read(void *pp, void *buf, size_t *size) {
return SZ_OK;
}
static SRes FileInStream_fmap_Seek(void *pp, Int64 *pos, ESzSeek origin) {
static SRes FileInStream_fmap_Seek(void *pp, Int64 *pos, ESzSeek origin)
{
CFileInStream *p = (CFileInStream *)pp;
switch (origin) {
@ -79,7 +80,8 @@ static SRes FileInStream_fmap_Seek(void *pp, Int64 *pos, ESzSeek origin) {
}
#define UTFBUFSZ 256
int cli_7unz (cli_ctx *ctx, size_t offset) {
int cli_7unz(cli_ctx *ctx, size_t offset)
{
CFileInStream archiveStream;
CLookToRead lookStream;
CSzArEx db;
@ -98,7 +100,7 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
LookToRead_CreateVTable(&lookStream, False);
if(archiveStream.s.Seek(&archiveStream.s, &begin_of_archive, SZ_SEEK_SET) != 0)
if (archiveStream.s.Seek(&archiveStream.s, &begin_of_archive, SZ_SEEK_SET) != 0)
return CL_CLEAN;
lookStream.realStream = &archiveStream.s;
@ -106,10 +108,10 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
SzArEx_Init(&db);
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
if(res == SZ_ERROR_ENCRYPTED && SCAN_HEURISTIC_ENCRYPTED_ARCHIVE) {
if (res == SZ_ERROR_ENCRYPTED && SCAN_HEURISTIC_ENCRYPTED_ARCHIVE) {
cli_dbgmsg("cli_7unz: Encrypted header found in archive.\n");
found = cli_append_virus(ctx, "Heuristics.Encrypted.7Zip");
} else if(res == SZ_OK) {
} else if (res == SZ_OK) {
UInt32 i, blockIndex = 0xFFFFFFFF;
Byte *outBuffer = 0;
size_t outBufferSize = 0;
@ -123,13 +125,13 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
size_t j;
int newnamelen, fd;
if((found = cli_checklimits("7unz", ctx, 0, 0, 0)))
if ((found = cli_checklimits("7unz", ctx, 0, 0, 0)))
break;
if (f->IsDir)
continue;
if(cli_checklimits("7unz", ctx, f->Size, 0, 0))
if (cli_checklimits("7unz", ctx, f->Size, 0, 0))
continue;
if (!db.FileNameOffsets)
@ -137,10 +139,10 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
else {
newnamelen = SzArEx_GetFileNameUtf16(&db, i, NULL);
if (newnamelen > namelen) {
if(namelen > UTFBUFSZ)
if (namelen > UTFBUFSZ)
free(utf16name);
utf16name = cli_malloc(newnamelen*2);
if(!utf16name) {
utf16name = cli_malloc(newnamelen * 2);
if (!utf16name) {
found = CL_EMEM;
break;
}
@ -150,15 +152,15 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
}
name = (char *)utf16name;
for(j=0; j<(size_t)newnamelen; j++) /* FIXME */
for (j = 0; j < (size_t)newnamelen; j++) /* FIXME */
name[j] = utf16name[j];
name[j] = 0;
cli_dbgmsg("cli_7unz: extracting %s\n", name);
res = SzArEx_Extract(&db, &lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp);
if(res == SZ_ERROR_ENCRYPTED) {
if (res == SZ_ERROR_ENCRYPTED) {
encrypted = 1;
if(SCAN_HEURISTIC_ENCRYPTED_ARCHIVE) {
if (SCAN_HEURISTIC_ENCRYPTED_ARCHIVE) {
cli_dbgmsg("cli_7unz: Encrypted files found in archive.\n");
found = cli_append_virus(ctx, "Heuristics.Encrypted.7Zip");
if (found != CL_CLEAN) {
@ -170,7 +172,7 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
}
}
}
if(cli_matchmeta(ctx, name, 0, f->Size, encrypted, i, f->CrcDefined ? f->Crc : 0, NULL)) {
if (cli_matchmeta(ctx, name, 0, f->Size, encrypted, i, f->CrcDefined ? f->Crc : 0, NULL)) {
found = CL_VIRUS;
viruses_found++;
if (!SCAN_ALLMATCHES)
@ -179,21 +181,20 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
if (res != SZ_OK)
cli_dbgmsg("cli_unz: extraction failed with %d\n", res);
else {
if((found = cli_gentempfd(ctx->engine->tmpdir, &name, &fd)))
if ((found = cli_gentempfd(ctx->engine->tmpdir, &name, &fd)))
break;
cli_dbgmsg("cli_7unz: Saving to %s\n", name);
if((size_t)cli_writen(fd, outBuffer + offset, outSizeProcessed) != outSizeProcessed)
if ((size_t)cli_writen(fd, outBuffer + offset, outSizeProcessed) != outSizeProcessed)
found = CL_EWRITE;
else
if ((found = cli_magic_scandesc(fd, name, ctx)) == CL_VIRUS)
else if ((found = cli_magic_scandesc(fd, name, ctx)) == CL_VIRUS)
viruses_found++;
close(fd);
if(!ctx->engine->keeptmp && cli_unlink(name))
if (!ctx->engine->keeptmp && cli_unlink(name))
found = CL_EUNLINK;
free(name);
if(found != CL_CLEAN)
if (found != CL_CLEAN)
if (!(SCAN_ALLMATCHES && found == CL_VIRUS))
break;
}
@ -201,7 +202,7 @@ int cli_7unz (cli_ctx *ctx, size_t offset) {
IAlloc_Free(&allocImp, outBuffer);
}
SzArEx_Free(&db, &allocImp);
if(namelen > UTFBUFSZ)
if (namelen > UTFBUFSZ)
free(utf16name);
if (res == SZ_OK)

View file

@ -28,6 +28,6 @@
#include "others.h"
int cli_7unz (cli_ctx *, size_t);
int cli_7unz(cli_ctx *, size_t);
#endif

View file

@ -37,9 +37,9 @@
/* #define DEBUG_ADC */
#ifdef DEBUG_ADC
# define adc_dbgmsg(...) cli_dbgmsg( __VA_ARGS__ )
#define adc_dbgmsg(...) cli_dbgmsg(__VA_ARGS__)
#else
# define adc_dbgmsg(...) ;
#define adc_dbgmsg(...) ;
#endif
/* Initialize values and collect buffer
@ -104,8 +104,7 @@ int adc_decompress(adc_stream *strm)
}
if (needsInput && (strm->avail_in == 0)) {
break;
}
else {
} else {
didNothing = 0;
}
@ -120,13 +119,11 @@ int adc_decompress(adc_stream *strm)
strm->state = ADC_STATE_RAWDATA;
strm->offset = 0;
strm->length = (bData & 0x7F) + 1;
}
else if (bData & 0x40) {
} else if (bData & 0x40) {
strm->state = ADC_STATE_LONGOP2;
strm->offset = 0;
strm->length = (bData & 0x3F) + 4;
}
else {
} else {
strm->state = ADC_STATE_SHORTOP;
strm->offset = (bData & 0x3) * 0x100;
strm->length = ((bData & 0x3C) >> 2) + 3;
@ -209,8 +206,7 @@ int adc_decompress(adc_stream *strm)
if (strm->offset > 0x10000) {
cli_dbgmsg("adc_decompress: bad LOOKBACK offset %u\n", strm->offset);
return ADC_DATA_ERROR;
}
else if ((strm->state == ADC_STATE_SHORTLOOK) && (strm->offset > 0x400)) {
} else if ((strm->state == ADC_STATE_SHORTLOOK) && (strm->offset > 0x400)) {
cli_dbgmsg("adc_decompress: bad LOOKBACK offset %u\n", strm->offset);
return ADC_DATA_ERROR;
}
@ -224,8 +220,7 @@ int adc_decompress(adc_stream *strm)
}
if (strm->curr >= (strm->buffer + strm->offset)) {
bData = *(uint8_t *)(strm->curr - strm->offset);
}
else {
} else {
bData = *(uint8_t *)(strm->curr + ADC_BUFF_SIZE - strm->offset);
}
/* store to output */
@ -261,8 +256,7 @@ int adc_decompress(adc_stream *strm)
if (strm->state == ADC_STATE_GETTYPE) {
/* Nothing left to do */
return ADC_STREAM_END;
}
else {
} else {
/* Ended mid phrase */
cli_dbgmsg("adc_decompress: stream ended mid-phrase, state %u\n", strm->state);
return ADC_DATA_ERROR;
@ -291,4 +285,3 @@ int adc_decompressEnd(adc_stream *strm)
return ADC_OK;
}

View file

@ -40,9 +40,9 @@
//#define DEBUG_APM_PARSE
#ifdef DEBUG_APM_PARSE
# define apm_parsemsg(...) cli_dbgmsg( __VA_ARGS__)
#define apm_parsemsg(...) cli_dbgmsg(__VA_ARGS__)
#else
# define apm_parsemsg(...) ;
#define apm_parsemsg(...) ;
#endif
static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info *aptable, size_t sectorsize, int old_school);
@ -125,9 +125,9 @@ int cli_scanapm(cli_ctx *ctx)
}
/* check if partition table partition */
if (strncmp((char*)aptable.type, "Apple_Partition_Map", 32) &&
strncmp((char*)aptable.type, "Apple_partition_map", 32) &&
strncmp((char*)aptable.type, "Apple_patition_map", 32)){
if (strncmp((char *)aptable.type, "Apple_Partition_Map", 32) &&
strncmp((char *)aptable.type, "Apple_partition_map", 32) &&
strncmp((char *)aptable.type, "Apple_patition_map", 32)) {
cli_dbgmsg("cli_scanapm: Initial Apple Partition Map partition is not detected\n");
return CL_EFORMAT;
}
@ -145,8 +145,8 @@ int cli_scanapm(cli_ctx *ctx)
/* print debugging info on partition tables */
cli_dbgmsg("APM Partition Table:\n");
cli_dbgmsg("Name: %s\n", (char*)aptable.name);
cli_dbgmsg("Type: %s\n", (char*)aptable.type);
cli_dbgmsg("Name: %s\n", (char *)aptable.name);
cli_dbgmsg("Type: %s\n", (char *)aptable.type);
cli_dbgmsg("Signature: %x\n", aptable.signature);
cli_dbgmsg("Partition Count: %u\n", aptable.numPartitions);
cli_dbgmsg("Blocks: [%u, +%u), ([%lu, +%lu))\n",
@ -157,8 +157,7 @@ int cli_scanapm(cli_ctx *ctx)
/* check engine maxpartitions limit */
if (aptable.numPartitions < ctx->engine->maxpartitions) {
max_prtns = aptable.numPartitions;
}
else {
} else {
max_prtns = ctx->engine->maxpartitions;
}
@ -185,9 +184,9 @@ int cli_scanapm(cli_ctx *ctx)
}
/* check if a out-of-order partition map */
if (!strncmp((char*)apentry.type, "Apple_Partition_Map", 32) ||
!strncmp((char*)apentry.type, "Apple_partition_map", 32) ||
!strncmp((char*)apentry.type, "Apple_patition_map", 32)) {
if (!strncmp((char *)apentry.type, "Apple_Partition_Map", 32) ||
!strncmp((char *)apentry.type, "Apple_partition_map", 32) ||
!strncmp((char *)apentry.type, "Apple_patition_map", 32)) {
cli_dbgmsg("cli_scanapm: Out of order Apple Partition Map partition\n");
continue;
@ -197,27 +196,27 @@ int cli_scanapm(cli_ctx *ctx)
partsize = apentry.pBlockCount * sectorsize;
/* re-calculate if old_school and aligned [512 * 4 => 2048] */
if (old_school && ((i % 4) == 0)) {
if (!strncmp((char*)apentry.type, "Apple_Driver", 32) ||
!strncmp((char*)apentry.type, "Apple_Driver43", 32) ||
!strncmp((char*)apentry.type, "Apple_Driver43_CD", 32) ||
!strncmp((char*)apentry.type, "Apple_Driver_ATA", 32) ||
!strncmp((char*)apentry.type, "Apple_Driver_ATAPI", 32) ||
!strncmp((char*)apentry.type, "Apple_Patches", 32)) {
if (!strncmp((char *)apentry.type, "Apple_Driver", 32) ||
!strncmp((char *)apentry.type, "Apple_Driver43", 32) ||
!strncmp((char *)apentry.type, "Apple_Driver43_CD", 32) ||
!strncmp((char *)apentry.type, "Apple_Driver_ATA", 32) ||
!strncmp((char *)apentry.type, "Apple_Driver_ATAPI", 32) ||
!strncmp((char *)apentry.type, "Apple_Patches", 32)) {
partsize = apentry.pBlockCount * 2048;
}
}
/* check if invalid partition */
if ((partoff == 0) || (partoff+partsize > maplen)) {
if ((partoff == 0) || (partoff + partsize > maplen)) {
cli_dbgmsg("cli_scanapm: Detected invalid Apple partition entry\n");
continue;
}
/* print debugging info on partition */
cli_dbgmsg("APM Partition Entry %u:\n", i);
cli_dbgmsg("Name: %s\n", (char*)apentry.name);
cli_dbgmsg("Type: %s\n", (char*)apentry.type);
cli_dbgmsg("Name: %s\n", (char *)apentry.name);
cli_dbgmsg("Type: %s\n", (char *)apentry.type);
cli_dbgmsg("Signature: %x\n", apentry.signature);
cli_dbgmsg("Partition Count: %u\n", apentry.numPartitions);
cli_dbgmsg("Blocks: [%u, +%u), ([%lu, +%lu))\n",
@ -255,8 +254,7 @@ static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info *aptable, size
/* check engine maxpartitions limit */
if (aptable->numPartitions < ctx->engine->maxpartitions) {
max_prtns = aptable->numPartitions;
}
else {
} else {
max_prtns = ctx->engine->maxpartitions;
}
@ -274,12 +272,12 @@ static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info *aptable, size
apentry.pBlockCount = be32_to_host(apentry.pBlockCount);
/* re-calculate if old_school and aligned [512 * 4 => 2048] */
if (old_school && ((i % 4) == 0)) {
if (!strncmp((char*)apentry.type, "Apple_Driver", 32) ||
!strncmp((char*)apentry.type, "Apple_Driver43", 32) ||
!strncmp((char*)apentry.type, "Apple_Driver43_CD", 32) ||
!strncmp((char*)apentry.type, "Apple_Driver_ATA", 32) ||
!strncmp((char*)apentry.type, "Apple_Driver_ATAPI", 32) ||
!strncmp((char*)apentry.type, "Apple_Patches", 32)) {
if (!strncmp((char *)apentry.type, "Apple_Driver", 32) ||
!strncmp((char *)apentry.type, "Apple_Driver43", 32) ||
!strncmp((char *)apentry.type, "Apple_Driver43_CD", 32) ||
!strncmp((char *)apentry.type, "Apple_Driver_ATA", 32) ||
!strncmp((char *)apentry.type, "Apple_Driver_ATAPI", 32) ||
!strncmp((char *)apentry.type, "Apple_Patches", 32)) {
apentry.pBlockCount = apentry.pBlockCount * 4;
}
@ -288,11 +286,12 @@ static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info *aptable, size
tmp = prtn_intxn_list_check(&prtncheck, &pitxn, apentry.pBlockStart, apentry.pBlockCount);
if (tmp != CL_CLEAN) {
if (tmp == CL_VIRUS) {
apm_parsemsg("Name: %s\n", (char*)aptable.name);
apm_parsemsg("Type: %s\n", (char*)aptable.type);
apm_parsemsg("Name: %s\n", (char *)aptable.name);
apm_parsemsg("Type: %s\n", (char *)aptable.type);
cli_dbgmsg("cli_scanapm: detected intersection with partitions "
"[%u, %u]\n", pitxn, i);
"[%u, %u]\n",
pitxn, i);
ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
if (ret == CL_VIRUS)
virus_found = 1;
@ -308,7 +307,7 @@ static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info *aptable, size
pos += sectorsize;
}
leave:
leave:
prtn_intxn_list_free(&prtncheck);
if (virus_found)
return CL_VIRUS;

View file

@ -61,20 +61,20 @@
/* 8-byte driver description entry for ddmap, big endian */
struct apm_driver_desc_entry {
uint32_t block __attribute__ ((packed));
uint16_t size __attribute__ ((packed));
uint16_t type __attribute__ ((packed));
uint32_t block __attribute__((packed));
uint16_t size __attribute__((packed));
uint16_t type __attribute__((packed));
}; //NOTE may need to be renamed
/* 512(82)-byte driver descriptor map (Block0), big endian */
struct apm_driver_desc_map {
uint16_t signature __attribute__ ((packed));
uint16_t blockSize __attribute__ ((packed));
uint32_t blockCount __attribute__ ((packed));
uint16_t deviceType __attribute__ ((packed));
uint16_t deviceID __attribute__ ((packed));
uint32_t driverData __attribute__ ((packed));
uint16_t driverCount __attribute__ ((packed));
uint16_t signature __attribute__((packed));
uint16_t blockSize __attribute__((packed));
uint32_t blockCount __attribute__((packed));
uint16_t deviceType __attribute__((packed));
uint16_t deviceID __attribute__((packed));
uint32_t driverData __attribute__((packed));
uint16_t driverCount __attribute__((packed));
struct apm_driver_desc_entry driverTable[8];
/* zeroes fill remainder of sector (430 bytes in 512 sector size) */
};
@ -84,23 +84,23 @@ struct apm_driver_desc_map {
* struct to describe their details
*/
struct apm_partition_info {
uint16_t signature __attribute__ ((packed));
uint16_t reserved __attribute__ ((packed));
uint32_t numPartitions __attribute__ ((packed));
uint32_t pBlockStart __attribute__ ((packed));
uint32_t pBlockCount __attribute__ ((packed));
uint16_t signature __attribute__((packed));
uint16_t reserved __attribute__((packed));
uint32_t numPartitions __attribute__((packed));
uint32_t pBlockStart __attribute__((packed));
uint32_t pBlockCount __attribute__((packed));
uint8_t name[32];
uint8_t type[32];
uint32_t lBlockStart __attribute__ ((packed));
uint32_t lBlockCount __attribute__ ((packed));
uint32_t flags __attribute__ ((packed));
uint32_t bootBlockStart __attribute__ ((packed));
uint32_t bootSize __attribute__ ((packed));
uint32_t bootAddr __attribute__ ((packed));
uint32_t bootAddr2 __attribute__ ((packed));
uint32_t bootEntry __attribute__ ((packed));
uint32_t bootEntry2 __attribute__ ((packed));
uint32_t bootChecksum __attribute__ ((packed));
uint32_t lBlockStart __attribute__((packed));
uint32_t lBlockCount __attribute__((packed));
uint32_t flags __attribute__((packed));
uint32_t bootBlockStart __attribute__((packed));
uint32_t bootSize __attribute__((packed));
uint32_t bootAddr __attribute__((packed));
uint32_t bootAddr2 __attribute__((packed));
uint32_t bootEntry __attribute__((packed));
uint32_t bootEntry2 __attribute__((packed));
uint32_t bootChecksum __attribute__((packed));
uint8_t processor[16];
/* zeroes fill remainder of sector (376 bytes in 512 sector size) */
};

View file

@ -33,9 +33,9 @@ void arc4_init(struct arc4_state *a, const uint8_t *key, unsigned keylength)
uint8_t j;
uint32_t *S = &a->S[0];
for (i=0; i < 256;i ++)
for (i = 0; i < 256; i++)
S[i] = i;
for (i=0,j=0; i < 256; i++) {
for (i = 0, j = 0; i < 256; i++) {
uint8_t tmp = S[i];
j = j + S[i] + key[i % keylength];
S[i] = S[j];

File diff suppressed because it is too large Load diff

View file

@ -28,7 +28,6 @@
#include "rebuildpe.h"
#include "aspack.h"
#define ASPACK_BLOCKS_OFFSET_212 0x57c
#define ASPACK_BLOCKS_OFFSET_OTHER 0x5d8
#define ASPACK_BLOCKS_OFFSET_242 0x5e4
@ -66,10 +65,10 @@ struct ASPK {
uint8_t array1[19];
};
static inline int readstream(struct ASPK *stream) {
static inline int readstream(struct ASPK *stream)
{
while (stream->bitpos >= 8) {
if (stream->input>=stream->iend) return 0;
if (stream->input >= stream->iend) return 0;
stream->hash = (stream->hash << 8) | *stream->input;
stream->input++;
stream->bitpos -= 8;
@ -77,34 +76,42 @@ static inline int readstream(struct ASPK *stream) {
return 1;
}
static uint32_t getdec(struct ASPK *stream, uint8_t which, int *err) {
static uint32_t getdec(struct ASPK *stream, uint8_t which, int *err)
{
uint32_t ret;
uint8_t pos;
uint32_t *d3 = stream->decarray3[which];
uint32_t *d4 = stream->decarray4[which];
*err=1;
*err = 1;
if (!readstream(stream)) return 0;
ret = (stream->hash >> (8 - stream->bitpos)) & 0xfffe00;
if (ret < d3[8]) {
if ((ret>>16) >= 0x100) return 0;
if (!(pos=stream->dict_helper[which].ends[ret>>16]) || pos>= 24) return 0; /* 0<pos<24 */
if ((ret >> 16) >= 0x100) return 0;
if (!(pos = stream->dict_helper[which].ends[ret >> 16]) || pos >= 24) return 0; /* 0<pos<24 */
} else {
if (ret < d3[10]) {
if (ret < d3[9]) pos = 9;
else pos = 10;
if (ret < d3[9])
pos = 9;
else
pos = 10;
} else {
if (ret < d3[11] ) pos = 11;
if (ret < d3[11])
pos = 11;
else {
if (ret < d3[12]) pos = 12;
if (ret < d3[12])
pos = 12;
else {
if (ret < d3[13]) pos = 13;
if (ret < d3[13])
pos = 13;
else {
if (ret < d3[14]) pos = 14;
else pos = 15;
if (ret < d3[14])
pos = 14;
else
pos = 15;
}
}
}
@ -112,24 +119,24 @@ static uint32_t getdec(struct ASPK *stream, uint8_t which, int *err) {
}
stream->bitpos += pos;
ret = ((ret - d3[pos-1]) >> (24 - pos)) + d4[pos];
ret = ((ret - d3[pos - 1]) >> (24 - pos)) + d4[pos];
if (ret >= stream->dict_helper[which].size) return 0;
ret = stream->dict_helper[which].starts[ret];
*err=0;
*err = 0;
return ret;
}
static uint8_t build_decrypt_array(struct ASPK *stream, uint8_t* array, uint8_t which) {
static uint8_t build_decrypt_array(struct ASPK *stream, uint8_t *array, uint8_t which)
{
uint32_t sum = 0, counter = 23, i, endoff = 0, bus[18], dict[18];
uint32_t *d3 = stream->decarray3[which];
uint32_t *d4 = stream->decarray4[which];
memset(bus,0,sizeof(bus));
memset(dict,0,sizeof(dict));
memset(bus, 0, sizeof(bus));
memset(dict, 0, sizeof(dict));
for (i = 0; i < stream->dict_helper[which].size; i++) {
/* within bounds - see comments in build_decrypt_dictionaries */
@ -142,18 +149,18 @@ static uint8_t build_decrypt_array(struct ASPK *stream, uint8_t* array, uint8_t
i = 0;
while (counter >= 9) { /* 0<=i<=14 */
sum += (bus[i+1] << counter);
sum += (bus[i + 1] << counter);
if (sum > 0x1000000) return 0;
d3[i+1] = sum;
d4[i+1] = dict[i+1] = bus[i] + d4[i];
d3[i + 1] = sum;
d4[i + 1] = dict[i + 1] = bus[i] + d4[i];
if (counter >= 0x10) {
uint32_t old = endoff;
endoff = d3[i+1] >> 0x10;
if (endoff-old) {
if (!CLI_ISCONTAINED(stream->dict_helper[which].ends, 0x100, stream->dict_helper[which].ends+old, endoff-old)) return 0;
memset((stream->dict_helper[which].ends + old), i+1, endoff-old);
endoff = d3[i + 1] >> 0x10;
if (endoff - old) {
if (!CLI_ISCONTAINED(stream->dict_helper[which].ends, 0x100, stream->dict_helper[which].ends + old, endoff - old)) return 0;
memset((stream->dict_helper[which].ends + old), i + 1, endoff - old);
}
}
@ -164,10 +171,10 @@ static uint8_t build_decrypt_array(struct ASPK *stream, uint8_t* array, uint8_t
if (sum != 0x1000000) return 0;
i = 0;
for (i=0; i < stream->dict_helper[which].size; i++) {
for (i = 0; i < stream->dict_helper[which].size; i++) {
if (array[i]) { /* within bounds - see above */
if (array[i] > 17) return 0;
if (dict[array[i]]>=stream->dict_helper[which].size) return 0;
if (dict[array[i]] >= stream->dict_helper[which].size) return 0;
stream->dict_helper[which].starts[dict[array[i]]] = i;
dict[array[i]]++;
}
@ -176,24 +183,24 @@ static uint8_t build_decrypt_array(struct ASPK *stream, uint8_t* array, uint8_t
return 1;
}
static uint8_t getbits(struct ASPK *stream, uint32_t num, int *err) {
static uint8_t getbits(struct ASPK *stream, uint32_t num, int *err)
{
uint8_t retvalue;
if (!readstream(stream)) {
*err=1;
*err = 1;
return 0;
}
*err = 0;
retvalue = ((stream->hash >> (8 - stream->bitpos))&0xffffff) >> (24 - num);
retvalue = ((stream->hash >> (8 - stream->bitpos)) & 0xffffff) >> (24 - num);
stream->bitpos += num;
return retvalue;
}
static int build_decrypt_dictionaries(struct ASPK *stream) {
static int build_decrypt_dictionaries(struct ASPK *stream)
{
unsigned int counter;
uint32_t ret;
int oob;
@ -202,7 +209,7 @@ static int build_decrypt_dictionaries(struct ASPK *stream) {
if (oob) return 0;
for (counter = 0; counter < 19; counter++) {
stream->array1[counter]=getbits(stream, 4, &oob);
stream->array1[counter] = getbits(stream, 4, &oob);
if (oob) return 0;
}
@ -214,12 +221,14 @@ static int build_decrypt_dictionaries(struct ASPK *stream) {
if (oob) return 0;
if (ret >= 16) {
if (ret != 16) {
if (ret == 17) ret = 3 + getbits(stream, 3, &oob);
else ret = 11 + getbits(stream, 7, &oob);
if (ret == 17)
ret = 3 + getbits(stream, 3, &oob);
else
ret = 11 + getbits(stream, 7, &oob);
if (oob) return 0;
while (ret) {
if (counter >= 757) break;
stream->array2[1+counter] = 0;
stream->array2[1 + counter] = 0;
counter++;
ret--;
}
@ -228,37 +237,37 @@ static int build_decrypt_dictionaries(struct ASPK *stream) {
if (oob) return 0;
while (ret) {
if (counter >= 757) break;
stream->array2[1+counter] = stream->array2[counter];
stream->array2[1 + counter] = stream->array2[counter];
counter++;
ret--;
}
}
} else {
stream->array2[1+counter] = (stream->decrypt_dict[counter] + ret) & 0xF;
stream->array2[1 + counter] = (stream->decrypt_dict[counter] + ret) & 0xF;
counter++;
}
}
if (!build_decrypt_array(stream, &stream->array2[1], 0) /* array2[758-1=757] - [0].size=721 */ || !build_decrypt_array(stream, &stream->array2[722], 1) /* array2[758-722=36] - [1].size=28 */ || !build_decrypt_array(stream, &stream->array2[750], 2) /* array2[758-750=8] - [2].size=8 */ ) return 0;
if (!build_decrypt_array(stream, &stream->array2[1], 0) /* array2[758-1=757] - [0].size=721 */ || !build_decrypt_array(stream, &stream->array2[722], 1) /* array2[758-722=36] - [1].size=28 */ || !build_decrypt_array(stream, &stream->array2[750], 2) /* array2[758-750=8] - [2].size=8 */) return 0;
stream->dict_ok = 0;
for (counter = 0; counter < 8; counter++) {
if (stream->array2[750+counter] != 3) {
if (stream->array2[750 + counter] != 3) {
stream->dict_ok = 1;
break;
}
}
memcpy(stream->decrypt_dict,&stream->array2[1],757);
memcpy(stream->decrypt_dict, &stream->array2[1], 757);
return 1;
}
static int decrypt(struct ASPK *stream, uint8_t *stuff, uint32_t size, uint8_t *output) {
static int decrypt(struct ASPK *stream, uint8_t *stuff, uint32_t size, uint8_t *output)
{
/* ep+6d6 -> ep+748 = 0x72*/
uint32_t gen, backsize, backbytes, useold, counter = 0;
uint32_t hist[4]={0,0,0,0};
uint32_t hist[4] = {0, 0, 0, 0};
int oob;
cli_dbgmsg("Aspack: decrypt size:%x\n", size);
@ -274,15 +283,15 @@ static int decrypt(struct ASPK *stream, uint8_t *stuff, uint32_t size, uint8_t *
if (!build_decrypt_dictionaries(stream)) return 0;
continue;
}
if ((backbytes = (gen - 256) >> 3)>=58) return 0; /* checks init_array + stuff */
if ((backbytes = (gen - 256) >> 3) >= 58) return 0; /* checks init_array + stuff */
backsize = ((gen - 256) & 7) + 2;
if ((backsize-2)==7) {
if ((backsize - 2) == 7) {
uint8_t hlp;
gen = getdec(stream, 1, &oob);
if (oob || gen>=0x56) return 0;
if (oob || gen >= 0x56) return 0;
hlp = stuff[gen + 0x1c];
if (!readstream(stream)) return 0;
backsize += stuff[gen] + (( (stream->hash >> (8 - stream->bitpos)) & 0xffffff ) >> (0x18 - hlp));
backsize += stuff[gen] + (((stream->hash >> (8 - stream->bitpos)) & 0xffffff) >> (0x18 - hlp));
stream->bitpos += hlp;
}
@ -291,12 +300,12 @@ static int decrypt(struct ASPK *stream, uint8_t *stuff, uint32_t size, uint8_t *
if (!stream->dict_ok || gen < 3) {
if (!readstream(stream)) return 0;
useold += ((stream->hash >> ( 8 - stream->bitpos) ) & 0xffffff) >> (24 - gen);
useold += ((stream->hash >> (8 - stream->bitpos)) & 0xffffff) >> (24 - gen);
stream->bitpos += gen;
} else {
gen -= 3;
if (!readstream(stream)) return 0;
useold += ((((stream->hash >> ( 8 - stream->bitpos)) & 0xffffff) >> (24 - gen)) * 8);
useold += ((((stream->hash >> (8 - stream->bitpos)) & 0xffffff) >> (24 - gen)) * 8);
stream->bitpos += gen;
useold += getdec(stream, 2, &oob);
if (oob) return 0;
@ -311,14 +320,14 @@ static int decrypt(struct ASPK *stream, uint8_t *stuff, uint32_t size, uint8_t *
} else {
hist[2] = hist[1];
hist[1] = hist[0];
hist[0] = backbytes = useold-3;
hist[0] = backbytes = useold - 3;
}
backbytes++;
if (!backbytes || backbytes>counter || backsize>size-counter) return 0;
if (!backbytes || backbytes > counter || backsize > size - counter) return 0;
while (backsize--) {
output[counter] = output[counter-backbytes];
output[counter] = output[counter - backbytes];
counter++;
}
}
@ -326,17 +335,17 @@ static int decrypt(struct ASPK *stream, uint8_t *stuff, uint32_t size, uint8_t *
return 1;
}
static int decomp_block(struct ASPK *stream, uint32_t size, uint8_t *stuff, uint8_t *output) {
memset(stream->decarray3,0,sizeof(stream->decarray3));
memset(stream->decarray4,0,sizeof(stream->decarray4));
static int decomp_block(struct ASPK *stream, uint32_t size, uint8_t *stuff, uint8_t *output)
{
memset(stream->decarray3, 0, sizeof(stream->decarray3));
memset(stream->decarray4, 0, sizeof(stream->decarray4));
memset(stream->decrypt_dict, 0, 757);
stream->bitpos = 0x20;
if (!build_decrypt_dictionaries(stream)) return 0;
return decrypt(stream, stuff, size, output);
}
#define INIT_DICT_HELPER(n,sz) \
#define INIT_DICT_HELPER(n, sz) \
stream.dict_helper[n].starts = (uint32_t *)wrkbuf; \
stream.dict_helper[n].ends = &wrkbuf[sz * sizeof(uint32_t)]; \
stream.dict_helper[n].size = sz; \
@ -345,7 +354,7 @@ static int decomp_block(struct ASPK *stream, uint32_t size, uint8_t *stuff, uint
int unaspack(uint8_t *image, unsigned int size, struct cli_exe_section *sections, uint16_t sectcount, uint32_t ep, uint32_t base, int f, aspack_version_t version)
{
struct ASPK stream;
uint32_t i=0, j=0;
uint32_t i = 0, j = 0;
uint8_t *blocks = NULL, *wrkbuf;
uint32_t block_rva = 1, block_size;
struct cli_exe_section *outsects;
@ -379,7 +388,7 @@ int unaspack(uint8_t *image, unsigned int size, struct cli_exe_section *sections
return 0;
}
blocks = image+ep+blocks_offset;
blocks = image + ep + blocks_offset;
if (!(wrkbuf = cli_calloc(0x1800, sizeof(uint8_t)))) {
cli_dbgmsg("Aspack: Unable to allocate dictionary\n");
@ -396,61 +405,59 @@ int unaspack(uint8_t *image, unsigned int size, struct cli_exe_section *sections
for (i = 0; i < 58; i++) {
stream.init_array[i] = j;
j += ( 1 << image[ep+i+stream_init_multiplier_offset]); /* boundchecked in pe.c */
j += (1 << image[ep + i + stream_init_multiplier_offset]); /* boundchecked in pe.c */
}
memset(stream.array1,0,sizeof(stream.array1));
memset(stream.array2,0,sizeof(stream.array2));
memset(stream.array1, 0, sizeof(stream.array1));
memset(stream.array2, 0, sizeof(stream.array2));
i=0;
while (CLI_ISCONTAINED(image, size, blocks, 8) && (block_rva = cli_readint32(blocks)) && (block_size = cli_readint32(blocks+4)) && CLI_ISCONTAINED(image, size, image+block_rva, block_size)) {
i = 0;
while (CLI_ISCONTAINED(image, size, blocks, 8) && (block_rva = cli_readint32(blocks)) && (block_size = cli_readint32(blocks + 4)) && CLI_ISCONTAINED(image, size, image + block_rva, block_size)) {
cli_dbgmsg("Aspack: unpacking block rva:%x - sz:%x\n", block_rva, block_size);
wrkbuf = (uint8_t *)cli_calloc(block_size+0x10e, sizeof(uint8_t));
wrkbuf = (uint8_t *)cli_calloc(block_size + 0x10e, sizeof(uint8_t));
if (!wrkbuf) {
cli_dbgmsg("Aspack: Null work buff\n");
break;
}
stream.input = wrkbuf;
stream.iend = &wrkbuf[block_size+0x10e];
stream.iend = &wrkbuf[block_size + 0x10e];
memcpy(wrkbuf, image + block_rva, block_size);
if (!decomp_block(&stream, block_size, &image[ep+comp_block_offset], image + block_rva)) {
if (!decomp_block(&stream, block_size, &image[ep + comp_block_offset], image + block_rva)) {
cli_dbgmsg("Aspack: decomp_block failed\n");
free(wrkbuf);
break;
}
else
} else
cli_dbgmsg("Aspack: decomp block succeed\n");
free(wrkbuf);
if (i==0 && block_size>7) { /* first sect j/c unrolling */
if (i == 0 && block_size > 7) { /* first sect j/c unrolling */
while (i < block_size - 6) {
uint8_t curbyte = image[block_rva+i];
uint8_t curbyte = image[block_rva + i];
if (curbyte == 0xe8 || curbyte == 0xe9) {
wrkbuf = &image[block_rva+i+1];
if (*wrkbuf == image[ep+wrkbuf_offset]) {
wrkbuf = &image[block_rva + i + 1];
if (*wrkbuf == image[ep + wrkbuf_offset]) {
uint32_t target = cli_readint32(wrkbuf) & 0xffffff00;
CLI_ROL(target, 0x18);
cli_writeint32(wrkbuf, target - i);
i+=4;
i += 4;
}
}
i++;
}
}
if (version == ASPACK_VER_212) {
blocks+=8;
blocks += 8;
} else {
blocks += 12;
block_size = cli_readint32(blocks+4);
while (!((block_size +0x10e) & 0xffffffff))
{
block_size = cli_readint32(blocks + 4);
while (!((block_size + 0x10e) & 0xffffffff)) {
blocks += 12;
block_size = cli_readint32(blocks+4);
block_size = cli_readint32(blocks + 4);
}
}
}
@ -463,18 +470,18 @@ int unaspack(uint8_t *image, unsigned int size, struct cli_exe_section *sections
return 0;
}
if(sectcount>2 && ep == sections[sectcount-2].rva && !sections[sectcount-1].rsz) {
sectcount-=2;
if (sectcount > 2 && ep == sections[sectcount - 2].rva && !sections[sectcount - 1].rsz) {
sectcount -= 2;
}
if(!(outsects=cli_malloc(sizeof(struct cli_exe_section)*sectcount))) {
if (!(outsects = cli_malloc(sizeof(struct cli_exe_section) * sectcount))) {
cli_dbgmsg("Aspack: OOM - rebuild failed\n");
cli_writen(f, image, size);
return 1; /* No whatsoheader - won't infloop in pe.c */
}
memcpy(outsects, sections, sizeof(struct cli_exe_section)*sectcount);
for(i=0; i<sectcount; i++) {
outsects[i].raw=outsects[i].rva;
outsects[i].rsz=outsects[i].vsz;
memcpy(outsects, sections, sizeof(struct cli_exe_section) * sectcount);
for (i = 0; i < sectcount; i++) {
outsects[i].raw = outsects[i].rva;
outsects[i].rsz = outsects[i].vsz;
}
if (!cli_rebuildpe((char *)image, outsects, sectcount, base, cli_readint32(image + ep + 0x39b), 0, 0, f)) {
cli_dbgmsg("Aspack: rebuild failed\n");
@ -485,4 +492,3 @@ int unaspack(uint8_t *image, unsigned int size, struct cli_exe_section *sections
free(outsects);
return 1;
}

View file

@ -25,16 +25,16 @@
#include "cltypes.h"
#include "execs.h"
#define ASPACK_EP_OFFSET_212 (58+0x70e)
#define ASPACK_EP_OFFSET_OTHER (58+0x76a)
#define ASPACK_EP_OFFSET_242 (58+0x776)
#define ASPACK_EP_OFFSET_212 (58 + 0x70e)
#define ASPACK_EP_OFFSET_OTHER (58 + 0x76a)
#define ASPACK_EP_OFFSET_242 (58 + 0x776)
#define ASPACK_EPBUFF_OFFSET_212 (0x3b9)
#define ASPACK_EPBUFF_OFFSET_OTHER (0x41f)
#define ASPACK_EPBUFF_OFFSET_242 (0x42B)
typedef enum aspack_version_tag {
ASPACK_VER_NONE=0,
ASPACK_VER_NONE = 0,
ASPACK_VER_212,
ASPACK_VER_OTHER,
ASPACK_VER_242

View file

@ -46,36 +46,36 @@
static int fpu_words = FPU_ENDIAN_INITME;
/* FIXME: use unicode detection and normalization from edwin */
static unsigned int u2a(uint8_t *dest, unsigned int len) {
static unsigned int u2a(uint8_t *dest, unsigned int len)
{
uint8_t *src = dest;
unsigned int i,j;
unsigned int i, j;
if (len<2)
if (len < 2)
return len;
if (len>4 && src[0]==0xff && src[1]==0xfe && src[2]) {
len-=2;
src+=2;
if (len > 4 && src[0] == 0xff && src[1] == 0xfe && src[2]) {
len -= 2;
src += 2;
} else {
unsigned int cnt=0;
j = (len > 20) ? 20 : (len&~1);
unsigned int cnt = 0;
j = (len > 20) ? 20 : (len & ~1);
for (i=0; i<j; i+=2)
cnt+=(src[i]!=0 && src[i+1]==0);
for (i = 0; i < j; i += 2)
cnt += (src[i] != 0 && src[i + 1] == 0);
if (cnt*4 < j)
if (cnt * 4 < j)
return len;
}
j=len;
len>>=1;
for (i=0; i<j; i+=2)
j = len;
len >>= 1;
for (i = 0; i < j; i += 2)
*dest++ = src[i];
return len;
}
/*********************
MT realted stuff
*********************/
@ -86,7 +86,8 @@ struct MT {
uint32_t mt[624];
};
static uint8_t MT_getnext(struct MT *MT) {
static uint8_t MT_getnext(struct MT *MT)
{
uint32_t r;
if (!--MT->items) {
@ -96,11 +97,11 @@ static uint8_t MT_getnext(struct MT *MT) {
MT->items = 624;
MT->next = mt;
for (i=0; i<227; i++)
mt[i] = ((((mt[i] ^ mt[i+1])&0x7ffffffe)^mt[i])>>1)^((0-(mt[i+1]&1))&0x9908b0df)^mt[i+397];
for (; i<623; i++)
mt[i] = ((((mt[i] ^ mt[i+1])&0x7ffffffe)^mt[i])>>1)^((0-(mt[i+1]&1))&0x9908b0df)^mt[i-227];
mt[623] = ((((mt[623] ^ mt[0])&0x7ffffffe)^mt[623])>>1)^((0-(mt[0]&1))&0x9908b0df)^mt[i-227];
for (i = 0; i < 227; i++)
mt[i] = ((((mt[i] ^ mt[i + 1]) & 0x7ffffffe) ^ mt[i]) >> 1) ^ ((0 - (mt[i + 1] & 1)) & 0x9908b0df) ^ mt[i + 397];
for (; i < 623; i++)
mt[i] = ((((mt[i] ^ mt[i + 1]) & 0x7ffffffe) ^ mt[i]) >> 1) ^ ((0 - (mt[i + 1] & 1)) & 0x9908b0df) ^ mt[i - 227];
mt[623] = ((((mt[623] ^ mt[0]) & 0x7ffffffe) ^ mt[623]) >> 1) ^ ((0 - (mt[0] & 1)) & 0x9908b0df) ^ mt[i - 227];
}
r = *(MT->next++);
@ -111,22 +112,22 @@ static uint8_t MT_getnext(struct MT *MT) {
return (uint8_t)(r >> 1);
}
static void MT_decrypt(uint8_t *buf, unsigned int size, uint32_t seed) {
static void MT_decrypt(uint8_t *buf, unsigned int size, uint32_t seed)
{
struct MT MT;
unsigned int i;
uint32_t *mt = MT.mt;
*mt=seed;
for(i=1; i<624; i++)
mt[i] = i+0x6c078965*((mt[i-1]>>30)^mt[i-1]);
*mt = seed;
for (i = 1; i < 624; i++)
mt[i] = i + 0x6c078965 * ((mt[i - 1] >> 30) ^ mt[i - 1]);
MT.items = 1;
MT.next = MT.mt;
while(size--)
while (size--)
*buf++ ^= MT_getnext(&MT);
}
/*********************
inflate stuff
*********************/
@ -154,68 +155,67 @@ struct UNP {
uint32_t error;
};
static uint32_t getbits(struct UNP *UNP, uint32_t size) {
static uint32_t getbits(struct UNP *UNP, uint32_t size)
{
UNP->bitmap.half.h = 0;
if (size > UNP->bits_avail && ((size - UNP->bits_avail - 1)/16+1)*2 > UNP->csize - UNP->cur_input) {
if (size > UNP->bits_avail && ((size - UNP->bits_avail - 1) / 16 + 1) * 2 > UNP->csize - UNP->cur_input) {
cli_dbgmsg("autoit: getbits() - not enough bits available\n");
UNP->error = 1;
return 0; /* won't infloop nor spam */
}
while (size) {
if (!UNP->bits_avail) {
UNP->bitmap.half.l |= UNP->inputbuf[UNP->cur_input++]<<8;
UNP->bitmap.half.l |= UNP->inputbuf[UNP->cur_input++] << 8;
UNP->bitmap.half.l |= UNP->inputbuf[UNP->cur_input++];
UNP->bits_avail = 16;
}
UNP->bitmap.full<<=1;
UNP->bitmap.full <<= 1;
UNP->bits_avail--;
size--;
}
return (uint32_t)UNP->bitmap.half.h;
}
/*********************
autoit3 EA05 handler
*********************/
static int ea05(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
static int ea05(cli_ctx *ctx, const uint8_t *base, char *tmpd)
{
uint8_t b[300], comp;
uint32_t s, m4sum=0;
uint32_t s, m4sum = 0;
int i, ret, det = 0;
unsigned int files=0;
unsigned int files = 0;
char tempfile[1024];
struct UNP UNP;
fmap_t *map = *ctx->fmap;
if(!fmap_need_ptr_once(map, base, 16))
if (!fmap_need_ptr_once(map, base, 16))
return CL_CLEAN;
for (i=0; i<16; i++)
for (i = 0; i < 16; i++)
m4sum += *base++;
while((ret=cli_checklimits("autoit", ctx, 0, 0, 0))==CL_CLEAN) {
if(!fmap_need_ptr_once(map, base, 8))
while ((ret = cli_checklimits("autoit", ctx, 0, 0, 0)) == CL_CLEAN) {
if (!fmap_need_ptr_once(map, base, 8))
return (det ? CL_VIRUS : CL_CLEAN);
/* MT_decrypt(buf,4,0x16fa); waste of time */
if((uint32_t)cli_readint32(base) != 0xceb06dff) {
if ((uint32_t)cli_readint32(base) != 0xceb06dff) {
cli_dbgmsg("autoit: no FILE magic found, extraction complete\n");
return (det ? CL_VIRUS : CL_CLEAN);
}
s = cli_readint32(base+4) ^ 0x29bc;
if ((int32_t)s<0)
s = cli_readint32(base + 4) ^ 0x29bc;
if ((int32_t)s < 0)
return (det ? CL_VIRUS : CL_CLEAN); /* the original code wouldn't seek back here */
base += 8;
if(cli_debug_flag && s<sizeof(b)) {
if (cli_debug_flag && s < sizeof(b)) {
if (!fmap_need_ptr_once(map, base, s))
return (det ? CL_VIRUS : CL_CLEAN);
memcpy(b, base, s);
MT_decrypt(b,s,s+0xa25e);
b[s]='\0';
MT_decrypt(b, s, s + 0xa25e);
b[s] = '\0';
cli_dbgmsg("autoit: magic string '%s'\n", b);
}
base += s;
@ -223,15 +223,15 @@ static int ea05(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
if (!fmap_need_ptr_once(map, base, 4))
return (det ? CL_VIRUS : CL_CLEAN);
s = cli_readint32(base) ^ 0x29ac;
if ((int32_t)s<0)
if ((int32_t)s < 0)
return (det ? CL_VIRUS : CL_CLEAN); /* the original code wouldn't seek back here */
base += 4;
if (cli_debug_flag && s<sizeof(b)) {
if (cli_debug_flag && s < sizeof(b)) {
if (!fmap_need_ptr_once(map, base, s))
return (det ? CL_VIRUS : CL_CLEAN);
memcpy(b, base, s);
MT_decrypt(b,s,s+0xf25e);
b[s]='\0';
MT_decrypt(b, s, s + 0xf25e);
b[s] = '\0';
cli_dbgmsg("autoit: original filename '%s'\n", b);
}
base += s;
@ -239,24 +239,24 @@ static int ea05(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
if (!fmap_need_ptr_once(map, base, 13))
return (det ? CL_VIRUS : CL_CLEAN);
comp = *base;
UNP.csize = cli_readint32(base+1) ^ 0x45aa;
if ((int32_t)UNP.csize<0) {
UNP.csize = cli_readint32(base + 1) ^ 0x45aa;
if ((int32_t)UNP.csize < 0) {
cli_dbgmsg("autoit: bad file size - giving up\n");
return (det ? CL_VIRUS : CL_CLEAN);
}
if(!UNP.csize) {
if (!UNP.csize) {
cli_dbgmsg("autoit: skipping empty file\n");
base += 13 + 16;
continue;
}
cli_dbgmsg("autoit: compressed size: %x\n", UNP.csize);
cli_dbgmsg("autoit: advertised uncompressed size %x\n", cli_readint32(base+5) ^ 0x45aa);
cli_dbgmsg("autoit: ref chksum: %x\n", cli_readint32(base+9) ^ 0xc3d2);
cli_dbgmsg("autoit: advertised uncompressed size %x\n", cli_readint32(base + 5) ^ 0x45aa);
cli_dbgmsg("autoit: ref chksum: %x\n", cli_readint32(base + 9) ^ 0xc3d2);
base += 13 + 16;
if(cli_checklimits("autoit", ctx, UNP.csize, 0, 0)!=CL_CLEAN) {
if (cli_checklimits("autoit", ctx, UNP.csize, 0, 0) != CL_CLEAN) {
base += UNP.csize;
continue;
}
@ -275,19 +275,19 @@ static int ea05(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
}
memcpy(UNP.inputbuf, base, UNP.csize);
base += UNP.csize;
MT_decrypt(UNP.inputbuf,UNP.csize,0x22af+m4sum);
MT_decrypt(UNP.inputbuf, UNP.csize, 0x22af + m4sum);
if (comp == 1) {
cli_dbgmsg("autoit: file is compressed\n");
if (cli_readint32(UNP.inputbuf)!=0x35304145) {
if (cli_readint32(UNP.inputbuf) != 0x35304145) {
cli_dbgmsg("autoit: bad magic or unsupported version\n");
free(UNP.inputbuf);
continue;
}
if(!(UNP.usize = be32_to_host(*(uint32_t *)(UNP.inputbuf+4))))
if (!(UNP.usize = be32_to_host(*(uint32_t *)(UNP.inputbuf + 4))))
UNP.usize = UNP.csize; /* only a specifically crafted or badly corrupted sample should land here */
if(cli_checklimits("autoit", ctx, UNP.usize, 0, 0)!=CL_CLEAN) {
if (cli_checklimits("autoit", ctx, UNP.usize, 0, 0) != CL_CLEAN) {
free(UNP.inputbuf);
continue;
}
@ -306,33 +306,33 @@ static int ea05(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
while (!UNP.error && UNP.cur_output < UNP.usize) {
if (getbits(&UNP, 1)) {
uint32_t bb, bs, addme=0;
uint32_t bb, bs, addme = 0;
bb = getbits(&UNP, 15);
if ((bs = getbits(&UNP, 2))==3) {
if ((bs = getbits(&UNP, 2)) == 3) {
addme = 3;
if((bs = getbits(&UNP, 3))==7) {
if ((bs = getbits(&UNP, 3)) == 7) {
addme = 10;
if((bs = getbits(&UNP, 5))==31) {
if ((bs = getbits(&UNP, 5)) == 31) {
addme = 41;
if((bs = getbits(&UNP, 8))==255) {
if ((bs = getbits(&UNP, 8)) == 255) {
addme = 296;
while((bs = getbits(&UNP, 8))==255) {
addme+=255;
while ((bs = getbits(&UNP, 8)) == 255) {
addme += 255;
}
}
}
}
}
bs += 3+addme;
bs += 3 + addme;
if(!CLI_ISCONTAINED(UNP.outputbuf, UNP.usize, &UNP.outputbuf[UNP.cur_output], bs) ||
!CLI_ISCONTAINED(UNP.outputbuf, UNP.usize, &UNP.outputbuf[UNP.cur_output-bb], bs)) {
if (!CLI_ISCONTAINED(UNP.outputbuf, UNP.usize, &UNP.outputbuf[UNP.cur_output], bs) ||
!CLI_ISCONTAINED(UNP.outputbuf, UNP.usize, &UNP.outputbuf[UNP.cur_output - bb], bs)) {
UNP.error = 1;
break;
}
while(bs--) {
UNP.outputbuf[UNP.cur_output]=UNP.outputbuf[UNP.cur_output-bb];
while (bs--) {
UNP.outputbuf[UNP.cur_output] = UNP.outputbuf[UNP.cur_output - bb];
UNP.cur_output++;
}
} else {
@ -359,7 +359,7 @@ static int ea05(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
UNP.usize = UNP.csize;
}
if (UNP.usize<4) {
if (UNP.usize < 4) {
cli_dbgmsg("autoit: file is too short\n");
free(UNP.outputbuf);
continue;
@ -370,21 +370,21 @@ static int ea05(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
/* FIXME: REGRESSION NEEDED! */
/* UNP.usize = u2a(UNP.outputbuf, UNP.usize); */
snprintf(tempfile, 1023, "%s"PATHSEP"autoit.%.3u", tmpd, files);
tempfile[1023]='\0';
if((i = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
snprintf(tempfile, 1023, "%s" PATHSEP "autoit.%.3u", tmpd, files);
tempfile[1023] = '\0';
if ((i = open(tempfile, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU)) < 0) {
cli_dbgmsg("autoit: Can't create file %s\n", tempfile);
free(UNP.outputbuf);
return CL_ECREAT;
}
if(cli_writen(i, UNP.outputbuf, UNP.usize) != (int32_t)UNP.usize) {
if (cli_writen(i, UNP.outputbuf, UNP.usize) != (int32_t)UNP.usize) {
cli_dbgmsg("autoit: cannot write %d bytes\n", UNP.usize);
close(i);
free(UNP.outputbuf);
return CL_EWRITE;
}
free(UNP.outputbuf);
if(ctx->engine->keeptmp)
if (ctx->engine->keeptmp)
cli_dbgmsg("autoit: file extracted to %s\n", tempfile);
else
cli_dbgmsg("autoit: file successfully extracted\n");
@ -393,28 +393,27 @@ static int ea05(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
close(i);
return CL_ESEEK;
}
if(cli_magic_scandesc(i, tempfile, ctx) == CL_VIRUS) {
if (cli_magic_scandesc(i, tempfile, ctx) == CL_VIRUS) {
if (!SCAN_ALLMATCHES) {
close(i);
if(!ctx->engine->keeptmp)
if(cli_unlink(tempfile)) return CL_EUNLINK;
if (!ctx->engine->keeptmp)
if (cli_unlink(tempfile)) return CL_EUNLINK;
return CL_VIRUS;
}
det = 1;
}
close(i);
if(!ctx->engine->keeptmp)
if (!ctx->engine->keeptmp)
if (cli_unlink(tempfile)) return CL_EUNLINK;
}
return (det ? CL_VIRUS : ret);
}
/*********************
LAME realted stuff
*********************/
#define ROFL(a,b) (( a << (b % (sizeof(a)<<3) )) | (a >> ( (sizeof(a)<<3) - (b % (sizeof(a)<<3 )) ) ))
#define ROFL(a, b) ((a << (b % (sizeof(a) << 3))) | (a >> ((sizeof(a) << 3) - (b % (sizeof(a) << 3)))))
struct LAME {
uint32_t c0;
@ -422,8 +421,8 @@ struct LAME {
uint32_t grp1[17];
};
static double LAME_fpusht(struct LAME *l) {
static double LAME_fpusht(struct LAME *l)
{
union {
double as_double;
struct {
@ -432,17 +431,17 @@ static double LAME_fpusht(struct LAME *l) {
} as_uint;
} ret;
uint32_t rolled = ROFL(l->grp1[l->c0],9) + ROFL(l->grp1[l->c1],13);
uint32_t rolled = ROFL(l->grp1[l->c0], 9) + ROFL(l->grp1[l->c1], 13);
l->grp1[l->c0] = rolled;
if (!l->c0--) l->c0 = 16;
if (!l->c1--) l->c1 = 16;
/* if (l->grp1[l->c0] == l->grp2[0]) { */
/* if (!memcmp(l->grp1, (uint32_t *)l + 0x24 - l->c0, 0x44)) */
/* return 0.0; */
/* } */
/* if (l->grp1[l->c0] == l->grp2[0]) { */
/* if (!memcmp(l->grp1, (uint32_t *)l + 0x24 - l->c0, 0x44)) */
/* return 0.0; */
/* } */
if (fpu_words == FPU_ENDIAN_LITTLE) {
ret.as_uint.lo = rolled << 0x14;
@ -454,11 +453,11 @@ static double LAME_fpusht(struct LAME *l) {
return ret.as_double - 1.0;
}
static void LAME_srand(struct LAME *l, uint32_t seed) {
static void LAME_srand(struct LAME *l, uint32_t seed)
{
unsigned int i;
for (i=0; i<17; i++) {
for (i = 0; i < 17; i++) {
seed *= 0x53A9B4FB; /*1403630843*/
seed = 1 - seed;
l->grp1[i] = seed;
@ -471,43 +470,46 @@ static void LAME_srand(struct LAME *l, uint32_t seed) {
LAME_fpusht(l);
}
static uint8_t LAME_getnext(struct LAME *l) {
static uint8_t LAME_getnext(struct LAME *l)
{
double x;
uint8_t ret;
LAME_fpusht(l);
x = LAME_fpusht(l) * 256.0;
if ((int32_t)x < 256) ret = (uint8_t)x;
else ret=0xff;
if ((int32_t)x < 256)
ret = (uint8_t)x;
else
ret = 0xff;
return ret;
}
static void LAME_decrypt (uint8_t *cypher, uint32_t size, uint16_t seed) {
static void LAME_decrypt(uint8_t *cypher, uint32_t size, uint16_t seed)
{
struct LAME lame;
/* mt_srand_timewrap(struct srand_struc bufDC); */
LAME_srand(&lame, (uint32_t)seed);
while(size--)
*cypher++^=LAME_getnext(&lame);
while (size--)
*cypher++ ^= LAME_getnext(&lame);
}
/*********************
autoit3 EA06 handler
*********************/
static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd)
{
uint8_t b[600], comp, script, *buf;
uint32_t s;
int i, ret, det = 0;
unsigned int files=0;
unsigned int files = 0;
char tempfile[1024];
const char prefixes[] = { '\0', '\0', '@', '$', '\0', '.', '"', '#' };
const char *opers[] = { ",", "=", ">", "<", "<>", ">=", "<=", "(", ")", "+", "-", "/", "*", "&", "[", "]", "==", "^", "+=", "-=", "/=", "*=", "&=" };
const char prefixes[] = {'\0', '\0', '@', '$', '\0', '.', '"', '#'};
const char *opers[] = {",", "=", ">", "<", "<>", ">=", "<=", "(", ")", "+", "-", "/", "*", "&", "[", "]", "==", "^", "+=", "-=", "/=", "*=", "&="};
struct UNP UNP;
fmap_t *map = *ctx->fmap;
/* Useless due to a bug in CRC calculation - LMAO!!1 */
/* if (cli_readn(desc, buf, 24)!=24) */
/* return CL_CLEAN; */
@ -515,73 +517,74 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
/* buf+=0x10; */
base += 16; /* for now we just skip the garbage */
while((ret=cli_checklimits("cli_autoit", ctx, 0, 0, 0))==CL_CLEAN) {
if(!fmap_need_ptr_once(map, base, 8))
while ((ret = cli_checklimits("cli_autoit", ctx, 0, 0, 0)) == CL_CLEAN) {
if (!fmap_need_ptr_once(map, base, 8))
return (det ? CL_VIRUS : CL_CLEAN);
/* LAME_decrypt(buf, 4, 0x18ee); waste of time */
if(cli_readint32(base) != 0x52ca436b) {
if (cli_readint32(base) != 0x52ca436b) {
cli_dbgmsg("autoit: no FILE magic found, giving up\n");
return (det ? CL_VIRUS : CL_CLEAN);
}
script = 0;
s = cli_readint32(base+4) ^ 0xadbc;
if ((int32_t)(s*2)<0)
s = cli_readint32(base + 4) ^ 0xadbc;
if ((int32_t)(s * 2) < 0)
return (det ? CL_VIRUS : CL_CLEAN); /* the original code wouldn't seek back here */
base += 8;
if(s < sizeof(b) / 2) {
if(!fmap_need_ptr_once(map, base, s*2))
if (s < sizeof(b) / 2) {
if (!fmap_need_ptr_once(map, base, s * 2))
return (det ? CL_VIRUS : CL_CLEAN);
memcpy(b, base, s*2);
LAME_decrypt(b,s*2,s+0xb33f);
u2a(b,s*2);
memcpy(b, base, s * 2);
LAME_decrypt(b, s * 2, s + 0xb33f);
u2a(b, s * 2);
cli_dbgmsg("autoit: magic string '%s'\n", b);
if (s==19 && !memcmp(">>>AUTOIT SCRIPT<<<", b, 19))
if (s == 19 && !memcmp(">>>AUTOIT SCRIPT<<<", b, 19))
script = 1;
} else {
cli_dbgmsg("autoit: magic string too long to print\n");
}
base += s*2;
base += s * 2;
if (!fmap_need_ptr_once(map, base, 4))
return (det ? CL_VIRUS : CL_CLEAN);
s = cli_readint32(base) ^ 0xf820;
if ((int32_t)(s*2)<0)
if ((int32_t)(s * 2) < 0)
return (det ? CL_VIRUS : CL_CLEAN); /* the original code wouldn't seek back here */
base += 4;
if(cli_debug_flag && s<sizeof(b) / 2) {
if(!fmap_need_ptr_once(map, base, s*2))
if (cli_debug_flag && s < sizeof(b) / 2) {
if (!fmap_need_ptr_once(map, base, s * 2))
return (det ? CL_VIRUS : CL_CLEAN);
memcpy(b, base, s*2);
LAME_decrypt(b,s*2,s+0xf479);
b[s*2]='\0'; b[s*2+1]='\0';
u2a(b,s*2);
memcpy(b, base, s * 2);
LAME_decrypt(b, s * 2, s + 0xf479);
b[s * 2] = '\0';
b[s * 2 + 1] = '\0';
u2a(b, s * 2);
cli_dbgmsg("autoit: original filename '%s'\n", b);
}
base += s*2;
base += s * 2;
if(!fmap_need_ptr_once(map, base, 13))
if (!fmap_need_ptr_once(map, base, 13))
return (det ? CL_VIRUS : CL_CLEAN);
comp = *base;
UNP.csize = cli_readint32(base+1) ^ 0x87bc;
if ((int32_t)UNP.csize<0) {
UNP.csize = cli_readint32(base + 1) ^ 0x87bc;
if ((int32_t)UNP.csize < 0) {
cli_dbgmsg("autoit: bad file size - giving up\n");
return (det ? CL_VIRUS : CL_CLEAN);
}
if(!UNP.csize) {
if (!UNP.csize) {
cli_dbgmsg("autoit: skipping empty file\n");
base += 13 + 16;
continue;
}
cli_dbgmsg("autoit: compressed size: %x\n", UNP.csize);
cli_dbgmsg("autoit: advertised uncompressed size %x\n", cli_readint32(base+5) ^ 0x87bc);
cli_dbgmsg("autoit: ref chksum: %x\n", cli_readint32(base+9) ^ 0xa685);
cli_dbgmsg("autoit: advertised uncompressed size %x\n", cli_readint32(base + 5) ^ 0x87bc);
cli_dbgmsg("autoit: ref chksum: %x\n", cli_readint32(base + 9) ^ 0xa685);
base += 13 + 16;
if(cli_checklimits("autoit", ctx, UNP.csize, 0, 0)!=CL_CLEAN) {
if (cli_checklimits("autoit", ctx, UNP.csize, 0, 0) != CL_CLEAN) {
base += UNP.csize;
continue;
}
@ -601,19 +604,19 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
}
memcpy(UNP.inputbuf, base, UNP.csize);
base += UNP.csize;
LAME_decrypt(UNP.inputbuf,UNP.csize,0x2477 /* + m4sum (broken by design) */ );
LAME_decrypt(UNP.inputbuf, UNP.csize, 0x2477 /* + m4sum (broken by design) */);
if (comp == 1) {
cli_dbgmsg("autoit: file is compressed\n");
if (cli_readint32(UNP.inputbuf)!=0x36304145) {
if (cli_readint32(UNP.inputbuf) != 0x36304145) {
cli_dbgmsg("autoit: bad magic or unsupported version\n");
free(UNP.inputbuf);
continue;
}
if(!(UNP.usize = be32_to_host(*(uint32_t *)(UNP.inputbuf+4))))
if (!(UNP.usize = be32_to_host(*(uint32_t *)(UNP.inputbuf + 4))))
UNP.usize = UNP.csize; /* only a specifically crafted or badly corrupted sample should land here */
if(cli_checklimits("autoit", ctx, UNP.usize, 0, 0)!=CL_CLEAN) {
if (cli_checklimits("autoit", ctx, UNP.usize, 0, 0) != CL_CLEAN) {
free(UNP.inputbuf);
continue;
}
@ -631,33 +634,33 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
while (!UNP.error && UNP.cur_output < UNP.usize) {
if (!getbits(&UNP, 1)) {
uint32_t bb, bs, addme=0;
uint32_t bb, bs, addme = 0;
bb = getbits(&UNP, 15);
if ((bs = getbits(&UNP, 2))==3) {
if ((bs = getbits(&UNP, 2)) == 3) {
addme = 3;
if((bs = getbits(&UNP, 3))==7) {
if ((bs = getbits(&UNP, 3)) == 7) {
addme = 10;
if((bs = getbits(&UNP, 5))==31) {
if ((bs = getbits(&UNP, 5)) == 31) {
addme = 41;
if((bs = getbits(&UNP, 8))==255) {
if ((bs = getbits(&UNP, 8)) == 255) {
addme = 296;
while((bs = getbits(&UNP, 8))==255) {
addme+=255;
while ((bs = getbits(&UNP, 8)) == 255) {
addme += 255;
}
}
}
}
}
bs += 3+addme;
bs += 3 + addme;
if(!CLI_ISCONTAINED(UNP.outputbuf, UNP.usize, &UNP.outputbuf[UNP.cur_output], bs) ||
!CLI_ISCONTAINED(UNP.outputbuf, UNP.usize, &UNP.outputbuf[UNP.cur_output-bb], bs)) {
if (!CLI_ISCONTAINED(UNP.outputbuf, UNP.usize, &UNP.outputbuf[UNP.cur_output], bs) ||
!CLI_ISCONTAINED(UNP.outputbuf, UNP.usize, &UNP.outputbuf[UNP.cur_output - bb], bs)) {
UNP.error = 1;
break;
}
while(bs--) {
UNP.outputbuf[UNP.cur_output]=UNP.outputbuf[UNP.cur_output-bb];
while (bs--) {
UNP.outputbuf[UNP.cur_output] = UNP.outputbuf[UNP.cur_output - bb];
UNP.cur_output++;
}
} else {
@ -677,7 +680,7 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
UNP.usize = UNP.csize;
}
if (UNP.usize<4) {
if (UNP.usize < 4) {
cli_dbgmsg("autoit: file is too short\n");
free(UNP.outputbuf);
continue;
@ -698,14 +701,14 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
while (!UNP.error && UNP.bits_avail && UNP.cur_input < UNP.usize) {
uint8_t op;
switch((op = UNP.outputbuf[UNP.cur_input++])) {
switch ((op = UNP.outputbuf[UNP.cur_input++])) {
case 5: /* <INT> */
if (UNP.cur_input >= UNP.usize-4) {
if (UNP.cur_input >= UNP.usize - 4) {
UNP.error = 1;
cli_dbgmsg("autoit: not enough space for an int\n");
break;
}
if (UNP.cur_output+12 >= UNP.csize) {
if (UNP.cur_output + 12 >= UNP.csize) {
uint8_t *newout;
UNP.csize += 512;
if (!(newout = cli_realloc(buf, UNP.csize))) {
@ -722,12 +725,12 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
case 0x10: /* <INT64> */
{
uint64_t val;
if (UNP.usize < 8 || UNP.cur_input >= UNP.usize-8) {
if (UNP.usize < 8 || UNP.cur_input >= UNP.usize - 8) {
UNP.error = 1;
cli_dbgmsg("autoit: not enough space for an int64\n");
break;
}
if (UNP.cur_output+20 >= UNP.csize) {
if (UNP.cur_output + 20 >= UNP.csize) {
uint8_t *newout;
UNP.csize += 512;
if (!(newout = cli_realloc(buf, UNP.csize))) {
@ -736,22 +739,22 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
}
buf = newout;
}
val = (uint64_t)cli_readint32((char *)&UNP.outputbuf[UNP.cur_input+4]);
val <<=32;
val = (uint64_t)cli_readint32((char *)&UNP.outputbuf[UNP.cur_input + 4]);
val <<= 32;
val += (uint64_t)cli_readint32((char *)&UNP.outputbuf[UNP.cur_input]);
snprintf((char *)&buf[UNP.cur_output], 20, "0x%016lx ", (unsigned long int) val);
snprintf((char *)&buf[UNP.cur_output], 20, "0x%016lx ", (unsigned long int)val);
UNP.cur_output += 19;
UNP.cur_input += 8;
break;
}
case 0x20: /* <DOUBLE> */
if (UNP.usize < 8 || UNP.cur_input >= UNP.usize-8) {
if (UNP.usize < 8 || UNP.cur_input >= UNP.usize - 8) {
UNP.error = 1;
cli_dbgmsg("autoit: not enough space for a double\n");
break;
}
if (UNP.cur_output+40 >= UNP.csize) {
if (UNP.cur_output + 40 >= UNP.csize) {
uint8_t *newout;
UNP.csize += 512;
if (!(newout = cli_realloc(buf, UNP.csize))) {
@ -768,12 +771,12 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
uint8_t *j = (uint8_t *)&x;
unsigned int i;
for(i=0; i<8; i++)
j[7-i]=UNP.outputbuf[UNP.cur_input+i];
for (i = 0; i < 8; i++)
j[7 - i] = UNP.outputbuf[UNP.cur_input + i];
snprintf((char *)&buf[UNP.cur_output], 39, "%g ", x); /* FIXME: check */
} while(0);
buf[UNP.cur_output+38]=' ';
buf[UNP.cur_output+39]='\0';
} while (0);
buf[UNP.cur_output + 38] = ' ';
buf[UNP.cur_output + 39] = '\0';
UNP.cur_output += strlen((char *)&buf[UNP.cur_output]);
UNP.cur_input += 8;
break;
@ -789,21 +792,21 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
{
uint32_t chars, dchars, i;
if (UNP.cur_input >= UNP.usize-4) {
if (UNP.cur_input >= UNP.usize - 4) {
UNP.error = 1;
cli_dbgmsg("autoit: not enough space for size\n");
break;
}
chars = cli_readint32((char *)&UNP.outputbuf[UNP.cur_input]);
dchars = chars*2;
UNP.cur_input+=4;
dchars = chars * 2;
UNP.cur_input += 4;
if (UNP.usize < dchars || UNP.cur_input >= UNP.usize-dchars) {
if (UNP.usize < dchars || UNP.cur_input >= UNP.usize - dchars) {
UNP.error = 1;
cli_dbgmsg("autoit: size too big - needed %d, total %d, avail %d\n", dchars, UNP.usize, UNP.usize - UNP.cur_input);
break;
}
if (UNP.cur_output+chars+3 >= UNP.csize) {
if (UNP.cur_output + chars + 3 >= UNP.csize) {
uint8_t *newout;
UNP.csize += chars + 512;
if (!(newout = cli_realloc(buf, UNP.csize))) {
@ -813,25 +816,24 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
buf = newout;
}
if(prefixes[op-0x30])
buf[UNP.cur_output++] = prefixes[op-0x30];
if (prefixes[op - 0x30])
buf[UNP.cur_output++] = prefixes[op - 0x30];
if (chars) {
for (i = 0; i<dchars; i+=2) {
UNP.outputbuf[UNP.cur_input+i] ^= (uint8_t)chars;
UNP.outputbuf[UNP.cur_input+i+1] ^= (uint8_t)(chars>>8);
for (i = 0; i < dchars; i += 2) {
UNP.outputbuf[UNP.cur_input + i] ^= (uint8_t)chars;
UNP.outputbuf[UNP.cur_input + i + 1] ^= (uint8_t)(chars >> 8);
}
u2a(&UNP.outputbuf[UNP.cur_input], dchars);
memcpy(&buf[UNP.cur_output], &UNP.outputbuf[UNP.cur_input], chars);
UNP.cur_output += chars;
UNP.cur_input += dchars;
}
if (op==0x36)
if (op == 0x36)
buf[UNP.cur_output++] = '"';
if (op!=0x34)
if (op != 0x34)
buf[UNP.cur_output++] = ' ';
}
break;
} break;
case 0x40: /* , */
case 0x41: /* = */
@ -856,7 +858,7 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
case 0x54: /* /= */
case 0x55: /* *= */
case 0x56: /* &= */
if (UNP.cur_output+4 >= UNP.csize) {
if (UNP.cur_output + 4 >= UNP.csize) {
uint8_t *newout;
UNP.csize += 512;
if (!(newout = cli_realloc(buf, UNP.csize))) {
@ -865,12 +867,12 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
}
buf = newout;
}
UNP.cur_output += snprintf((char *)&buf[UNP.cur_output], 4, "%s ", opers[op-0x40]);
UNP.cur_output += snprintf((char *)&buf[UNP.cur_output], 4, "%s ", opers[op - 0x40]);
break;
case 0x7f:
UNP.bits_avail--;
if (UNP.cur_output+1 >= UNP.csize) {
if (UNP.cur_output + 1 >= UNP.csize) {
uint8_t *newout;
UNP.csize += 512;
if (!(newout = cli_realloc(buf, UNP.csize))) {
@ -879,7 +881,7 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
}
buf = newout;
}
buf[UNP.cur_output++]='\n';
buf[UNP.cur_output++] = '\n';
break;
default:
@ -894,43 +896,43 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
free(UNP.outputbuf);
} else {
buf = UNP.outputbuf;
UNP.cur_output = UNP.usize ;
UNP.cur_output = UNP.usize;
}
snprintf(tempfile, 1023, "%s"PATHSEP"autoit.%.3u", tmpd, files);
tempfile[1023]='\0';
if((i = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
snprintf(tempfile, 1023, "%s" PATHSEP "autoit.%.3u", tmpd, files);
tempfile[1023] = '\0';
if ((i = open(tempfile, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU)) < 0) {
cli_dbgmsg("autoit: Can't create file %s\n", tempfile);
free(buf);
return CL_ECREAT;
}
if(cli_writen(i, buf, UNP.cur_output) != (int32_t)UNP.cur_output) {
if (cli_writen(i, buf, UNP.cur_output) != (int32_t)UNP.cur_output) {
cli_dbgmsg("autoit: cannot write %d bytes\n", UNP.usize);
close(i);
free(buf);
return CL_EWRITE;
}
free(buf);
if(ctx->engine->keeptmp)
cli_dbgmsg("autoit: %s extracted to %s\n", (script)?"script":"file", tempfile);
if (ctx->engine->keeptmp)
cli_dbgmsg("autoit: %s extracted to %s\n", (script) ? "script" : "file", tempfile);
else
cli_dbgmsg("autoit: %s successfully extracted\n", (script)?"script":"file");
cli_dbgmsg("autoit: %s successfully extracted\n", (script) ? "script" : "file");
if (lseek(i, 0, SEEK_SET) == -1) {
cli_dbgmsg("autoit: call to lseek() has failed\n");
close(i);
return CL_ESEEK;
}
if(cli_magic_scandesc(i, tempfile, ctx) == CL_VIRUS) {
if (cli_magic_scandesc(i, tempfile, ctx) == CL_VIRUS) {
if (!SCAN_ALLMATCHES) {
close(i);
if(!ctx->engine->keeptmp)
if (!ctx->engine->keeptmp)
if (cli_unlink(tempfile)) return CL_EUNLINK;
return CL_VIRUS;
}
det = 1;
}
close(i);
if(!ctx->engine->keeptmp)
if (!ctx->engine->keeptmp)
if (cli_unlink(tempfile)) return CL_EUNLINK;
}
return (det ? CL_VIRUS : ret);
@ -940,7 +942,8 @@ static int ea06(cli_ctx *ctx, const uint8_t *base, char *tmpd) {
autoit3 wrapper
*********************/
int cli_scanautoit(cli_ctx *ctx, off_t offset) {
int cli_scanautoit(cli_ctx *ctx, off_t offset)
{
const uint8_t *version;
int r;
char *tmpd;
@ -948,7 +951,7 @@ int cli_scanautoit(cli_ctx *ctx, off_t offset) {
cli_dbgmsg("in scanautoit()\n");
if(!(version = fmap_need_off_once(map, offset, sizeof(*version))))
if (!(version = fmap_need_off_once(map, offset, sizeof(*version))))
return CL_EREAD;
if (!(tmpd = cli_gentemp(ctx->engine->tmpdir)))
@ -961,7 +964,7 @@ int cli_scanautoit(cli_ctx *ctx, off_t offset) {
if (ctx->engine->keeptmp)
cli_dbgmsg("autoit: Extracting files to %s\n", tmpd);
switch(*version) {
switch (*version) {
case 0x35:
r = ea05(ctx, version + 1, tmpd);
break;
@ -972,8 +975,7 @@ int cli_scanautoit(cli_ctx *ctx, off_t offset) {
cli_dbgmsg("autoit: EA06 support not available"
"(cannot extract ea06 doubles, unknown floating double representation).\n");
r = CL_CLEAN;
}
else
} else
r = ea06(ctx, version + 1, tmpd);
break;
default:

View file

@ -6,19 +6,19 @@
#include "bignum_fast.h"
typedef fp_int mp_int;
#define mp_cmp fp_cmp
#define mp_toradix_n(a,b,c,d) fp_toradix_n(a,b,c,d)
#define mp_toradix_n(a, b, c, d) fp_toradix_n(a, b, c, d)
#define mp_init(a) (fp_init(a), 0)
#define mp_add fp_add
#define mp_init_multi(a,b,c,d) (mp_init(a), mp_init(b), mp_init(c), 0)
#define mp_init_multi(a, b, c, d) (mp_init(a), mp_init(b), mp_init(c), 0)
#define mp_read_unsigned_bin(a,b,c) (fp_read_unsigned_bin(a, b, c), 0)
#define mp_read_unsigned_bin(a, b, c) (fp_read_unsigned_bin(a, b, c), 0)
#define mp_div fp_div
#define mp_clear_multi(...)
#define mp_copy(a,b) (fp_copy(a,b), 0)
#define mp_copy(a, b) (fp_copy(a, b), 0)
#define mp_unsigned_bin_size fp_unsigned_bin_size
#define mp_to_unsigned_bin(a,b) (fp_to_unsigned_bin(a,b), 0)
#define mp_to_unsigned_bin(a, b) (fp_to_unsigned_bin(a, b), 0)
#define mp_read_radix fp_read_radix
#define mp_exptmod fp_exptmod
#define mp_get_int(a) ((a)->used > 0 ? (a)->dp[0] : 0)

View file

@ -31,11 +31,11 @@
#include <limits.h>
#ifndef MIN
#define MIN(x,y) ((x)<(y)?(x):(y))
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif
#ifndef MAX
#define MAX(x,y) ((x)>(y)?(x):(y))
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#endif
/* externally define this symbol to ignore the default settings, useful for changing the build from the make process */
@ -103,168 +103,167 @@
/* autodetect x86-64 and make sure we are using 64-bit digits with x86-64 asm */
#if defined(__x86_64__)
#if defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM)
#error x86-64 detected, x86-32/SSE2/ARM optimizations are not valid!
#endif
#if !defined(TFM_X86_64) && !defined(TFM_NO_ASM)
#define TFM_X86_64
#endif
#if defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM)
#error x86-64 detected, x86-32/SSE2/ARM optimizations are not valid!
#endif
#if !defined(TFM_X86_64) && !defined(TFM_NO_ASM)
#define TFM_X86_64
#endif
#endif
#if defined(TFM_X86_64)
#if !defined(FP_64BIT)
#define FP_64BIT
#endif
#if !defined(FP_64BIT)
#define FP_64BIT
#endif
#endif
/* try to detect x86-32 */
#if defined(__i386__) && !defined(TFM_SSE2)
#if defined(TFM_X86_64) || defined(TFM_ARM)
#error x86-32 detected, x86-64/ARM optimizations are not valid!
#endif
#if !defined(TFM_X86) && !defined(TFM_NO_ASM)
#define TFM_X86
#endif
#if defined(TFM_X86_64) || defined(TFM_ARM)
#error x86-32 detected, x86-64/ARM optimizations are not valid!
#endif
#if !defined(TFM_X86) && !defined(TFM_NO_ASM)
#define TFM_X86
#endif
#endif
/* make sure we're 32-bit for x86-32/sse/arm/ppc32 */
#if (defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM) || defined(TFM_PPC32)) && defined(FP_64BIT)
#warning x86-32, SSE2 and ARM, PPC32 optimizations require 32-bit digits (undefining)
#undef FP_64BIT
#warning x86-32, SSE2 and ARM, PPC32 optimizations require 32-bit digits (undefining)
#undef FP_64BIT
#endif
/* multi asms? */
#ifdef TFM_X86
#define TFM_ASM
#define TFM_ASM
#endif
#ifdef TFM_X86_64
#ifdef TFM_ASM
#error TFM_ASM already defined!
#endif
#define TFM_ASM
#ifdef TFM_ASM
#error TFM_ASM already defined!
#endif
#define TFM_ASM
#endif
#ifdef TFM_SSE2
#ifdef TFM_ASM
#error TFM_ASM already defined!
#endif
#define TFM_ASM
#ifdef TFM_ASM
#error TFM_ASM already defined!
#endif
#define TFM_ASM
#endif
#ifdef TFM_ARM
#ifdef TFM_ASM
#error TFM_ASM already defined!
#endif
#define TFM_ASM
#ifdef TFM_ASM
#error TFM_ASM already defined!
#endif
#define TFM_ASM
#endif
#ifdef TFM_PPC32
#ifdef TFM_ASM
#error TFM_ASM already defined!
#endif
#define TFM_ASM
#ifdef TFM_ASM
#error TFM_ASM already defined!
#endif
#define TFM_ASM
#endif
#ifdef TFM_PPC64
#ifdef TFM_ASM
#error TFM_ASM already defined!
#endif
#define TFM_ASM
#ifdef TFM_ASM
#error TFM_ASM already defined!
#endif
#define TFM_ASM
#endif
#ifdef TFM_AVR32
#ifdef TFM_ASM
#error TFM_ASM already defined!
#endif
#define TFM_ASM
#ifdef TFM_ASM
#error TFM_ASM already defined!
#endif
#define TFM_ASM
#endif
/* we want no asm? */
#ifdef TFM_NO_ASM
#undef TFM_X86
#undef TFM_X86_64
#undef TFM_SSE2
#undef TFM_ARM
#undef TFM_PPC32
#undef TFM_PPC64
#undef TFM_AVR32
#undef TFM_ASM
#undef TFM_X86
#undef TFM_X86_64
#undef TFM_SSE2
#undef TFM_ARM
#undef TFM_PPC32
#undef TFM_PPC64
#undef TFM_AVR32
#undef TFM_ASM
#endif
/* ECC helpers */
#ifdef TFM_ECC192
#ifdef FP_64BIT
#define TFM_MUL3
#define TFM_SQR3
#else
#define TFM_MUL6
#define TFM_SQR6
#endif
#ifdef FP_64BIT
#define TFM_MUL3
#define TFM_SQR3
#else
#define TFM_MUL6
#define TFM_SQR6
#endif
#endif
#ifdef TFM_ECC224
#ifdef FP_64BIT
#define TFM_MUL4
#define TFM_SQR4
#else
#define TFM_MUL7
#define TFM_SQR7
#endif
#ifdef FP_64BIT
#define TFM_MUL4
#define TFM_SQR4
#else
#define TFM_MUL7
#define TFM_SQR7
#endif
#endif
#ifdef TFM_ECC256
#ifdef FP_64BIT
#define TFM_MUL4
#define TFM_SQR4
#else
#define TFM_MUL8
#define TFM_SQR8
#endif
#ifdef FP_64BIT
#define TFM_MUL4
#define TFM_SQR4
#else
#define TFM_MUL8
#define TFM_SQR8
#endif
#endif
#ifdef TFM_ECC384
#ifdef FP_64BIT
#define TFM_MUL6
#define TFM_SQR6
#else
#define TFM_MUL12
#define TFM_SQR12
#endif
#ifdef FP_64BIT
#define TFM_MUL6
#define TFM_SQR6
#else
#define TFM_MUL12
#define TFM_SQR12
#endif
#endif
#ifdef TFM_ECC521
#ifdef FP_64BIT
#define TFM_MUL9
#define TFM_SQR9
#else
#define TFM_MUL17
#define TFM_SQR17
#endif
#ifdef FP_64BIT
#define TFM_MUL9
#define TFM_SQR9
#else
#define TFM_MUL17
#define TFM_SQR17
#endif
#endif
/* some default configurations.
*/
#if defined(FP_64BIT)
/* for GCC only on supported platforms */
/* for GCC only on supported platforms */
#ifndef CRYPT
typedef unsigned long ulong64;
typedef unsigned long ulong64;
#endif
typedef ulong64 fp_digit;
typedef unsigned long fp_word __attribute__ ((mode(TI)));
typedef ulong64 fp_digit;
typedef unsigned long fp_word __attribute__((mode(TI)));
#else
/* this is to make porting into LibTomCrypt easier :-) */
/* this is to make porting into LibTomCrypt easier :-) */
#ifndef CRYPT
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ulong64;
typedef signed __int64 long64;
#else
typedef unsigned long long ulong64;
typedef signed long long long64;
#endif
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ulong64;
typedef signed __int64 long64;
#else
typedef unsigned long long ulong64;
typedef signed long long long64;
#endif
/* The code requires that fp_word be twice the size of fp_digit.
#endif
/* The code requires that fp_word be twice the size of fp_digit.
* Add size-checking for special case (both long and long long are 64) */
#if (SIZEOF_LONG == 8) && (SIZEOF_LONG_LONG == 8)
typedef unsigned int fp_digit;
#else
typedef unsigned long fp_digit;
#endif
typedef ulong64 fp_word;
#if (SIZEOF_LONG == 8) && (SIZEOF_LONG_LONG == 8)
typedef unsigned int fp_digit;
#else
typedef unsigned long fp_digit;
#endif
typedef ulong64 fp_word;
#endif
/* # of digits this is */
@ -275,16 +274,16 @@
* You can externally define this or it defaults to 4096-bits [allowing multiplications upto 2048x2048 bits ]
*/
#ifndef FP_MAX_SIZE
#define FP_MAX_SIZE (8192+(8*DIGIT_BIT))
#define FP_MAX_SIZE (8192 + (8 * DIGIT_BIT))
#endif
/* will this lib work? */
#if (CHAR_BIT & 7)
#error CHAR_BIT must be a multiple of eight.
#error CHAR_BIT must be a multiple of eight.
#endif
#define FP_MASK (fp_digit)(-1)
#define FP_SIZE (FP_MAX_SIZE/DIGIT_BIT)
#define FP_SIZE (FP_MAX_SIZE / DIGIT_BIT)
/* signs */
#define FP_ZPOS 0
@ -333,11 +332,24 @@ void fp_set(fp_int *a, fp_digit b);
#define fp_init_copy(a, b) fp_copy(b, a)
/* clamp digits */
#define fp_clamp(a) { while ((a)->used && (a)->dp[(a)->used-1] == 0) --((a)->used); (a)->sign = (a)->used ? (a)->sign : FP_ZPOS; }
#define fp_clamp(a) \
{ \
while ((a)->used && (a)->dp[(a)->used - 1] == 0) --((a)->used); \
(a)->sign = (a)->used ? (a)->sign : FP_ZPOS; \
}
/* negate and absolute */
#define fp_neg(a, b) { fp_copy(a, b); (b)->sign ^= 1; fp_clamp(b); }
#define fp_abs(a, b) { fp_copy(a, b); (b)->sign = 0; }
#define fp_neg(a, b) \
{ \
fp_copy(a, b); \
(b)->sign ^= 1; \
fp_clamp(b); \
}
#define fp_abs(a, b) \
{ \
fp_copy(a, b); \
(b)->sign = 0; \
}
/* right shift x digits */
void fp_rshd(fp_int *a, int x);
@ -355,7 +367,7 @@ int fp_cmp_mag(fp_int *a, fp_int *b);
void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d);
void fp_mod_2d(fp_int *a, int b, fp_int *c);
void fp_mul_2d(fp_int *a, int b, fp_int *c);
void fp_2expt (fp_int *a, int b);
void fp_2expt(fp_int *a, int b);
void fp_mul_2(fp_int *a, fp_int *c);
void fp_div_2(fp_int *a, fp_int *c);
@ -437,7 +449,7 @@ int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);
/* primality stuff */
/* perform a Miller-Rabin test of a to the base b and store result in "result" */
void fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result);
void fp_prime_miller_rabin(fp_int *a, fp_int *b, int *result);
/* 256 trial divisions + 8 Miller-Rabins, returns FP_YES if probable prime */
int fp_isprime(fp_int *a);
@ -451,7 +463,7 @@ int fp_isprime(fp_int *a);
/* callback for fp_prime_random, should fill dst with random bytes and return how many read [upto len] */
typedef int tfm_prime_callback(unsigned char *dst, int len, void *dat);
#define fp_prime_random(a, t, size, bbs, cb, dat) fp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?TFM_PRIME_BBS:0, cb, dat)
#define fp_prime_random(a, t, size, bbs, cb, dat) fp_prime_random_ex(a, t, ((size)*8) + 1, (bbs == 1) ? TFM_PRIME_BBS : 0, cb, dat)
int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback cb, void *dat);
@ -468,8 +480,7 @@ void fp_to_signed_bin(fp_int *a, unsigned char *b);
int fp_read_radix(fp_int *a, const char *str, int radix);
int fp_toradix(fp_int *a, char *str, int radix);
int fp_toradix_n(fp_int * a, char *str, int radix, int maxlen);
int fp_toradix_n(fp_int *a, char *str, int radix, int maxlen);
/* VARIOUS LOW LEVEL STUFFS */
void s_fp_add(fp_int *a, fp_int *b, fp_int *c);
@ -579,7 +590,6 @@ extern const char *fp_s_rmap;
#endif
/* $Source: /cvs/libtom/tomsfastmath/src/headers/tfm.h,v $ */
/* $Revision: 1.3 $ */
/* $Date: 2007/02/27 02:38:44 $ */

View file

@ -33,7 +33,6 @@
#include "fmap.h"
#include "binhex.h"
// clang-format off
static const uint8_t hqxtbl[] = {
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f */
@ -50,68 +49,74 @@ static const uint8_t hqxtbl[] = {
#define BH_FLUSH_SZ (BUFSIZ - 256)
int cli_binhex(cli_ctx *ctx) {
int cli_binhex(cli_ctx *ctx)
{
fmap_t *map = *ctx->fmap;
const uint8_t *encoded = NULL;
uint8_t decoded[BUFSIZ], spare_bits = 0, last_byte = 0, this_byte = 0, offset = 0;
size_t enc_done=0, enc_todo=map->len;
unsigned int dec_done=0, chunksz = 0, chunkoff=0;
size_t enc_done = 0, enc_todo = map->len;
unsigned int dec_done = 0, chunksz = 0, chunkoff = 0;
uint32_t datalen = 0, reslen = 0;
int in_data = 0, in_run = 0, datafd, resfd, ret = CL_CLEAN;
enum binhex_phase { IN_BANNER, IN_HEADER, IN_DATA, IN_LIMBO1, IN_LIMBO2, IN_RES } write_phase = IN_BANNER;
enum binhex_phase { IN_BANNER,
IN_HEADER,
IN_DATA,
IN_LIMBO1,
IN_LIMBO2,
IN_RES } write_phase = IN_BANNER;
char *dname, *rname;
cli_dbgmsg("in cli_binhex\n");
if(!map->len) return CL_CLEAN;
if (!map->len) return CL_CLEAN;
if((ret = cli_gentempfd(ctx->engine->tmpdir, &dname, &datafd)) != CL_SUCCESS)
if ((ret = cli_gentempfd(ctx->engine->tmpdir, &dname, &datafd)) != CL_SUCCESS)
return ret;
if((ret = cli_gentempfd(ctx->engine->tmpdir, &rname, &resfd)) != CL_SUCCESS) {
if ((ret = cli_gentempfd(ctx->engine->tmpdir, &rname, &resfd)) != CL_SUCCESS) {
close(datafd);
if(cli_unlink(dname)) ret = CL_EUNLINK;
if (cli_unlink(dname)) ret = CL_EUNLINK;
free(dname);
return ret;
}
memset(decoded, 0, 24);
while(1) {
while (1) {
uint8_t b;
if(!enc_todo || dec_done >= BH_FLUSH_SZ) {
if(write_phase == IN_HEADER) {
if (!enc_todo || dec_done >= BH_FLUSH_SZ) {
if (write_phase == IN_HEADER) {
uint32_t namelen = (uint32_t)decoded[0], hdrlen = 1 + namelen + 1 + 4 + 4 + 2;
if(!dec_done) {
if (!dec_done) {
cli_dbgmsg("cli_binhex: file is empty\n");
break;
}
datalen = (decoded[hdrlen]<<24) | (decoded[hdrlen+1]<<16) | (decoded[hdrlen+2]<<8) | decoded[hdrlen+3];
datalen = (decoded[hdrlen] << 24) | (decoded[hdrlen + 1] << 16) | (decoded[hdrlen + 2] << 8) | decoded[hdrlen + 3];
hdrlen += 4;
reslen = (decoded[hdrlen]<<24) | (decoded[hdrlen+1]<<16) | (decoded[hdrlen+2]<<8) | decoded[hdrlen+3];
reslen = (decoded[hdrlen] << 24) | (decoded[hdrlen + 1] << 16) | (decoded[hdrlen + 2] << 8) | decoded[hdrlen + 3];
hdrlen += 4 + 2;
decoded[namelen+1] = 0;
if(dec_done <= hdrlen) {
decoded[namelen + 1] = 0;
if (dec_done <= hdrlen) {
cli_dbgmsg("cli_binhex: file too short for header\n");
break;
}
if((ret = cli_checklimits("cli_binhex(data)", ctx, datalen, 0, 0)) != CL_CLEAN)
if ((ret = cli_checklimits("cli_binhex(data)", ctx, datalen, 0, 0)) != CL_CLEAN)
break;
if(cli_checklimits("cli_binhex(resources)", ctx, reslen, 0, 0) != CL_CLEAN)
if (cli_checklimits("cli_binhex(resources)", ctx, reslen, 0, 0) != CL_CLEAN)
reslen = 0;
cli_dbgmsg("cli_binhex: decoding '%s' - %u bytes of data to %s - %u bytes or resources to %s\n", decoded+1, datalen, dname, reslen, rname);
cli_dbgmsg("cli_binhex: decoding '%s' - %u bytes of data to %s - %u bytes or resources to %s\n", decoded + 1, datalen, dname, reslen, rname);
memmove(decoded, &decoded[hdrlen], dec_done - hdrlen);
dec_done -= hdrlen;
write_phase++;
}
if(dec_done && write_phase == IN_DATA) {
if (dec_done && write_phase == IN_DATA) {
unsigned int todo = MIN(dec_done, datalen);
datalen -= todo;
dec_done -= todo;
if(cli_writen(datafd, decoded, todo)!=(int)todo) {
if (cli_writen(datafd, decoded, todo) != (int)todo) {
ret = CL_EWRITE;
break;
}
if(!datalen) {
if (!datalen) {
write_phase++;
if (lseek(datafd, 0, SEEK_SET) == -1) {
cli_dbgmsg("cli_binhex: call to lseek() has failed\n");
@ -119,46 +124,46 @@ int cli_binhex(cli_ctx *ctx) {
break;
}
ret = cli_magic_scandesc(datafd, dname, ctx);
if(ret == CL_VIRUS) break;
if (ret == CL_VIRUS) break;
}
if(dec_done)
if (dec_done)
memmove(decoded, &decoded[todo], dec_done);
}
if(dec_done && write_phase == IN_LIMBO1) {
if(dec_done > 1) {
if(reslen<5) {
if (dec_done && write_phase == IN_LIMBO1) {
if (dec_done > 1) {
if (reslen < 5) {
cli_dbgmsg("cli_binhex: skipping resources (too small)\n");
break;
}
dec_done-=2;
write_phase+=2;
if(dec_done)
dec_done -= 2;
write_phase += 2;
if (dec_done)
memmove(decoded, &decoded[2], dec_done);
} else {
dec_done--;
write_phase++;
if(dec_done)
if (dec_done)
memmove(decoded, &decoded[1], dec_done);
}
}
if(dec_done && write_phase == IN_LIMBO2) {
if(reslen<5) {
if (dec_done && write_phase == IN_LIMBO2) {
if (reslen < 5) {
cli_dbgmsg("cli_binhex: skipping resources (too small)\n");
break;
}
write_phase++;
if(--dec_done)
if (--dec_done)
memmove(decoded, &decoded[1], dec_done);
}
if(dec_done && write_phase == IN_RES) {
if (dec_done && write_phase == IN_RES) {
unsigned int todo = MIN(dec_done, reslen);
reslen -= todo;
dec_done -= todo;
if(cli_writen(resfd, decoded, todo)!=(int)todo) {
if (cli_writen(resfd, decoded, todo) != (int)todo) {
ret = CL_EWRITE;
break;
}
if(!reslen) {
if (!reslen) {
if (lseek(resfd, 0, SEEK_SET) == -1) {
cli_dbgmsg("cli_binhex: call to lseek() has failed\n");
ret = CL_ESEEK;
@ -168,8 +173,8 @@ int cli_binhex(cli_ctx *ctx) {
break;
}
}
if(!enc_todo) {
if(write_phase == IN_DATA) {
if (!enc_todo) {
if (write_phase == IN_DATA) {
cli_dbgmsg("cli_binhex: scanning partially extracted data fork\n");
if (lseek(datafd, 0, SEEK_SET) == -1) {
cli_dbgmsg("cli_binhex: call to lseek() has failed\n");
@ -177,7 +182,7 @@ int cli_binhex(cli_ctx *ctx) {
break;
}
ret = cli_magic_scandesc(datafd, dname, ctx);
} else if(write_phase == IN_RES) {
} else if (write_phase == IN_RES) {
cli_dbgmsg("cli_binhex: scanning partially extracted resource fork\n");
if (lseek(resfd, 0, SEEK_SET) == -1) {
cli_dbgmsg("cli_binhex: call to lseek() has failed\n");
@ -192,11 +197,10 @@ int cli_binhex(cli_ctx *ctx) {
// 'chunksz' must be 0 the first iteration,
// so that 'encoded' will be initialized before first dereference.
if(!chunksz)
{
if (!chunksz) {
chunksz = MIN(enc_todo, map->pgsz);
encoded = fmap_need_off_once(map, enc_done, chunksz);
if(!encoded) {
if (!encoded) {
ret = CL_EREAD;
break;
}
@ -208,50 +212,50 @@ int cli_binhex(cli_ctx *ctx) {
enc_done++;
enc_todo--;
if((char)b == '\r' || (char)b == '\n') {
if ((char)b == '\r' || (char)b == '\n') {
in_data = 1;
continue;
}
if(!in_data) continue;
if(write_phase == IN_BANNER) {
if((char)b != ':') {
if (!in_data) continue;
if (write_phase == IN_BANNER) {
if ((char)b != ':') {
cli_dbgmsg("cli_binhex: broken file (missing stream start identifier)\n");
break;
}
write_phase++;
}
if((char)b == ':')
if ((char)b == ':')
continue;
if(b > 0x7f || (b = hqxtbl[b]) == 0xff) {
cli_dbgmsg("cli_binhex: Invalid character (%02x)\n", encoded[chunkoff-1]);
if (b > 0x7f || (b = hqxtbl[b]) == 0xff) {
cli_dbgmsg("cli_binhex: Invalid character (%02x)\n", encoded[chunkoff - 1]);
break;
}
switch((offset++) & 3) { /* 6 bits per char */
switch ((offset++) & 3) { /* 6 bits per char */
case 0: /* left-6h */
spare_bits = b<<2;
spare_bits = b << 2;
continue;
case 1: /* left-2l + middle-4h */
this_byte = spare_bits | (b>>4);
spare_bits = b<<4;
this_byte = spare_bits | (b >> 4);
spare_bits = b << 4;
break;
case 2: /* middle-4l + right-2h */
this_byte = spare_bits | (b>>2);
spare_bits = b<<6;
this_byte = spare_bits | (b >> 2);
spare_bits = b << 6;
break;
case 3: /* right-6l */
this_byte = spare_bits | b;
}
if(in_run) {
if (in_run) {
in_run = 0;
if(!this_byte)
if (!this_byte)
this_byte = 0x90;
else {
while(--this_byte)
while (--this_byte)
decoded[dec_done++] = last_byte;
continue;
}
} else if(this_byte == 0x90) {
} else if (this_byte == 0x90) {
in_run = 1;
continue;
}
@ -261,9 +265,9 @@ int cli_binhex(cli_ctx *ctx) {
close(datafd);
close(resfd);
if(!ctx->engine->keeptmp) {
if(cli_unlink(dname) && ret != CL_VIRUS) ret = CL_EUNLINK;
if(cli_unlink(rname) && ret != CL_VIRUS) ret = CL_EUNLINK;
if (!ctx->engine->keeptmp) {
if (cli_unlink(dname) && ret != CL_VIRUS) ret = CL_EUNLINK;
if (cli_unlink(rname) && ret != CL_VIRUS) ret = CL_EUNLINK;
}
free(dname);
free(rname);

View file

@ -65,7 +65,7 @@ blobCreate(void)
{
#ifdef CL_DEBUG
blob *b = (blob *)cli_calloc(1, sizeof(blob));
if(b)
if (b)
b->magic = BLOBCLASS;
cli_dbgmsg("blobCreate\n");
return b;
@ -74,8 +74,7 @@ blobCreate(void)
#endif
}
void
blobDestroy(blob *b)
void blobDestroy(blob *b)
{
#ifdef CL_DEBUG
cli_dbgmsg("blobDestroy %d\n", b->magic);
@ -86,9 +85,9 @@ blobDestroy(blob *b)
assert(b != NULL);
assert(b->magic == BLOBCLASS);
if(b->name)
if (b->name)
free(b->name);
if(b->data)
if (b->data)
free(b->data);
#ifdef CL_DEBUG
b->magic = INVALIDCLASS;
@ -96,14 +95,13 @@ blobDestroy(blob *b)
free(b);
}
void
blobArrayDestroy(blob *blobList[], int n)
void blobArrayDestroy(blob *blobList[], int n)
{
assert(blobList != NULL);
while(--n >= 0) {
while (--n >= 0) {
cli_dbgmsg("blobArrayDestroy: %d\n", n);
if(blobList[n]) {
if (blobList[n]) {
blobDestroy(blobList[n]);
blobList[n] = NULL;
}
@ -122,9 +120,9 @@ blobToMem(blob *b)
assert(b != NULL);
assert(b->magic == BLOBCLASS);
if(!b->isClosed)
if (!b->isClosed)
blobClose(b);
if(b->name)
if (b->name)
free(b->name);
#ifdef CL_DEBUG
b->magic = INVALIDCLASS;
@ -136,8 +134,7 @@ blobToMem(blob *b)
}
/*ARGSUSED*/
void
blobSetFilename(blob *b, const char *dir, const char *filename)
void blobSetFilename(blob *b, const char *dir, const char *filename)
{
assert(b != NULL);
assert(b->magic == BLOBCLASS);
@ -147,12 +144,12 @@ blobSetFilename(blob *b, const char *dir, const char *filename)
cli_dbgmsg("blobSetFilename: %s\n", filename);
if(b->name)
if (b->name)
free(b->name);
b->name = cli_strdup(filename);
if(b->name)
if (b->name)
sanitiseName(b->name);
}
@ -168,8 +165,7 @@ blobGetFilename(const blob *b)
/*
* Returns <0 for failure
*/
int
blobAddData(blob *b, const unsigned char *data, size_t len)
int blobAddData(blob *b, const unsigned char *data, size_t len)
{
#if HAVE_CLI_GETPAGESIZE
static int pagesize;
@ -180,10 +176,10 @@ blobAddData(blob *b, const unsigned char *data, size_t len)
assert(b->magic == BLOBCLASS);
assert(data != NULL);
if(len == 0)
if (len == 0)
return 0;
if(b->isClosed) {
if (b->isClosed) {
/*
* Should be cli_dbgmsg, but I want to see them for now,
* and cli_dbgmsg doesn't support debug levels
@ -201,44 +197,44 @@ blobAddData(blob *b, const unsigned char *data, size_t len)
* the most optimum
*/
#if HAVE_CLI_GETPAGESIZE
if(pagesize == 0) {
if (pagesize == 0) {
pagesize = cli_getpagesize();
if(pagesize == 0)
if (pagesize == 0)
pagesize = 4096;
}
growth = pagesize;
if(len >= (size_t)pagesize)
if (len >= (size_t)pagesize)
growth = ((len / pagesize) + 1) * pagesize;
/*cli_dbgmsg("blobGrow: b->size %lu, b->len %lu, len %lu, growth = %u\n",
b->size, b->len, len, growth);*/
if(b->data == NULL) {
if (b->data == NULL) {
assert(b->len == 0);
assert(b->size == 0);
b->size = growth;
b->data = cli_malloc(growth);
} else if(b->size < b->len + (off_t)len) {
} else if (b->size < b->len + (off_t)len) {
unsigned char *p = cli_realloc(b->data, b->size + growth);
if(p == NULL)
if (p == NULL)
return -1;
b->size += growth;
b->data = p;
}
#else
if(b->data == NULL) {
if (b->data == NULL) {
assert(b->len == 0);
assert(b->size == 0);
b->size = (off_t)len * 4;
b->data = cli_malloc(b->size);
} else if(b->size < b->len + (off_t)len) {
} else if (b->size < b->len + (off_t)len) {
unsigned char *p = cli_realloc(b->data, b->size + (len * 4));
if(p == NULL)
if (p == NULL)
return -1;
b->size += (off_t)len * 4;
@ -246,7 +242,7 @@ blobAddData(blob *b, const unsigned char *data, size_t len)
}
#endif
if(b->data) {
if (b->data) {
memcpy(&b->data[b->len], data, len);
b->len += (off_t)len;
}
@ -259,7 +255,7 @@ blobGetData(const blob *b)
assert(b != NULL);
assert(b->magic == BLOBCLASS);
if(b->len == 0)
if (b->len == 0)
return NULL;
return b->data;
}
@ -273,13 +269,12 @@ blobGetDataSize(const blob *b)
return b->len;
}
void
blobClose(blob *b)
void blobClose(blob *b)
{
assert(b != NULL);
assert(b->magic == BLOBCLASS);
if(b->isClosed) {
if (b->isClosed) {
cli_warnmsg("Attempt to close a previously closed blob\n");
return;
}
@ -288,8 +283,8 @@ blobClose(blob *b)
* Nothing more is going to be added to this blob. If it'll save more
* than a trivial amount (say 64 bytes) of memory, shrink the allocation
*/
if((b->size - b->len) >= 64) {
if(b->len == 0) { /* Not likely */
if ((b->size - b->len) >= 64) {
if (b->len == 0) { /* Not likely */
free(b->data);
b->data = NULL;
cli_dbgmsg("blobClose: recovered all %lu bytes\n",
@ -298,7 +293,7 @@ blobClose(blob *b)
} else {
unsigned char *ptr = cli_realloc(b->data, b->len);
if(ptr == NULL)
if (ptr == NULL)
return;
cli_dbgmsg("blobClose: recovered %lu bytes from %lu\n",
@ -314,24 +309,23 @@ blobClose(blob *b)
/*
* Returns 0 if the blobs are the same
*/
int
blobcmp(const blob *b1, const blob *b2)
int blobcmp(const blob *b1, const blob *b2)
{
size_t s1, s2;
assert(b1 != NULL);
assert(b2 != NULL);
if(b1 == b2)
if (b1 == b2)
return 0;
s1 = blobGetDataSize(b1);
s2 = blobGetDataSize(b2);
if(s1 != s2)
if (s1 != s2)
return 1;
if((s1 == 0) && (s2 == 0))
if ((s1 == 0) && (s2 == 0))
return 0;
return memcmp(blobGetData(b1), blobGetData(b2), s1);
@ -340,16 +334,15 @@ blobcmp(const blob *b1, const blob *b2)
/*
* Return clamav return code
*/
int
blobGrow(blob *b, size_t len)
int blobGrow(blob *b, size_t len)
{
assert(b != NULL);
assert(b->magic == BLOBCLASS);
if(len == 0)
if (len == 0)
return CL_SUCCESS;
if(b->isClosed) {
if (b->isClosed) {
/*
* Should be cli_dbgmsg, but I want to see them for now,
* and cli_dbgmsg doesn't support debug levels
@ -357,17 +350,17 @@ blobGrow(blob *b, size_t len)
cli_warnmsg("Growing closed blob\n");
b->isClosed = 0;
}
if(b->data == NULL) {
if (b->data == NULL) {
assert(b->len == 0);
assert(b->size == 0);
b->data = cli_malloc(len);
if(b->data)
if (b->data)
b->size = (off_t)len;
} else {
unsigned char *ptr = cli_realloc(b->data, b->size + len);
if(ptr) {
if (ptr) {
b->size += (off_t)len;
b->data = ptr;
}
@ -381,7 +374,7 @@ fileblobCreate(void)
{
#ifdef CL_DEBUG
fileblob *fb = (fileblob *)cli_calloc(1, sizeof(fileblob));
if(fb)
if (fb)
fb->b.magic = BLOBCLASS;
cli_dbgmsg("blobCreate\n");
return fb;
@ -394,10 +387,9 @@ fileblobCreate(void)
* Returns CL_CLEAN or CL_VIRUS. Destroys the fileblob and removes the file
* if possible
*/
int
fileblobScanAndDestroy(fileblob *fb)
int fileblobScanAndDestroy(fileblob *fb)
{
switch(fileblobScan(fb)) {
switch (fileblobScan(fb)) {
case CL_VIRUS:
fileblobDestructiveDestroy(fb);
return CL_VIRUS;
@ -413,19 +405,18 @@ fileblobScanAndDestroy(fileblob *fb)
/*
* Destroy the fileblob, and remove the file associated with it
*/
void
fileblobDestructiveDestroy(fileblob *fb)
void fileblobDestructiveDestroy(fileblob *fb)
{
if(fb->fp && fb->fullname) {
if (fb->fp && fb->fullname) {
fclose(fb->fp);
cli_dbgmsg("fileblobDestructiveDestroy: %s\n", fb->fullname);
if(!fb->ctx || !fb->ctx->engine->keeptmp)
if (!fb->ctx || !fb->ctx->engine->keeptmp)
cli_unlink(fb->fullname);
free(fb->fullname);
fb->fp = NULL;
fb->fullname = NULL;
}
if(fb->b.name) {
if (fb->b.name) {
free(fb->b.name);
fb->b.name = NULL;
}
@ -436,17 +427,16 @@ fileblobDestructiveDestroy(fileblob *fb)
* Destroy the fileblob, and remove the file associated with it if that file is
* empty
*/
void
fileblobDestroy(fileblob *fb)
void fileblobDestroy(fileblob *fb)
{
assert(fb != NULL);
assert(fb->b.magic == BLOBCLASS);
if(fb->b.name && fb->fp) {
if (fb->b.name && fb->fp) {
fclose(fb->fp);
if(fb->fullname) {
if (fb->fullname) {
cli_dbgmsg("fileblobDestroy: %s\n", fb->fullname);
if(!fb->isNotEmpty) {
if (!fb->isNotEmpty) {
cli_dbgmsg("fileblobDestroy: not saving empty file\n");
cli_unlink(fb->fullname);
}
@ -454,9 +444,9 @@ fileblobDestroy(fileblob *fb)
free(fb->b.name);
assert(fb->b.data == NULL);
} else if(fb->b.data) {
} else if (fb->b.data) {
free(fb->b.data);
if(fb->b.name) {
if (fb->b.name) {
cli_errmsg("fileblobDestroy: %s not saved: report to https://bugzilla.clamav.net\n",
(fb->fullname) ? fb->fullname : fb->b.name);
free(fb->b.name);
@ -464,7 +454,7 @@ fileblobDestroy(fileblob *fb)
cli_errmsg("fileblobDestroy: file not saved (%lu bytes): report to https://bugzilla.clamav.net\n",
(unsigned long)fb->b.len);
}
if(fb->fullname)
if (fb->fullname)
free(fb->fullname);
#ifdef CL_DEBUG
fb->b.magic = INVALIDCLASS;
@ -472,33 +462,32 @@ fileblobDestroy(fileblob *fb)
free(fb);
}
void
fileblobPartialSet(fileblob *fb, const char *fullname, const char *arg)
void fileblobPartialSet(fileblob *fb, const char *fullname, const char *arg)
{
UNUSEDPARAM(arg);
if(fb->b.name)
if (fb->b.name)
return;
assert(fullname != NULL);
cli_dbgmsg("fileblobPartialSet: saving to %s\n", fullname);
fb->fd = open(fullname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY|O_EXCL, 0600);
if(fb->fd < 0) {
cli_errmsg("fileblobPartialSet: unable to create file: %s\n",fullname);
fb->fd = open(fullname, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_EXCL, 0600);
if (fb->fd < 0) {
cli_errmsg("fileblobPartialSet: unable to create file: %s\n", fullname);
return;
}
fb->fp = fdopen(fb->fd, "wb");
if(fb->fp == NULL) {
if (fb->fp == NULL) {
cli_errmsg("fileblobSetFilename: fdopen failed\n");
close(fb->fd);
return;
}
blobSetFilename(&fb->b, fb->ctx ? fb->ctx->engine->tmpdir : NULL, fullname);
if(fb->b.data)
if(fileblobAddData(fb, fb->b.data, fb->b.len) == 0) {
if (fb->b.data)
if (fileblobAddData(fb, fb->b.data, fb->b.len) == 0) {
free(fb->b.data);
fb->b.data = NULL;
fb->b.len = fb->b.size = 0;
@ -507,12 +496,11 @@ fileblobPartialSet(fileblob *fb, const char *fullname, const char *arg)
fb->fullname = cli_strdup(fullname);
}
void
fileblobSetFilename(fileblob *fb, const char *dir, const char *filename)
void fileblobSetFilename(fileblob *fb, const char *dir, const char *filename)
{
char *fullname;
if(fb->b.name)
if (fb->b.name)
return;
assert(filename != NULL);
@ -528,20 +516,20 @@ fileblobSetFilename(fileblob *fb, const char *dir, const char *filename)
assert(filename != NULL);
if (cli_gentempfd(dir, &fullname, &fb->fd)!=CL_SUCCESS) return;
if (cli_gentempfd(dir, &fullname, &fb->fd) != CL_SUCCESS) return;
cli_dbgmsg("fileblobSetFilename: file %s saved to %s\n", filename, fullname);
fb->fp = fdopen(fb->fd, "wb");
if(fb->fp == NULL) {
if (fb->fp == NULL) {
cli_errmsg("fileblobSetFilename: fdopen failed\n");
close(fb->fd);
free(fullname);
return;
}
if(fb->b.data)
if(fileblobAddData(fb, fb->b.data, fb->b.len) == 0) {
if (fb->b.data)
if (fileblobAddData(fb, fb->b.data, fb->b.len) == 0) {
free(fb->b.data);
fb->b.data = NULL;
fb->b.len = fb->b.size = 0;
@ -550,34 +538,33 @@ fileblobSetFilename(fileblob *fb, const char *dir, const char *filename)
fb->fullname = fullname;
}
int
fileblobAddData(fileblob *fb, const unsigned char *data, size_t len)
int fileblobAddData(fileblob *fb, const unsigned char *data, size_t len)
{
if(len == 0)
if (len == 0)
return 0;
assert(data != NULL);
if(fb->fp) {
if (fb->fp) {
#if defined(MAX_SCAN_SIZE) && (MAX_SCAN_SIZE > 0)
const cli_ctx *ctx = fb->ctx;
if(fb->isInfected) /* pretend all was written */
if (fb->isInfected) /* pretend all was written */
return 0;
if(ctx) {
if (ctx) {
int do_scan = 1;
if(cli_checklimits("fileblobAddData", ctx, fb->bytes_scanned, 0, 0)!=CL_CLEAN)
if (cli_checklimits("fileblobAddData", ctx, fb->bytes_scanned, 0, 0) != CL_CLEAN)
do_scan = 0;
if(fb->bytes_scanned > MAX_SCAN_SIZE)
if (fb->bytes_scanned > MAX_SCAN_SIZE)
do_scan = 0;
if(do_scan) {
if(ctx->scanned)
if (do_scan) {
if (ctx->scanned)
*ctx->scanned += (unsigned long)len / CL_COUNT_PRECISION;
fb->bytes_scanned += (unsigned long)len;
if((len > 5) && cli_updatelimits(ctx, len)==CL_CLEAN && (cli_scanbuff(data, (unsigned int)len, 0, ctx->virname, ctx->engine, CL_TYPE_BINARY_DATA, NULL) == CL_VIRUS)) {
if ((len > 5) && cli_updatelimits(ctx, len) == CL_CLEAN && (cli_scanbuff(data, (unsigned int)len, 0, ctx->virname, ctx->engine, CL_TYPE_BINARY_DATA, NULL) == CL_VIRUS)) {
cli_dbgmsg("fileblobAddData: found %s\n", cli_get_last_virus_str(ctx->virname));
fb->isInfected = 1;
}
@ -585,7 +572,7 @@ fileblobAddData(fileblob *fb, const unsigned char *data, size_t len)
}
#endif
if(fwrite(data, len, 1, fb->fp) != 1) {
if (fwrite(data, len, 1, fb->fp) != 1) {
cli_errmsg("fileblobAddData: Can't write %lu bytes to temporary file %s\n",
(unsigned long)len, fb->b.name);
return -1;
@ -602,8 +589,7 @@ fileblobGetFilename(const fileblob *fb)
return blobGetFilename(&(fb->b));
}
void
fileblobSetCTX(fileblob *fb, cli_ctx *ctx)
void fileblobSetCTX(fileblob *fb, cli_ctx *ctx)
{
fb->ctx = ctx;
}
@ -614,22 +600,21 @@ fileblobSetCTX(fileblob *fb, cli_ctx *ctx)
* CL_CLEAN means unknown
* CL_VIRUS means infected
*/
int
fileblobScan(const fileblob *fb)
int fileblobScan(const fileblob *fb)
{
int rc;
cli_ctx *ctx = fb->ctx;
STATBUF sb;
int virus_found = 0;
if(fb->isInfected)
if (fb->isInfected)
return CL_VIRUS;
if(fb->fp == NULL || fb->fullname == NULL) {
if (fb->fp == NULL || fb->fullname == NULL) {
/* shouldn't happen, scan called before fileblobSetFilename */
cli_warnmsg("fileblobScan, fullname == NULL\n");
return CL_ENULLARG; /* there is no CL_UNKNOWN */
}
if(fb->ctx == NULL) {
if (fb->ctx == NULL) {
/* fileblobSetCTX hasn't been called */
cli_dbgmsg("fileblobScan, ctx == NULL\n");
return CL_CLEAN; /* there is no CL_UNKNOWN */
@ -638,14 +623,14 @@ fileblobScan(const fileblob *fb)
fflush(fb->fp);
lseek(fb->fd, 0, SEEK_SET);
FSTAT(fb->fd, &sb);
if(cli_matchmeta(fb->ctx, fb->b.name, sb.st_size, sb.st_size, 0, 0, 0, NULL) == CL_VIRUS) {
if (cli_matchmeta(fb->ctx, fb->b.name, sb.st_size, sb.st_size, 0, 0, 0, NULL) == CL_VIRUS) {
if (!SCAN_ALLMATCHES)
return CL_VIRUS;
virus_found = 1;
}
rc = cli_magic_scandesc(fb->fd, fb->fullname, fb->ctx);
if(rc == CL_VIRUS || virus_found != 0) {
if (rc == CL_VIRUS || virus_found != 0) {
cli_dbgmsg("%s is infected\n", fb->fullname);
return CL_VIRUS;
}
@ -657,8 +642,7 @@ fileblobScan(const fileblob *fb)
* Doesn't perform a full scan just lets the caller know if something suspicious has
* been seen yet
*/
int
fileblobInfected(const fileblob *fb)
int fileblobInfected(const fileblob *fb)
{
return fb->isInfected;
}
@ -668,12 +652,11 @@ fileblobInfected(const fileblob *fb)
* FIXME: What does QNX want? There is no #ifdef C_QNX, but if there were
* it may be best to treat it like MSDOS
*/
void
sanitiseName(char *name)
void sanitiseName(char *name)
{
char c;
while((c = *name)) {
if(c!='.' && c!='_' && (c>'z' || c<'0' || (c>'9' && c<'A') || (c>'Z' && c<'a')))
while ((c = *name)) {
if (c != '.' && c != '_' && (c > 'z' || c < '0' || (c > '9' && c < 'A') || (c > 'Z' && c < 'a')))
*name = '_';
name++;
}

View file

@ -31,66 +31,65 @@
* Usually bytecode.cvd will contain this bytecode */
static const char* builtin_bc_startup =
"ClamBCafhhbfkjmld|afefdfggifnf```aa```|biacflfafmfbfcfmb`cnbacacmbachcccmbgfbfcc`ccchcbfdf``bgcaap`clamcoincidencejb:4096\n"
"\n"
"Teddaaahdabahdacahdadahdaeahdafahdagahebfgebidebegebdgebgdebkdebcgebbgebageb`gebofebnfebmfebedeblfebkfebjfebadcbgab`bb`bb`bb`bb`bb`bb`bbifbifbifbifbifbifbifahahahahahahahahahebneebifaaaaaaaab`baabb`bb`baacb`bbadb`baacb`bboeb`baacb`bb`bb`baadb`bbadb`bb`baadb`bbadbadb`bdbadahdbkaahdbbcahdbibahdb`eahdbddahdbodahdbdaahdaiahdakahdamahdahahdbncahdbnbah\n"
"Ebjdaibcdbbf|bcaefnfgfifnfefoedfcfofnfffoelfeffgeflf``bbdbbf|bkaefnfgfifnfefoeffegnfcfdgifofnfaflfifdgigoelfeffgeflf``agbcf|baadfefbfeggfoe`gbgifnfdgoeegifnfdg``bcabcf|afdgefcgdgbc``afbdf|b`adfefbfeggfoe`gbgifnfdgoecgdgbg``bhdbef|b`agfefdgoeefnffgifbgofnfmfefnfdg``aabff|afdgefcgdgac``bidbgf|bdadfifcgafbflfefoebfigdgefcfofdfefoeifff``bjdbgf|aodfifcgafbflfefoejfifdgoeifff``\n"
"G`b`c`@`b`aAa`bfgBifBkeBccBdcBmeBhcBfcB`bBdfBefBdgBefBcfBdgBefBdfBlbB`bBjdBidBdeB`bBnfBefBefBdfBcgB`bB`gBefBnfBdgBifBegBmfB`bBofBbgB`bBbfBefBdgBdgBefBbg@`bidBifBccBhcBfc@`bidBifBdcBhcBfc@`begBcdB`eBeeB`bBdfBofBefBcgBnfBgbBdgB`bBcgBegB`gB`gBofBbgBdgB`bBcdBmdBodBfeBlbB`bBggBofBegBlfBdfB`bBnfBefBefBdfB`bB`cBnbBicBgcB`bBhbBldBldBfeBmdB`bBbcBnbBhcBibB`bBdgBofB`bBggBofBbgBkfBab@`bidBifBecBhcBfc@`bdgB`gBefBnfBdgBifBegBmf@`bidBifBfcBhcBfc@`bgdBkfBfc@`bidBkfBfcBmbBbc@`bidBkfBfcBmbBcc@`bkdBafBdgBhfBlfBofBnf@`bcgBafBdgBhfBlfBofBnfBmbBdgBbfBifBbgBdf@`bbgBggBifBnfBcfBhfBifB`gBmbBcfBfc@`bagBggBifBnfBcfBhfBifB`gBbc@`bgdBcfBcc@`b`gBbeBgeBheB`bBmfBafB`gB`gBifBnfBgfB`bBdfBefBnfBifBefBdfBnb@`bofBneBceBedBldBifBnfBegBhgB`bBifBcgB`bB`gBbgBefBfgBefBnfBdgBifBnfBgfB`bBgbBefBhgBefBcfBmfBefBmfBgbB`bBafBcfBcfBefBcgBcgBnbAjBbeBegBnfB`bB`bBgbBcgBefBdgBcgBefBbfBofBofBlfB`bBmbB`eB`bBcfBlfBafBmfBdfBoeBegBcgBefBoeBjfBifBdgB`bBofBnfBgbBnb@`bnfBneB`eBafBheB`bBifBcgB`bB`gBbgBefBfgBefBnfBdgBifBnfBgfB`bBgbBmfB`gBbgBofBdgBefBcfBdgBgbB`bBafBcfBcfBefBcgBcgBnbAjBbeBegBnfB`bBgbB`gBafBhgBcfBdgBlfB`bBmbBcfBmfB`bBlcBefBhgBefBcfBegBdgBafBbfBlfBefBncBgb@`bmfBneBbeBgeBheB`bBmfBafB`gB`gBifBnfBgfB`bBdfBefBnfBifBefBdfB`bBffBofBbgB`bBegBnfBkfBnfBofBggBnfB`bBbgBefBafBcgBofBnfBnbB`eBlfBefBafBcgBefB`bBbgBefB`gBofBbgBdgB`bBdgBofB`bBhfBdgBdgB`gBjcBobBobBbfBegBgfBcgBnbBcfBlfBafBmfBafBfgBnbBnfBefBdgAj@`bed@`blfBcgBdgBafBbgBdgBegB`gBjcB`bBbfBigBdgBefBcfBofBdfBefB`bBefBhgBefBcfBegBdgBifBofBnfB`bBifBnfB`bBafBegBdgBofB`bBmfBofBdfBef@`bkfBcgBdgBafBbgBdgBegB`gBjcB`bBbfBigBdgBefBcfBofBdfBefB`bBefBhgBefBcfBegBdgBifBofBnfB`bBggBifBdgBhfB`bBifBnfBdgBefBbgB`gBbgBefBdgBefBbgB`bBofBnfBlfBig@`bjfBcgBdgBafBbgBdgBegB`gBjcB`bBbfBigBdgBefBcfBofBdfBefB`bBdfBifBcgBafBbfBlfBefBdf@`bad@Ab`bad@Ac`bad@Ad`bad@Ae`bad@Af`bad@Ag`bad@Ah`bad@Ai`bad@Aj`bad@Ak`bad@Al`bad@Am`bad@An`bad@Ao`bad@B`a`bad@Baa`bad@Bba`bad@Bca`bad@Bda`bad@Bea`bad@Bfa`bad@Bga`bad@Bha`\n"
"A`b`bLblib`bab`b`b`b`bneab`b`bad`ah`aa`bad`ah`aa`b`f`bad`b`b`aa`b`b`aa`b`b`b`b`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`b`b`bad`ah`b`b`b`b`aa`b`b`bad`ah`aa`ah`b`b`b`b`aa`b`b`b`b`aa`b`b`b`b`bad`ah`aa`bad`ah`aa`b`b`aa`b`b`b`b`aa`aa`aa`aa`aa`b`b`b`b`b`b`ah`aa`bcd`b`b`aa`bcd`b`b`bcd`b`b`aa`b`b`aa`b`b`b`b`aa`bad`ah`b`b`aa`b`b`aa`bad`ah`b`b`b`b`bad`ah`b`b`b`b`bad`ah`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`bad`ah`b`b`b`b`bcd`b`b`b`b`b`b`bad`ah`b`b`b`b`bcd`b`b`b`b`bcd`b`b`aa`b`b`bcd`b`b`aa`b`b`bcd`b`b`aa`b`b`b`b`aa`b`b`b`b`aa`b`b`b`b`Fbbnbec\n"
"Bb`badabbbhdacClnadbadaedbboeacBdadahafgbaeaaageaahaf@aTaaagblaaa\n"
"BbadahdbboeacB`adahaigbahaaajeaahaiAaaTaaajabbaa\n"
"Bb`fakdbboeacAidbadaldbb`fak@db`bamkbalBja`Aedaaaneab`bam@db`b`bbAadabTaaanadac\n"
"Bb`baokbalBka`Aedaab`aeab`bao@db`bab`ab`ab`b`bbababTbaad\n"
"Bb`bbaabbabbaab`bbbaabcbjdBia`@dbaab`bbcaab`bbdaabdaiab`bbcaBicdTaabdaaebaa\n"
"Bb`bbeakbalBma`Aedaabfaeab`bbea@db`b`bbAadaaTaabfab`aaf\n"
"Bb`bbgakbalBna`Ahdaabhaeab`bbga@db`b`bbAadaaTaabhab`aag\n"
"Bb`bbiakbalBoa`Aedaabjaeab`bbia@db`b`bbAadaaTaabjab`aah\n"
"Bb`bbkakbalB`b`Acdaablaeab`bbka@db`b`bbAadaaTaablab`aai\n"
"Bb`bbmakbalBab`Aedaabnaeab`bbma@db`b`bbAadaaTaabnab`aaj\n"
"Bb`bboakbalBbb`Aedaab`beab`bboa@db`b`bbAadaaTaab`bb`aak\n"
"Bb`bbabkbalBcb`Agdaabbbeab`bbab@db`b`bbAadaaTaabbbb`aal\n"
"Bb`bbcbkbalBdb`Amdaabdbeab`bbcb@db`b`bbAadaaTaabdbb`aam\n"
"Bb`bbebkbalBeb`Akdaabfbeab`bbeb@db`b`bbAadaaTaabfbb`aan\n"
"Bb`bbgbkbalBfb`Aidaabhbeab`bbgb@db`b`bbAadaaTaabhbb`aao\n"
"Bb`bbibkbalBgb`Acdaabjbeab`bbib@db`baa`abjbb`b`bbaaaaTbab`a\n"
"Bb`bbkbbbaabkbb`bblbabcbjdBla`@dbkbTbabaa\n"
"BbadbmbdbboeacBeadahbnbgbbmbb`bbob`abnbb`bb`ck`bobAadaabaceab`bb`c@dTaabacbbabha\n"
"Bb`bbbcabcbjdBhb`@dAadbadbccdbboeacBaadahbdcgbbccaabeceaahbdcAjaTaabecbcabla\n"
"Bahbfcgbbmbb`bbgc`abfcb`bbhck`bgcAbdaabiceab`bbhc@dTaabicbeabda\n"
"Bb`bbjcabcbjdBib`@dAadTbabla\n"
"Bb`bbkck`bgcAhdaablceab`bbkc@dTaablcbgabfa\n"
"Bb`bbmcabcbjdBjb`@dAadTbabla\n"
"Bb`bbncabcbjdBkb`@dAadTbabla\n"
"BbadbocdbboeacBaadahb`dgbbocaabadeaahb`dAjaTaabadbjabia\n"
"BbadbbddbboeacBbadahbcdgbbbdaabddeaahbcdAfaTaabddbjabla\n"
"Bb`bbedk`bobB`adaabfdeab`bbed@dTaabfdblabka\n"
"Bb`bbgdabcbjdBjb`@dAadTbabla\n"
"Bb`bbhdabcbidBlb`@d@daabidnab`bbhdAadTaabidb`bbma\n"
"Baabjdnab`bbhdAbdTaabjdboabna\n"
"Baabkdeab`bbhdAbdTaabkdbcbbdb\n"
"Baabldeab`bbhdAadTaabldbbbbdb\n"
"Baabmdeab`bbhd@dTaabmdbabbdb\n"
"Bb`bbndabbafBmb`@dTbabdb\n"
"Bb`bbodabbafBnb`@dTbabdb\n"
"Bb`bb`eabbafBob`@dTbabdb\n"
"Bahbaegbaeaabbeeaahbae@aTaabbebfbbeb\n"
"BbcdbcedbboeacAddb`bbdegbbceaabeeeab`bbde@db`b`bbEamjnmd`Taabeebdcbfb\n"
"BbcdbfedbboeacAfdb`bbgegbbfebcdbhedbboeacAedb`bbiegbbheaabjeiab`bbgebieb`b`bbEbmjnmd`Taabjebdcbgb\n"
"Bb`bbkeab`bbdaableeab`bbiebkeb`b`bbEcmjnmd`Taablebhbbdc\n"
"Bb`bbmegbbfeb`bbneab`bcdaaboeeab`bbmebneb`b`bbEdmjnmd`Taaboebibbdc\n"
"Bbadb`fdbboeacAndahbafgbb`fb`bbbf`abafaabcflbb`bbdf`abcfaabefeab`bbbfbdfb`b`bbEemjnmd`Taabefbjbbdc\n"
"BbadbffdbboeacBaadahbgfgbbffb`bbhf`abgfb`bbifh`bhfBhadbadbjfdbboeacB`adahbkfgbbjfb`bblf`abkfb`bbmfh`blfBdadbadbnfdbboeacBcadahbofgbbnfb`bb`g`abofb`bbagh`b`gB`adb`bbbggbbheb`bbcgh`bbgAhdb`bbdggbbfeb`bbegl`bmfbifb`bbfgl`begbcgb`bbggl`bfgbdgb`bbhgl`bggbagb`bbigh`bbfBladbadbjgdbboeacAodahbkggbbjgb`bblg`abkgb`bbmgh`blgBhadbcdbngdbboeacAddb`bboggbbngb`bb`hl`bogbigb`bbahl`b`hbmgbadbbhdbboeacBeadahbchgbbbhb`bbdh`abchb`bbehh`bdhBhadbcdbfhdbboeacAcdb`bbghgbbfhb`bbhhl`behbghbcdbihdbboeac@db`bbjhgbbihaabkheab`bbhgbjhTaabkhblbbkb\n"
"Bb`bblhabaagbhgTcab`bEfmjnmd\n"
"BbcdbmhdbboeacAadb`bbnhgbbmhaaboheab`bbahbnhTaabohbnbbmb\n"
"Bb`bb`iabaagbahTcab`bEgmjnmd\n"
"BbcdbaidbboeacAbdb`bbbigbbaiaabcieab`bbhhbbiTaabcib`cbob\n"
"Bb`bbdiabaagbhhTcab`bEhmjnmd\n"
"Bb`bbeiabbaaHonnkm``odHm``oonnkdaabfieab`bbeiHhgfedcbadTaabfibbcbac\n"
"Bb`bbgiabaagbeiTcab`bEimjnmd\n"
"Bb`bbhiababcaDm``odaabiieab`bbhiDo``mdb`b`bbHnejkjgjmd`Taabiibdcbcc\n"
"Bb`bbjiabaagbhiTcab`bF`amjnmd\n"
"Bb`bbkibb`bkiTcab`bbkiE\n"
;
"ClamBCafhhbfkjmld|afefdfggifnf```aa```|biacflfafmfbfcfmb`cnbacacmbachcccmbgfbfcc`ccchcbfdf``bgcaap`clamcoincidencejb:4096\n"
"\n"
"Teddaaahdabahdacahdadahdaeahdafahdagahebfgebidebegebdgebgdebkdebcgebbgebageb`gebofebnfebmfebedeblfebkfebjfebadcbgab`bb`bb`bb`bb`bb`bb`bbifbifbifbifbifbifbifahahahahahahahahahebneebifaaaaaaaab`baabb`bb`baacb`bbadb`baacb`bboeb`baacb`bb`bb`baadb`bbadb`bb`baadb`bbadbadb`bdbadahdbkaahdbbcahdbibahdb`eahdbddahdbodahdbdaahdaiahdakahdamahdahahdbncahdbnbah\n"
"Ebjdaibcdbbf|bcaefnfgfifnfefoedfcfofnfffoelfeffgeflf``bbdbbf|bkaefnfgfifnfefoeffegnfcfdgifofnfaflfifdgigoelfeffgeflf``agbcf|baadfefbfeggfoe`gbgifnfdgoeegifnfdg``bcabcf|afdgefcgdgbc``afbdf|b`adfefbfeggfoe`gbgifnfdgoecgdgbg``bhdbef|b`agfefdgoeefnffgifbgofnfmfefnfdg``aabff|afdgefcgdgac``bidbgf|bdadfifcgafbflfefoebfigdgefcfofdfefoeifff``bjdbgf|aodfifcgafbflfefoejfifdgoeifff``\n"
"G`b`c`@`b`aAa`bfgBifBkeBccBdcBmeBhcBfcB`bBdfBefBdgBefBcfBdgBefBdfBlbB`bBjdBidBdeB`bBnfBefBefBdfBcgB`bB`gBefBnfBdgBifBegBmfB`bBofBbgB`bBbfBefBdgBdgBefBbg@`bidBifBccBhcBfc@`bidBifBdcBhcBfc@`begBcdB`eBeeB`bBdfBofBefBcgBnfBgbBdgB`bBcgBegB`gB`gBofBbgBdgB`bBcdBmdBodBfeBlbB`bBggBofBegBlfBdfB`bBnfBefBefBdfB`bB`cBnbBicBgcB`bBhbBldBldBfeBmdB`bBbcBnbBhcBibB`bBdgBofB`bBggBofBbgBkfBab@`bidBifBecBhcBfc@`bdgB`gBefBnfBdgBifBegBmf@`bidBifBfcBhcBfc@`bgdBkfBfc@`bidBkfBfcBmbBbc@`bidBkfBfcBmbBcc@`bkdBafBdgBhfBlfBofBnf@`bcgBafBdgBhfBlfBofBnfBmbBdgBbfBifBbgBdf@`bbgBggBifBnfBcfBhfBifB`gBmbBcfBfc@`bagBggBifBnfBcfBhfBifB`gBbc@`bgdBcfBcc@`b`gBbeBgeBheB`bBmfBafB`gB`gBifBnfBgfB`bBdfBefBnfBifBefBdfBnb@`bofBneBceBedBldBifBnfBegBhgB`bBifBcgB`bB`gBbgBefBfgBefBnfBdgBifBnfBgfB`bBgbBefBhgBefBcfBmfBefBmfBgbB`bBafBcfBcfBefBcgBcgBnbAjBbeBegBnfB`bB`bBgbBcgBefBdgBcgBefBbfBofBofBlfB`bBmbB`eB`bBcfBlfBafBmfBdfBoeBegBcgBefBoeBjfBifBdgB`bBofBnfBgbBnb@`bnfBneB`eBafBheB`bBifBcgB`bB`gBbgBefBfgBefBnfBdgBifBnfBgfB`bBgbBmfB`gBbgBofBdgBefBcfBdgBgbB`bBafBcfBcfBefBcgBcgBnbAjBbeBegBnfB`bBgbB`gBafBhgBcfBdgBlfB`bBmbBcfBmfB`bBlcBefBhgBefBcfBegBdgBafBbfBlfBefBncBgb@`bmfBneBbeBgeBheB`bBmfBafB`gB`gBifBnfBgfB`bBdfBefBnfBifBefBdfB`bBffBofBbgB`bBegBnfBkfBnfBofBggBnfB`bBbgBefBafBcgBofBnfBnbB`eBlfBefBafBcgBefB`bBbgBefB`gBofBbgBdgB`bBdgBofB`bBhfBdgBdgB`gBjcBobBobBbfBegBgfBcgBnbBcfBlfBafBmfBafBfgBnbBnfBefBdgAj@`bed@`blfBcgBdgBafBbgBdgBegB`gBjcB`bBbfBigBdgBefBcfBofBdfBefB`bBefBhgBefBcfBegBdgBifBofBnfB`bBifBnfB`bBafBegBdgBofB`bBmfBofBdfBef@`bkfBcgBdgBafBbgBdgBegB`gBjcB`bBbfBigBdgBefBcfBofBdfBefB`bBefBhgBefBcfBegBdgBifBofBnfB`bBggBifBdgBhfB`bBifBnfBdgBefBbgB`gBbgBefBdgBefBbgB`bBofBnfBlfBig@`bjfBcgBdgBafBbgBdgBegB`gBjcB`bBbfBigBdgBefBcfBofBdfBefB`bBdfBifBcgBafBbfBlfBefBdf@`bad@Ab`bad@Ac`bad@Ad`bad@Ae`bad@Af`bad@Ag`bad@Ah`bad@Ai`bad@Aj`bad@Ak`bad@Al`bad@Am`bad@An`bad@Ao`bad@B`a`bad@Baa`bad@Bba`bad@Bca`bad@Bda`bad@Bea`bad@Bfa`bad@Bga`bad@Bha`\n"
"A`b`bLblib`bab`b`b`b`bneab`b`bad`ah`aa`bad`ah`aa`b`f`bad`b`b`aa`b`b`aa`b`b`b`b`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`aa`b`b`b`b`bad`ah`b`b`b`b`aa`b`b`bad`ah`aa`ah`b`b`b`b`aa`b`b`b`b`aa`b`b`b`b`bad`ah`aa`bad`ah`aa`b`b`aa`b`b`b`b`aa`aa`aa`aa`aa`b`b`b`b`b`b`ah`aa`bcd`b`b`aa`bcd`b`b`bcd`b`b`aa`b`b`aa`b`b`b`b`aa`bad`ah`b`b`aa`b`b`aa`bad`ah`b`b`b`b`bad`ah`b`b`b`b`bad`ah`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`bad`ah`b`b`b`b`bcd`b`b`b`b`b`b`bad`ah`b`b`b`b`bcd`b`b`b`b`bcd`b`b`aa`b`b`bcd`b`b`aa`b`b`bcd`b`b`aa`b`b`b`b`aa`b`b`b`b`aa`b`b`b`b`Fbbnbec\n"
"Bb`badabbbhdacClnadbadaedbboeacBdadahafgbaeaaageaahaf@aTaaagblaaa\n"
"BbadahdbboeacB`adahaigbahaaajeaahaiAaaTaaajabbaa\n"
"Bb`fakdbboeacAidbadaldbb`fak@db`bamkbalBja`Aedaaaneab`bam@db`b`bbAadabTaaanadac\n"
"Bb`baokbalBka`Aedaab`aeab`bao@db`bab`ab`ab`b`bbababTbaad\n"
"Bb`bbaabbabbaab`bbbaabcbjdBia`@dbaab`bbcaab`bbdaabdaiab`bbcaBicdTaabdaaebaa\n"
"Bb`bbeakbalBma`Aedaabfaeab`bbea@db`b`bbAadaaTaabfab`aaf\n"
"Bb`bbgakbalBna`Ahdaabhaeab`bbga@db`b`bbAadaaTaabhab`aag\n"
"Bb`bbiakbalBoa`Aedaabjaeab`bbia@db`b`bbAadaaTaabjab`aah\n"
"Bb`bbkakbalB`b`Acdaablaeab`bbka@db`b`bbAadaaTaablab`aai\n"
"Bb`bbmakbalBab`Aedaabnaeab`bbma@db`b`bbAadaaTaabnab`aaj\n"
"Bb`bboakbalBbb`Aedaab`beab`bboa@db`b`bbAadaaTaab`bb`aak\n"
"Bb`bbabkbalBcb`Agdaabbbeab`bbab@db`b`bbAadaaTaabbbb`aal\n"
"Bb`bbcbkbalBdb`Amdaabdbeab`bbcb@db`b`bbAadaaTaabdbb`aam\n"
"Bb`bbebkbalBeb`Akdaabfbeab`bbeb@db`b`bbAadaaTaabfbb`aan\n"
"Bb`bbgbkbalBfb`Aidaabhbeab`bbgb@db`b`bbAadaaTaabhbb`aao\n"
"Bb`bbibkbalBgb`Acdaabjbeab`bbib@db`baa`abjbb`b`bbaaaaTbab`a\n"
"Bb`bbkbbbaabkbb`bblbabcbjdBla`@dbkbTbabaa\n"
"BbadbmbdbboeacBeadahbnbgbbmbb`bbob`abnbb`bb`ck`bobAadaabaceab`bb`c@dTaabacbbabha\n"
"Bb`bbbcabcbjdBhb`@dAadbadbccdbboeacBaadahbdcgbbccaabeceaahbdcAjaTaabecbcabla\n"
"Bahbfcgbbmbb`bbgc`abfcb`bbhck`bgcAbdaabiceab`bbhc@dTaabicbeabda\n"
"Bb`bbjcabcbjdBib`@dAadTbabla\n"
"Bb`bbkck`bgcAhdaablceab`bbkc@dTaablcbgabfa\n"
"Bb`bbmcabcbjdBjb`@dAadTbabla\n"
"Bb`bbncabcbjdBkb`@dAadTbabla\n"
"BbadbocdbboeacBaadahb`dgbbocaabadeaahb`dAjaTaabadbjabia\n"
"BbadbbddbboeacBbadahbcdgbbbdaabddeaahbcdAfaTaabddbjabla\n"
"Bb`bbedk`bobB`adaabfdeab`bbed@dTaabfdblabka\n"
"Bb`bbgdabcbjdBjb`@dAadTbabla\n"
"Bb`bbhdabcbidBlb`@d@daabidnab`bbhdAadTaabidb`bbma\n"
"Baabjdnab`bbhdAbdTaabjdboabna\n"
"Baabkdeab`bbhdAbdTaabkdbcbbdb\n"
"Baabldeab`bbhdAadTaabldbbbbdb\n"
"Baabmdeab`bbhd@dTaabmdbabbdb\n"
"Bb`bbndabbafBmb`@dTbabdb\n"
"Bb`bbodabbafBnb`@dTbabdb\n"
"Bb`bb`eabbafBob`@dTbabdb\n"
"Bahbaegbaeaabbeeaahbae@aTaabbebfbbeb\n"
"BbcdbcedbboeacAddb`bbdegbbceaabeeeab`bbde@db`b`bbEamjnmd`Taabeebdcbfb\n"
"BbcdbfedbboeacAfdb`bbgegbbfebcdbhedbboeacAedb`bbiegbbheaabjeiab`bbgebieb`b`bbEbmjnmd`Taabjebdcbgb\n"
"Bb`bbkeab`bbdaableeab`bbiebkeb`b`bbEcmjnmd`Taablebhbbdc\n"
"Bb`bbmegbbfeb`bbneab`bcdaaboeeab`bbmebneb`b`bbEdmjnmd`Taaboebibbdc\n"
"Bbadb`fdbboeacAndahbafgbb`fb`bbbf`abafaabcflbb`bbdf`abcfaabefeab`bbbfbdfb`b`bbEemjnmd`Taabefbjbbdc\n"
"BbadbffdbboeacBaadahbgfgbbffb`bbhf`abgfb`bbifh`bhfBhadbadbjfdbboeacB`adahbkfgbbjfb`bblf`abkfb`bbmfh`blfBdadbadbnfdbboeacBcadahbofgbbnfb`bb`g`abofb`bbagh`b`gB`adb`bbbggbbheb`bbcgh`bbgAhdb`bbdggbbfeb`bbegl`bmfbifb`bbfgl`begbcgb`bbggl`bfgbdgb`bbhgl`bggbagb`bbigh`bbfBladbadbjgdbboeacAodahbkggbbjgb`bblg`abkgb`bbmgh`blgBhadbcdbngdbboeacAddb`bboggbbngb`bb`hl`bogbigb`bbahl`b`hbmgbadbbhdbboeacBeadahbchgbbbhb`bbdh`abchb`bbehh`bdhBhadbcdbfhdbboeacAcdb`bbghgbbfhb`bbhhl`behbghbcdbihdbboeac@db`bbjhgbbihaabkheab`bbhgbjhTaabkhblbbkb\n"
"Bb`bblhabaagbhgTcab`bEfmjnmd\n"
"BbcdbmhdbboeacAadb`bbnhgbbmhaaboheab`bbahbnhTaabohbnbbmb\n"
"Bb`bb`iabaagbahTcab`bEgmjnmd\n"
"BbcdbaidbboeacAbdb`bbbigbbaiaabcieab`bbhhbbiTaabcib`cbob\n"
"Bb`bbdiabaagbhhTcab`bEhmjnmd\n"
"Bb`bbeiabbaaHonnkm``odHm``oonnkdaabfieab`bbeiHhgfedcbadTaabfibbcbac\n"
"Bb`bbgiabaagbeiTcab`bEimjnmd\n"
"Bb`bbhiababcaDm``odaabiieab`bbhiDo``mdb`b`bbHnejkjgjmd`Taabiibdcbcc\n"
"Bb`bbjiabaagbhiTcab`bF`amjnmd\n"
"Bb`bbkibb`bkiTcab`bbkiE\n";
/* source-code for builtin_bc_startup: */
#if 0
const uint16_t __clambc_kind = BC_STARTUP;
@ -224,6 +223,5 @@ int entrypoint()
return 0xda7aba5e;
}
#endif
#endif

File diff suppressed because it is too large Load diff

View file

@ -72,7 +72,7 @@ struct cli_bc {
uint32_t numGlobalBytes;
uint8_t *globalBytes;
uint32_t sigtime_id, sigmatch_id;
char * hook_name;
char *hook_name;
};
struct cli_all_bc {
@ -123,12 +123,11 @@ void cli_bytevalue_describe(const struct cli_bc *bc, unsigned funcid);
void cli_byteinst_describe(const struct cli_bc_inst *inst, unsigned *bbnum);
void cli_bytefunc_describe(const struct cli_bc *bc, unsigned funcid);
/* Hooks */
struct cli_exe_info;
struct cli_ctx_tag;
struct cli_target_info;
int cli_bytecode_runlsig(struct cli_ctx_tag *ctx, struct cli_target_info *info, const struct cli_all_bc *bcs, unsigned bc_idx, const uint32_t* lsigcnt, const uint32_t *lsigsuboff, fmap_t *map);
int cli_bytecode_runlsig(struct cli_ctx_tag *ctx, struct cli_target_info *info, const struct cli_all_bc *bcs, unsigned bc_idx, const uint32_t *lsigcnt, const uint32_t *lsigsuboff, fmap_t *map);
int cli_bytecode_runhook(struct cli_ctx_tag *cctx, const struct cl_engine *engine, struct cli_bc_ctx *ctx, unsigned id, fmap_t *map);
#ifdef __cplusplus
@ -142,11 +141,11 @@ void cli_bytecode_printversion(void);
void cli_bytecode_debug_printsrc(const struct cli_bc_ctx *ctx);
void cli_printcxxver(void);
typedef void (*bc_dbg_callback_trace)(struct cli_bc_ctx*, unsigned event);
typedef void (*bc_dbg_callback_trace_op)(struct cli_bc_ctx*, const char *op);
typedef void (*bc_dbg_callback_trace_val)(struct cli_bc_ctx*, const char *name, uint32_t value);
typedef void (*bc_dbg_callback_trace_ptr)(struct cli_bc_ctx*, const void *val);
void cli_bytecode_context_set_trace(struct cli_bc_ctx*, unsigned level,
typedef void (*bc_dbg_callback_trace)(struct cli_bc_ctx *, unsigned event);
typedef void (*bc_dbg_callback_trace_op)(struct cli_bc_ctx *, const char *op);
typedef void (*bc_dbg_callback_trace_val)(struct cli_bc_ctx *, const char *name, uint32_t value);
typedef void (*bc_dbg_callback_trace_ptr)(struct cli_bc_ctx *, const void *val);
void cli_bytecode_context_set_trace(struct cli_bc_ctx *, unsigned level,
bc_dbg_callback_trace,
bc_dbg_callback_trace_op,
bc_dbg_callback_trace_val,

File diff suppressed because it is too large Load diff

View file

@ -42,7 +42,7 @@ struct cli_exe_section;
struct DISASM_RESULT;
#endif
/**
/**
\group_pe
* Invalid RVA specified
*/
@ -54,12 +54,12 @@ struct DISASM_RESULT;
*/
enum BytecodeKind {
/** generic bytecode, not tied a specific hook */
BC_GENERIC=0,
BC_GENERIC = 0,
/** triggered at startup, only one is allowed per ClamAV startup */
BC_STARTUP=1,
_BC_START_HOOKS=256,
BC_STARTUP = 1,
_BC_START_HOOKS = 256,
/** executed on a logical trigger */
BC_LOGICAL=256,
BC_LOGICAL = 256,
/** specifies a PE unpacker, executed on PE files on a logical trigger */
BC_PE_UNPACKER,
/** specifies a PDF hook, executes at a predetermined point of PDF parsing for PDF files */
@ -134,7 +134,7 @@ enum pdf_phase {
* PDF flags
*/
enum pdf_flag {
BAD_PDF_VERSION=0, /* */
BAD_PDF_VERSION = 0, /* */
BAD_PDF_HEADERPOS, /* */
BAD_PDF_TRAILER, /* */
BAD_PDF_TOOMANYOBJS, /* */
@ -162,7 +162,7 @@ enum pdf_flag {
* PDF obj flags
*/
enum pdf_objflags {
OBJ_STREAM=0, /* */
OBJ_STREAM = 0, /* */
OBJ_DICT, /* */
OBJ_EMBEDDED_FILE, /* */
OBJ_FILTER_AH, /* */
@ -194,7 +194,7 @@ enum pdf_objflags {
* JSON types
*/
enum bc_json_type {
JSON_TYPE_NULL=0, /* */
JSON_TYPE_NULL = 0, /* */
JSON_TYPE_BOOLEAN, /* */
JSON_TYPE_DOUBLE, /* */
JSON_TYPE_INT, /* */
@ -296,14 +296,14 @@ uint32_t test1(uint32_t a, uint32_t b);
* @param[out] data pointer to buffer where data is read into
* @return amount read.
*/
int32_t read(uint8_t *data, int32_t size);
int32_t read(uint8_t* data, int32_t size);
/**
\group_file
*/
enum {
/**set file position to specified absolute position */
SEEK_SET=0,
SEEK_SET = 0,
/**set file position relative to current position */
SEEK_CUR,
/**set file position relative to file end*/
@ -320,7 +320,7 @@ enum {
* byte
* @return amount of bytes successfully written
*/
int32_t write(uint8_t *data, int32_t size);
int32_t write(uint8_t* data, int32_t size);
/**
\group_file
@ -339,7 +339,7 @@ int32_t seek(int32_t pos, uint32_t whence);
* @param[in] len length of the virusname
* @return 0
*/
uint32_t setvirusname(const uint8_t *name, uint32_t len);
uint32_t setvirusname(const uint8_t* name, uint32_t len);
/**
\group_debug
@ -348,7 +348,7 @@ uint32_t setvirusname(const uint8_t *name, uint32_t len);
* @param[in] len length of message to print
* @return 0
*/
uint32_t debug_print_str(const uint8_t *str, uint32_t len);
uint32_t debug_print_str(const uint8_t* str, uint32_t len);
/**
\group_debug
@ -436,7 +436,7 @@ uint32_t test2(uint32_t a);
* @return 0 - success
* @return -1 - failure
*/
int32_t get_pe_section(struct cli_exe_section *section, uint32_t num);
int32_t get_pe_section(struct cli_exe_section* section, uint32_t num);
/**
\group_file
@ -564,7 +564,7 @@ uint32_t buffer_pipe_read_avail(int32_t id);
* specified amount
*/
//uint8_t *buffer_pipe_read_get(int32_t id, uint32_t amount);
const uint8_t *buffer_pipe_read_get(int32_t id, uint32_t amount);
const uint8_t* buffer_pipe_read_get(int32_t id, uint32_t amount);
/**
\group_adt
@ -593,7 +593,7 @@ uint32_t buffer_pipe_write_avail(int32_t id);
* @return pointer to write buffer, or NULL if requested amount
* is more than what is available in the buffer
*/
uint8_t *buffer_pipe_write_get(int32_t id, uint32_t size);
uint8_t* buffer_pipe_write_get(int32_t id, uint32_t size);
/**
\group_adt
@ -782,7 +782,7 @@ int32_t atoi(const uint8_t* str, int32_t size);
* @param[in] len length of \p str
* @return 0
*/
uint32_t debug_print_str_start(const uint8_t *str, uint32_t len);
uint32_t debug_print_str_start(const uint8_t* str, uint32_t len);
/**
\group_debug
@ -792,7 +792,7 @@ uint32_t debug_print_str_start(const uint8_t *str, uint32_t len);
* @param[in] len length of \p str
* @return 0
*/
uint32_t debug_print_str_nonl(const uint8_t *str, uint32_t len);
uint32_t debug_print_str_nonl(const uint8_t* str, uint32_t len);
/**
\group_string
@ -823,7 +823,7 @@ int32_t map_new(int32_t keysize, int32_t valuesize);
* @return 1 - if key didn't exist before
* @return <0 - if ksize doesn't match keysize specified at table creation
*/
int32_t map_addkey(const uint8_t *key, int32_t ksize, int32_t id);
int32_t map_addkey(const uint8_t* key, int32_t ksize, int32_t id);
/**
\group_adt
@ -834,7 +834,7 @@ int32_t map_addkey(const uint8_t *key, int32_t ksize, int32_t id);
* @return 0 - if update was successful
* @return <0 - if there is no last key
*/
int32_t map_setvalue(const uint8_t *value, int32_t vsize, int32_t id);
int32_t map_setvalue(const uint8_t* value, int32_t vsize, int32_t id);
/**
\group_adt
@ -903,7 +903,7 @@ int32_t map_done(int32_t id);
* match_pos + \p len < \p maxpos
* @return offset in the current file if match is found, -1 otherwise
*/
int32_t file_find_limit(const uint8_t *data, uint32_t len, int32_t maxpos);
int32_t file_find_limit(const uint8_t* data, uint32_t len, int32_t maxpos);
/* ------------- Engine Query ----------------------------------------------- */
/**
@ -971,7 +971,7 @@ int32_t input_switch(int32_t extracted_file);
* @param[in] len - size of \p env
* @return 0
*/
uint32_t get_environment(struct cli_environment *env, uint32_t len);
uint32_t get_environment(struct cli_environment* env, uint32_t len);
/**
\group_env
@ -984,7 +984,7 @@ uint32_t get_environment(struct cli_environment *env, uint32_t len);
* @return 1 - JIT disabled
* @return 2 - fully disabled
*/
uint32_t disable_bytecode_if(const int8_t *reason, uint32_t len, uint32_t cond);
uint32_t disable_bytecode_if(const int8_t* reason, uint32_t len, uint32_t cond);
/**
\group_env
@ -1077,7 +1077,7 @@ uint32_t pdf_getobjsize(int32_t objidx);
* @return NULL - invalid objidx/amount
* @return pointer - pointer to original object */
//uint8_t *pdf_getobj(int32_t objidx, uint32_t amount);
const uint8_t *pdf_getobj(int32_t objidx, uint32_t amount);
const uint8_t* pdf_getobj(int32_t objidx, uint32_t amount);
/**
\group_pdf
@ -1303,7 +1303,7 @@ int32_t json_get_int(int32_t objid);
* @param[in] scan_options enum value for desired scan option category.
* @return CL_SCAN_<OPTION>_* flags
*/
uint32_t engine_scan_options_ex(const uint8_t *option_name, uint32_t name_len);
uint32_t engine_scan_options_ex(const uint8_t* option_name, uint32_t name_len);
/* ----------------- END 0.101 APIs ---------------------------------- */
#endif

View file

@ -39,7 +39,8 @@
#include <sys/utsname.h>
#endif
#define CHECK_ARCH(a) if (!strcmp(TARGET_ARCH_TYPE, #a)) env->arch = arch_##a
#define CHECK_ARCH(a) \
if (!strcmp(TARGET_ARCH_TYPE, #a)) env->arch = arch_##a
extern int have_clamjit;
@ -61,13 +62,13 @@ static void cli_print_environment(struct cli_environment *env)
env->dconf_level,
env->big_endian,
env->sizeof_ptr,
(env->cpp_version >> 16)&0xff,
(env->cpp_version >> 8)&0xff,
env->cpp_version&0xff,
(env->cpp_version >> 16) & 0xff,
(env->cpp_version >> 8) & 0xff,
env->cpp_version & 0xff,
env->os_features,
(env->c_version >> 16)&0xff,
(env->c_version >> 8)&0xff,
env->c_version&0xff);
(env->c_version >> 16) & 0xff,
(env->c_version >> 8) & 0xff,
env->c_version & 0xff);
cli_dbgmsg("check_platform( OS CPU COM FL DCONF,BE PTR CXX VV.VV.VV, FLG CC VV.VV.VV)\n");
cli_dbgmsg("Engine version: %s\n", env->engine_version);
cli_dbgmsg("Host triple: %s\n", env->triple);
@ -93,7 +94,7 @@ static int detect_PaX(void)
while (fgets(line, sizeof(line), f)) {
if (!memcmp(line, "PaX:", 4)) {
pax = 1;
if (!strchr(line,'m'))
if (!strchr(line, 'm'))
pax = 2;
break;
}
@ -187,13 +188,13 @@ void cli_detect_environment(struct cli_environment *env)
#else
env->big_endian = 1;
#endif
env->sizeof_ptr = sizeof(void*);
env->sizeof_ptr = sizeof(void *);
/* -- Detect arch -- */
CHECK_ARCH(i386);
else CHECK_ARCH(x86_64);
else if (!strcmp(TARGET_ARCH_TYPE,"amd64")) env->arch = arch_x86_64;
else if (!strcmp(TARGET_ARCH_TYPE,"ppc")) env->arch = arch_ppc32;/* llvm will fix ppc64 */
else if (!strcmp(TARGET_ARCH_TYPE, "amd64")) env->arch = arch_x86_64;
else if (!strcmp(TARGET_ARCH_TYPE, "ppc")) env->arch = arch_ppc32; /* llvm will fix ppc64 */
else CHECK_ARCH(arm);
else CHECK_ARCH(sparc);
else CHECK_ARCH(sparc64);
@ -301,10 +302,10 @@ void cli_detect_environment(struct cli_environment *env)
INIT_STRFIELD(env->sysname, "Microsoft Windows");
else
INIT_STRFIELD(env->sysname, "Microsoft Windows Server");
snprintf((char*)env->release, sizeof(env->release), "%d.%d SP%d.%d",
snprintf((char *)env->release, sizeof(env->release), "%d.%d SP%d.%d",
info.dwMajorVersion, info.dwMinorVersion,
info.wServicePackMajor, info.wServicePackMinor);
snprintf((char*)env->version, sizeof(env->version),"Build %d",
snprintf((char *)env->version, sizeof(env->version), "Build %d",
info.dwBuildNumber);
}
}

View file

@ -28,7 +28,7 @@
#define BYTECODE_DETECT_H
/* mostly from m4/acinclude.m4 */
enum arch_list {
arch_unknown=0,
arch_unknown = 0,
arch_i386,
arch_x86_64,
arch_ppc32,
@ -47,7 +47,7 @@ enum arch_list {
/* from ClamAV's configure.in */
enum os_kind_conf {
os_unknown=0,
os_unknown = 0,
os_aix,
os_beos,
os_bsd,
@ -69,7 +69,7 @@ enum os_kind_conf {
};
enum os_kind_llvm {
llvm_os_UnknownOS=0,
llvm_os_UnknownOS = 0,
llvm_os_AuroraUX,
llvm_os_Cygwin,
llvm_os_Darwin,
@ -103,9 +103,9 @@ enum compiler_list {
};
enum endian_list {
endian_little=0,
endian_big=1,
endian_ANY=0xf
endian_little = 0,
endian_big = 1,
endian_ANY = 0xf
};
enum os_feature_bits {
@ -127,8 +127,8 @@ struct cli_environment {
uint32_t dconf_level;
int8_t engine_version[65];
/* detailed runtime info */
int8_t triple[65];/* LLVM only */
int8_t cpu[65];/* LLVM only */
int8_t triple[65]; /* LLVM only */
int8_t cpu[65]; /* LLVM only */
/* uname */
int8_t sysname[65];
int8_t release[65];
@ -138,8 +138,8 @@ struct cli_environment {
uint8_t big_endian;
uint8_t sizeof_ptr;
uint8_t arch;
uint8_t os_category;/* from configure */
uint8_t os;/* from LLVM if available */
uint8_t os_category; /* from configure */
uint8_t os; /* from LLVM if available */
uint8_t compiler;
uint8_t has_jit_compiled;
uint8_t os_features;
@ -147,11 +147,12 @@ struct cli_environment {
};
#ifndef __CLAMBC__
#define MAKE_VERSION(a,b,c,d) ((a << 24) | (b << 16) | (c << 8) | d)
#define INIT_STRFIELD(field, value) do {\
strncpy((char*)(field), (value), sizeof(field)-1);\
(field)[sizeof(field)-1]=0;\
} while (0)
#define MAKE_VERSION(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | d)
#define INIT_STRFIELD(field, value) \
do { \
strncpy((char *)(field), (value), sizeof(field) - 1); \
(field)[sizeof(field) - 1] = 0; \
} while (0)
#endif
void cli_detect_env_jit(struct cli_environment *env);

View file

@ -33,7 +33,7 @@
int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
{
unsigned i;
for (i=0;i<bcs->count;i++) {
for (i = 0; i < bcs->count; i++) {
if (bcs->all_bcs[i].state == bc_skip)
continue;
if (bcs->all_bcs[i].state != bc_loaded &&
@ -68,7 +68,8 @@ int cli_bytecode_done_jit(struct cli_all_bc *allbc, int partial)
return CL_SUCCESS;
}
void cli_bytecode_debug(int argc, char **argv) {
void cli_bytecode_debug(int argc, char **argv)
{
/* Empty */
UNUSEDPARAM(argc);
UNUSEDPARAM(argv);
@ -79,14 +80,16 @@ int bytecode_init(void)
return 0;
}
void cli_bytecode_debug_printsrc(const struct cli_bc_ctx *ctx) {
void cli_bytecode_debug_printsrc(const struct cli_bc_ctx *ctx)
{
/* Empty */
UNUSEDPARAM(ctx);
}
void cli_bytecode_printversion(void) {
void cli_bytecode_printversion(void)
{
printf("LLVM is not compiled or not linked\n");
}
int have_clamjit=0;
int have_clamjit = 0;
void cli_printcxxver()
{
/* Empty */

View file

@ -39,8 +39,8 @@ typedef uint16_t bbid_t;
typedef uint16_t funcid_t;
struct cli_bc_callop {
operand_t* ops;
uint16_t* opsizes;
operand_t *ops;
uint16_t *opsizes;
funcid_t funcid;
uint8_t numOps;
};
@ -54,7 +54,7 @@ struct branch {
struct cli_bc_cast {
uint64_t mask;
operand_t source;
uint8_t size;/* 0: 1-bit, 1: 8b, 2: 16b, 3: 32b, 4: 64b */
uint8_t size; /* 0: 1-bit, 1: 8b, 2: 16b, 3: 32b, 4: 64b */
};
typedef uint8_t interp_op_t;
@ -62,7 +62,7 @@ struct cli_bc_inst {
enum bc_opcode opcode;
uint16_t type;
operand_t dest;
interp_op_t interp_op;/* opcode for interpreter */
interp_op_t interp_op; /* opcode for interpreter */
union {
operand_t unaryop;
struct cli_bc_cast cast;
@ -83,9 +83,9 @@ struct cli_bc_func {
uint8_t numArgs;
uint16_t numLocals;
uint32_t numInsts;
uint32_t numValues;/* without constants */
uint32_t numValues; /* without constants */
uint32_t numConstants;
uint32_t numBytes;/* stack size */
uint32_t numBytes; /* stack size */
uint16_t numBB;
uint16_t returnType;
uint16_t *types;
@ -105,12 +105,12 @@ struct cli_bc_dbgnode_element {
struct cli_bc_dbgnode {
unsigned numelements;
struct cli_bc_dbgnode_element* elements;
struct cli_bc_dbgnode_element *elements;
};
#define MAX_OP ~0u
enum trace_level {
trace_none=0,
trace_none = 0,
trace_func,
trace_param,
trace_scope,
@ -162,7 +162,7 @@ enum bc_events {
};
struct cli_bc_ctx {
uint8_t timeout;/* must be first byte in struct! */
uint8_t timeout; /* must be first byte in struct! */
uint16_t funcid;
unsigned numParams;
/* id and params of toplevel function called */
@ -185,7 +185,7 @@ struct cli_bc_ctx {
uint32_t lsigoff[64];
uint32_t pdf_nobjs;
struct pdf_obj **pdf_objs;
uint32_t* pdf_flags;
uint32_t *pdf_flags;
uint32_t pdf_size;
uint32_t pdf_startoff;
unsigned pdf_phase;
@ -210,14 +210,14 @@ struct cli_bc_ctx {
unsigned line;
unsigned col;
mpool_t *mpool;
struct bc_inflate* inflates;
struct bc_inflate *inflates;
struct bc_buffer *buffers;
unsigned nbuffers;
unsigned nhashsets;
unsigned njsnorms;
unsigned jsnormwritten;
struct cli_hashset *hashsets;
struct bc_jsnorm* jsnorms;
struct bc_jsnorm *jsnorms;
char *jsnormdir;
struct cli_map *maps;
unsigned nmaps;

File diff suppressed because it is too large Load diff

View file

@ -39,7 +39,9 @@ static pthread_mutex_t pool_mutex = PTHREAD_MUTEX_INITIALIZER;
#define pthread_mutex_lock(x) 0
#define pthread_mutex_unlock(x)
#define pthread_mutex_init(a, b) 0
#define pthread_mutex_destroy(a) do { } while(0)
#define pthread_mutex_destroy(a) \
do { \
} while (0)
#endif
/* The number of root trees and the chooser function
@ -47,7 +49,10 @@ static pthread_mutex_t pool_mutex = PTHREAD_MUTEX_INITIALIZER;
/* #define TREES 1 */
/* static inline unsigned int getkey(uint8_t *hash) { return 0; } */
#define TREES 256
static inline unsigned int getkey(uint8_t *hash) { return *hash; }
static inline unsigned int getkey(uint8_t *hash)
{
return *hash;
}
/* #define TREES 4096 */
/* static inline unsigned int getkey(uint8_t *hash) { return hash[0] | ((unsigned int)(hash[1] & 0xf)<<8) ; } */
/* #define TREES 65536 */
@ -56,7 +61,6 @@ static inline unsigned int getkey(uint8_t *hash) { return *hash; }
/* The number of nodes in each tree */
#define NODES 256
/* The replacement policy algorithm to use */
/* #define USE_LRUHASHCACHE */
#define USE_SPLAY
@ -112,7 +116,7 @@ static inline int cacheset_lookup_internal(struct cache_set *map,
const char *md5, size_t size,
uint32_t *insert_pos, int deletedok)
{
const struct cache_key*data = map->data;
const struct cache_key *data = map->data;
uint32_t capmask = NODES - 1;
const struct cache_key *k;
uint32_t idx, tries = 0;
@ -166,7 +170,6 @@ static inline void lru_addtail(struct cache_set *map, struct cache_key *newkey)
map->lru_tail = newkey;
}
static void cacheset_add(struct cache_set *map, unsigned char *md5, size_t size, mpool_t *mempool);
static int cacheset_init(struct cache_set *map, mpool_t *mempool);
@ -183,8 +186,8 @@ static void cacheset_rehash(struct cache_set *map, mpool_t *mempool)
return;
key = map->lru_head;
for (i=0;key && i < tmp_set.maxelements/2;i++) {
cacheset_add(&tmp_set, (unsigned char*)&key->digest, key->size, mempool);
for (i = 0; key && i < tmp_set.maxelements / 2; i++) {
cacheset_add(&tmp_set, (unsigned char *)&key->digest, key->size, mempool);
key = key->lru_next;
}
pthread_mutex_lock(&pool_mutex);
@ -262,7 +265,8 @@ static int cacheset_lookup(struct cache_set *map, unsigned char *md5, size_t siz
return 1;
}
static int cacheset_init(struct cache_set *map, mpool_t *mempool) {
static int cacheset_init(struct cache_set *map, mpool_t *mempool)
{
map->data = mpool_calloc(mempool, NODES, sizeof(*map->data));
if (!map->data)
return CL_EMEM;
@ -273,7 +277,8 @@ static int cacheset_init(struct cache_set *map, mpool_t *mempool) {
return 0;
}
static inline void cacheset_destroy(struct cache_set *cs, mpool_t *mempool) {
static inline void cacheset_destroy(struct cache_set *cs, mpool_t *mempool)
{
mpool_free(mempool, cs->data);
cs->data = NULL;
}
@ -302,43 +307,45 @@ struct cache_set { /* a tree */
};
/* Allocates all the nodes and sets up the replacement chain */
static int cacheset_init(struct cache_set *cs, mpool_t *mempool) {
static int cacheset_init(struct cache_set *cs, mpool_t *mempool)
{
unsigned int i;
cs->data = mpool_calloc(mempool, NODES, sizeof(*cs->data));
cs->root = NULL;
if(!cs->data)
if (!cs->data)
return 1;
for(i=1; i<NODES; i++) {
cs->data[i-1].next = &cs->data[i];
cs->data[i].prev = &cs->data[i-1];
for (i = 1; i < NODES; i++) {
cs->data[i - 1].next = &cs->data[i];
cs->data[i].prev = &cs->data[i - 1];
}
cs->first = cs->data;
cs->last = &cs->data[NODES-1];
cs->last = &cs->data[NODES - 1];
return 0;
}
/* Frees all the nodes */
static inline void cacheset_destroy(struct cache_set *cs, mpool_t *mempool) {
static inline void cacheset_destroy(struct cache_set *cs, mpool_t *mempool)
{
mpool_free(mempool, cs->data);
cs->data = NULL;
}
/* The left/right cooser for the splay tree */
static inline int cmp(int64_t *a, ssize_t sa, int64_t *b, ssize_t sb) {
if(a[1] < b[1]) return -1;
if(a[1] > b[1]) return 1;
if(a[0] < b[0]) return -1;
if(a[0] > b[0]) return 1;
if(sa < sb) return -1;
if(sa > sb) return 1;
static inline int cmp(int64_t *a, ssize_t sa, int64_t *b, ssize_t sb)
{
if (a[1] < b[1]) return -1;
if (a[1] > b[1]) return 1;
if (a[0] < b[0]) return -1;
if (a[0] > b[0]) return 1;
if (sa < sb) return -1;
if (sa > sb) return 1;
return 0;
}
/* #define PRINT_TREE */
#ifdef PRINT_TREE
#define ptree printf
@ -349,55 +356,59 @@ static inline int cmp(int64_t *a, ssize_t sa, int64_t *b, ssize_t sb) {
/* Debug function to print the tree and check its consistency */
/* #define CHECK_TREE */
#ifdef CHECK_TREE
static int printtree(struct cache_set *cs, struct node *n, int d) {
static int printtree(struct cache_set *cs, struct node *n, int d)
{
int i;
int ab = 0;
if ((n == NULL) || (cs == NULL) || (cs->data == NULL)) return 0;
if(n == cs->root) { ptree("--------------------------\n"); }
ab |= printtree(cs, n->right, d+1);
if(n->right) {
if(cmp(n->digest, n->size, n->right->digest, n->right->size) >= 0) {
for (i=0; i<d; i++) ptree(" ");
if (n == cs->root) {
ptree("--------------------------\n");
}
ab |= printtree(cs, n->right, d + 1);
if (n->right) {
if (cmp(n->digest, n->size, n->right->digest, n->right->size) >= 0) {
for (i = 0; i < d; i++) ptree(" ");
ptree("^^^^ %lld >= %lld\n", n->digest[1], n->right->digest[1]);
ab = 1;
}
}
for (i=0; i<d; i++) ptree(" ");
ptree("%08x(%02u)\n", n->digest[1]>>48, n - cs->data);
if(n->left) {
if(cmp(n->digest, n->size, n->left->digest, n->left->size) <= 0) {
for (i=0; i<d; i++) ptree(" ");
for (i = 0; i < d; i++) ptree(" ");
ptree("%08x(%02u)\n", n->digest[1] >> 48, n - cs->data);
if (n->left) {
if (cmp(n->digest, n->size, n->left->digest, n->left->size) <= 0) {
for (i = 0; i < d; i++) ptree(" ");
ptree("vvvv %lld <= %lld\n", n->digest[1], n->left->digest[1]);
ab = 1;
}
}
if(d){
if(!n->up) {
if (d) {
if (!n->up) {
printf("no parent, [node %02u]!\n", n - cs->data);
ab = 1;
} else {
if(n->up->left != n && n->up->right != n) {
if (n->up->left != n && n->up->right != n) {
printf("broken parent [node %02u, parent node %02u]\n", n - cs->data, n->up - cs->data);
ab = 1;
}
}
} else {
if(n->up) {
if (n->up) {
printf("root with a parent, [node %02u]!\n", n - cs->data);
ab = 1;
}
}
ab |= printtree(cs, n->left, d+1);
ab |= printtree(cs, n->left, d + 1);
return ab;
}
#else
#define printtree(a,b,c) (0)
#define printtree(a, b, c) (0)
#endif
/* For troubleshooting only; prints out one specific node */
/* #define PRINT_NODE */
#ifdef PRINT_NODE
static void printnode(const char *prefix, struct cache_set *cs, struct node *n) {
static void printnode(const char *prefix, struct cache_set *cs, struct node *n)
{
if (!prefix || !cs || !cs->data) {
printf("bad args!\n");
return;
@ -409,101 +420,103 @@ static void printnode(const char *prefix, struct cache_set *cs, struct node *n)
printf("%s node [%02u]:", prefix, n - cs->data);
printf(" size=%lu digest=%llx,%llx\n", (unsigned long)(n->size), n->digest[0], n->digest[1]);
printf("\tleft=");
if(n->left)
if (n->left)
printf("%02u ", n->left - cs->data);
else
printf("NULL ");
printf("right=");
if(n->right)
if (n->right)
printf("%02u ", n->right - cs->data);
else
printf("NULL ");
printf("up=");
if(n->up)
if (n->up)
printf("%02u ", n->up - cs->data);
else
printf("NULL ");
printf("\tprev=");
if(n->prev)
if (n->prev)
printf("%02u ", n->prev - cs->data);
else
printf("NULL ");
printf("next=");
if(n->next)
if (n->next)
printf("%02u\n", n->next - cs->data);
else
printf("NULL\n");
}
#else
#define printnode(a,b,c) (0)
#define printnode(a, b, c) (0)
#endif
/* #define PRINT_CHAINS */
#ifdef PRINT_CHAINS
/* For troubleshooting only, print the chain forwards and back */
static inline void printchain(const char *prefix, struct cache_set *cs) {
static inline void printchain(const char *prefix, struct cache_set *cs)
{
if (!cs || !cs->data) return;
if (prefix) printf("%s: ", prefix);
printf("chain by next: ");
{
unsigned int i = 0;
struct node *x = cs->first;
while(x) {
while (x) {
printf("%02d,", x - cs->data);
x=x->next;
x = x->next;
i++;
}
printf(" [count=%u]\nchain by prev: ", i);
x=cs->last;
i=0;
while(x) {
x = cs->last;
i = 0;
while (x) {
printf("%02d,", x - cs->data);
x=x->prev;
x = x->prev;
i++;
}
printf(" [count=%u]\n", i);
}
}
#else
#define printchain(a,b) (0)
#define printchain(a, b) (0)
#endif
/* Looks up a node and splays it up to the root of the tree */
static int splay(int64_t *md5, size_t len, struct cache_set *cs) {
static int splay(int64_t *md5, size_t len, struct cache_set *cs)
{
struct node next = {{0, 0}, NULL, NULL, NULL, NULL, NULL, 0, 0}, *right = &next, *left = &next, *temp, *root = cs->root;
int comp, found = 0;
if(!root)
if (!root)
return 0;
while(1) {
while (1) {
comp = cmp(md5, len, root->digest, root->size);
if(comp < 0) {
if(!root->left) break;
if(cmp(md5, len, root->left->digest, root->left->size) < 0) {
if (comp < 0) {
if (!root->left) break;
if (cmp(md5, len, root->left->digest, root->left->size) < 0) {
temp = root->left;
root->left = temp->right;
if(temp->right) temp->right->up = root;
if (temp->right) temp->right->up = root;
temp->right = root;
root->up = temp;
root = temp;
if(!root->left) break;
if (!root->left) break;
}
right->left = root;
root->up = right;
right = root;
root = root->left;
} else if(comp > 0) {
if(!root->right) break;
if(cmp(md5, len, root->right->digest, root->right->size) > 0) {
} else if (comp > 0) {
if (!root->right) break;
if (cmp(md5, len, root->right->digest, root->right->size) > 0) {
temp = root->right;
root->right = temp->left;
if(temp->left) temp->left->up = root;
if (temp->left) temp->left->up = root;
temp->left = root;
root->up = temp;
root = temp;
if(!root->right) break;
if (!root->right) break;
}
left->right = root;
root->up = left;
@ -516,32 +529,32 @@ static int splay(int64_t *md5, size_t len, struct cache_set *cs) {
}
left->right = root->left;
if(root->left) root->left->up = left;
if (root->left) root->left->up = left;
right->left = root->right;
if(root->right) root->right->up = right;
if (root->right) root->right->up = right;
root->left = next.right;
if(next.right) next.right->up = root;
if (next.right) next.right->up = root;
root->right = next.left;
if(next.left) next.left->up = root;
if (next.left) next.left->up = root;
root->up = NULL;
cs->root = root;
return found;
}
/* Looks up an hash in the tree and maintains the replacement chain */
static inline int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size, uint32_t reclevel) {
static inline int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size, uint32_t reclevel)
{
int64_t hash[2];
memcpy(hash, md5, 16);
if(splay(hash, size, cs)) {
if (splay(hash, size, cs)) {
struct node *o = cs->root->prev, *p = cs->root, *q = cs->root->next;
#ifdef PRINT_CHAINS
printf("promoting %02d\n", p - cs->data);
printchain("before", cs);
#endif
if(q) {
if(o)
if (q) {
if (o)
o->next = q;
else
cs->first = q;
@ -554,7 +567,7 @@ static inline int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size
#ifdef PRINT_CHAINS
printchain("after", cs);
#endif
if(reclevel >= p->minrec)
if (reclevel >= p->minrec)
return 1;
}
return 0;
@ -563,54 +576,54 @@ static inline int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size
/* If the hash is present nothing happens.
Otherwise a new node is created for the hash picking one from the begin of the chain.
Used nodes are moved to the end of the chain */
static inline void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t size, uint32_t reclevel) {
static inline void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t size, uint32_t reclevel)
{
struct node *newnode;
int64_t hash[2];
memcpy(hash, md5, 16);
if(splay(hash, size, cs)) {
if(cs->root->minrec > reclevel)
if (splay(hash, size, cs)) {
if (cs->root->minrec > reclevel)
cs->root->minrec = reclevel;
return; /* Already there */
}
ptree("1:\n");
if(printtree(cs, cs->root, 0)) {
if (printtree(cs, cs->root, 0)) {
cli_errmsg("cacheset_add: inconsistent tree before choosing newnode, good luck\n");
return;
}
newnode = cs->first;
while(newnode) {
if(!newnode->right && !newnode->left)
while (newnode) {
if (!newnode->right && !newnode->left)
break;
if(newnode->next) {
if(newnode == newnode->next) {
if (newnode->next) {
if (newnode == newnode->next) {
cli_errmsg("cacheset_add: cache chain in a bad state\n");
return;
}
newnode = newnode->next;
}
else {
} else {
cli_warnmsg("cacheset_add: end of chain reached\n");
return;
}
}
if(!newnode) {
if (!newnode) {
cli_errmsg("cacheset_add: tree has got no end nodes\n");
return;
}
if(newnode->up) {
if(newnode->up->left == newnode)
if (newnode->up) {
if (newnode->up->left == newnode)
newnode->up->left = NULL;
else
newnode->up->right = NULL;
}
if(newnode->prev)
if (newnode->prev)
newnode->prev->next = newnode->next;
if(newnode->next)
if (newnode->next)
newnode->next->prev = newnode->prev;
if(cs->first == newnode)
if (cs->first == newnode)
cs->first = newnode->next;
newnode->prev = cs->last;
@ -619,16 +632,16 @@ static inline void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t
cs->last = newnode;
ptree("2:\n");
if(printtree(cs, cs->root, 0)) {
if (printtree(cs, cs->root, 0)) {
cli_errmsg("cacheset_add: inconsistent tree before adding newnode, good luck\n");
return;
}
if(!cs->root) {
if (!cs->root) {
newnode->left = NULL;
newnode->right = NULL;
} else {
if(cmp(hash, size, cs->root->digest, cs->root->size) < 0) {
if (cmp(hash, size, cs->root->digest, cs->root->size) < 0) {
newnode->left = cs->root->left;
newnode->right = cs->root;
cs->root->left = NULL;
@ -637,8 +650,8 @@ static inline void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t
newnode->left = cs->root;
cs->root->right = NULL;
}
if(newnode->left) newnode->left->up = newnode;
if(newnode->right) newnode->right->up = newnode;
if (newnode->left) newnode->left->up = newnode;
if (newnode->right) newnode->right->up = newnode;
}
newnode->digest[0] = hash[0];
newnode->digest[1] = hash[1];
@ -648,7 +661,7 @@ static inline void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t
cs->root = newnode;
ptree("3: %lld\n", hash[1]);
if(printtree(cs, cs->root, 0)) {
if (printtree(cs, cs->root, 0)) {
cli_errmsg("cacheset_add: inconsistent tree after adding newnode, good luck\n");
return;
}
@ -658,13 +671,14 @@ static inline void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t
/* If the hash is not present nothing happens other than splaying the tree.
Otherwise the identified node is removed from the tree and then placed back at
the front of the chain. */
static inline void cacheset_remove(struct cache_set *cs, unsigned char *md5, size_t size) {
static inline void cacheset_remove(struct cache_set *cs, unsigned char *md5, size_t size)
{
struct node *targetnode;
struct node *reattachnode;
int64_t hash[2];
memcpy(hash, md5, 16);
if(splay(hash, size, cs) != 1) {
if (splay(hash, size, cs) != 1) {
cli_dbgmsg("cacheset_remove: node not found in tree\n");
return; /* No op */
}
@ -674,13 +688,12 @@ static inline void cacheset_remove(struct cache_set *cs, unsigned char *md5, siz
printnode("targetnode", cs, targetnode);
/* First fix the tree */
if(targetnode->left == NULL) {
if (targetnode->left == NULL) {
/* At left edge so prune */
cs->root = targetnode->right;
if(cs->root)
if (cs->root)
cs->root->up = NULL;
}
else {
} else {
/* new root will come from leftside tree */
cs->root = targetnode->left;
cs->root->up = NULL;
@ -704,17 +717,17 @@ static inline void cacheset_remove(struct cache_set *cs, unsigned char *md5, siz
targetnode->right = NULL;
/* Tree is fixed, so now fix chain around targetnode */
if(targetnode->prev)
if (targetnode->prev)
targetnode->prev->next = targetnode->next;
if(targetnode->next)
if (targetnode->next)
targetnode->next->prev = targetnode->prev;
if(cs->last == targetnode)
if (cs->last == targetnode)
cs->last = targetnode->prev;
/* Put targetnode at front of chain, if not there already */
if(cs->first != targetnode) {
if (cs->first != targetnode) {
targetnode->next = cs->first;
if(cs->first)
if (cs->first)
cs->first->prev = targetnode;
cs->first = targetnode;
}
@ -728,7 +741,6 @@ static inline void cacheset_remove(struct cache_set *cs, unsigned char *md5, siz
}
#endif /* USE_SPLAY */
/* COMMON STUFF --------------------------------------------------------------------- */
struct CACHE {
@ -739,11 +751,12 @@ struct CACHE {
};
/* Allocates the trees for the engine cache */
int cli_cache_init(struct cl_engine *engine) {
int cli_cache_init(struct cl_engine *engine)
{
struct CACHE *cache;
unsigned int i, j;
if(!engine) {
if (!engine) {
cli_errmsg("cli_cache_init: mpool malloc fail\n");
return 1;
}
@ -753,22 +766,22 @@ int cli_cache_init(struct cl_engine *engine) {
return 0;
}
if(!(cache = mpool_malloc(engine->mempool, sizeof(struct CACHE) * TREES))) {
if (!(cache = mpool_malloc(engine->mempool, sizeof(struct CACHE) * TREES))) {
cli_errmsg("cli_cache_init: mpool malloc fail\n");
return 1;
}
for(i=0; i<TREES; i++) {
if(pthread_mutex_init(&cache[i].mutex, NULL)) {
for (i = 0; i < TREES; i++) {
if (pthread_mutex_init(&cache[i].mutex, NULL)) {
cli_errmsg("cli_cache_init: mutex init fail\n");
for(j=0; j<i; j++) cacheset_destroy(&cache[j].cacheset, engine->mempool);
for(j=0; j<i; j++) pthread_mutex_destroy(&cache[j].mutex);
for (j = 0; j < i; j++) cacheset_destroy(&cache[j].cacheset, engine->mempool);
for (j = 0; j < i; j++) pthread_mutex_destroy(&cache[j].mutex);
mpool_free(engine->mempool, cache);
return 1;
}
if(cacheset_init(&cache[i].cacheset, engine->mempool)) {
for(j=0; j<i; j++) cacheset_destroy(&cache[j].cacheset, engine->mempool);
for(j=0; j<=i; j++) pthread_mutex_destroy(&cache[j].mutex);
if (cacheset_init(&cache[i].cacheset, engine->mempool)) {
for (j = 0; j < i; j++) cacheset_destroy(&cache[j].cacheset, engine->mempool);
for (j = 0; j <= i; j++) pthread_mutex_destroy(&cache[j].mutex);
mpool_free(engine->mempool, cache);
return 1;
}
@ -778,18 +791,19 @@ int cli_cache_init(struct cl_engine *engine) {
}
/* Frees the engine cache */
void cli_cache_destroy(struct cl_engine *engine) {
void cli_cache_destroy(struct cl_engine *engine)
{
struct CACHE *cache;
unsigned int i;
if(!engine || !(cache = engine->cache))
if (!engine || !(cache = engine->cache))
return;
if (engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) {
return;
}
for(i=0; i<TREES; i++) {
for (i = 0; i < TREES; i++) {
cacheset_destroy(&cache[i].cacheset, engine->mempool);
pthread_mutex_destroy(&cache[i].mutex);
}
@ -797,13 +811,14 @@ void cli_cache_destroy(struct cl_engine *engine) {
}
/* Looks up an hash in the proper tree */
static int cache_lookup_hash(unsigned char *md5, size_t len, struct CACHE *cache, uint32_t reclevel) {
static int cache_lookup_hash(unsigned char *md5, size_t len, struct CACHE *cache, uint32_t reclevel)
{
unsigned int key = getkey(md5);
int ret = CL_VIRUS;
struct CACHE *c;
c = &cache[key];
if(pthread_mutex_lock(&c->mutex)) {
if (pthread_mutex_lock(&c->mutex)) {
cli_errmsg("cache_lookup_hash: cache_lookup_hash: mutex lock fail\n");
return ret;
}
@ -817,12 +832,13 @@ static int cache_lookup_hash(unsigned char *md5, size_t len, struct CACHE *cache
}
/* Adds an hash to the cache */
void cache_add(unsigned char *md5, size_t size, cli_ctx *ctx) {
void cache_add(unsigned char *md5, size_t size, cli_ctx *ctx)
{
unsigned int key = getkey(md5);
uint32_t level;
struct CACHE *c;
if(!ctx || !ctx->engine || !ctx->engine->cache)
if (!ctx || !ctx->engine || !ctx->engine->cache)
return;
if (ctx->engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) {
@ -838,7 +854,7 @@ void cache_add(unsigned char *md5, size_t size, cli_ctx *ctx) {
return;
}
c = &ctx->engine->cache[key];
if(pthread_mutex_lock(&c->mutex)) {
if (pthread_mutex_lock(&c->mutex)) {
cli_errmsg("cli_add: mutex lock fail\n");
return;
}
@ -861,11 +877,12 @@ void cache_add(unsigned char *md5, size_t size, cli_ctx *ctx) {
}
/* Removes a hash from the cache */
void cache_remove(unsigned char *md5, size_t size, const struct cl_engine *engine) {
void cache_remove(unsigned char *md5, size_t size, const struct cl_engine *engine)
{
unsigned int key = getkey(md5);
struct CACHE *c;
if(!engine || !engine->cache)
if (!engine || !engine->cache)
return;
if (engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) {
@ -876,7 +893,7 @@ void cache_remove(unsigned char *md5, size_t size, const struct cl_engine *engin
/* cli_warnmsg("cache_remove: key is %u\n", key); */
c = &engine->cache[key];
if(pthread_mutex_lock(&c->mutex)) {
if (pthread_mutex_lock(&c->mutex)) {
cli_errmsg("cli_add: mutex lock fail\n");
return;
}
@ -909,11 +926,11 @@ int cache_get_MD5(unsigned char *hash, cli_ctx *ctx)
if (!(hashctx))
return CL_VIRUS;
while(todo) {
while (todo) {
const void *buf;
size_t readme = todo < FILEBUFF ? todo : FILEBUFF;
if(!(buf = fmap_need_off_once(map, at, readme))) {
if (!(buf = fmap_need_off_once(map, at, readme))) {
cl_hash_destroy(hashctx);
return CL_EREAD;
}
@ -936,11 +953,12 @@ int cache_get_MD5(unsigned char *hash, cli_ctx *ctx)
/* Hashes a file onto the provided buffer and looks it up the cache.
Returns CL_VIRUS if found, CL_CLEAN if not FIXME or a recoverable error,
and returns CL_EREAD if unrecoverable */
int cache_check(unsigned char *hash, cli_ctx *ctx) {
int cache_check(unsigned char *hash, cli_ctx *ctx)
{
fmap_t *map;
int ret;
if(!ctx || !ctx->engine || !ctx->engine->cache)
if (!ctx || !ctx->engine || !ctx->engine->cache)
return CL_VIRUS;
if (ctx->engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) {

View file

@ -32,7 +32,7 @@
#include <openssl/err.h>
/* Certain OSs already use 64bit variables in their stat struct */
#if ( !defined(__FreeBSD__) && !defined(__APPLE__) )
#if (!defined(__FreeBSD__) && !defined(__APPLE__))
#define STAT64_BLACKLIST 1
#else
#define STAT64_BLACKLIST 0
@ -46,7 +46,7 @@
#define CLAMSTAT stat64
#define LSTAT lstat64
#define FSTAT fstat64
#define safe_open(a, b) open(a, b|O_LARGEFILE)
#define safe_open(a, b) open(a, b | O_LARGEFILE)
#else
#define STATBUF struct stat
@ -68,8 +68,7 @@
#include "cltypes.h"
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#define CL_COUNT_PRECISION 4096
@ -110,7 +109,7 @@ typedef enum cl_error_t {
CL_EMAXFILES,
CL_EFORMAT,
CL_EPARSE,
CL_EBYTECODE,/* may be reported in testmode */
CL_EBYTECODE, /* may be reported in testmode */
CL_EBYTECODE_TESTFAIL, /* may be reported in testmode */
/* c4w error codes */
@ -308,13 +307,13 @@ enum cl_engine_field {
};
enum bytecode_security {
CL_BYTECODE_TRUST_ALL=0, /* obsolete */
CL_BYTECODE_TRUST_ALL = 0, /* obsolete */
CL_BYTECODE_TRUST_SIGNED, /* default */
CL_BYTECODE_TRUST_NOTHING /* paranoid setting */
};
enum bytecode_mode {
CL_BYTECODE_MODE_AUTO=0, /* JIT if possible, fallback to interpreter */
CL_BYTECODE_MODE_AUTO = 0, /* JIT if possible, fallback to interpreter */
CL_BYTECODE_MODE_JIT, /* force JIT */
CL_BYTECODE_MODE_INTERPRETER, /* force interpreter */
CL_BYTECODE_MODE_TEST, /* both JIT and interpreter, compare results, all failures are fatal */
@ -572,7 +571,7 @@ enum cl_msg {
/* leave room for more message levels in the future */
CL_MSG_INFO_VERBOSE = 32, /* verbose */
CL_MSG_WARN = 64, /* LibClamAV WARNING: */
CL_MSG_ERROR = 128/* LibClamAV ERROR: */
CL_MSG_ERROR = 128 /* LibClamAV ERROR: */
};
/**
@ -646,7 +645,7 @@ extern void cl_engine_set_clcb_hash(struct cl_engine *engine, clcb_hash callback
* @return CL_VIRUS to blacklist
* @return CL_CLEAN to continue scanning
*/
typedef cl_error_t (*clcb_meta)(const char* container_type, unsigned long fsize_container, const char *filename,
typedef cl_error_t (*clcb_meta)(const char *container_type, unsigned long fsize_container, const char *filename,
unsigned long fsize_real, int is_encrypted, unsigned int filepos_container, void *context);
/**
* @brief Set a custom archive metadata matching callback function.
@ -813,7 +812,7 @@ extern void cl_engine_set_clcb_stats_get_size(struct cl_engine *engine, clcb_sta
*
* @param cbdata The statistics data. Probably a pointer to a malloc'd struct.
*/
typedef char * (*clcb_stats_get_hostid)(void *cbdata);
typedef char *(*clcb_stats_get_hostid)(void *cbdata);
/**
* @brief Set a custom callback function to get the machine's unique host ID.
*
@ -844,7 +843,7 @@ extern void cl_engine_stats_enable(struct cl_engine *engine);
* @param scanoptions Scanning options.
* @return cl_error_t CL_CLEAN, CL_VIRUS, or an error code if an error occured during the scan.
*/
extern int cl_scandesc(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options* scanoptions);
extern int cl_scandesc(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions);
/**
* @brief Scan a file, given a file descriptor.
@ -860,7 +859,7 @@ extern int cl_scandesc(int desc, const char *filename, const char **virname, uns
* @param[in/out] context An opaque context structure allowing the caller to record details about the sample being scanned.
* @return cl_error_t CL_CLEAN, CL_VIRUS, or an error code if an error occured during the scan.
*/
extern int cl_scandesc_callback(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options* scanoptions, void *context);
extern int cl_scandesc_callback(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions, void *context);
/**
* @brief Scan a file, given a filename.
@ -872,7 +871,7 @@ extern int cl_scandesc_callback(int desc, const char *filename, const char **vir
* @param scanoptions Scanning options.
* @return cl_error_t CL_CLEAN, CL_VIRUS, or an error code if an error occured during the scan.
*/
extern int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options* scanoptions);
extern int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions);
/**
* @brief Scan a file, given a filename.
@ -887,7 +886,7 @@ extern int cl_scanfile(const char *filename, const char **virname, unsigned long
* @param[in/out] context An opaque context structure allowing the caller to record details about the sample being scanned.
* @return cl_error_t CL_CLEAN, CL_VIRUS, or an error code if an error occured during the scan.
*/
extern int cl_scanfile_callback(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options* scanoptions, void *context);
extern int cl_scanfile_callback(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions, void *context);
/* ----------------------------------------------------------------------------
* Database handling.
@ -1053,7 +1052,7 @@ typedef struct cl_fmap cl_fmap_t;
* end-of-file, zero is returned. Otherwise, a -1 is returned
* and the global variable errno is set to indicate the error.
*/
typedef off_t (*clcb_pread)(void* handle, void *buf, size_t count, off_t offset);
typedef off_t (*clcb_pread)(void *handle, void *buf, size_t count, off_t offset);
/**
* @brief Open a map given a handle.
@ -1072,7 +1071,7 @@ typedef off_t (*clcb_pread)(void* handle, void *buf, size_t count, off_t offset)
* @param pread_cb A callback function to read data from the handle.
* @return cl_fmap_t* A map representing the handle interface.
*/
extern cl_fmap_t *cl_fmap_open_handle(void* handle, size_t offset, size_t len,
extern cl_fmap_t *cl_fmap_open_handle(void *handle, size_t offset, size_t len,
clcb_pread, int use_aging);
/**
@ -1097,7 +1096,7 @@ extern cl_fmap_t *cl_fmap_open_memory(const void *start, size_t len);
*
* @param map Map to be closed.
*/
extern void cl_fmap_close(cl_fmap_t*);
extern void cl_fmap_close(cl_fmap_t *);
/**
* @brief Scan custom data.

View file

@ -29,7 +29,7 @@ struct bytecode_metadata {
uint64_t timestamp;
unsigned formatlevel;
unsigned minfunc, maxfunc;
unsigned maxresource;/* reserved */
unsigned maxresource; /* reserved */
unsigned targetExclude;
};
@ -38,7 +38,7 @@ struct bytecode_metadata {
#define BC_HEADER "ClamBC"
enum bc_opcode {
OP_BC_ADD=1,
OP_BC_ADD = 1,
OP_BC_SUB,
OP_BC_MUL,
OP_BC_UDIV,
@ -117,8 +117,7 @@ static const unsigned char operand_counts[] = {
/* OP_BC_ISBIGENDIAN */
0,
/* OP_BC_ABORT, OP_BSWAP*, OP_PTRDIFF32, OP_PTRINT64 */
0, 1, 1, 1, 2, 1
};
0, 1, 1, 1, 2, 1};
enum bc_global {
_FIRST_GLOBAL = 0x8000,

View file

@ -39,31 +39,31 @@
#elif defined(_MSC_VER)
#include <stdint.h>
#else
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned char uint8_t;
#if SIZEOF_INT == 2
typedef signed int int16_t;
typedef unsigned int uint16_t;
typedef signed int int16_t;
typedef unsigned int uint16_t;
#elif SIZEOF_SHORT == 2
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
#endif
#if SIZEOF_INT == 4
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
#elif SIZEOF_LONG == 4
typedef signed long int32_t;
typedef unsigned long uint32_t;
typedef signed long int32_t;
typedef unsigned long uint32_t;
#endif
#if SIZEOF_LONG == 8
typedef signed long int64_t;
typedef unsigned long uint64_t;
typedef signed long int64_t;
typedef unsigned long uint64_t;
#elif SIZEOF_LONG_LONG == 8
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#endif
#endif

View file

@ -47,16 +47,16 @@
*/
static size_t base64_len(const char *data, size_t len)
{
int padding=0;
int padding = 0;
size_t i;
if (!len)
return 0;
for (i=len-1; i > 0 && data[i] == '='; i--)
for (i = len - 1; i > 0 && data[i] == '='; i--)
padding++;
return (size_t)((3*len)/4 - padding);
return (size_t)((3 * len) / 4 - padding);
}
/** Decode a base64-encoded string
@ -71,7 +71,7 @@ void *cl_base64_decode(char *data, size_t len, void *obuf, size_t *olen, int one
BIO *bio, *b64;
void *buf;
buf = (obuf) ? obuf : malloc(base64_len(data, len)+1);
buf = (obuf) ? obuf : malloc(base64_len(data, len) + 1);
if (!(buf))
return NULL;
@ -130,7 +130,7 @@ char *cl_base64_encode(void *data, size_t len)
elen = (size_t)BIO_get_mem_data(bio, &buf);
/* Ensure we're dealing with a NULL-terminated string */
p = (char *)malloc(elen+1);
p = (char *)malloc(elen + 1);
if (NULL == p) {
BIO_free(b64);
return NULL;
@ -151,7 +151,7 @@ int main(int argc, char *argv[])
char *plaintext, *encoded, *decoded;
unsigned char *sha_plaintext, *sha_decoded;
size_t len;
int ret=0;
int ret = 0;
unsigned int shalen;
initialize_crypto();

View file

@ -89,8 +89,8 @@ struct cpio_hdr_newc {
static void sanitname(char *name)
{
while(*name) {
if(!isascii(*name) || strchr("%\\\t\n\r", *name))
while (*name) {
if (!isascii(*name) || strchr("%\\\t\n\r", *name))
*name = '_';
name++;
}
@ -106,17 +106,16 @@ int cli_scancpio_old(cli_ctx *ctx)
off_t pos = 0;
int virus_found = 0;
while(fmap_readn(*ctx->fmap, &hdr_old, pos, sizeof(hdr_old)) == sizeof(hdr_old)) {
while (fmap_readn(*ctx->fmap, &hdr_old, pos, sizeof(hdr_old)) == sizeof(hdr_old)) {
pos += sizeof(hdr_old);
if(!hdr_old.magic && trailer) {
if (!hdr_old.magic && trailer) {
ret = CL_SUCCESS;
goto leave;
}
if(hdr_old.magic == 070707) {
if (hdr_old.magic == 070707) {
conv = 0;
} else if(hdr_old.magic == 0143561) {
} else if (hdr_old.magic == 0143561) {
conv = 1;
} else {
cli_dbgmsg("cli_scancpio_old: Invalid magic number\n");
@ -126,7 +125,7 @@ int cli_scancpio_old(cli_ctx *ctx)
cli_dbgmsg("CPIO: -- File %u --\n", ++file);
if(hdr_old.namesize) {
if (hdr_old.namesize) {
hdr_namesize = EC16(hdr_old.namesize, conv);
namesize = MIN(sizeof(name), hdr_namesize);
if ((uint32_t)fmap_readn(*ctx->fmap, &name, pos, namesize) != namesize) {
@ -137,50 +136,49 @@ int cli_scancpio_old(cli_ctx *ctx)
name[namesize - 1] = 0;
sanitname(name);
cli_dbgmsg("CPIO: Name: %s\n", name);
if(!strcmp(name, "TRAILER!!!"))
if (!strcmp(name, "TRAILER!!!"))
trailer = 1;
if(namesize < hdr_namesize) {
if(hdr_namesize % 2)
if (namesize < hdr_namesize) {
if (hdr_namesize % 2)
hdr_namesize++;
pos += hdr_namesize - namesize;
} else if(hdr_namesize % 2)
} else if (hdr_namesize % 2)
pos++;
}
filesize = (uint32_t) (EC16(hdr_old.filesize[0], conv) << 16 | EC16(hdr_old.filesize[1], conv));
filesize = (uint32_t)(EC16(hdr_old.filesize[0], conv) << 16 | EC16(hdr_old.filesize[1], conv));
cli_dbgmsg("CPIO: Filesize: %u\n", filesize);
if(!filesize)
if (!filesize)
continue;
if(cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL) == CL_VIRUS) {
if (cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL) == CL_VIRUS) {
if (!SCAN_ALLMATCHES)
return CL_VIRUS;
virus_found = 1;
}
if((EC16(hdr_old.mode, conv) & 0170000) != 0100000) {
if ((EC16(hdr_old.mode, conv) & 0170000) != 0100000) {
cli_dbgmsg("CPIO: Not a regular file, skipping\n");
} else {
ret = cli_checklimits("cli_scancpio_old", ctx, filesize, 0, 0);
if(ret == CL_EMAXFILES) {
if (ret == CL_EMAXFILES) {
goto leave;
} else if(ret == CL_SUCCESS) {
} else if (ret == CL_SUCCESS) {
ret = cli_map_scan(*ctx->fmap, pos, filesize, ctx, CL_TYPE_ANY);
if(ret == CL_VIRUS) {
if (ret == CL_VIRUS) {
if (!SCAN_ALLMATCHES)
return ret;
virus_found = 1;
}
}
}
if(filesize % 2)
if (filesize % 2)
filesize++;
pos += filesize;
}
leave:
leave:
if (virus_found != 0)
return CL_VIRUS;
return ret;
@ -196,13 +194,12 @@ int cli_scancpio_odc(cli_ctx *ctx)
off_t pos = 0;
int virus_found = 0;
while(fmap_readn(*ctx->fmap, &hdr_odc, pos, sizeof(hdr_odc)) == sizeof(hdr_odc)) {
while (fmap_readn(*ctx->fmap, &hdr_odc, pos, sizeof(hdr_odc)) == sizeof(hdr_odc)) {
pos += sizeof(hdr_odc);
if(!hdr_odc.magic[0] && trailer)
if (!hdr_odc.magic[0] && trailer)
goto leave;
if(strncmp(hdr_odc.magic, "070707", 6)) {
if (strncmp(hdr_odc.magic, "070707", 6)) {
cli_dbgmsg("cli_scancpio_odc: Invalid magic string\n");
ret = CL_EFORMAT;
goto leave;
@ -212,12 +209,12 @@ int cli_scancpio_odc(cli_ctx *ctx)
strncpy(buff, hdr_odc.namesize, 6);
buff[6] = 0;
if(sscanf(buff, "%o", &hdr_namesize) != 1) {
if (sscanf(buff, "%o", &hdr_namesize) != 1) {
cli_dbgmsg("cli_scancpio_odc: Can't convert name size\n");
ret = CL_EFORMAT;
goto leave;
}
if(hdr_namesize) {
if (hdr_namesize) {
namesize = MIN(sizeof(name), hdr_namesize);
if ((uint32_t)fmap_readn(*ctx->fmap, &name, pos, namesize) != namesize) {
cli_dbgmsg("cli_scancpio_odc: Can't read file name\n");
@ -228,37 +225,36 @@ int cli_scancpio_odc(cli_ctx *ctx)
name[namesize - 1] = 0;
sanitname(name);
cli_dbgmsg("CPIO: Name: %s\n", name);
if(!strcmp(name, "TRAILER!!!"))
if (!strcmp(name, "TRAILER!!!"))
trailer = 1;
if(namesize < hdr_namesize)
if (namesize < hdr_namesize)
pos += hdr_namesize - namesize;
}
strncpy(buff, hdr_odc.filesize, 11);
buff[11] = 0;
if(sscanf(buff, "%o", &filesize) != 1) {
if (sscanf(buff, "%o", &filesize) != 1) {
cli_dbgmsg("cli_scancpio_odc: Can't convert file size\n");
ret = CL_EFORMAT;
goto leave;
}
cli_dbgmsg("CPIO: Filesize: %u\n", filesize);
if(!filesize)
if (!filesize)
continue;
if(cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL) == CL_VIRUS) {
if (cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL) == CL_VIRUS) {
if (!SCAN_ALLMATCHES)
return CL_VIRUS;
virus_found = 1;
}
ret = cli_checklimits("cli_scancpio_odc", ctx, filesize, 0, 0);
if(ret == CL_EMAXFILES) {
if (ret == CL_EMAXFILES) {
goto leave;
} else if(ret == CL_SUCCESS) {
} else if (ret == CL_SUCCESS) {
ret = cli_map_scan(*ctx->fmap, pos, filesize, ctx, CL_TYPE_ANY);
if(ret == CL_VIRUS) {
if (ret == CL_VIRUS) {
if (!SCAN_ALLMATCHES)
return ret;
virus_found = 1;
@ -268,7 +264,7 @@ int cli_scancpio_odc(cli_ctx *ctx)
pos += filesize;
}
leave:
leave:
if (virus_found != 0)
return CL_VIRUS;
return ret;
@ -286,12 +282,12 @@ int cli_scancpio_newc(cli_ctx *ctx, int crc)
memset(name, 0, 513);
while(fmap_readn(*ctx->fmap, &hdr_newc, pos, sizeof(hdr_newc)) == sizeof(hdr_newc)) {
while (fmap_readn(*ctx->fmap, &hdr_newc, pos, sizeof(hdr_newc)) == sizeof(hdr_newc)) {
pos += sizeof(hdr_newc);
if(!hdr_newc.magic[0] && trailer)
if (!hdr_newc.magic[0] && trailer)
goto leave;
if((!crc && strncmp(hdr_newc.magic, "070701", 6)) || (crc && strncmp(hdr_newc.magic, "070702", 6))) {
if ((!crc && strncmp(hdr_newc.magic, "070701", 6)) || (crc && strncmp(hdr_newc.magic, "070702", 6))) {
cli_dbgmsg("cli_scancpio_newc: Invalid magic string\n");
ret = CL_EFORMAT;
goto leave;
@ -301,12 +297,12 @@ int cli_scancpio_newc(cli_ctx *ctx, int crc)
strncpy(buff, hdr_newc.namesize, 8);
buff[8] = 0;
if(sscanf(buff, "%x", &hdr_namesize) != 1) {
if (sscanf(buff, "%x", &hdr_namesize) != 1) {
cli_dbgmsg("cli_scancpio_newc: Can't convert name size\n");
ret = CL_EFORMAT;
goto leave;
}
if(hdr_namesize) {
if (hdr_namesize) {
namesize = MIN(sizeof(name), hdr_namesize);
if ((uint32_t)fmap_readn(*ctx->fmap, &name, pos, namesize) != namesize) {
cli_dbgmsg("cli_scancpio_newc: Can't read file name\n");
@ -317,54 +313,54 @@ int cli_scancpio_newc(cli_ctx *ctx, int crc)
name[namesize - 1] = 0;
sanitname(name);
cli_dbgmsg("CPIO: Name: %s\n", name);
if(!strcmp(name, "TRAILER!!!"))
if (!strcmp(name, "TRAILER!!!"))
trailer = 1;
pad = (4 - (sizeof(hdr_newc) + hdr_namesize) % 4) % 4;
if(namesize < hdr_namesize) {
if(pad)
if (namesize < hdr_namesize) {
if (pad)
hdr_namesize += pad;
pos += hdr_namesize - namesize;
} else if(pad)
} else if (pad)
pos += pad;
}
strncpy(buff, hdr_newc.filesize, 8);
buff[8] = 0;
if(sscanf(buff, "%x", &filesize) != 1) {
if (sscanf(buff, "%x", &filesize) != 1) {
cli_dbgmsg("cli_scancpio_newc: Can't convert file size\n");
ret = CL_EFORMAT;
goto leave;
}
cli_dbgmsg("CPIO: Filesize: %u\n", filesize);
if(!filesize)
if (!filesize)
continue;
if(cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL) == CL_VIRUS) {
if (cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL) == CL_VIRUS) {
if (!SCAN_ALLMATCHES)
return CL_VIRUS;
virus_found = 1;
}
ret = cli_checklimits("cli_scancpio_newc", ctx, filesize, 0, 0);
if(ret == CL_EMAXFILES) {
if (ret == CL_EMAXFILES) {
goto leave;
} else if(ret == CL_SUCCESS) {
} else if (ret == CL_SUCCESS) {
ret = cli_map_scan(*ctx->fmap, pos, filesize, ctx, CL_TYPE_ANY);
if(ret == CL_VIRUS) {
if (ret == CL_VIRUS) {
if (!SCAN_ALLMATCHES)
return ret;
virus_found = 1;
}
}
if((pad = filesize % 4))
if ((pad = filesize % 4))
filesize += (4 - pad);
pos += filesize;
}
leave:
leave:
if (virus_found != 0)
return CL_VIRUS;
return ret;

View file

@ -42,10 +42,10 @@
#define OID_2_16_840_1_101_3_4_2_3 "\x60\x86\x48\x01\x65\x03\x04\x02\x03"
#define OID_sha512 OID_2_16_840_1_101_3_4_2_3
int cli_crt_init(cli_crt *x509) {
int cli_crt_init(cli_crt *x509)
{
int ret;
if((ret = mp_init_multi(&x509->n, &x509->e, &x509->sig, NULL))) {
if ((ret = mp_init_multi(&x509->n, &x509->e, &x509->sig, NULL))) {
cli_errmsg("cli_crt_init: mp_init_multi failed with %d\n", ret);
return 1;
}
@ -57,7 +57,8 @@ int cli_crt_init(cli_crt *x509) {
return 0;
}
void cli_crt_clear(cli_crt *x509) {
void cli_crt_clear(cli_crt *x509)
{
UNUSEDPARAM(x509);
mp_clear_multi(&x509->n, &x509->e, &x509->sig, NULL);
}
@ -77,10 +78,11 @@ void cli_crt_clear(cli_crt *x509) {
* lookup. That way, certs with more specific values can get added to the
* whitelist by functions like crtmgr_add and increase the probability of
* successful signature verification. */
cli_crt *crtmgr_whitelist_lookup(crtmgr *m, cli_crt *x509) {
cli_crt *crtmgr_whitelist_lookup(crtmgr *m, cli_crt *x509)
{
cli_crt *i;
for(i = m->crts; i; i = i->next) {
if(!i->isBlacklisted &&
for (i = m->crts; i; i = i->next) {
if (!i->isBlacklisted &&
x509->not_before >= i->not_before &&
x509->not_after <= i->not_after &&
(i->certSign | x509->certSign) == i->certSign &&
@ -98,7 +100,8 @@ cli_crt *crtmgr_whitelist_lookup(crtmgr *m, cli_crt *x509) {
return NULL;
}
cli_crt *crtmgr_blacklist_lookup(crtmgr *m, cli_crt *x509) {
cli_crt *crtmgr_blacklist_lookup(crtmgr *m, cli_crt *x509)
{
cli_crt *i;
for (i = m->crts; i; i = i->next) {
// The CRB rules are based on subject, serial, and public key,
@ -120,7 +123,8 @@ cli_crt *crtmgr_blacklist_lookup(crtmgr *m, cli_crt *x509) {
/* Determine whether x509 already exists in m. The fields compared depend on
* whether x509 is a blacklist entry or a trusted certificate */
cli_crt *crtmgr_lookup(crtmgr *m, cli_crt *x509) {
cli_crt *crtmgr_lookup(crtmgr *m, cli_crt *x509)
{
if (x509->isBlacklisted) {
return crtmgr_blacklist_lookup(m, x509);
} else {
@ -128,7 +132,8 @@ cli_crt *crtmgr_lookup(crtmgr *m, cli_crt *x509) {
}
}
int crtmgr_add(crtmgr *m, cli_crt *x509) {
int crtmgr_add(crtmgr *m, cli_crt *x509)
{
cli_crt *i;
int ret = 0;
@ -145,15 +150,15 @@ int crtmgr_add(crtmgr *m, cli_crt *x509) {
}
i = cli_malloc(sizeof(*i));
if(!i)
if (!i)
return 1;
if((ret = mp_init_multi(&i->n, &i->e, &i->sig, NULL))) {
if ((ret = mp_init_multi(&i->n, &i->e, &i->sig, NULL))) {
cli_warnmsg("crtmgr_add: failed to mp_init failed with %d\n", ret);
free(i);
return 1;
}
if((ret = mp_copy(&x509->n, &i->n)) || (ret = mp_copy(&x509->e, &i->e)) || (ret = mp_copy(&x509->sig, &i->sig))) {
if ((ret = mp_copy(&x509->n, &i->n)) || (ret = mp_copy(&x509->e, &i->e)) || (ret = mp_copy(&x509->sig, &i->sig))) {
cli_warnmsg("crtmgr_add: failed to mp_init failed with %d\n", ret);
cli_crt_clear(i);
free(i);
@ -181,7 +186,7 @@ int crtmgr_add(crtmgr *m, cli_crt *x509) {
i->isBlacklisted = x509->isBlacklisted;
i->next = m->crts;
i->prev = NULL;
if(m->crts)
if (m->crts)
m->crts->prev = i;
m->crts = i;
@ -189,20 +194,22 @@ int crtmgr_add(crtmgr *m, cli_crt *x509) {
return 0;
}
void crtmgr_init(crtmgr *m) {
void crtmgr_init(crtmgr *m)
{
m->crts = NULL;
m->items = 0;
}
void crtmgr_del(crtmgr *m, cli_crt *x509) {
void crtmgr_del(crtmgr *m, cli_crt *x509)
{
cli_crt *i;
for(i = m->crts; i; i = i->next) {
if(i==x509) {
if(i->prev)
for (i = m->crts; i; i = i->next) {
if (i == x509) {
if (i->prev)
i->prev->next = i->next;
else
m->crts = i->next;
if(i->next)
if (i->next)
i->next->prev = i->prev;
cli_crt_clear(x509);
if ((x509->name))
@ -214,12 +221,14 @@ void crtmgr_del(crtmgr *m, cli_crt *x509) {
}
}
void crtmgr_free(crtmgr *m) {
while(m->items)
void crtmgr_free(crtmgr *m)
{
while (m->items)
crtmgr_del(m, m->crts);
}
static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashtype, const uint8_t *refhash) {
static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashtype, const uint8_t *refhash)
{
int keylen = mp_unsigned_bin_size(&x509->n), siglen = mp_unsigned_bin_size(sig);
int ret, j, objlen, hashlen;
uint8_t d[513];
@ -240,46 +249,46 @@ static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashty
return 1;
}
if((ret = mp_init(&x))) {
if ((ret = mp_init(&x))) {
cli_errmsg("crtmgr_rsa_verify: mp_init failed with %d\n", ret);
return 1;
}
do {
if(MAX(keylen, siglen) - MIN(keylen, siglen) > 1) {
if (MAX(keylen, siglen) - MIN(keylen, siglen) > 1) {
cli_dbgmsg("crtmgr_rsa_verify: keylen and siglen differ by more than one\n");
break;
}
if((ret = mp_exptmod(sig, &x509->e, &x509->n, &x))) {
if ((ret = mp_exptmod(sig, &x509->e, &x509->n, &x))) {
cli_warnmsg("crtmgr_rsa_verify: verification failed: mp_exptmod failed with %d\n", ret);
break;
}
if(mp_unsigned_bin_size(&x) != keylen - 1){
if (mp_unsigned_bin_size(&x) != keylen - 1) {
cli_dbgmsg("crtmgr_rsa_verify: keylen-1 doesn't match expected size of exptmod result\n");
break;
}
if(((unsigned int) mp_unsigned_bin_size(&x)) > sizeof(d)) {
if (((unsigned int)mp_unsigned_bin_size(&x)) > sizeof(d)) {
cli_dbgmsg("crtmgr_rsa_verify: exptmod result would overrun working buffer\n");
break;
}
if((ret = mp_to_unsigned_bin(&x, d))) {
if ((ret = mp_to_unsigned_bin(&x, d))) {
cli_warnmsg("crtmgr_rsa_verify: mp_unsigned_bin_size failed with %d\n", ret);
break;
}
if(*d != 1) {/* block type 1 */
if (*d != 1) { /* block type 1 */
cli_dbgmsg("crtmgr_rsa_verify: expected block type 1 at d[0]\n");
break;
}
keylen -= 1; /* 0xff padding */
for(j=1; j<keylen-2; j++)
if(d[j] != 0xff)
for (j = 1; j < keylen - 2; j++)
if (d[j] != 0xff)
break;
if(j == keylen - 2) {
if (j == keylen - 2) {
cli_dbgmsg("crtmgr_rsa_verify: only encountered 0xFF padding parsing cert\n");
break;
}
if(d[j] != 0) { /* 0x00 separator */
if (d[j] != 0) { /* 0x00 separator */
cli_dbgmsg("crtmgr_rsa_verify: expected 0x00 separator\n");
break;
}
@ -287,46 +296,46 @@ static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashty
j++;
keylen -= j; /* asn1 size */
if(keylen < hashlen) {
if (keylen < hashlen) {
cli_dbgmsg("crtmgr_rsa_verify: encountered keylen less than hashlen\n");
break;
}
if(keylen > hashlen) {
if (keylen > hashlen) {
/* hash is asn1 der encoded */
/* SEQ { SEQ { OID, NULL }, OCTET STRING */
if(keylen < 2 || d[j] != 0x30 || d[j+1] + 2 != keylen) {
if (keylen < 2 || d[j] != 0x30 || d[j + 1] + 2 != keylen) {
cli_dbgmsg("crtmgr_rsa_verify: unexpected hash to be ASN1 DER encoded\n");
break;
}
keylen -= 2;
j+=2;
j += 2;
if(keylen <2 || d[j] != 0x30) {
if (keylen < 2 || d[j] != 0x30) {
cli_dbgmsg("crtmgr_rsa_verify: expected SEQUENCE at beginning of cert AlgorithmIdentifier\n");
break;
}
objlen = d[j+1];
objlen = d[j + 1];
keylen -= 2;
j+=2;
if(keylen < objlen) {
j += 2;
if (keylen < objlen) {
cli_dbgmsg("crtmgr_rsa_verify: key length mismatch in ASN1 DER hash encoding\n");
break;
}
if(objlen == 9) {
if (objlen == 9) {
// Check for OID type indicating a length of 5, OID_sha1, and the NULL type/value
if(hashtype != CLI_SHA1RSA || memcmp(&d[j], "\x06\x05" OID_sha1 "\x05\x00", 9)) {
if (hashtype != CLI_SHA1RSA || memcmp(&d[j], "\x06\x05" OID_sha1 "\x05\x00", 9)) {
cli_errmsg("crtmgr_rsa_verify: FIXME ACAB - CRYPTO MISSING?\n");
break;
}
} else if(objlen == 12) {
} else if (objlen == 12) {
// Check for OID type indicating a length of 8, OID_md5, and the NULL type/value
if(hashtype != CLI_MD5RSA || memcmp(&d[j], "\x06\x08" OID_md5 "\x05\x00", 12)) {
if (hashtype != CLI_MD5RSA || memcmp(&d[j], "\x06\x08" OID_md5 "\x05\x00", 12)) {
cli_errmsg("crtmgr_rsa_verify: FIXME ACAB - CRYPTO MISSING?\n");
break;
}
} else if(objlen == 13) {
} else if (objlen == 13) {
if (hashtype == CLI_SHA256RSA) {
// Check for OID type indicating a length of 9, OID_sha256, and the NULL type/value
if (0 != memcmp(&d[j], "\x06\x09" OID_sha256 "\x05\x00", 13)) {
@ -359,18 +368,18 @@ static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashty
keylen -= objlen;
j += objlen;
if(keylen < 2 || d[j] != 0x04 || d[j+1] != hashlen) {
if (keylen < 2 || d[j] != 0x04 || d[j + 1] != hashlen) {
cli_dbgmsg("crtmgr_rsa_verify: hash length mismatch in ASN1 DER hash encoding\n");
break;
}
keylen -= 2;
j+=2;
if(keylen != hashlen) {
j += 2;
if (keylen != hashlen) {
cli_dbgmsg("crtmgr_rsa_verify: extra data in the ASN1 DER hash encoding\n");
break;
}
}
if(memcmp(&d[j], refhash, hashlen)) {
if (memcmp(&d[j], refhash, hashlen)) {
// This is a common error case if we are using crtmgr_rsa_verify to
// determine whether we've found the right issuer certificate based
// (as is done by crtmgr_verify_crt). If we are pretty sure that
@ -382,7 +391,7 @@ static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashty
mp_clear(&x);
return 0;
} while(0);
} while (0);
mp_clear(&x);
return 1;
@ -392,7 +401,8 @@ static int crtmgr_rsa_verify(cli_crt *x509, mp_int *sig, cli_crt_hashtype hashty
* is present. Otherwise returns a pointer to the signer x509 certificate if
* one is found in the crtmgr and it's signature can be validated (NULL is
* returned otherwise.) */
cli_crt *crtmgr_verify_crt(crtmgr *m, cli_crt *x509) {
cli_crt *crtmgr_verify_crt(crtmgr *m, cli_crt *x509)
{
cli_crt *i = m->crts, *best = NULL;
int score = 0;
unsigned int possible = 0;
@ -408,17 +418,17 @@ cli_crt *crtmgr_verify_crt(crtmgr *m, cli_crt *x509) {
// that way, but the cert doesn't HAVE to be embedded. This case seems
// unlikely enough to ignore, though.
for(i = m->crts; i; i = i->next) {
if(i->certSign &&
for (i = m->crts; i; i = i->next) {
if (i->certSign &&
!i->isBlacklisted &&
!memcmp(i->subject, x509->issuer, sizeof(i->subject)) &&
!crtmgr_rsa_verify(i, &x509->sig, x509->hashtype, x509->tbshash)) {
int curscore;
if((x509->codeSign & i->codeSign) == x509->codeSign && (x509->timeSign & i->timeSign) == x509->timeSign)
if ((x509->codeSign & i->codeSign) == x509->codeSign && (x509->timeSign & i->timeSign) == x509->timeSign)
return i;
possible++;
curscore = (x509->codeSign & i->codeSign) + (x509->timeSign & i->timeSign);
if(curscore > score) {
if (curscore > score) {
best = i;
score = curscore;
}
@ -433,33 +443,34 @@ cli_crt *crtmgr_verify_crt(crtmgr *m, cli_crt *x509) {
return best;
}
cli_crt *crtmgr_verify_pkcs7(crtmgr *m, const uint8_t *issuer, const uint8_t *serial, const void *signature, unsigned int signature_len, cli_crt_hashtype hashtype, const uint8_t *refhash, cli_vrfy_type vrfytype) {
cli_crt *crtmgr_verify_pkcs7(crtmgr *m, const uint8_t *issuer, const uint8_t *serial, const void *signature, unsigned int signature_len, cli_crt_hashtype hashtype, const uint8_t *refhash, cli_vrfy_type vrfytype)
{
cli_crt *i;
mp_int sig;
int ret;
if(signature_len < 1024/8 || signature_len > 4096/8+1) {
if (signature_len < 1024 / 8 || signature_len > 4096 / 8 + 1) {
cli_dbgmsg("crtmgr_verify_pkcs7: unsupported sig len: %u\n", signature_len);
return NULL;
}
if((ret = mp_init(&sig))) {
if ((ret = mp_init(&sig))) {
cli_dbgmsg("crtmgr_verify_pkcs7: mp_init failed with %d\n", ret);
return NULL;
}
if((ret=mp_read_unsigned_bin(&sig, signature, signature_len))) {
if ((ret = mp_read_unsigned_bin(&sig, signature, signature_len))) {
cli_dbgmsg("crtmgr_verify_pkcs7: mp_read_unsigned_bin failed with %d\n", ret);
return NULL;
}
for(i = m->crts; i; i = i->next) {
if(vrfytype == VRFY_CODE && !i->codeSign)
for (i = m->crts; i; i = i->next) {
if (vrfytype == VRFY_CODE && !i->codeSign)
continue;
if(vrfytype == VRFY_TIME && !i->timeSign)
if (vrfytype == VRFY_TIME && !i->timeSign)
continue;
if(!memcmp(i->issuer, issuer, sizeof(i->issuer)) &&
if (!memcmp(i->issuer, issuer, sizeof(i->issuer)) &&
!memcmp(i->serial, serial, sizeof(i->serial))) {
if(!crtmgr_rsa_verify(i, &sig, hashtype, refhash)) {
if (!crtmgr_rsa_verify(i, &sig, hashtype, refhash)) {
break;
}
cli_dbgmsg("crtmgr_verify_pkcs7: found cert with matching issuer and serial but RSA verification failed\n");
@ -469,7 +480,8 @@ cli_crt *crtmgr_verify_pkcs7(crtmgr *m, const uint8_t *issuer, const uint8_t *se
return i;
}
int crtmgr_add_roots(struct cl_engine *engine, crtmgr *m) {
int crtmgr_add_roots(struct cl_engine *engine, crtmgr *m)
{
cli_crt *crt;
/*
* Certs are cached in engine->cmgr. Copy from there.

View file

@ -26,8 +26,15 @@
#include "bignum.h"
typedef enum {CLI_SHA1RSA, CLI_MD5RSA, CLI_MD2RSA, CLI_RSA, CLI_SHA256RSA, CLI_SHA384RSA, CLI_SHA512RSA } cli_crt_hashtype;
typedef enum {VRFY_CODE, VRFY_TIME} cli_vrfy_type;
typedef enum { CLI_SHA1RSA,
CLI_MD5RSA,
CLI_MD2RSA,
CLI_RSA,
CLI_SHA256RSA,
CLI_SHA384RSA,
CLI_SHA512RSA } cli_crt_hashtype;
typedef enum { VRFY_CODE,
VRFY_TIME } cli_vrfy_type;
#define CRT_RAWMAXLEN 64
typedef struct cli_crt_t {
@ -61,7 +68,6 @@ typedef struct {
unsigned int items;
} crtmgr;
int cli_crt_init(cli_crt *x509);
void cli_crt_clear(cli_crt *x509);
void crtmgr_init(crtmgr *m);
@ -73,5 +79,4 @@ cli_crt *crtmgr_verify_crt(crtmgr *m, cli_crt *x509);
cli_crt *crtmgr_verify_pkcs7(crtmgr *m, const uint8_t *issuer, const uint8_t *serial, const void *signature, unsigned int signature_len, cli_crt_hashtype hashtype, const uint8_t *refhash, cli_vrfy_type vrfytype);
int crtmgr_add_roots(struct cl_engine *engine, crtmgr *m);
#endif

View file

@ -65,21 +65,24 @@
#include "iowrap.h"
#if defined(_WIN32)
char * strptime(const char *buf, const char *fmt, struct tm *tm);
char *strptime(const char *buf, const char *fmt, struct tm *tm);
#endif
#if defined(_WIN32)
#define EXCEPTION_PREAMBLE __try {
#define EXCEPTION_POSTAMBLE } __except (filter_memcpy(GetExceptionCode(), GetExceptionInformation())) { \
winres=1; \
}
#define EXCEPTION_POSTAMBLE \
} \
__except (filter_memcpy(GetExceptionCode(), GetExceptionInformation())) \
{ \
winres = 1; \
}
#else
#define EXCEPTION_PREAMBLE
#define EXCEPTION_POSTAMBLE
#endif
#if !defined(MIN)
#define MIN(x,y) ((x)<(y)?(x):(y))
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif
#if !defined(HAVE_TIMEGM) && !defined(_WIN32)
@ -92,24 +95,22 @@ time_t timegm(struct tm *t)
time_t tl, tb;
struct tm *tg;
tl = mktime (t);
if (tl == -1)
{
tl = mktime(t);
if (tl == -1) {
t->tm_hour--;
tl = mktime (t);
tl = mktime(t);
if (tl == -1)
return -1; /* can't deal with output from strptime */
tl += 3600;
}
tg = gmtime (&tl);
tg = gmtime(&tl);
tg->tm_isdst = 0;
tb = mktime (tg);
tb = mktime(tg);
if (tb == -1)
{
if (tb == -1) {
tg->tm_hour--;
tb = mktime (tg);
tb = mktime(tg);
if (tb == -1)
return -1; /* can't deal with output from gmtime */
@ -120,7 +121,6 @@ time_t timegm(struct tm *t)
}
#endif
/**
* @brief This function initializes the openssl crypto system
*
@ -162,7 +162,7 @@ unsigned char *cl_hash_data(const char *alg, const void *buf, size_t len, unsign
const EVP_MD *md;
unsigned int i;
size_t cur;
int winres=0;
int winres = 0;
md = EVP_get_digestbyname(alg);
if (!(md))
@ -198,12 +198,12 @@ unsigned char *cl_hash_data(const char *alg, const void *buf, size_t len, unsign
return NULL;
}
cur=0;
cur = 0;
while (cur < len) {
size_t todo = MIN((unsigned long)EVP_MD_block_size(md), (unsigned long)(len-cur));
size_t todo = MIN((unsigned long)EVP_MD_block_size(md), (unsigned long)(len - cur));
EXCEPTION_PREAMBLE
if (!EVP_DigestUpdate(ctx, (void *)(((unsigned char *)buf)+cur), todo)) {
if (!EVP_DigestUpdate(ctx, (void *)(((unsigned char *)buf) + cur), todo)) {
if (!(obuf))
free(ret);
@ -285,7 +285,7 @@ unsigned char *cl_hash_file_fd_ctx(EVP_MD_CTX *ctx, int fd, unsigned int *olen)
int mdsz;
unsigned int hashlen;
STATBUF sb;
int winres=0;
int winres = 0;
unsigned int blocksize;
@ -831,7 +831,7 @@ X509 *cl_get_x509_from_mem(void *data, unsigned int len)
int cl_validate_certificate_chain_ts_dir(char *tsdir, char *certpath)
{
char **authorities=NULL, **t;
char **authorities = NULL, **t;
size_t nauths = 0;
int res;
DIR *dp;
@ -886,7 +886,7 @@ int cl_validate_certificate_chain_ts_dir(char *tsdir, char *certpath)
return -1;
}
sprintf(authorities[nauths], "%s"PATHSEP"%s", tsdir, dirent->d_name);
sprintf(authorities[nauths], "%s" PATHSEP "%s", tsdir, dirent->d_name);
nauths++;
}
@ -918,11 +918,11 @@ int cl_validate_certificate_chain_ts_dir(char *tsdir, char *certpath)
int cl_validate_certificate_chain(char **authorities, char *crlpath, char *certpath)
{
X509_STORE *store=NULL;
X509_STORE *store = NULL;
X509_STORE_CTX *store_ctx;
X509_LOOKUP *lookup=NULL;
X509_CRL *crl=NULL;
X509_VERIFY_PARAM *param=NULL;
X509_LOOKUP *lookup = NULL;
X509_CRL *crl = NULL;
X509_VERIFY_PARAM *param = NULL;
X509 *cert;
unsigned long i;
int res;
@ -960,7 +960,7 @@ int cl_validate_certificate_chain(char **authorities, char *crlpath, char *certp
}
/* Support multi-tiered setups */
for (i=0; authorities[i]; i++) {
for (i = 0; authorities[i]; i++) {
if (!X509_LOOKUP_load_file(lookup, authorities[i], X509_FILETYPE_PEM)) {
X509_STORE_free(store);
if ((crl))
@ -1058,8 +1058,8 @@ X509 *cl_load_cert(const char *certpath)
struct tm *cl_ASN1_GetTimeT(ASN1_TIME *timeobj)
{
struct tm *t;
char* str;
const char *fmt=NULL;
char *str;
const char *fmt = NULL;
time_t localt;
#ifdef _WIN32
struct tm localtm, *ltm;
@ -1087,8 +1087,7 @@ struct tm *cl_ASN1_GetTimeT(ASN1_TIME *timeobj)
} else {
str[3]--;
}
}
else if (timeobj->type == V_ASN1_GENERALIZEDTIME) {
} else if (timeobj->type == V_ASN1_GENERALIZEDTIME) {
/* four digit year */
fmt = "%Y%m%d%H%M%S";
if (str[5] == '0') {
@ -1123,7 +1122,7 @@ struct tm *cl_ASN1_GetTimeT(ASN1_TIME *timeobj)
X509_CRL *cl_load_crl(const char *file)
{
X509_CRL *x=NULL;
X509_CRL *x = NULL;
FILE *fp;
if (!(file))
@ -1179,7 +1178,7 @@ void *cl_hash_init(const char *alg)
int cl_update_hash(void *ctx, const void *data, size_t sz)
{
int winres=0;
int winres = 0;
if (!(ctx) || !(data))
return -1;
@ -1197,7 +1196,7 @@ int cl_update_hash(void *ctx, const void *data, size_t sz)
int cl_finish_hash(void *ctx, void *buf)
{
int res=0;
int res = 0;
if (!(ctx) || !(buf))
return -1;

View file

@ -56,9 +56,9 @@ static void cli_untgz_cleanup(char *path, gzFile infile, FILE *outfile, int fdd)
UNUSEDPARAM(fdd);
cli_dbgmsg("in cli_untgz_cleanup()\n");
if (path != NULL)
free (path);
free(path);
if (infile != NULL)
gzclose (infile);
gzclose(infile);
if (outfile != NULL)
fclose(outfile);
}
@ -73,59 +73,58 @@ static int cli_untgz(int fd, const char *destdir)
STATBUF foo;
gzFile infile = NULL;
cli_dbgmsg("in cli_untgz()\n");
if((fdd = dup(fd)) == -1) {
if ((fdd = dup(fd)) == -1) {
cli_errmsg("cli_untgz: Can't duplicate descriptor %d\n", fd);
return -1;
}
if((infile = gzdopen(fdd, "rb")) == NULL) {
if ((infile = gzdopen(fdd, "rb")) == NULL) {
cli_errmsg("cli_untgz: Can't gzdopen() descriptor %d, errno = %d\n", fdd, errno);
if(FSTAT(fdd, &foo) == 0)
if (FSTAT(fdd, &foo) == 0)
close(fdd);
return -1;
}
path = (char *) cli_calloc(sizeof(char), pathlen);
if(!path) {
path = (char *)cli_calloc(sizeof(char), pathlen);
if (!path) {
cli_errmsg("cli_untgz: Can't allocate memory for path\n");
cli_untgz_cleanup(NULL, infile, NULL, fdd);
return -1;
}
while(1) {
while (1) {
nread = gzread(infile, block, TAR_BLOCKSIZE);
if(!in_block && !nread)
if (!in_block && !nread)
break;
if(nread != TAR_BLOCKSIZE) {
if (nread != TAR_BLOCKSIZE) {
cli_errmsg("cli_untgz: Incomplete block read\n");
cli_untgz_cleanup(path, infile, outfile, fdd);
return -1;
}
if(!in_block) {
if (!in_block) {
if (block[0] == '\0') /* We're done */
break;
strncpy(name, block, 100);
name[100] = '\0';
if(strchr(name, '/')) {
if (strchr(name, '/')) {
cli_errmsg("cli_untgz: Slash separators are not allowed in CVD\n");
cli_untgz_cleanup(path, infile, outfile, fdd);
return -1;
}
snprintf(path, pathlen, "%s"PATHSEP"%s", destdir, name);
snprintf(path, pathlen, "%s" PATHSEP "%s", destdir, name);
cli_dbgmsg("cli_untgz: Unpacking %s\n", path);
type = block[156];
switch(type) {
switch (type) {
case '0':
case '\0':
break;
@ -139,8 +138,8 @@ static int cli_untgz(int fd, const char *destdir)
return -1;
}
if(outfile) {
if(fclose(outfile)) {
if (outfile) {
if (fclose(outfile)) {
cli_errmsg("cli_untgz: Cannot close file %s\n", path);
outfile = NULL;
cli_untgz_cleanup(path, infile, outfile, fdd);
@ -149,7 +148,7 @@ static int cli_untgz(int fd, const char *destdir)
outfile = NULL;
}
if(!(outfile = fopen(path, "wb"))) {
if (!(outfile = fopen(path, "wb"))) {
cli_errmsg("cli_untgz: Cannot create file %s\n", path);
cli_untgz_cleanup(path, infile, outfile, fdd);
return -1;
@ -158,7 +157,7 @@ static int cli_untgz(int fd, const char *destdir)
strncpy(osize, block + 124, 12);
osize[12] = '\0';
if((sscanf(osize, "%o", &size)) == 0) {
if ((sscanf(osize, "%o", &size)) == 0) {
cli_errmsg("cli_untgz: Invalid size in header\n");
cli_untgz_cleanup(path, infile, outfile, fdd);
return -1;
@ -171,14 +170,14 @@ static int cli_untgz(int fd, const char *destdir)
nbytes = size > TAR_BLOCKSIZE ? TAR_BLOCKSIZE : size;
nwritten = fwrite(block, 1, nbytes, outfile);
if(nwritten != nbytes) {
if (nwritten != nbytes) {
cli_errmsg("cli_untgz: Wrote %d instead of %d (%s)\n", nwritten, nbytes, path);
cli_untgz_cleanup(path, infile, outfile, fdd);
return -1;
}
size -= nbytes;
if(size == 0)
if (size == 0)
in_block = 0;
}
}
@ -191,15 +190,14 @@ static void cli_tgzload_cleanup(int comp, struct cli_dbio *dbio, int fdd)
{
UNUSEDPARAM(fdd);
cli_dbgmsg("in cli_tgzload_cleanup()\n");
if(comp) {
if (comp) {
gzclose(dbio->gzs);
dbio->gzs = NULL;
}
else {
} else {
fclose(dbio->fs);
dbio->fs = NULL;
}
if(dbio->buf != NULL) {
if (dbio->buf != NULL) {
free(dbio->buf);
dbio->buf = NULL;
}
@ -222,27 +220,27 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
cli_dbgmsg("in cli_tgzload()\n");
if(lseek(fd, 512, SEEK_SET) < 0) {
if (lseek(fd, 512, SEEK_SET) < 0) {
return CL_ESEEK;
}
if(cli_readn(fd, block, 7) != 7)
if (cli_readn(fd, block, 7) != 7)
return CL_EFORMAT; /* truncated file? */
if(!strncmp(block, "COPYING", 7))
if (!strncmp(block, "COPYING", 7))
compr = 0;
if(lseek(fd, 512, SEEK_SET) < 0) {
if (lseek(fd, 512, SEEK_SET) < 0) {
return CL_ESEEK;
}
if((fdd = dup(fd)) == -1) {
if ((fdd = dup(fd)) == -1) {
cli_errmsg("cli_tgzload: Can't duplicate descriptor %d\n", fd);
return CL_EDUP;
}
if(compr) {
if((dbio->gzs = gzdopen(fdd, "rb")) == NULL) {
if (compr) {
if ((dbio->gzs = gzdopen(fdd, "rb")) == NULL) {
cli_errmsg("cli_tgzload: Can't gzdopen() descriptor %d, errno = %d\n", fdd, errno);
if (fdd > -1)
close(fdd);
@ -250,7 +248,7 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
}
dbio->fs = NULL;
} else {
if((dbio->fs = fdopen(fdd, "rb")) == NULL) {
if ((dbio->fs = fdopen(fdd, "rb")) == NULL) {
cli_errmsg("cli_tgzload: Can't fdopen() descriptor %d, errno = %d\n", fdd, errno);
if (fdd > -1)
close(fdd);
@ -261,7 +259,7 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
dbio->bufsize = CLI_DEFAULT_DBIO_BUFSIZE;
dbio->buf = cli_malloc(dbio->bufsize);
if(!dbio->buf) {
if (!dbio->buf) {
cli_errmsg("cli_tgzload: Can't allocate memory for dbio->buf\n");
cli_tgzload_cleanup(compr, dbio, fdd);
return CL_EMALFDB;
@ -270,29 +268,29 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
dbio->usebuf = 1;
dbio->readpt = dbio->buf;
while(1) {
while (1) {
if(compr)
if (compr)
nread = gzread(dbio->gzs, block, TAR_BLOCKSIZE);
else
nread = fread(block, 1, TAR_BLOCKSIZE, dbio->fs);
if(!nread)
if (!nread)
break;
if(nread != TAR_BLOCKSIZE) {
if (nread != TAR_BLOCKSIZE) {
cli_errmsg("cli_tgzload: Incomplete block read\n");
cli_tgzload_cleanup(compr, dbio, fdd);
return CL_EMALFDB;
}
if(block[0] == '\0') /* We're done */
if (block[0] == '\0') /* We're done */
break;
strncpy(name, block, 100);
name[100] = '\0';
if(strchr(name, '/')) {
if (strchr(name, '/')) {
cli_errmsg("cli_tgzload: Slash separators are not allowed in CVD\n");
cli_tgzload_cleanup(compr, dbio, fdd);
return CL_EMALFDB;
@ -300,7 +298,7 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
type = block[156];
switch(type) {
switch (type) {
case '0':
case '\0':
break;
@ -317,7 +315,7 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
strncpy(osize, block + 124, 12);
osize[12] = '\0';
if((sscanf(osize, "%o", &size)) == 0) {
if ((sscanf(osize, "%o", &size)) == 0) {
cli_errmsg("cli_tgzload: Invalid size in header\n");
cli_tgzload_cleanup(compr, dbio, fdd);
return CL_EMALFDB;
@ -336,32 +334,32 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
dbio->bread = 0;
/* cli_dbgmsg("cli_tgzload: Loading %s, size: %u\n", name, size); */
if(compr)
off = (off_t) gzseek(dbio->gzs, 0, SEEK_CUR);
if (compr)
off = (off_t)gzseek(dbio->gzs, 0, SEEK_CUR);
else
off = ftell(dbio->fs);
if((!dbinfo && cli_strbcasestr(name, ".info")) || (dbinfo && (CLI_DBEXT(name) || cli_strbcasestr(name, ".ign") || cli_strbcasestr(name, ".ign2")))) {
if ((!dbinfo && cli_strbcasestr(name, ".info")) || (dbinfo && (CLI_DBEXT(name) || cli_strbcasestr(name, ".ign") || cli_strbcasestr(name, ".ign2")))) {
ret = cli_load(name, engine, signo, options, dbio);
if(ret) {
if (ret) {
cli_errmsg("cli_tgzload: Can't load %s\n", name);
cli_tgzload_cleanup(compr, dbio, fdd);
return CL_EMALFDB;
}
if(!dbinfo) {
if (!dbinfo) {
cli_tgzload_cleanup(compr, dbio, fdd);
return CL_SUCCESS;
} else {
db = dbinfo;
while(db && strcmp(db->name, name))
while (db && strcmp(db->name, name))
db = db->next;
if(!db) {
if (!db) {
cli_errmsg("cli_tgzload: File %s not found in .info\n", name);
cli_tgzload_cleanup(compr, dbio, fdd);
return CL_EMALFDB;
}
if(dbio->bread) {
if(db->size != dbio->bread) {
if (dbio->bread) {
if (db->size != dbio->bread) {
cli_errmsg("cli_tgzload: File %s not correctly loaded\n", name);
cli_tgzload_cleanup(compr, dbio, fdd);
return CL_EMALFDB;
@ -372,7 +370,7 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
cli_tgzload_cleanup(compr, dbio, fdd);
return CL_EMALFDB;
}
if(memcmp(db->hash, hash, 32)) {
if (memcmp(db->hash, hash, 32)) {
cli_errmsg("cli_tgzload: Invalid checksum for file %s\n", name);
cli_tgzload_cleanup(compr, dbio, fdd);
return CL_EMALFDB;
@ -381,15 +379,15 @@ static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, un
}
}
pad = size % TAR_BLOCKSIZE ? (TAR_BLOCKSIZE - (size % TAR_BLOCKSIZE)) : 0;
if(compr) {
if(off == gzseek(dbio->gzs, 0, SEEK_CUR))
if (compr) {
if (off == gzseek(dbio->gzs, 0, SEEK_CUR))
gzseek(dbio->gzs, size + pad, SEEK_CUR);
else if(pad)
else if (pad)
gzseek(dbio->gzs, pad, SEEK_CUR);
} else {
if(off == ftell(dbio->fs))
if (off == ftell(dbio->fs))
fseek(dbio->fs, size + pad, SEEK_CUR);
else if(pad)
else if (pad)
fseek(dbio->fs, pad, SEEK_CUR);
}
}
@ -403,24 +401,23 @@ struct cl_cvd *cl_cvdparse(const char *head)
struct cl_cvd *cvd;
char *pt;
if(strncmp(head, "ClamAV-VDB:", 11)) {
if (strncmp(head, "ClamAV-VDB:", 11)) {
cli_errmsg("cli_cvdparse: Not a CVD file\n");
return NULL;
}
if(!(cvd = (struct cl_cvd *) cli_malloc(sizeof(struct cl_cvd)))) {
if (!(cvd = (struct cl_cvd *)cli_malloc(sizeof(struct cl_cvd)))) {
cli_errmsg("cl_cvdparse: Can't allocate memory for cvd\n");
return NULL;
}
if(!(cvd->time = cli_strtok(head, 1, ":"))) {
if (!(cvd->time = cli_strtok(head, 1, ":"))) {
cli_errmsg("cli_cvdparse: Can't parse the creation time\n");
free(cvd);
return NULL;
}
if(!(pt = cli_strtok(head, 2, ":"))) {
if (!(pt = cli_strtok(head, 2, ":"))) {
cli_errmsg("cli_cvdparse: Can't parse the version number\n");
free(cvd->time);
free(cvd);
@ -429,7 +426,7 @@ struct cl_cvd *cl_cvdparse(const char *head)
cvd->version = atoi(pt);
free(pt);
if(!(pt = cli_strtok(head, 3, ":"))) {
if (!(pt = cli_strtok(head, 3, ":"))) {
cli_errmsg("cli_cvdparse: Can't parse the number of signatures\n");
free(cvd->time);
free(cvd);
@ -438,7 +435,7 @@ struct cl_cvd *cl_cvdparse(const char *head)
cvd->sigs = atoi(pt);
free(pt);
if(!(pt = cli_strtok(head, 4, ":"))) {
if (!(pt = cli_strtok(head, 4, ":"))) {
cli_errmsg("cli_cvdparse: Can't parse the functionality level\n");
free(cvd->time);
free(cvd);
@ -447,14 +444,14 @@ struct cl_cvd *cl_cvdparse(const char *head)
cvd->fl = atoi(pt);
free(pt);
if(!(cvd->md5 = cli_strtok(head, 5, ":"))) {
if (!(cvd->md5 = cli_strtok(head, 5, ":"))) {
cli_errmsg("cli_cvdparse: Can't parse the MD5 checksum\n");
free(cvd->time);
free(cvd);
return NULL;
}
if(!(cvd->dsig = cli_strtok(head, 6, ":"))) {
if (!(cvd->dsig = cli_strtok(head, 6, ":"))) {
cli_errmsg("cli_cvdparse: Can't parse the digital signature\n");
free(cvd->time);
free(cvd->md5);
@ -462,7 +459,7 @@ struct cl_cvd *cl_cvdparse(const char *head)
return NULL;
}
if(!(cvd->builder = cli_strtok(head, 7, ":"))) {
if (!(cvd->builder = cli_strtok(head, 7, ":"))) {
cli_errmsg("cli_cvdparse: Can't parse the builder name\n");
free(cvd->time);
free(cvd->md5);
@ -471,7 +468,7 @@ struct cl_cvd *cl_cvdparse(const char *head)
return NULL;
}
if((pt = cli_strtok(head, 8, ":"))) {
if ((pt = cli_strtok(head, 8, ":"))) {
cvd->stime = atoi(pt);
free(pt);
} else {
@ -489,13 +486,12 @@ struct cl_cvd *cl_cvdhead(const char *file)
int i;
unsigned int bread;
if((fs = fopen(file, "rb")) == NULL) {
if ((fs = fopen(file, "rb")) == NULL) {
cli_errmsg("cl_cvdhead: Can't open file %s\n", file);
return NULL;
}
if(!(bread = fread(head, 1, 512, fs))) {
if (!(bread = fread(head, 1, 512, fs))) {
cli_errmsg("cl_cvdhead: Can't read CVD header in %s\n", file);
fclose(fs);
return NULL;
@ -504,10 +500,11 @@ struct cl_cvd *cl_cvdhead(const char *file)
fclose(fs);
head[bread] = 0;
if((pt = strpbrk(head, "\n\r")))
if ((pt = strpbrk(head, "\n\r")))
*pt = 0;
for(i = bread - 1; i > 0 && (head[i] == ' ' || head[i] == '\n' || head[i] == '\r'); head[i] = 0, i--);
for (i = bread - 1; i > 0 && (head[i] == ' ' || head[i] == '\n' || head[i] == '\r'); head[i] = 0, i--)
;
return cl_cvdparse(head);
}
@ -527,23 +524,23 @@ static int cli_cvdverify(FILE *fs, struct cl_cvd *cvdpt, unsigned int skipsig)
char *md5, head[513];
int i;
fseek(fs, 0, SEEK_SET);
if(fread(head, 1, 512, fs) != 512) {
if (fread(head, 1, 512, fs) != 512) {
cli_errmsg("cli_cvdverify: Can't read CVD header\n");
return CL_ECVD;
}
head[512] = 0;
for(i = 511; i > 0 && (head[i] == ' ' || head[i] == 10); head[i] = 0, i--);
for (i = 511; i > 0 && (head[i] == ' ' || head[i] == 10); head[i] = 0, i--)
;
if((cvd = cl_cvdparse(head)) == NULL)
if ((cvd = cl_cvdparse(head)) == NULL)
return CL_ECVD;
if(cvdpt)
if (cvdpt)
memcpy(cvdpt, cvd, sizeof(struct cl_cvd));
if(skipsig) {
if (skipsig) {
cl_cvdfree(cvd);
return CL_SUCCESS;
}
@ -556,14 +553,14 @@ static int cli_cvdverify(FILE *fs, struct cl_cvd *cvdpt, unsigned int skipsig)
}
cli_dbgmsg("MD5(.tar.gz) = %s\n", md5);
if(strncmp(md5, cvd->md5, 32)) {
if (strncmp(md5, cvd->md5, 32)) {
cli_dbgmsg("cli_cvdverify: MD5 verification error\n");
free(md5);
cl_cvdfree(cvd);
return CL_EVERIFY;
}
if(cli_versig(md5, cvd->dsig)) {
if (cli_versig(md5, cvd->dsig)) {
cli_dbgmsg("cli_cvdverify: Digital signature verification error\n");
free(md5);
cl_cvdfree(cvd);
@ -581,13 +578,12 @@ int cl_cvdverify(const char *file)
FILE *fs;
int ret, dbtype = 0;
if((fs = fopen(file, "rb")) == NULL) {
if ((fs = fopen(file, "rb")) == NULL) {
cli_errmsg("cl_cvdverify: Can't open file %s\n", file);
return CL_EOPEN;
}
if(!(engine = cl_engine_new())) {
if (!(engine = cl_engine_new())) {
cli_errmsg("cld_cvdverify: Can't create new engine\n");
fclose(fs);
return CL_EMEM;
@ -622,27 +618,27 @@ int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigne
cli_dbgmsg("in cli_cvdload()\n");
/* verify */
if((ret = cli_cvdverify(fs, &cvd, dbtype)))
if ((ret = cli_cvdverify(fs, &cvd, dbtype)))
return ret;
if(dbtype <= 1) {
if (dbtype <= 1) {
/* check for duplicate db */
dupname = cli_strdup(filename);
if(!dupname)
if (!dupname)
return CL_EMEM;
dupname[strlen(dupname) - 2] = (dbtype == 1 ? 'v' : 'l');
if(!access(dupname, R_OK) && (dupfs = fopen(dupname, "rb"))) {
if((ret = cli_cvdverify(dupfs, &dupcvd, !dbtype))) {
if (!access(dupname, R_OK) && (dupfs = fopen(dupname, "rb"))) {
if ((ret = cli_cvdverify(dupfs, &dupcvd, !dbtype))) {
fclose(dupfs);
free(dupname);
return ret;
}
fclose(dupfs);
if(dupcvd.version > cvd.version) {
if (dupcvd.version > cvd.version) {
cli_warnmsg("Detected duplicate databases %s and %s. The %s database is older and will not be loaded, you should manually remove it from the database directory.\n", filename, dupname, filename);
free(dupname);
return CL_SUCCESS;
} else if(dupcvd.version == cvd.version && !dbtype) {
} else if (dupcvd.version == cvd.version && !dbtype) {
cli_warnmsg("Detected duplicate databases %s and %s, please manually remove one of them\n", filename, dupname);
free(dupname);
return CL_SUCCESS;
@ -651,16 +647,16 @@ int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigne
free(dupname);
}
if(strstr(filename, "daily.")) {
if (strstr(filename, "daily.")) {
time(&s_time);
if(cvd.stime > s_time) {
if(cvd.stime - (unsigned int ) s_time > 3600) {
if (cvd.stime > s_time) {
if (cvd.stime - (unsigned int)s_time > 3600) {
cli_warnmsg("******************************************************\n");
cli_warnmsg("*** Virus database timestamp in the future! ***\n");
cli_warnmsg("*** Please check the timezone and clock settings ***\n");
cli_warnmsg("******************************************************\n");
}
} else if((unsigned int) s_time - cvd.stime > 604800) {
} else if ((unsigned int)s_time - cvd.stime > 604800) {
cli_warnmsg("**************************************************\n");
cli_warnmsg("*** The virus database is older than 7 days! ***\n");
cli_warnmsg("*** Please update it as soon as possible. ***\n");
@ -670,7 +666,7 @@ int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigne
engine->dbversion[1] = cvd.stime;
}
if(cvd.fl > cl_retflevel()) {
if (cvd.fl > cl_retflevel()) {
cli_warnmsg("*******************************************************************\n");
cli_warnmsg("*** This version of the ClamAV engine is outdated. ***\n");
cli_warnmsg("*** Read https://www.clamav.net/documents/installing-clamav ***\n");
@ -679,38 +675,38 @@ int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigne
cfd = fileno(fs);
dbio.chkonly = 0;
if(dbtype == 2)
if (dbtype == 2)
ret = cli_tgzload(cfd, engine, signo, options | CL_DB_UNSIGNED, &dbio, NULL);
else
ret = cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL, &dbio, NULL);
if(ret != CL_SUCCESS)
if (ret != CL_SUCCESS)
return ret;
dbinfo = engine->dbinfo;
if(!dbinfo || !dbinfo->cvd || (dbinfo->cvd->version != cvd.version) || (dbinfo->cvd->sigs != cvd.sigs) || (dbinfo->cvd->fl != cvd.fl) || (dbinfo->cvd->stime != cvd.stime)) {
if (!dbinfo || !dbinfo->cvd || (dbinfo->cvd->version != cvd.version) || (dbinfo->cvd->sigs != cvd.sigs) || (dbinfo->cvd->fl != cvd.fl) || (dbinfo->cvd->stime != cvd.stime)) {
cli_errmsg("cli_cvdload: Corrupted CVD header\n");
return CL_EMALFDB;
}
dbinfo = engine->dbinfo ? engine->dbinfo->next : NULL;
if(!dbinfo) {
if (!dbinfo) {
cli_errmsg("cli_cvdload: dbinfo error\n");
return CL_EMALFDB;
}
dbio.chkonly = chkonly;
if(dbtype == 2)
if (dbtype == 2)
options |= CL_DB_UNSIGNED;
else
options |= CL_DB_SIGNED | CL_DB_OFFICIAL;
ret = cli_tgzload(cfd, engine, signo, options, &dbio, dbinfo);
while(engine->dbinfo) {
while (engine->dbinfo) {
dbinfo = engine->dbinfo;
engine->dbinfo = dbinfo->next;
mpool_free(engine->mempool, dbinfo->name);
mpool_free(engine->mempool, dbinfo->hash);
if(dbinfo->cvd)
if (dbinfo->cvd)
cl_cvdfree(dbinfo->cvd);
mpool_free(engine->mempool, dbinfo);
}
@ -722,12 +718,11 @@ int cli_cvdunpack(const char *file, const char *dir)
{
int fd, ret;
fd = open(file, O_RDONLY|O_BINARY);
if(fd == -1)
fd = open(file, O_RDONLY | O_BINARY);
if (fd == -1)
return -1;
if(lseek(fd, 512, SEEK_SET) < 0) {
if (lseek(fd, 512, SEEK_SET) < 0) {
close(fd);
return -1;
}

View file

@ -53,103 +53,102 @@ struct dconf_module {
static struct dconf_module modules[] = {
{ "PE", "PARITE", PE_CONF_PARITE, 1 },
{ "PE", "KRIZ", PE_CONF_KRIZ, 1 },
{ "PE", "MAGISTR", PE_CONF_MAGISTR, 1 },
{ "PE", "POLIPOS", PE_CONF_POLIPOS, 1 },
{ "PE", "MD5SECT", PE_CONF_MD5SECT, 1 },
{ "PE", "UPX", PE_CONF_UPX, 1 },
{ "PE", "FSG", PE_CONF_FSG, 1 },
{ "PE", "SWIZZOR", PE_CONF_SWIZZOR, 0 },
{"PE", "PARITE", PE_CONF_PARITE, 1},
{"PE", "KRIZ", PE_CONF_KRIZ, 1},
{"PE", "MAGISTR", PE_CONF_MAGISTR, 1},
{"PE", "POLIPOS", PE_CONF_POLIPOS, 1},
{"PE", "MD5SECT", PE_CONF_MD5SECT, 1},
{"PE", "UPX", PE_CONF_UPX, 1},
{"PE", "FSG", PE_CONF_FSG, 1},
{"PE", "SWIZZOR", PE_CONF_SWIZZOR, 0},
{ "PE", "PETITE", PE_CONF_PETITE, 1 },
{ "PE", "PESPIN", PE_CONF_PESPIN, 1 },
{ "PE", "YC", PE_CONF_YC, 1 },
{ "PE", "WWPACK", PE_CONF_WWPACK, 1 },
{"PE", "PETITE", PE_CONF_PETITE, 1},
{"PE", "PESPIN", PE_CONF_PESPIN, 1},
{"PE", "YC", PE_CONF_YC, 1},
{"PE", "WWPACK", PE_CONF_WWPACK, 1},
{ "PE", "NSPACK", PE_CONF_NSPACK, 1 },
{ "PE", "MEW", PE_CONF_MEW, 1 },
{ "PE", "UPACK", PE_CONF_UPACK, 1 },
{ "PE", "ASPACK", PE_CONF_ASPACK, 1 },
{ "PE", "CATALOG", PE_CONF_CATALOG, 1 },
{ "PE", "CERTS", PE_CONF_CERTS, 1 },
{ "PE", "MATCHICON", PE_CONF_MATCHICON, 1 },
{ "PE", "IMPTBL", PE_CONF_IMPTBL, 1 },
{"PE", "NSPACK", PE_CONF_NSPACK, 1},
{"PE", "MEW", PE_CONF_MEW, 1},
{"PE", "UPACK", PE_CONF_UPACK, 1},
{"PE", "ASPACK", PE_CONF_ASPACK, 1},
{"PE", "CATALOG", PE_CONF_CATALOG, 1},
{"PE", "CERTS", PE_CONF_CERTS, 1},
{"PE", "MATCHICON", PE_CONF_MATCHICON, 1},
{"PE", "IMPTBL", PE_CONF_IMPTBL, 1},
{ "ELF", NULL, 0x1, 1 },
{"ELF", NULL, 0x1, 1},
{ "MACHO", NULL, 0x1, 1 },
{"MACHO", NULL, 0x1, 1},
{ "ARCHIVE", "RAR", ARCH_CONF_RAR, 1 },
{ "ARCHIVE", "ZIP", ARCH_CONF_ZIP, 1 },
{ "ARCHIVE", "GZIP", ARCH_CONF_GZ, 1 },
{ "ARCHIVE", "BZIP", ARCH_CONF_BZ, 1 },
{ "ARCHIVE", "ARJ", ARCH_CONF_ARJ, 1 },
{ "ARCHIVE", "SZDD", ARCH_CONF_SZDD, 1 },
{ "ARCHIVE", "CAB", ARCH_CONF_CAB, 1 },
{ "ARCHIVE", "CHM", ARCH_CONF_CHM, 1 },
{ "ARCHIVE", "OLE2", ARCH_CONF_OLE2, 1 },
{ "ARCHIVE", "TAR", ARCH_CONF_TAR, 1 },
{ "ARCHIVE", "CPIO", ARCH_CONF_CPIO, 1 },
{ "ARCHIVE", "BINHEX", ARCH_CONF_BINHEX, 1 },
{ "ARCHIVE", "SIS", ARCH_CONF_SIS, 1 },
{ "ARCHIVE", "NSIS", ARCH_CONF_NSIS, 1 },
{ "ARCHIVE", "AUTOIT", ARCH_CONF_AUTOIT, 1 },
{ "ARCHIVE", "ISHIELD", ARCH_CONF_ISHIELD, 1 },
{ "ARCHIVE", "7zip", ARCH_CONF_7Z, 1 },
{ "ARCHIVE", "ISO9660", ARCH_CONF_ISO9660, 1 },
{ "ARCHIVE", "DMG", ARCH_CONF_DMG, 1 },
{ "ARCHIVE", "XAR", ARCH_CONF_XAR, 1 },
{ "ARCHIVE", "HFSPLUS", ARCH_CONF_HFSPLUS, 1 },
{ "ARCHIVE", "XZ", ARCH_CONF_XZ, 1 },
{ "ARCHIVE", "PASSWD", ARCH_CONF_PASSWD, 1 },
{ "ARCHIVE", "MBR", ARCH_CONF_MBR, 1 },
{ "ARCHIVE", "GPT", ARCH_CONF_GPT, 1 },
{ "ARCHIVE", "APM", ARCH_CONF_APM, 1 },
{"ARCHIVE", "RAR", ARCH_CONF_RAR, 1},
{"ARCHIVE", "ZIP", ARCH_CONF_ZIP, 1},
{"ARCHIVE", "GZIP", ARCH_CONF_GZ, 1},
{"ARCHIVE", "BZIP", ARCH_CONF_BZ, 1},
{"ARCHIVE", "ARJ", ARCH_CONF_ARJ, 1},
{"ARCHIVE", "SZDD", ARCH_CONF_SZDD, 1},
{"ARCHIVE", "CAB", ARCH_CONF_CAB, 1},
{"ARCHIVE", "CHM", ARCH_CONF_CHM, 1},
{"ARCHIVE", "OLE2", ARCH_CONF_OLE2, 1},
{"ARCHIVE", "TAR", ARCH_CONF_TAR, 1},
{"ARCHIVE", "CPIO", ARCH_CONF_CPIO, 1},
{"ARCHIVE", "BINHEX", ARCH_CONF_BINHEX, 1},
{"ARCHIVE", "SIS", ARCH_CONF_SIS, 1},
{"ARCHIVE", "NSIS", ARCH_CONF_NSIS, 1},
{"ARCHIVE", "AUTOIT", ARCH_CONF_AUTOIT, 1},
{"ARCHIVE", "ISHIELD", ARCH_CONF_ISHIELD, 1},
{"ARCHIVE", "7zip", ARCH_CONF_7Z, 1},
{"ARCHIVE", "ISO9660", ARCH_CONF_ISO9660, 1},
{"ARCHIVE", "DMG", ARCH_CONF_DMG, 1},
{"ARCHIVE", "XAR", ARCH_CONF_XAR, 1},
{"ARCHIVE", "HFSPLUS", ARCH_CONF_HFSPLUS, 1},
{"ARCHIVE", "XZ", ARCH_CONF_XZ, 1},
{"ARCHIVE", "PASSWD", ARCH_CONF_PASSWD, 1},
{"ARCHIVE", "MBR", ARCH_CONF_MBR, 1},
{"ARCHIVE", "GPT", ARCH_CONF_GPT, 1},
{"ARCHIVE", "APM", ARCH_CONF_APM, 1},
{ "DOCUMENT", "HTML", DOC_CONF_HTML, 1 },
{ "DOCUMENT", "RTF", DOC_CONF_RTF, 1 },
{ "DOCUMENT", "PDF", DOC_CONF_PDF, 1 },
{ "DOCUMENT", "SCRIPT", DOC_CONF_SCRIPT, 1 },
{ "DOCUMENT", "HTMLSKIPRAW", DOC_CONF_HTML_SKIPRAW, 1 },
{ "DOCUMENT", "JSNORM", DOC_CONF_JSNORM, 1 },
{ "DOCUMENT", "SWF", DOC_CONF_SWF, 1 },
{ "DOCUMENT", "OOXML", DOC_CONF_OOXML, 1 },
{ "DOCUMENT", "MSPML", DOC_CONF_MSXML, 1 },
{ "DOCUMENT", "HWP", DOC_CONF_HWP, 1 },
{"DOCUMENT", "HTML", DOC_CONF_HTML, 1},
{"DOCUMENT", "RTF", DOC_CONF_RTF, 1},
{"DOCUMENT", "PDF", DOC_CONF_PDF, 1},
{"DOCUMENT", "SCRIPT", DOC_CONF_SCRIPT, 1},
{"DOCUMENT", "HTMLSKIPRAW", DOC_CONF_HTML_SKIPRAW, 1},
{"DOCUMENT", "JSNORM", DOC_CONF_JSNORM, 1},
{"DOCUMENT", "SWF", DOC_CONF_SWF, 1},
{"DOCUMENT", "OOXML", DOC_CONF_OOXML, 1},
{"DOCUMENT", "MSPML", DOC_CONF_MSXML, 1},
{"DOCUMENT", "HWP", DOC_CONF_HWP, 1},
{ "MAIL", "MBOX", MAIL_CONF_MBOX, 1 },
{ "MAIL", "TNEF", MAIL_CONF_TNEF, 1 },
{"MAIL", "MBOX", MAIL_CONF_MBOX, 1},
{"MAIL", "TNEF", MAIL_CONF_TNEF, 1},
{ "OTHER", "UUENCODED", OTHER_CONF_UUENC, 1 },
{ "OTHER", "SCRENC", OTHER_CONF_SCRENC, 1 },
{ "OTHER", "RIFF", OTHER_CONF_RIFF, 1 },
{ "OTHER", "JPEG", OTHER_CONF_JPEG, 1 },
{ "OTHER", "CRYPTFF", OTHER_CONF_CRYPTFF, 1 },
{ "OTHER", "DLP", OTHER_CONF_DLP, 1 },
{ "OTHER", "MYDOOMLOG", OTHER_CONF_MYDOOMLOG, 1 },
{ "OTHER", "PREFILTERING", OTHER_CONF_PREFILTERING,1 },
{ "OTHER", "PDFNAMEOBJ", OTHER_CONF_PDFNAMEOBJ, 1 },
{ "OTHER", "PRTNINTXN", OTHER_CONF_PRTNINTXN, 1 },
{ "OTHER", "LZW", OTHER_CONF_LZW, 1 },
{"OTHER", "UUENCODED", OTHER_CONF_UUENC, 1},
{"OTHER", "SCRENC", OTHER_CONF_SCRENC, 1},
{"OTHER", "RIFF", OTHER_CONF_RIFF, 1},
{"OTHER", "JPEG", OTHER_CONF_JPEG, 1},
{"OTHER", "CRYPTFF", OTHER_CONF_CRYPTFF, 1},
{"OTHER", "DLP", OTHER_CONF_DLP, 1},
{"OTHER", "MYDOOMLOG", OTHER_CONF_MYDOOMLOG, 1},
{"OTHER", "PREFILTERING", OTHER_CONF_PREFILTERING, 1},
{"OTHER", "PDFNAMEOBJ", OTHER_CONF_PDFNAMEOBJ, 1},
{"OTHER", "PRTNINTXN", OTHER_CONF_PRTNINTXN, 1},
{"OTHER", "LZW", OTHER_CONF_LZW, 1},
{ "PHISHING", "ENGINE", PHISHING_CONF_ENGINE, 1 },
{ "PHISHING", "ENTCONV", PHISHING_CONF_ENTCONV, 1 },
{"PHISHING", "ENGINE", PHISHING_CONF_ENGINE, 1},
{"PHISHING", "ENTCONV", PHISHING_CONF_ENTCONV, 1},
{ "BYTECODE", "INTERPRETER", BYTECODE_INTERPRETER, 1 },
{ "BYTECODE", "JIT X86", BYTECODE_JIT_X86, 1 },
{ "BYTECODE", "JIT PPC", BYTECODE_JIT_PPC, 1 },
{ "BYTECODE", "JIT ARM", BYTECODE_JIT_ARM, 0 },
{"BYTECODE", "INTERPRETER", BYTECODE_INTERPRETER, 1},
{"BYTECODE", "JIT X86", BYTECODE_JIT_X86, 1},
{"BYTECODE", "JIT PPC", BYTECODE_JIT_PPC, 1},
{"BYTECODE", "JIT ARM", BYTECODE_JIT_ARM, 0},
{ "STATS", "DISABLED", DCONF_STATS_DISABLED, 0 },
{ "STATS", "PESECTION DISABLED", DCONF_STATS_PE_SECTION_DISABLED, 0 },
{"STATS", "DISABLED", DCONF_STATS_DISABLED, 0},
{"STATS", "PESECTION DISABLED", DCONF_STATS_PE_SECTION_DISABLED, 0},
{ "PCRE", "SUPPORT", PCRE_CONF_SUPPORT, 1 },
{ "PCRE", "OPTIONS", PCRE_CONF_OPTIONS, 1 },
{ "PCRE", "GLOBAL", PCRE_CONF_GLOBAL, 1 },
{"PCRE", "SUPPORT", PCRE_CONF_SUPPORT, 1},
{"PCRE", "OPTIONS", PCRE_CONF_OPTIONS, 1},
{"PCRE", "GLOBAL", PCRE_CONF_GLOBAL, 1},
{ NULL, NULL, 0, 0 }
};
{NULL, NULL, 0, 0}};
#ifdef USE_MPOOL
struct cli_dconf *cli_dconf_init(mpool_t *mempool)
@ -160,42 +159,42 @@ struct cli_dconf *cli_dconf_init(void)
unsigned int i;
struct cli_dconf *dconf;
dconf = (struct cli_dconf *) mpool_calloc(mempool, sizeof(struct cli_dconf), 1);
if(!dconf)
dconf = (struct cli_dconf *)mpool_calloc(mempool, sizeof(struct cli_dconf), 1);
if (!dconf)
return NULL;
for(i = 0; modules[i].mname; i++) {
if(!strcmp(modules[i].mname, "PE")) {
if(modules[i].state)
for (i = 0; modules[i].mname; i++) {
if (!strcmp(modules[i].mname, "PE")) {
if (modules[i].state)
dconf->pe |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "ELF")) {
if(modules[i].state)
} else if (!strcmp(modules[i].mname, "ELF")) {
if (modules[i].state)
dconf->elf |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "MACHO")) {
if(modules[i].state)
} else if (!strcmp(modules[i].mname, "MACHO")) {
if (modules[i].state)
dconf->macho |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "ARCHIVE")) {
if(modules[i].state)
} else if (!strcmp(modules[i].mname, "ARCHIVE")) {
if (modules[i].state)
dconf->archive |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "DOCUMENT")) {
if(modules[i].state)
} else if (!strcmp(modules[i].mname, "DOCUMENT")) {
if (modules[i].state)
dconf->doc |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "MAIL")) {
if(modules[i].state)
} else if (!strcmp(modules[i].mname, "MAIL")) {
if (modules[i].state)
dconf->mail |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "OTHER")) {
if(modules[i].state)
} else if (!strcmp(modules[i].mname, "OTHER")) {
if (modules[i].state)
dconf->other |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "PHISHING")) {
if(modules[i].state)
} else if (!strcmp(modules[i].mname, "PHISHING")) {
if (modules[i].state)
dconf->phishing |= modules[i].bflag;
} else if(!strcmp(modules[i].mname, "BYTECODE")) {
} else if (!strcmp(modules[i].mname, "BYTECODE")) {
if (modules[i].state)
dconf->bytecode |= modules[i].bflag;
} else if (!strcmp(modules[i].mname, "STATS")) {
@ -213,90 +212,89 @@ struct cli_dconf *cli_dconf_init(void)
void cli_dconf_print(struct cli_dconf *dconf)
{
unsigned int pe = 0, elf = 0, macho = 0, arch = 0, doc = 0, mail = 0;
unsigned int other = 0, phishing = 0, i, bytecode=0, stats=0, pcre=0;
unsigned int other = 0, phishing = 0, i, bytecode = 0, stats = 0, pcre = 0;
cli_dbgmsg("Dynamic engine configuration settings:\n");
cli_dbgmsg("--------------------------------------\n");
for(i = 0; modules[i].mname; i++) {
if(!strcmp(modules[i].mname, "PE")) {
if(!pe) {
for (i = 0; modules[i].mname; i++) {
if (!strcmp(modules[i].mname, "PE")) {
if (!pe) {
cli_dbgmsg("Module PE: %s\n", dconf->pe ? "On" : "Off");
pe = 1;
}
if(dconf->pe)
if (dconf->pe)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->pe & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "ELF")) {
if(!elf) {
} else if (!strcmp(modules[i].mname, "ELF")) {
if (!elf) {
cli_dbgmsg("Module ELF: %s\n", dconf->elf ? "On" : "Off");
elf = 1;
}
} else if(!strcmp(modules[i].mname, "MACHO")) {
if(!macho) {
} else if (!strcmp(modules[i].mname, "MACHO")) {
if (!macho) {
cli_dbgmsg("Module MACHO: %s\n", dconf->elf ? "On" : "Off");
macho = 1;
}
} else if(!strcmp(modules[i].mname, "ARCHIVE")) {
if(!arch) {
} else if (!strcmp(modules[i].mname, "ARCHIVE")) {
if (!arch) {
cli_dbgmsg("Module ARCHIVE: %s\n", dconf->archive ? "On" : "Off");
arch = 1;
}
if(dconf->archive)
if (dconf->archive)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->archive & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "DOCUMENT")) {
if(!doc) {
} else if (!strcmp(modules[i].mname, "DOCUMENT")) {
if (!doc) {
cli_dbgmsg("Module DOCUMENT: %s\n", dconf->doc ? "On" : "Off");
doc = 1;
}
if(dconf->doc)
if (dconf->doc)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->doc & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "MAIL")) {
if(!mail) {
} else if (!strcmp(modules[i].mname, "MAIL")) {
if (!mail) {
cli_dbgmsg("Module MAIL: %s\n", dconf->mail ? "On" : "Off");
mail = 1;
}
if(dconf->mail)
if (dconf->mail)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->mail & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "OTHER")) {
if(!other) {
} else if (!strcmp(modules[i].mname, "OTHER")) {
if (!other) {
cli_dbgmsg("Module OTHER: %s\n", dconf->other ? "On" : "Off");
other = 1;
}
if(dconf->other)
if (dconf->other)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->other & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "PHISHING")) {
if(!phishing) {
} else if (!strcmp(modules[i].mname, "PHISHING")) {
if (!phishing) {
cli_dbgmsg("Module PHISHING %s\n", dconf->phishing ? "On" : "Off");
phishing = 1;
}
if(dconf->phishing)
if (dconf->phishing)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->phishing & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if(!strcmp(modules[i].mname, "BYTECODE")) {
if(!bytecode) {
} else if (!strcmp(modules[i].mname, "BYTECODE")) {
if (!bytecode) {
cli_dbgmsg("Module BYTECODE %s\n", dconf->bytecode ? "On" : "Off");
bytecode = 1;
}
if(dconf->bytecode)
if (dconf->bytecode)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->bytecode & modules[i].bflag) ? "On" : "** Off **");
else
continue;
@ -337,27 +335,26 @@ static int chkflevel(const char *entry, int field)
{
char *pt;
if((pt = cli_strtok(entry, field, ":"))) { /* min version */
if(!isdigit(*pt)) {
if ((pt = cli_strtok(entry, field, ":"))) { /* min version */
if (!isdigit(*pt)) {
free(pt);
return 0;
}
if((unsigned int) atoi(pt) > CL_FLEVEL_DCONF) {
if ((unsigned int)atoi(pt) > CL_FLEVEL_DCONF) {
free(pt);
return 0;
}
free(pt);
if((pt = cli_strtok(entry, field + 1, ":"))) { /* max version */
if(!isdigit(*pt)) {
if ((pt = cli_strtok(entry, field + 1, ":"))) { /* max version */
if (!isdigit(*pt)) {
free(pt);
return 0;
}
if((unsigned int) atoi(pt) < CL_FLEVEL_DCONF) {
if ((unsigned int)atoi(pt) < CL_FLEVEL_DCONF) {
free(pt);
return 0;
}
@ -378,12 +375,12 @@ int cli_dconf_load(FILE *fs, struct cl_engine *engine, unsigned int options, str
UNUSEDPARAM(options);
while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) {
while (cli_dbgets(buffer, FILEBUFF, fs, dbio)) {
line++;
cli_chomp(buffer);
if(!strncmp(buffer, "PE:", 3) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 3, "0x%x", &val) == 1) {
if (!strncmp(buffer, "PE:", 3) && chkflevel(buffer, 2)) {
if (sscanf(buffer + 3, "0x%x", &val) == 1) {
engine->dconf->pe = val;
} else {
ret = CL_EMALFDB;
@ -391,8 +388,8 @@ int cli_dconf_load(FILE *fs, struct cl_engine *engine, unsigned int options, str
}
}
if(!strncmp(buffer, "ELF:", 4) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 4, "0x%x", &val) == 1) {
if (!strncmp(buffer, "ELF:", 4) && chkflevel(buffer, 2)) {
if (sscanf(buffer + 4, "0x%x", &val) == 1) {
engine->dconf->elf = val;
} else {
ret = CL_EMALFDB;
@ -400,8 +397,8 @@ int cli_dconf_load(FILE *fs, struct cl_engine *engine, unsigned int options, str
}
}
if(!strncmp(buffer, "MACHO:", 6) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 6, "0x%x", &val) == 1) {
if (!strncmp(buffer, "MACHO:", 6) && chkflevel(buffer, 2)) {
if (sscanf(buffer + 6, "0x%x", &val) == 1) {
engine->dconf->macho = val;
} else {
ret = CL_EMALFDB;
@ -409,8 +406,8 @@ int cli_dconf_load(FILE *fs, struct cl_engine *engine, unsigned int options, str
}
}
if(!strncmp(buffer, "ARCHIVE:", 8) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 8, "0x%x", &val) == 1) {
if (!strncmp(buffer, "ARCHIVE:", 8) && chkflevel(buffer, 2)) {
if (sscanf(buffer + 8, "0x%x", &val) == 1) {
engine->dconf->archive = val;
} else {
ret = CL_EMALFDB;
@ -418,8 +415,8 @@ int cli_dconf_load(FILE *fs, struct cl_engine *engine, unsigned int options, str
}
}
if(!strncmp(buffer, "DOCUMENT:", 9) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 9, "0x%x", &val) == 1) {
if (!strncmp(buffer, "DOCUMENT:", 9) && chkflevel(buffer, 2)) {
if (sscanf(buffer + 9, "0x%x", &val) == 1) {
engine->dconf->doc = val;
} else {
ret = CL_EMALFDB;
@ -427,8 +424,8 @@ int cli_dconf_load(FILE *fs, struct cl_engine *engine, unsigned int options, str
}
}
if(!strncmp(buffer, "MAIL:", 5) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 5, "0x%x", &val) == 1) {
if (!strncmp(buffer, "MAIL:", 5) && chkflevel(buffer, 2)) {
if (sscanf(buffer + 5, "0x%x", &val) == 1) {
engine->dconf->mail = val;
} else {
ret = CL_EMALFDB;
@ -436,8 +433,8 @@ int cli_dconf_load(FILE *fs, struct cl_engine *engine, unsigned int options, str
}
}
if(!strncmp(buffer, "OTHER:", 6) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 6, "0x%x", &val) == 1) {
if (!strncmp(buffer, "OTHER:", 6) && chkflevel(buffer, 2)) {
if (sscanf(buffer + 6, "0x%x", &val) == 1) {
engine->dconf->other = val;
} else {
ret = CL_EMALFDB;
@ -445,8 +442,8 @@ int cli_dconf_load(FILE *fs, struct cl_engine *engine, unsigned int options, str
}
}
if(!strncmp(buffer, "PHISHING:", 9) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 9, "0x%x", &val) == 1) {
if (!strncmp(buffer, "PHISHING:", 9) && chkflevel(buffer, 2)) {
if (sscanf(buffer + 9, "0x%x", &val) == 1) {
engine->dconf->phishing = val;
} else {
ret = CL_EMALFDB;
@ -454,8 +451,8 @@ int cli_dconf_load(FILE *fs, struct cl_engine *engine, unsigned int options, str
}
}
if(!strncmp(buffer, "BYTECODE:", 9) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 9, "0x%x", &val) == 1) {
if (!strncmp(buffer, "BYTECODE:", 9) && chkflevel(buffer, 2)) {
if (sscanf(buffer + 9, "0x%x", &val) == 1) {
engine->dconf->bytecode = val;
} else {
ret = CL_EMALFDB;
@ -463,8 +460,8 @@ int cli_dconf_load(FILE *fs, struct cl_engine *engine, unsigned int options, str
}
}
if(!strncmp(buffer, "STATS:", 6) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 6, "0x%x", &val) == 1) {
if (!strncmp(buffer, "STATS:", 6) && chkflevel(buffer, 2)) {
if (sscanf(buffer + 6, "0x%x", &val) == 1) {
engine->dconf->stats = val;
} else {
ret = CL_EMALFDB;
@ -472,8 +469,8 @@ int cli_dconf_load(FILE *fs, struct cl_engine *engine, unsigned int options, str
}
}
if(!strncmp(buffer, "PCRE:", 5) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 5, "0x%x", &val) == 1) {
if (!strncmp(buffer, "PCRE:", 5) && chkflevel(buffer, 2)) {
if (sscanf(buffer + 5, "0x%x", &val) == 1) {
engine->dconf->pcre = val;
} else {
ret = CL_EMALFDB;
@ -482,7 +479,7 @@ int cli_dconf_load(FILE *fs, struct cl_engine *engine, unsigned int options, str
}
}
if(ret) {
if (ret) {
cli_errmsg("Problem parsing configuration file at line %u\n", line);
return ret;
}

View file

@ -26,293 +26,293 @@
/** X86 opcode */
enum X86OPS {
OP_INVALID,
OP_AAA,/**< Ascii Adjust after Addition */
OP_AAD,/**< Ascii Adjust AX before Division */
OP_AAM,/**< Ascii Adjust AX after Multiply */
OP_AAS,/**< Ascii Adjust AL after Subtraction */
OP_ADD,/**< Add */
OP_ADC,/**< Add with Carry */
OP_AND,/**< Logical And */
OP_ARPL,/**< Adjust Requested Privilege Level */
OP_BOUND,/**< Check Array Index Against Bounds */
OP_BSF,/**< Bit Scan Forward */
OP_BSR,/**< Bit Scan Reverse */
OP_BSWAP,/**< Byte Swap */
OP_BT,/**< Bit Test */
OP_BTC,/**< Bit Test and Complement */
OP_BTR,/**< Bit Test and Reset */
OP_BTS,/**< Bit Test and Set */
OP_CALL,/**< Call */
OP_CDQ,/**< Convert DoubleWord to QuadWord*/
OP_AAA, /**< Ascii Adjust after Addition */
OP_AAD, /**< Ascii Adjust AX before Division */
OP_AAM, /**< Ascii Adjust AX after Multiply */
OP_AAS, /**< Ascii Adjust AL after Subtraction */
OP_ADD, /**< Add */
OP_ADC, /**< Add with Carry */
OP_AND, /**< Logical And */
OP_ARPL, /**< Adjust Requested Privilege Level */
OP_BOUND, /**< Check Array Index Against Bounds */
OP_BSF, /**< Bit Scan Forward */
OP_BSR, /**< Bit Scan Reverse */
OP_BSWAP, /**< Byte Swap */
OP_BT, /**< Bit Test */
OP_BTC, /**< Bit Test and Complement */
OP_BTR, /**< Bit Test and Reset */
OP_BTS, /**< Bit Test and Set */
OP_CALL, /**< Call */
OP_CDQ, /**< Convert DoubleWord to QuadWord*/
OP_CWD,
OP_CWDE,/**< Convert Word to DoubleWord */
OP_CBW,/**< Convert Byte to Word */
OP_CLC,/**< Clear Carry Flag */
OP_CLD,/**< Clear Direction Flag */
OP_CLI,/**< Clear Interrupt Flag */
OP_CLTS,/**< Clear Task-Switched Flag in CR0 */
OP_CMC,/**< Complement Carry Flag */
OP_CMOVO,/**< Conditional Move if Overflow */
OP_CMOVNO,/**< Conditional Move if Not Overflow */
OP_CMOVC,/**< Conditional Move if Carry */
OP_CMOVNC,/**< Conditional Move if Not Carry */
OP_CMOVZ,/**< Conditional Move if Zero */
OP_CMOVNZ,/**< Conditional Move if Non-Zero */
OP_CMOVBE,/**< Conditional Move if Below or Equal */
OP_CMOVA,/**< Conditional Move if Above */
OP_CMOVS,/**< Conditional Move if Sign */
OP_CMOVNS,/**< Conditional Move if Not Sign */
OP_CMOVP,/**< Conditional Move if Parity */
OP_CMOVNP,/**< Conditional Move if Not Parity */
OP_CMOVL,/**< Conditional Move if Less */
OP_CMOVGE,/**< Conditional Move if Greater or Equal */
OP_CMOVLE,/**< Conditional Move if Less than or Equal */
OP_CMOVG,/**< Conditional Move if Greater */
OP_CMP,/**< Compare */
OP_CMPSD,/**< Compare String DoubleWord */
OP_CMPSW,/**< Compare String Word */
OP_CMPSB,/**< Compare String Byte */
OP_CMPXCHG,/**< Compare and Exchange */
OP_CMPXCHG8B,/**< Compare and Exchange Bytes */
OP_CPUID,/**< CPU Identification */
OP_DAA,/**< Decimal Adjust AL after Addition */
OP_DAS,/**< Decimal Adjust AL after Subtraction */
OP_DEC,/**< Decrement by 1 */
OP_DIV,/**< Unsigned Divide */
OP_ENTER,/**< Make Stack Frame for Procedure Parameters */
OP_FWAIT,/**< Wait */
OP_HLT,/**< Halt */
OP_IDIV,/**< Signed Divide */
OP_IMUL,/**< Signed Multiply */
OP_INC,/**< Increment by 1 */
OP_IN,/**< INput from port */
OP_INSD,/**< INput from port to String Doubleword */
OP_INSW,/**< INput from port to String Word */
OP_INSB,/**< INput from port to String Byte */
OP_INT,/**< INTerrupt */
OP_INT3,/**< INTerrupt 3 (breakpoint) */
OP_INTO,/**< INTerrupt 4 if Overflow */
OP_INVD,/**< Invalidate Internal Caches */
OP_INVLPG,/**< Invalidate TLB Entry */
OP_IRET,/**< Interrupt Return */
OP_JO,/**< Jump if Overflow */
OP_JNO,/**< Jump if Not Overflow */
OP_JC,/**< Jump if Carry */
OP_JNC,/**< Jump if Not Carry */
OP_JZ,/**< Jump if Zero */
OP_JNZ,/**< Jump if Not Zero */
OP_JBE,/**< Jump if Below or Equal */
OP_JA,/**< Jump if Above */
OP_JS,/**< Jump if Sign */
OP_JNS,/**< Jump if Not Sign */
OP_JP,/**< Jump if Parity */
OP_JNP,/**< Jump if Not Parity */
OP_JL,/**< Jump if Less */
OP_JGE,/**< Jump if Greater or Equal */
OP_JLE,/**< Jump if Less or Equal */
OP_JG,/**< Jump if Greater */
OP_JMP,/**< Jump (unconditional) */
OP_LAHF,/**< Load Status Flags into AH Register */
OP_LAR,/**< load Access Rights Byte */
OP_LDS,/**< Load Far Pointer into DS */
OP_LES,/**< Load Far Pointer into ES */
OP_LFS,/**< Load Far Pointer into FS */
OP_LGS,/**< Load Far Pointer into GS */
OP_LEA,/**< Load Effective Address */
OP_LEAVE,/**< High Level Procedure Exit */
OP_LGDT,/**< Load Global Descript Table Register */
OP_LIDT,/**< Load Interrupt Descriptor Table Register */
OP_LLDT,/**< Load Local Descriptor Table Register */
OP_PREFIX_LOCK,/**< Assert LOCK# Signal Prefix */
OP_LODSD,/**< Load String Dword*/
OP_LODSW,/**< Load String Word */
OP_LODSB,/**< Load String Byte */
OP_LOOP,/**< Loop According to ECX Counter */
OP_LOOPE,/**< Loop According to ECX Counter and ZF=1 */
OP_LOOPNE,/**< Loop According to ECX Counter and ZF=0 */
OP_JECXZ,/**< Jump if ECX is Zero */
OP_LSL,/**< Load Segment Limit */
OP_LSS,/**< Load Far Pointer into SS */
OP_LTR,/**< Load Task Register */
OP_MOV,/**< Move */
OP_MOVSD,/**< Move Data from String to String Doubleword */
OP_MOVSW,/**< Move Data from String to String Word */
OP_MOVSB,/**< Move Data from String to String Byte */
OP_MOVSX,/**< Move with Sign-Extension */
OP_MOVZX,/**< Move with Zero-Extension */
OP_MUL,/**< Unsigned Multiply */
OP_NEG,/**< Two's Complement Negation */
OP_NOP,/**< No Operation */
OP_NOT,/**< One's Complement Negation */
OP_OR,/**< Logical Inclusive OR */
OP_OUT,/**< Output to Port */
OP_OUTSD,/**< Output String to Port Doubleword */
OP_OUTSW,/**< Output String to Port Word */
OP_OUTSB,/**< Output String to Port Bytes */
OP_PUSH,/**< Push Onto the Stack */
OP_PUSHAD,/**< Push All Double General Purpose Registers */
OP_CWDE, /**< Convert Word to DoubleWord */
OP_CBW, /**< Convert Byte to Word */
OP_CLC, /**< Clear Carry Flag */
OP_CLD, /**< Clear Direction Flag */
OP_CLI, /**< Clear Interrupt Flag */
OP_CLTS, /**< Clear Task-Switched Flag in CR0 */
OP_CMC, /**< Complement Carry Flag */
OP_CMOVO, /**< Conditional Move if Overflow */
OP_CMOVNO, /**< Conditional Move if Not Overflow */
OP_CMOVC, /**< Conditional Move if Carry */
OP_CMOVNC, /**< Conditional Move if Not Carry */
OP_CMOVZ, /**< Conditional Move if Zero */
OP_CMOVNZ, /**< Conditional Move if Non-Zero */
OP_CMOVBE, /**< Conditional Move if Below or Equal */
OP_CMOVA, /**< Conditional Move if Above */
OP_CMOVS, /**< Conditional Move if Sign */
OP_CMOVNS, /**< Conditional Move if Not Sign */
OP_CMOVP, /**< Conditional Move if Parity */
OP_CMOVNP, /**< Conditional Move if Not Parity */
OP_CMOVL, /**< Conditional Move if Less */
OP_CMOVGE, /**< Conditional Move if Greater or Equal */
OP_CMOVLE, /**< Conditional Move if Less than or Equal */
OP_CMOVG, /**< Conditional Move if Greater */
OP_CMP, /**< Compare */
OP_CMPSD, /**< Compare String DoubleWord */
OP_CMPSW, /**< Compare String Word */
OP_CMPSB, /**< Compare String Byte */
OP_CMPXCHG, /**< Compare and Exchange */
OP_CMPXCHG8B, /**< Compare and Exchange Bytes */
OP_CPUID, /**< CPU Identification */
OP_DAA, /**< Decimal Adjust AL after Addition */
OP_DAS, /**< Decimal Adjust AL after Subtraction */
OP_DEC, /**< Decrement by 1 */
OP_DIV, /**< Unsigned Divide */
OP_ENTER, /**< Make Stack Frame for Procedure Parameters */
OP_FWAIT, /**< Wait */
OP_HLT, /**< Halt */
OP_IDIV, /**< Signed Divide */
OP_IMUL, /**< Signed Multiply */
OP_INC, /**< Increment by 1 */
OP_IN, /**< INput from port */
OP_INSD, /**< INput from port to String Doubleword */
OP_INSW, /**< INput from port to String Word */
OP_INSB, /**< INput from port to String Byte */
OP_INT, /**< INTerrupt */
OP_INT3, /**< INTerrupt 3 (breakpoint) */
OP_INTO, /**< INTerrupt 4 if Overflow */
OP_INVD, /**< Invalidate Internal Caches */
OP_INVLPG, /**< Invalidate TLB Entry */
OP_IRET, /**< Interrupt Return */
OP_JO, /**< Jump if Overflow */
OP_JNO, /**< Jump if Not Overflow */
OP_JC, /**< Jump if Carry */
OP_JNC, /**< Jump if Not Carry */
OP_JZ, /**< Jump if Zero */
OP_JNZ, /**< Jump if Not Zero */
OP_JBE, /**< Jump if Below or Equal */
OP_JA, /**< Jump if Above */
OP_JS, /**< Jump if Sign */
OP_JNS, /**< Jump if Not Sign */
OP_JP, /**< Jump if Parity */
OP_JNP, /**< Jump if Not Parity */
OP_JL, /**< Jump if Less */
OP_JGE, /**< Jump if Greater or Equal */
OP_JLE, /**< Jump if Less or Equal */
OP_JG, /**< Jump if Greater */
OP_JMP, /**< Jump (unconditional) */
OP_LAHF, /**< Load Status Flags into AH Register */
OP_LAR, /**< load Access Rights Byte */
OP_LDS, /**< Load Far Pointer into DS */
OP_LES, /**< Load Far Pointer into ES */
OP_LFS, /**< Load Far Pointer into FS */
OP_LGS, /**< Load Far Pointer into GS */
OP_LEA, /**< Load Effective Address */
OP_LEAVE, /**< High Level Procedure Exit */
OP_LGDT, /**< Load Global Descript Table Register */
OP_LIDT, /**< Load Interrupt Descriptor Table Register */
OP_LLDT, /**< Load Local Descriptor Table Register */
OP_PREFIX_LOCK, /**< Assert LOCK# Signal Prefix */
OP_LODSD, /**< Load String Dword*/
OP_LODSW, /**< Load String Word */
OP_LODSB, /**< Load String Byte */
OP_LOOP, /**< Loop According to ECX Counter */
OP_LOOPE, /**< Loop According to ECX Counter and ZF=1 */
OP_LOOPNE, /**< Loop According to ECX Counter and ZF=0 */
OP_JECXZ, /**< Jump if ECX is Zero */
OP_LSL, /**< Load Segment Limit */
OP_LSS, /**< Load Far Pointer into SS */
OP_LTR, /**< Load Task Register */
OP_MOV, /**< Move */
OP_MOVSD, /**< Move Data from String to String Doubleword */
OP_MOVSW, /**< Move Data from String to String Word */
OP_MOVSB, /**< Move Data from String to String Byte */
OP_MOVSX, /**< Move with Sign-Extension */
OP_MOVZX, /**< Move with Zero-Extension */
OP_MUL, /**< Unsigned Multiply */
OP_NEG, /**< Two's Complement Negation */
OP_NOP, /**< No Operation */
OP_NOT, /**< One's Complement Negation */
OP_OR, /**< Logical Inclusive OR */
OP_OUT, /**< Output to Port */
OP_OUTSD, /**< Output String to Port Doubleword */
OP_OUTSW, /**< Output String to Port Word */
OP_OUTSB, /**< Output String to Port Bytes */
OP_PUSH, /**< Push Onto the Stack */
OP_PUSHAD, /**< Push All Double General Purpose Registers */
OP_PUSHA,
OP_PUSHFD,/**< Push EFLAGS Register onto the Stack */
OP_PUSHFD, /**< Push EFLAGS Register onto the Stack */
OP_PUSHF,
OP_POP,/**< Pop a Value from the Stack */
OP_POPAD,/**< Pop All Double General Purpose Registers from the Stack */
OP_POPFD,/**< Pop Stack into EFLAGS Register */
OP_POP, /**< Pop a Value from the Stack */
OP_POPAD, /**< Pop All Double General Purpose Registers from the Stack */
OP_POPFD, /**< Pop Stack into EFLAGS Register */
OP_POPF,
OP_RCL,/**< Rotate Carry Left */
OP_RCR,/**< Rotate Carry Right */
OP_RDMSR,/**< Read from Model Specific Register */
OP_RDPMC,/**< Read Performance Monitoring Counters */
OP_RDTSC,/**< Read Time-Stamp Counter */
OP_PREFIX_REPE,/**< Repeat String Operation Prefix while Equal */
OP_PREFIX_REPNE,/**< Repeat String Operation Prefix while Not Equal */
OP_RETF,/**< Return from Far Procedure */
OP_RETN,/**< Return from Near Procedure */
OP_ROL,/**< Rotate Left */
OP_ROR,/**< Rotate Right */
OP_RSM,/**< Resume from System Management Mode */
OP_SAHF,/**< Store AH into Flags */
OP_SAR,/**< Shift Arithmetic Right */
OP_SBB,/**< Subtract with Borrow */
OP_SCASD,/**< Scan String Doubleword */
OP_SCASW,/**< Scan String Word */
OP_SCASB,/**< Scan String Byte */
OP_SETO,/**< Set Byte on Overflow */
OP_SETNO,/**< Set Byte on Not Overflow */
OP_SETC,/**< Set Byte on Carry */
OP_SETNC,/**< Set Byte on Not Carry */
OP_SETZ,/**< Set Byte on Zero */
OP_SETNZ,/**< Set Byte on Not Zero */
OP_SETBE,/**< Set Byte on Below or Equal */
OP_SETA,/**< Set Byte on Above */
OP_SETS,/**< Set Byte on Sign */
OP_SETNS,/**< Set Byte on Not Sign */
OP_SETP,/**< Set Byte on Parity */
OP_SETNP,/**< Set Byte on Not Parity */
OP_SETL,/**< Set Byte on Less */
OP_SETGE,/**< Set Byte on Greater or Equal */
OP_SETLE,/**< Set Byte on Less or Equal */
OP_SETG,/**< Set Byte on Greater */
OP_SGDT,/**< Store Global Descriptor Table Register */
OP_SIDT,/**< Store Interrupt Descriptor Table Register */
OP_SHL,/**< Shift Left */
OP_SHLD,/**< Double Precision Shift Left */
OP_SHR,/**< Shift Right */
OP_SHRD,/**< Double Precision Shift Right */
OP_SLDT,/**< Store Local Descriptor Table Register */
OP_STOSD,/**< Store String Doubleword */
OP_STOSW,/**< Store String Word */
OP_STOSB,/**< Store String Byte */
OP_STR,/**< Store Task Register */
OP_STC,/**< Set Carry Flag */
OP_STD,/**< Set Direction Flag */
OP_STI,/**< Set Interrupt Flag */
OP_SUB,/**< Subtract */
OP_SYSCALL,/**< Fast System Call */
OP_SYSENTER,/**< Fast System Call */
OP_SYSEXIT,/**< Fast Return from Fast System Call */
OP_SYSRET,/**< Return from Fast System Call */
OP_TEST,/**< Logical Compare */
OP_UD2,/**< Undefined Instruction */
OP_VERR,/**< Verify a Segment for Reading */
OP_VERRW,/**< Verify a Segment for Writing */
OP_WBINVD,/**< Write Back and Invalidate Cache */
OP_WRMSR,/**< Write to Model Specific Register */
OP_XADD,/**< Exchange and Add */
OP_XCHG,/**< Exchange Register/Memory with Register */
OP_XLAT,/**< Table Look-up Translation */
OP_XOR,/**< Logical Exclusive OR */
OP_RCL, /**< Rotate Carry Left */
OP_RCR, /**< Rotate Carry Right */
OP_RDMSR, /**< Read from Model Specific Register */
OP_RDPMC, /**< Read Performance Monitoring Counters */
OP_RDTSC, /**< Read Time-Stamp Counter */
OP_PREFIX_REPE, /**< Repeat String Operation Prefix while Equal */
OP_PREFIX_REPNE, /**< Repeat String Operation Prefix while Not Equal */
OP_RETF, /**< Return from Far Procedure */
OP_RETN, /**< Return from Near Procedure */
OP_ROL, /**< Rotate Left */
OP_ROR, /**< Rotate Right */
OP_RSM, /**< Resume from System Management Mode */
OP_SAHF, /**< Store AH into Flags */
OP_SAR, /**< Shift Arithmetic Right */
OP_SBB, /**< Subtract with Borrow */
OP_SCASD, /**< Scan String Doubleword */
OP_SCASW, /**< Scan String Word */
OP_SCASB, /**< Scan String Byte */
OP_SETO, /**< Set Byte on Overflow */
OP_SETNO, /**< Set Byte on Not Overflow */
OP_SETC, /**< Set Byte on Carry */
OP_SETNC, /**< Set Byte on Not Carry */
OP_SETZ, /**< Set Byte on Zero */
OP_SETNZ, /**< Set Byte on Not Zero */
OP_SETBE, /**< Set Byte on Below or Equal */
OP_SETA, /**< Set Byte on Above */
OP_SETS, /**< Set Byte on Sign */
OP_SETNS, /**< Set Byte on Not Sign */
OP_SETP, /**< Set Byte on Parity */
OP_SETNP, /**< Set Byte on Not Parity */
OP_SETL, /**< Set Byte on Less */
OP_SETGE, /**< Set Byte on Greater or Equal */
OP_SETLE, /**< Set Byte on Less or Equal */
OP_SETG, /**< Set Byte on Greater */
OP_SGDT, /**< Store Global Descriptor Table Register */
OP_SIDT, /**< Store Interrupt Descriptor Table Register */
OP_SHL, /**< Shift Left */
OP_SHLD, /**< Double Precision Shift Left */
OP_SHR, /**< Shift Right */
OP_SHRD, /**< Double Precision Shift Right */
OP_SLDT, /**< Store Local Descriptor Table Register */
OP_STOSD, /**< Store String Doubleword */
OP_STOSW, /**< Store String Word */
OP_STOSB, /**< Store String Byte */
OP_STR, /**< Store Task Register */
OP_STC, /**< Set Carry Flag */
OP_STD, /**< Set Direction Flag */
OP_STI, /**< Set Interrupt Flag */
OP_SUB, /**< Subtract */
OP_SYSCALL, /**< Fast System Call */
OP_SYSENTER, /**< Fast System Call */
OP_SYSEXIT, /**< Fast Return from Fast System Call */
OP_SYSRET, /**< Return from Fast System Call */
OP_TEST, /**< Logical Compare */
OP_UD2, /**< Undefined Instruction */
OP_VERR, /**< Verify a Segment for Reading */
OP_VERRW, /**< Verify a Segment for Writing */
OP_WBINVD, /**< Write Back and Invalidate Cache */
OP_WRMSR, /**< Write to Model Specific Register */
OP_XADD, /**< Exchange and Add */
OP_XCHG, /**< Exchange Register/Memory with Register */
OP_XLAT, /**< Table Look-up Translation */
OP_XOR, /**< Logical Exclusive OR */
OP_PREFIX_OPSIZE,
OP_PREFIX_ADDRSIZE,
OP_PREFIX_SEGMENT,
OP_2BYTE,
OP_FPU,/**< FPU operation */
OP_FPU, /**< FPU operation */
OP_F2XM1,/**< Compute 2x-1 */
OP_FABS,/**< Absolute Value */
OP_FADD,/**< Floating Point Add */
OP_FADDP,/**< Floating Point Add, Pop */
OP_FBLD,/**< Load Binary Coded Decimal */
OP_FBSTP,/**< Store BCD Integer and Pop */
OP_FCHS,/**< Change Sign */
OP_FCLEX,/**< Clear Exceptions */
OP_FCMOVB,/**< Floating Point Move on Below */
OP_FCMOVBE,/**< Floating Point Move on Below or Equal */
OP_FCMOVE,/**< Floating Point Move on Equal */
OP_FCMOVNB,/**< Floating Point Move on Not Below */
OP_FCMOVNBE,/**< Floating Point Move on Not Below or Equal */
OP_FCMOVNE,/**< Floating Point Move on Not Equal */
OP_FCMOVNU,/**< Floating Point Move on Not Unordered */
OP_FCMOVU,/**< Floating Point Move on Unordered */
OP_FCOM,/**< Compare Floating Pointer Values and Set FPU Flags */
OP_FCOMI,/**< Compare Floating Pointer Values and Set EFLAGS */
OP_FCOMIP,/**< Compare Floating Pointer Values and Set EFLAGS, Pop */
OP_FCOMP,/**< Compare Floating Pointer Values and Set FPU Flags, Pop */
OP_FCOMPP,/**< Compare Floating Pointer Values and Set FPU Flags, Pop Twice */
OP_FCOS,/**< Cosine */
OP_FDECSTP,/**< Decrement Stack Top Pointer */
OP_FDIV,/**< Floating Point Divide */
OP_FDIVP,/**< Floating Point Divide, Pop */
OP_FDIVR,/**< Floating Point Reverse Divide */
OP_FDIVRP,/**< Floating Point Reverse Divide, Pop */
OP_FFREE,/**< Free Floating Point Register */
OP_FIADD,/**< Floating Point Add */
OP_FICOM,/**< Compare Integer */
OP_FICOMP,/**< Compare Integer, Pop */
OP_FIDIV,/**< Floating Point Divide by Integer */
OP_FIDIVR,/**< Floating Point Reverse Divide by Integer */
OP_FILD,/**< Load Integer */
OP_FIMUL,/**< Floating Point Multiply with Integer */
OP_FINCSTP,/**< Increment Stack-Top Pointer */
OP_FINIT,/**< Initialize Floating-Point Unit */
OP_FIST,/**< Store Integer */
OP_FISTP,/**< Store Integer, Pop */
OP_FISTTP,/**< Store Integer with Truncation */
OP_FISUB,/**< Floating Point Integer Subtract */
OP_FISUBR,/**< Floating Point Reverse Integer Subtract */
OP_FLD,/**< Load Floating Point Value */
OP_FLD1,/**< Load Constant 1 */
OP_FLDCW,/**< Load x87 FPU Control Word */
OP_FLDENV,/**< Load x87 FPU Environment */
OP_FLDL2E,/**< Load Constant log_2(e) */
OP_FLDL2T,/**< Load Constant log_2(10) */
OP_FLDLG2,/**< Load Constant log_10(2) */
OP_FLDLN2,/**< Load Constant log_e(2) */
OP_FLDPI,/**< Load Constant PI */
OP_FLDZ,/**< Load Constant Zero */
OP_FMUL,/**< Floating Point Multiply */
OP_FMULP,/**< Floating Point Multiply, Pop */
OP_FNOP,/**< No Operation */
OP_FPATAN,/**< Partial Arctangent */
OP_FPREM,/**< Partial Remainder */
OP_FPREM1,/**< Partial Remainder */
OP_FPTAN,/**< Partial Tangent */
OP_FRNDINT,/**< Round to Integer */
OP_FRSTOR,/**< Restore x86 FPU State */
OP_FSCALE,/**< Scale */
OP_FSIN,/* Sine */
OP_FSINCOS,/**< Sine and Cosine */
OP_FSQRT,/**< Square Root */
OP_FSAVE,/**< Store x87 FPU State */
OP_FST,/**< Store Floating Point Value */
OP_FSTCW,/**< Store x87 FPU Control Word */
OP_FSTENV,/**< Store x87 FPU Environment */
OP_FSTP,/**< Store Floating Point Value, Pop */
OP_FSTSW,/**< Store x87 FPU Status Word */
OP_FSUB,/**< Floating Point Subtract */
OP_FSUBP,/**< Floating Point Subtract, Pop */
OP_FSUBR,/**< Floating Point Reverse Subtract */
OP_FSUBRP,/**< Floating Point Reverse Subtract, Pop */
OP_FTST,/**< Floating Point Test */
OP_FUCOM,/**< Floating Point Unordered Compare */
OP_FUCOMI,/**< Floating Point Unordered Compare with Integer */
OP_FUCOMIP,/**< Floating Point Unorder Compare with Integer, Pop */
OP_FUCOMP,/**< Floating Point Unorder Compare, Pop */
OP_FUCOMPP,/**< Floating Point Unorder Compare, Pop Twice */
OP_FXAM,/**< Examine ModR/M */
OP_FXCH,/**< Exchange Register Contents */
OP_FXTRACT,/**< Extract Exponent and Significand */
OP_FYL2X,/**< Compute y*log2x */
OP_F2XM1, /**< Compute 2x-1 */
OP_FABS, /**< Absolute Value */
OP_FADD, /**< Floating Point Add */
OP_FADDP, /**< Floating Point Add, Pop */
OP_FBLD, /**< Load Binary Coded Decimal */
OP_FBSTP, /**< Store BCD Integer and Pop */
OP_FCHS, /**< Change Sign */
OP_FCLEX, /**< Clear Exceptions */
OP_FCMOVB, /**< Floating Point Move on Below */
OP_FCMOVBE, /**< Floating Point Move on Below or Equal */
OP_FCMOVE, /**< Floating Point Move on Equal */
OP_FCMOVNB, /**< Floating Point Move on Not Below */
OP_FCMOVNBE, /**< Floating Point Move on Not Below or Equal */
OP_FCMOVNE, /**< Floating Point Move on Not Equal */
OP_FCMOVNU, /**< Floating Point Move on Not Unordered */
OP_FCMOVU, /**< Floating Point Move on Unordered */
OP_FCOM, /**< Compare Floating Pointer Values and Set FPU Flags */
OP_FCOMI, /**< Compare Floating Pointer Values and Set EFLAGS */
OP_FCOMIP, /**< Compare Floating Pointer Values and Set EFLAGS, Pop */
OP_FCOMP, /**< Compare Floating Pointer Values and Set FPU Flags, Pop */
OP_FCOMPP, /**< Compare Floating Pointer Values and Set FPU Flags, Pop Twice */
OP_FCOS, /**< Cosine */
OP_FDECSTP, /**< Decrement Stack Top Pointer */
OP_FDIV, /**< Floating Point Divide */
OP_FDIVP, /**< Floating Point Divide, Pop */
OP_FDIVR, /**< Floating Point Reverse Divide */
OP_FDIVRP, /**< Floating Point Reverse Divide, Pop */
OP_FFREE, /**< Free Floating Point Register */
OP_FIADD, /**< Floating Point Add */
OP_FICOM, /**< Compare Integer */
OP_FICOMP, /**< Compare Integer, Pop */
OP_FIDIV, /**< Floating Point Divide by Integer */
OP_FIDIVR, /**< Floating Point Reverse Divide by Integer */
OP_FILD, /**< Load Integer */
OP_FIMUL, /**< Floating Point Multiply with Integer */
OP_FINCSTP, /**< Increment Stack-Top Pointer */
OP_FINIT, /**< Initialize Floating-Point Unit */
OP_FIST, /**< Store Integer */
OP_FISTP, /**< Store Integer, Pop */
OP_FISTTP, /**< Store Integer with Truncation */
OP_FISUB, /**< Floating Point Integer Subtract */
OP_FISUBR, /**< Floating Point Reverse Integer Subtract */
OP_FLD, /**< Load Floating Point Value */
OP_FLD1, /**< Load Constant 1 */
OP_FLDCW, /**< Load x87 FPU Control Word */
OP_FLDENV, /**< Load x87 FPU Environment */
OP_FLDL2E, /**< Load Constant log_2(e) */
OP_FLDL2T, /**< Load Constant log_2(10) */
OP_FLDLG2, /**< Load Constant log_10(2) */
OP_FLDLN2, /**< Load Constant log_e(2) */
OP_FLDPI, /**< Load Constant PI */
OP_FLDZ, /**< Load Constant Zero */
OP_FMUL, /**< Floating Point Multiply */
OP_FMULP, /**< Floating Point Multiply, Pop */
OP_FNOP, /**< No Operation */
OP_FPATAN, /**< Partial Arctangent */
OP_FPREM, /**< Partial Remainder */
OP_FPREM1, /**< Partial Remainder */
OP_FPTAN, /**< Partial Tangent */
OP_FRNDINT, /**< Round to Integer */
OP_FRSTOR, /**< Restore x86 FPU State */
OP_FSCALE, /**< Scale */
OP_FSIN, /* Sine */
OP_FSINCOS, /**< Sine and Cosine */
OP_FSQRT, /**< Square Root */
OP_FSAVE, /**< Store x87 FPU State */
OP_FST, /**< Store Floating Point Value */
OP_FSTCW, /**< Store x87 FPU Control Word */
OP_FSTENV, /**< Store x87 FPU Environment */
OP_FSTP, /**< Store Floating Point Value, Pop */
OP_FSTSW, /**< Store x87 FPU Status Word */
OP_FSUB, /**< Floating Point Subtract */
OP_FSUBP, /**< Floating Point Subtract, Pop */
OP_FSUBR, /**< Floating Point Reverse Subtract */
OP_FSUBRP, /**< Floating Point Reverse Subtract, Pop */
OP_FTST, /**< Floating Point Test */
OP_FUCOM, /**< Floating Point Unordered Compare */
OP_FUCOMI, /**< Floating Point Unordered Compare with Integer */
OP_FUCOMIP, /**< Floating Point Unorder Compare with Integer, Pop */
OP_FUCOMP, /**< Floating Point Unorder Compare, Pop */
OP_FUCOMPP, /**< Floating Point Unorder Compare, Pop Twice */
OP_FXAM, /**< Examine ModR/M */
OP_FXCH, /**< Exchange Register Contents */
OP_FXTRACT, /**< Extract Exponent and Significand */
OP_FYL2X, /**< Compute y*log2x */
OP_FYL2XP1 /**< Compute y*log2(x+1) */
};
@ -327,24 +327,71 @@ enum DIS_ACCESS {
/** for mem access, immediate and relative */
enum DIS_SIZE {
SIZEB,/**< Byte size access */
SIZEW,/**< Word size access */
SIZED,/**< Doubleword size access */
SIZEF,/**< 6-byte access (seg+reg pair)*/
SIZEQ,/**< Quadword access */
SIZET,/**< 10-byte access */
SIZEB, /**< Byte size access */
SIZEW, /**< Word size access */
SIZED, /**< Doubleword size access */
SIZEF, /**< 6-byte access (seg+reg pair)*/
SIZEQ, /**< Quadword access */
SIZET, /**< 10-byte access */
SIZEPTR /** ptr */
};
/** X86 registers */
enum X86REGS {
X86_REG_EAX, X86_REG_ECX, X86_REG_EDX, X86_REG_EBX, X86_REG_ESP, X86_REG_EBP, X86_REG_ESI, X86_REG_EDI,
X86_REG_AX, X86_REG_CX, X86_REG_DX, X86_REG_BX, X86_REG_SP, X86_REG_BP, X86_REG_SI, X86_REG_DI,
X86_REG_AH, X86_REG_CH, X86_REG_DH, X86_REG_BH, X86_REG_AL, X86_REG_CL, X86_REG_DL, X86_REG_BL,
X86_REG_ES, X86_REG_CS, X86_REG_SS, X86_REG_DS, X86_REG_FS, X86_REG_GS,
X86_REG_CR0, X86_REG_CR1, X86_REG_CR2, X86_REG_CR3, X86_REG_CR4, X86_REG_CR5, X86_REG_CR6, X86_REG_CR7,
X86_REG_DR0, X86_REG_DR1, X86_REG_DR2, X86_REG_DR3, X86_REG_DR4, X86_REG_DR5, X86_REG_DR6, X86_REG_DR7,
X86_REG_ST0, X86_REG_ST1, X86_REG_ST2, X86_REG_ST3, X86_REG_ST4, X86_REG_ST5, X86_REG_ST6, X86_REG_ST7,
X86_REG_EAX,
X86_REG_ECX,
X86_REG_EDX,
X86_REG_EBX,
X86_REG_ESP,
X86_REG_EBP,
X86_REG_ESI,
X86_REG_EDI,
X86_REG_AX,
X86_REG_CX,
X86_REG_DX,
X86_REG_BX,
X86_REG_SP,
X86_REG_BP,
X86_REG_SI,
X86_REG_DI,
X86_REG_AH,
X86_REG_CH,
X86_REG_DH,
X86_REG_BH,
X86_REG_AL,
X86_REG_CL,
X86_REG_DL,
X86_REG_BL,
X86_REG_ES,
X86_REG_CS,
X86_REG_SS,
X86_REG_DS,
X86_REG_FS,
X86_REG_GS,
X86_REG_CR0,
X86_REG_CR1,
X86_REG_CR2,
X86_REG_CR3,
X86_REG_CR4,
X86_REG_CR5,
X86_REG_CR6,
X86_REG_CR7,
X86_REG_DR0,
X86_REG_DR1,
X86_REG_DR2,
X86_REG_DR3,
X86_REG_DR4,
X86_REG_DR5,
X86_REG_DR6,
X86_REG_DR7,
X86_REG_ST0,
X86_REG_ST1,
X86_REG_ST2,
X86_REG_ST3,
X86_REG_ST4,
X86_REG_ST5,
X86_REG_ST6,
X86_REG_ST7,
X86_REG_INVALID
};
@ -358,4 +405,3 @@ struct DISASM_RESULT {
uint8_t extra[29];
};
#endif

View file

@ -1183,31 +1183,30 @@ static const struct OPCODES x86ops[2][256] = {{
static const char *dis_size[] = {"byte", "word", "dword", "fword", "qword", "tword", "acab"};
static const char *x86regs[] = {
"eax","ecx","edx","ebx","esp","ebp","esi","edi",
"ax","cx","dx","bx","sp","bp","si","di",
"ah","ch","dh","bh","al","cl","dl","bl",
"es","cs","ss","ds","fs","gs",
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
"ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
"ah", "ch", "dh", "bh", "al", "cl", "dl", "bl",
"es", "cs", "ss", "ds", "fs", "gs",
"cr0", "cr1 (rsvd)", "cr2", "cr3", "cr4", "cr5 (rsvd)", "cr6 (rsvd)", "cr7 (rsvd)",
"dr0", "dr1", "dr2", "dr3", "dr4 (rsvd)", "dr5 (rsvd)", "dr6", "dr7",
"st(0)", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
""
};
""};
static void spam_x86(struct DISASMED *s, char *hr) {
static void spam_x86(struct DISASMED *s, char *hr)
{
int i;
char comma[2]={'\0','\0'};
char comma[2] = {'\0', '\0'};
strcpy(hr, mnemonic[s->real_op]);
hr += strlen(hr);
for (i=0; i<3; i++) {
switch(s->args[i].access) {
for (i = 0; i < 3; i++) {
switch (s->args[i].access) {
case ACCESS_NOARG:
break;
case ACCESS_IMM:
case ACCESS_REL:
if (s->args[i].arg.rq >=0)
if (s->args[i].arg.rq >= 0)
hr += sprintf(hr, "%s %lx", comma, (long)s->args[i].arg.q);
else
hr += sprintf(hr, "%s -%x", comma, -(int)s->args[i].arg.rq);
@ -1216,30 +1215,30 @@ static void spam_x86(struct DISASMED *s, char *hr) {
hr += sprintf(hr, "%s %s", comma, x86regs[s->args[i].reg]);
break;
case ACCESS_MEM: {
const char *gotstuff="";
const char *gotstuff = "";
hr += sprintf(hr, "%s %s ptr ", comma, dis_size[s->args[i].size]);
if(s->segment) hr += sprintf(hr, "%s:", x86regs[s->segment]);
if (s->segment) hr += sprintf(hr, "%s:", x86regs[s->segment]);
*hr++ = '[';
*hr = '\0';
if(s->args[i].arg.marg.r1!=X86_REG_INVALID) {
switch(s->args[i].arg.marg.scale) {
if (s->args[i].arg.marg.r1 != X86_REG_INVALID) {
switch (s->args[i].arg.marg.scale) {
case 1:
hr += sprintf(hr, "%s", x86regs[s->args[i].arg.marg.r1]);
gotstuff="+";
gotstuff = "+";
break;
case 0:
break;
default:
hr += sprintf(hr, "%s*%d", x86regs[s->args[i].arg.marg.r1],s->args[i].arg.marg.scale);
gotstuff="+";
hr += sprintf(hr, "%s*%d", x86regs[s->args[i].arg.marg.r1], s->args[i].arg.marg.scale);
gotstuff = "+";
}
}
if(s->args[i].arg.marg.r2!=X86_REG_INVALID) {
if (s->args[i].arg.marg.r2 != X86_REG_INVALID) {
hr += sprintf(hr, "%s%s", gotstuff, x86regs[s->args[i].arg.marg.r2]);
gotstuff="+";
gotstuff = "+";
}
if(s->args[i].arg.marg.disp) {
if(*gotstuff=='+' && s->args[i].arg.marg.disp<0)
if (s->args[i].arg.marg.disp) {
if (*gotstuff == '+' && s->args[i].arg.marg.disp < 0)
hr += sprintf(hr, "-%x", -s->args[i].arg.marg.disp);
else
hr += sprintf(hr, "%s%x", gotstuff, s->args[i].arg.marg.disp);
@ -1248,43 +1247,52 @@ static void spam_x86(struct DISASMED *s, char *hr) {
*hr = '\0';
}
}
comma[0]=',';
comma[0] = ',';
}
}
#define INVALIDATE \
{ \
s->table_op = OP_INVALID; \
s->state = STATE_ERROR; \
goto disasm_failed; \
}
#define GETBYTE(X) \
if (len--) { \
X = *command; \
command++; \
} else \
INVALIDATE;
#define GETSIZE(X) (x86ops[table][s->table_op].X != SIZE_WD ? x86ops[table][s->table_op].X : ((s->opsize) ? SIZE_WORD : SIZE_DWORD))
#define INVALIDATE {s->table_op=OP_INVALID; s->state=STATE_ERROR; goto disasm_failed;}
#define GETBYTE(X) if(len--) {X=*command; command++;} else INVALIDATE;
#define GETSIZE(X) (x86ops[table][s->table_op].X!=SIZE_WD?x86ops[table][s->table_op].X:((s->opsize)?SIZE_WORD:SIZE_DWORD))
static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struct DISASMED *s) {
unsigned int reversed=0, i;
static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struct DISASMED *s)
{
unsigned int reversed = 0, i;
uint8_t b;
unsigned int table = 0;
memset(s, 0, sizeof(struct DISASMED));
s->state = STATE_GETOP;
while(1) {
while (1) {
switch (s->state) {
case STATE_GETOP:
GETBYTE(s->table_op);
s->real_op=x86ops[table][s->table_op].op;
switch(s->real_op) {
s->real_op = x86ops[table][s->table_op].op;
switch (s->real_op) {
case OP_FPU:
s->state = STATE_DECODEX87;
break;
case OP_2BYTE:
table=1;
table = 1;
break;
case OP_PREFIX_OPSIZE:
s->opsize=1; /* FIXME: check double prefixes */
s->opsize = 1; /* FIXME: check double prefixes */
break;
case OP_PREFIX_ADDRSIZE:
s->adsize=1; /* FIXME: check double prefixes */
s->adsize = 1; /* FIXME: check double prefixes */
break;
case OP_PREFIX_SEGMENT:
assert(x86ops[table][s->table_op].dmethod>=ADDR_REG_ES && x86ops[table][s->table_op].dmethod<=ADDR_REG_GS);
assert(x86ops[table][s->table_op].dmethod >= ADDR_REG_ES && x86ops[table][s->table_op].dmethod <= ADDR_REG_GS);
s->segment = regmap[SIZE_WORD][x86ops[table][s->table_op].dmethod];
break;
default:
@ -1301,84 +1309,84 @@ static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struc
uint8_t idx;
table = s->table_op - 0xd8;
assert(table<8);
assert(table < 8);
GETBYTE(rm);
if (rm>=0xc0) { /* ST */
rm&=0x3f;
if ((s->real_op=x87_st[table][rm].op)==OP_INVALID) INVALIDATE;
switch(x87_st[table][rm].args) {
if (rm >= 0xc0) { /* ST */
rm &= 0x3f;
if ((s->real_op = x87_st[table][rm].op) == OP_INVALID) INVALIDATE;
switch (x87_st[table][rm].args) {
case X87_S:
reversed = 1;
case X87_R:
s->args[reversed^1].access = ACCESS_REG;
s->args[reversed^1].reg = X86_REG_ST0;
s->args[reversed ^ 1].access = ACCESS_REG;
s->args[reversed ^ 1].reg = X86_REG_ST0;
case X87_ONE:
s->args[reversed].access = ACCESS_REG;
s->args[reversed].reg = X86_REG_ST0 + (rm&7);
s->args[reversed].reg = X86_REG_ST0 + (rm & 7);
break;
case X87_NONE:
break;
default:
assert("Bad data in x87_st"==0);
assert("Bad data in x87_st" == 0);
}
s->state = STATE_FINALIZE;
continue;
}
/* MRM */
mod=rm>>6;
rop=(rm>>3)&7;
rm&=7;
mod = rm >> 6;
rop = (rm >> 3) & 7;
rm &= 7;
if ((s->real_op=x87_mrm[table][rop].op)==OP_INVALID) INVALIDATE;
if ((s->real_op = x87_mrm[table][rop].op) == OP_INVALID) INVALIDATE;
s->args[0].size = x87_mrm[table][rop].size;
s->args[0].access = ACCESS_MEM;
if(!s->adsize) {
if (rm==4) {
if (!s->adsize) {
if (rm == 4) {
GETBYTE(base);
scale=base>>6;
idx=(base>>3)&7;
base&=7;
scale = base >> 6;
idx = (base >> 3) & 7;
base &= 7;
s->args[0].arg.marg.scale = 1<<scale;
if((s->args[0].arg.marg.r2=mrm_regmap[SIZED][base])==X86_REG_EBP && mod==0) {
s->args[0].arg.marg.r2=X86_REG_INVALID;
mod=2;
s->args[0].arg.marg.scale = 1 << scale;
if ((s->args[0].arg.marg.r2 = mrm_regmap[SIZED][base]) == X86_REG_EBP && mod == 0) {
s->args[0].arg.marg.r2 = X86_REG_INVALID;
mod = 2;
}
if((s->args[0].arg.marg.r1=mrm_regmap[SIZED][idx])==X86_REG_ESP) {
s->args[0].arg.marg.r1=s->args[0].arg.marg.r2;
s->args[0].arg.marg.scale = (s->args[0].arg.marg.r2!=X86_REG_INVALID);
s->args[0].arg.marg.r2=X86_REG_INVALID;
if ((s->args[0].arg.marg.r1 = mrm_regmap[SIZED][idx]) == X86_REG_ESP) {
s->args[0].arg.marg.r1 = s->args[0].arg.marg.r2;
s->args[0].arg.marg.scale = (s->args[0].arg.marg.r2 != X86_REG_INVALID);
s->args[0].arg.marg.r2 = X86_REG_INVALID;
}
} else {
if (mod==0 && rm==5) {
mod=2;
s->args[0].arg.marg.r1=X86_REG_INVALID;
if (mod == 0 && rm == 5) {
mod = 2;
s->args[0].arg.marg.r1 = X86_REG_INVALID;
} else {
s->args[0].arg.marg.scale=1;
s->args[0].arg.marg.r1=mrm_regmap[SIZED][rm];
s->args[0].arg.marg.scale = 1;
s->args[0].arg.marg.r1 = mrm_regmap[SIZED][rm];
}
s->args[0].arg.marg.r2=X86_REG_INVALID;
s->args[0].arg.marg.r2 = X86_REG_INVALID;
}
if(mod==2) mod+=mod;
for (i=0; i<mod; i++) {
if (mod == 2) mod += mod;
for (i = 0; i < mod; i++) {
GETBYTE(b);
s->args[0].arg.marg.disp+=b<<(i*8);
s->args[0].arg.marg.disp += b << (i * 8);
/* FIXME: signextend to dword */
}
} else {
if (mod==0 && rm==6) {
s->args[0].arg.marg.r1=X86_REG_INVALID;
mod=2;
if (mod == 0 && rm == 6) {
s->args[0].arg.marg.r1 = X86_REG_INVALID;
mod = 2;
} else {
s->args[0].arg.marg.scale=1;
s->args[0].arg.marg.r1=mrm_regmapw[rm].r1;
s->args[0].arg.marg.r2=mrm_regmapw[rm].r2;
s->args[0].arg.marg.scale = 1;
s->args[0].arg.marg.r1 = mrm_regmapw[rm].r1;
s->args[0].arg.marg.r2 = mrm_regmapw[rm].r2;
}
for (i=0; i<mod; i++) {
for (i = 0; i < mod; i++) {
GETBYTE(b);
s->args[0].arg.marg.disp+=b<<(i*8);
s->args[0].arg.marg.disp += b << (i * 8);
/* FIXME: signextend to dword */
}
}
@ -1387,24 +1395,34 @@ static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struc
}
case STATE_CHECKDTYPE:
switch(x86ops[table][s->table_op].dmethod) {
case ADDR_REG_FS: case ADDR_REG_GS:
switch (x86ops[table][s->table_op].dmethod) {
case ADDR_REG_FS:
case ADDR_REG_GS:
/* FIXME: does this exist? */
case ADDR_REG_ES: case ADDR_REG_CS: case ADDR_REG_SS: case ADDR_REG_DS:
assert(x86ops[table][s->table_op].dsize==SIZE_WORD);
case ADDR_REG_ESP: case ADDR_REG_EBP: case ADDR_REG_ESI: case ADDR_REG_EDI:
assert(x86ops[table][s->table_op].dsize!=SIZE_BYTE && x86ops[table][s->table_op].dsize!=SIZE_BYTEH);
case ADDR_REG_EAX: case ADDR_REG_ECX: case ADDR_REG_EDX: case ADDR_REG_EBX:
assert(x86ops[table][s->table_op].dsize<=SIZE_WD);
case ADDR_REG_ES:
case ADDR_REG_CS:
case ADDR_REG_SS:
case ADDR_REG_DS:
assert(x86ops[table][s->table_op].dsize == SIZE_WORD);
case ADDR_REG_ESP:
case ADDR_REG_EBP:
case ADDR_REG_ESI:
case ADDR_REG_EDI:
assert(x86ops[table][s->table_op].dsize != SIZE_BYTE && x86ops[table][s->table_op].dsize != SIZE_BYTEH);
case ADDR_REG_EAX:
case ADDR_REG_ECX:
case ADDR_REG_EDX:
case ADDR_REG_EBX:
assert(x86ops[table][s->table_op].dsize <= SIZE_WD);
s->args[0].access = ACCESS_REG;
s->args[0].reg = regmap[GETSIZE(dsize)][x86ops[table][s->table_op].dmethod];
s->state = STATE_CHECKSTYPE;
continue;
case ADDR_NOADDR:
if (x86ops[table][s->table_op].dsize!=SIZE_NOSIZE) {
assert(x86ops[table][s->table_op].dsize==SIZE_WD);
s->real_op+=(s->opsize!=0);
if (x86ops[table][s->table_op].dsize != SIZE_NOSIZE) {
assert(x86ops[table][s->table_op].dsize == SIZE_WD);
s->real_op += (s->opsize != 0);
}
s->args[0].access = ACCESS_NOARG;
s->state = STATE_FINALIZE;
@ -1413,18 +1431,18 @@ static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struc
case ADDR_RELJ:
case ADDR_IMMED: {
uint8_t sz;
s->args[0].access = x86ops[table][s->table_op].dmethod-ADDR_IMMED+ACCESS_IMM;
assert(x86ops[table][s->table_op].dsize<SIZE_NOSIZE && s->opsize<2);
sz=sizemap[x86ops[table][s->table_op].dsize][s->opsize];
assert(sz!=255);
s->args[0].size = sz>>1; /* FIXME: size does matter - 6aff vs 666aff :( */
for (i=0; i<sz; i++) {
s->args[0].access = x86ops[table][s->table_op].dmethod - ADDR_IMMED + ACCESS_IMM;
assert(x86ops[table][s->table_op].dsize < SIZE_NOSIZE && s->opsize < 2);
sz = sizemap[x86ops[table][s->table_op].dsize][s->opsize];
assert(sz != 255);
s->args[0].size = sz >> 1; /* FIXME: size does matter - 6aff vs 666aff :( */
for (i = 0; i < sz; i++) {
GETBYTE(b);
s->args[0].arg.q+=(uint64_t)b<<(i*8);
s->args[0].arg.q += (uint64_t)b << (i * 8);
}
/* if (x86ops[table][s->table_op].dmethod==ADDR_RELJ) { */
s->args[0].arg.q<<=((8-sz)*8);
s->args[0].arg.rq>>=((8-sz)*8);
s->args[0].arg.q <<= ((8 - sz) * 8);
s->args[0].arg.rq >>= ((8 - sz) * 8);
/* } */
s->state = STATE_CHECKSTYPE;
continue;
@ -1449,15 +1467,15 @@ static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struc
uint8_t scale;
uint8_t base;
uint8_t idx;
int64_t shiftme=0;
const uint8_t (*p)[8];
int64_t shiftme = 0;
const uint8_t(*p)[8];
GETBYTE(rm);
mod=rm>>6;
rop=(rm>>3)&7;
rm&=7;
mod = rm >> 6;
rop = (rm >> 3) & 7;
rm &= 7;
switch(x86ops[table][s->table_op].dmethod) {
switch (x86ops[table][s->table_op].dmethod) {
case ADDR_MRM_GEN_RC:
case ADDR_MRM_GEN_CR:
p = mrm_cregmap;
@ -1479,112 +1497,115 @@ static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struc
s->args[reversed].size = SIZEB;
switch (x86ops[table][s->table_op].dsize) {
case SIZE_DWORD:
s->args[reversed].size=SIZED;
s->args[reversed].size = SIZED;
break;
case SIZE_WD:
s->args[reversed].size+=(s->opsize==0);
s->args[reversed].size += (s->opsize == 0);
case SIZE_WORD:
s->args[reversed].size++;
case SIZE_BYTE:
break;
default:
assert("Bad size"==0);
assert("Bad size" == 0);
}
s->args[reversed^1].access = ACCESS_REG;
if ((s->args[reversed^1].reg = p[s->args[reversed].size][rop]) == X86_REG_INVALID) INVALIDATE;
s->args[reversed ^ 1].access = ACCESS_REG;
if ((s->args[reversed ^ 1].reg = p[s->args[reversed].size][rop]) == X86_REG_INVALID) INVALIDATE;
/* MOVZX size fixxup */
if(s->real_op == OP_MOVZX || s->real_op == OP_MOVSX)
if (s->real_op == OP_MOVZX || s->real_op == OP_MOVSX)
s->args[reversed].size = SIZEB + (s->table_op & 1);
if(mod==3) {
if(x86ops[table][s->table_op].dmethod==ADDR_MRM_GEN_GM || x86ops[table][s->table_op].dmethod==ADDR_MRM_EXTRA_1A_M) INVALIDATE;
if (mod == 3) {
if (x86ops[table][s->table_op].dmethod == ADDR_MRM_GEN_GM || x86ops[table][s->table_op].dmethod == ADDR_MRM_EXTRA_1A_M) INVALIDATE;
s->args[reversed].access = ACCESS_REG;
s->args[reversed].reg = mrm_regmap[s->args[reversed].size][rm];
if(x86ops[table][s->table_op].dmethod==ADDR_MRM_EXTRA_1A) {
if (x86ops[table][s->table_op].dmethod == ADDR_MRM_EXTRA_1A) {
uint8_t opcache = s->real_op;
assert(opcache<(sizeof(extra_1a)/sizeof(extra_1a[0][0])));
s->args[0].size+=extra_1a[opcache][rop].addsz;
if((s->real_op=extra_1a[opcache][rop].op)==OP_INVALID) INVALIDATE;
s->args[1].access=ACCESS_NOARG;
if (opcache==6 && rop!=0) {
assert(opcache < (sizeof(extra_1a) / sizeof(extra_1a[0][0])));
s->args[0].size += extra_1a[opcache][rop].addsz;
if ((s->real_op = extra_1a[opcache][rop].op) == OP_INVALID) INVALIDATE;
s->args[1].access = ACCESS_NOARG;
if (opcache == 6 && rop != 0) {
/* f6-f7 - GRP3 - handle test E[bv],I[bv] vs the rest */
s->state = STATE_FINALIZE;
continue;
}
} else s->cur++;
} else
s->cur++;
s->state = STATE_CHECKSTYPE;
continue;
}
s->args[reversed].access = ACCESS_MEM;
if(!s->adsize) {
if (rm==4) {
if (!s->adsize) {
if (rm == 4) {
GETBYTE(base);
scale=base>>6;
idx=(base>>3)&7;
base&=7;
scale = base >> 6;
idx = (base >> 3) & 7;
base &= 7;
s->args[reversed].arg.marg.scale = 1<<scale;
if((s->args[reversed].arg.marg.r2=mrm_regmap[SIZED][base])==X86_REG_EBP && mod==0) {
s->args[reversed].arg.marg.r2=X86_REG_INVALID;
mod=2;
s->args[reversed].arg.marg.scale = 1 << scale;
if ((s->args[reversed].arg.marg.r2 = mrm_regmap[SIZED][base]) == X86_REG_EBP && mod == 0) {
s->args[reversed].arg.marg.r2 = X86_REG_INVALID;
mod = 2;
}
if((s->args[reversed].arg.marg.r1=mrm_regmap[SIZED][idx])==X86_REG_ESP) {
s->args[reversed].arg.marg.r1=s->args[reversed].arg.marg.r2;
s->args[reversed].arg.marg.scale = (s->args[reversed].arg.marg.r2!=X86_REG_INVALID);
s->args[reversed].arg.marg.r2=X86_REG_INVALID;
if ((s->args[reversed].arg.marg.r1 = mrm_regmap[SIZED][idx]) == X86_REG_ESP) {
s->args[reversed].arg.marg.r1 = s->args[reversed].arg.marg.r2;
s->args[reversed].arg.marg.scale = (s->args[reversed].arg.marg.r2 != X86_REG_INVALID);
s->args[reversed].arg.marg.r2 = X86_REG_INVALID;
}
} else {
if (mod==0 && rm==5) {
mod=2;
s->args[reversed].arg.marg.r1=X86_REG_INVALID;
if (mod == 0 && rm == 5) {
mod = 2;
s->args[reversed].arg.marg.r1 = X86_REG_INVALID;
} else {
s->args[reversed].arg.marg.scale=1;
s->args[reversed].arg.marg.r1=mrm_regmap[SIZED][rm];
s->args[reversed].arg.marg.scale = 1;
s->args[reversed].arg.marg.r1 = mrm_regmap[SIZED][rm];
}
s->args[reversed].arg.marg.r2=X86_REG_INVALID;
s->args[reversed].arg.marg.r2 = X86_REG_INVALID;
}
if(mod==2) mod+=mod;
for (i=0; i<mod; i++) {
if (mod == 2) mod += mod;
for (i = 0; i < mod; i++) {
GETBYTE(b);
shiftme+=b<<(i*8);
shiftme += b << (i * 8);
}
if(mod) {
shiftme<<=((8-mod)*8);
s->args[reversed].arg.marg.disp=shiftme>>((8-mod)*8);
} else s->args[reversed].arg.marg.disp=0;
if (mod) {
shiftme <<= ((8 - mod) * 8);
s->args[reversed].arg.marg.disp = shiftme >> ((8 - mod) * 8);
} else
s->args[reversed].arg.marg.disp = 0;
} else {
if (mod==0 && rm==6) {
s->args[reversed].arg.marg.r1=X86_REG_INVALID;
mod=2;
if (mod == 0 && rm == 6) {
s->args[reversed].arg.marg.r1 = X86_REG_INVALID;
mod = 2;
} else {
s->args[reversed].arg.marg.scale=1;
s->args[reversed].arg.marg.r1=mrm_regmapw[rm].r1;
s->args[reversed].arg.marg.r2=mrm_regmapw[rm].r2;
s->args[reversed].arg.marg.scale = 1;
s->args[reversed].arg.marg.r1 = mrm_regmapw[rm].r1;
s->args[reversed].arg.marg.r2 = mrm_regmapw[rm].r2;
}
for (i=0; i<mod; i++) {
for (i = 0; i < mod; i++) {
GETBYTE(b);
shiftme+=b<<(i*8);
shiftme += b << (i * 8);
}
shiftme<<=((8-mod)*8);
s->args[reversed].arg.marg.disp=shiftme>>((8-mod)*8);
shiftme <<= ((8 - mod) * 8);
s->args[reversed].arg.marg.disp = shiftme >> ((8 - mod) * 8);
}
if(x86ops[table][s->table_op].dmethod==ADDR_MRM_EXTRA_1A || x86ops[table][s->table_op].dmethod==ADDR_MRM_EXTRA_1A_M) {
if (x86ops[table][s->table_op].dmethod == ADDR_MRM_EXTRA_1A || x86ops[table][s->table_op].dmethod == ADDR_MRM_EXTRA_1A_M) {
uint8_t opcache = s->real_op;
assert(opcache<(sizeof(extra_1a)/sizeof(extra_1a[0][0])));
s->args[0].size+=extra_1a[opcache][rop].addsz;
if ((s->real_op=extra_1a[opcache][rop].op)==OP_INVALID) INVALIDATE;
s->args[1].access=ACCESS_NOARG;
if (opcache==6 && rop!=0) {
assert(opcache < (sizeof(extra_1a) / sizeof(extra_1a[0][0])));
s->args[0].size += extra_1a[opcache][rop].addsz;
if ((s->real_op = extra_1a[opcache][rop].op) == OP_INVALID) INVALIDATE;
s->args[1].access = ACCESS_NOARG;
if (opcache == 6 && rop != 0) {
/* f6-f7 - GRP3 - handle test E[bv],I[bv] vs the rest */
s->state = STATE_FINALIZE;
continue;
}
} else s->cur++;
} else
s->cur++;
s->state = STATE_CHECKSTYPE;
continue;
}
@ -1592,31 +1613,30 @@ static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struc
case ADDR_OFFSET: {
uint8_t sz;
s->args[0].access = ACCESS_MEM;
assert((x86ops[table][s->table_op].dsize==SIZE_BYTE || x86ops[table][s->table_op].dsize==SIZE_WD) && s->adsize<2);
sz=sizemap[SIZE_WD][s->adsize];
assert(sz!=255);
assert(s->opsize<2);
s->args[0].size=sizemap[x86ops[table][s->table_op].dsize][s->opsize];
assert(s->args[0].size!=255);
s->args[0].size>>=1;
s->args[0].arg.marg.r1=X86_REG_INVALID;
s->args[0].arg.marg.r2=X86_REG_INVALID;
for (i=0; i<sz; i++) {
assert((x86ops[table][s->table_op].dsize == SIZE_BYTE || x86ops[table][s->table_op].dsize == SIZE_WD) && s->adsize < 2);
sz = sizemap[SIZE_WD][s->adsize];
assert(sz != 255);
assert(s->opsize < 2);
s->args[0].size = sizemap[x86ops[table][s->table_op].dsize][s->opsize];
assert(s->args[0].size != 255);
s->args[0].size >>= 1;
s->args[0].arg.marg.r1 = X86_REG_INVALID;
s->args[0].arg.marg.r2 = X86_REG_INVALID;
for (i = 0; i < sz; i++) {
GETBYTE(b);
s->args[0].arg.marg.disp+=b<<(i*8);
s->args[0].arg.marg.disp += b << (i * 8);
}
s->state = STATE_CHECKSTYPE;
continue;
}
default:
assert("BAD DST METHOD"==0);
assert("BAD DST METHOD" == 0);
}
case STATE_CHECKSTYPE:
s->cur++;
switch(x86ops[table][s->table_op].smethod) {
switch (x86ops[table][s->table_op].smethod) {
case ADDR_NOADDR:
s->state = STATE_FINALIZE;
continue;
@ -1624,15 +1644,15 @@ static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struc
case ADDR_IMMED: {
uint8_t sz;
s->args[s->cur].access = ACCESS_IMM;
assert((x86ops[table][s->table_op].ssize==SIZE_WD || x86ops[table][s->table_op].ssize==SIZE_BYTE) && s->opsize<2);
sz=sizemap[x86ops[table][s->table_op].ssize][s->opsize];
s->args[s->cur].size = sz>>1;
for (i=0; i<sz; i++) {
assert((x86ops[table][s->table_op].ssize == SIZE_WD || x86ops[table][s->table_op].ssize == SIZE_BYTE) && s->opsize < 2);
sz = sizemap[x86ops[table][s->table_op].ssize][s->opsize];
s->args[s->cur].size = sz >> 1;
for (i = 0; i < sz; i++) {
GETBYTE(b);
s->args[s->cur].arg.q+=b<<(i*8);
s->args[s->cur].arg.q += b << (i * 8);
}
s->args[s->cur].arg.q<<=((8-sz)*8);
s->args[s->cur].arg.rq>>=((8-sz)*8);
s->args[s->cur].arg.q <<= ((8 - sz) * 8);
s->args[s->cur].arg.rq >>= ((8 - sz) * 8);
s->state = STATE_FINALIZE;
continue;
}
@ -1640,7 +1660,7 @@ static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struc
case ADDR_REG_EAX:
case ADDR_REG_ECX:
case ADDR_REG_EDX:
assert(x86ops[table][s->table_op].ssize<=SIZE_WD);
assert(x86ops[table][s->table_op].ssize <= SIZE_WD);
s->args[s->cur].access = ACCESS_REG;
s->args[s->cur].reg = regmap[GETSIZE(ssize)][x86ops[table][s->table_op].smethod];
s->state = STATE_FINALIZE;
@ -1656,25 +1676,25 @@ static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struc
case ADDR_OFFSET: {
uint8_t sz;
s->args[1].access = ACCESS_MEM;
assert((x86ops[table][s->table_op].ssize==SIZE_BYTE || x86ops[table][s->table_op].ssize==SIZE_WD) && s->adsize<2);
sz=sizemap[SIZE_WD][s->adsize];
assert(sz!=255);
assert(s->opsize<2);
s->args[1].size=sizemap[x86ops[table][s->table_op].ssize][s->opsize];
assert(s->args[1].size!=255);
s->args[1].size>>=1;
s->args[1].arg.marg.r1=X86_REG_INVALID;
s->args[1].arg.marg.r2=X86_REG_INVALID;
for (i=0; i<sz; i++) {
assert((x86ops[table][s->table_op].ssize == SIZE_BYTE || x86ops[table][s->table_op].ssize == SIZE_WD) && s->adsize < 2);
sz = sizemap[SIZE_WD][s->adsize];
assert(sz != 255);
assert(s->opsize < 2);
s->args[1].size = sizemap[x86ops[table][s->table_op].ssize][s->opsize];
assert(s->args[1].size != 255);
s->args[1].size >>= 1;
s->args[1].arg.marg.r1 = X86_REG_INVALID;
s->args[1].arg.marg.r2 = X86_REG_INVALID;
for (i = 0; i < sz; i++) {
GETBYTE(b);
s->args[1].arg.marg.disp+=b<<(i*8);
s->args[1].arg.marg.disp += b << (i * 8);
}
s->state = STATE_FINALIZE;
continue;
}
default:
assert("BAD SRC METHOD"==0);
assert("BAD SRC METHOD" == 0);
}
case STATE_ERROR:
@ -1682,16 +1702,16 @@ static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struc
return NULL;
case STATE_FINALIZE:
if (s->real_op==OP_INVALID) INVALIDATE;
if (s->real_op == OP_INVALID) INVALIDATE;
return command;
default:
assert("INVALID STATE"==0);
assert("INVALID STATE" == 0);
}
}
}
const uint8_t* cli_disasm_one(const uint8_t* buff, unsigned int len,
const uint8_t *cli_disasm_one(const uint8_t *buff, unsigned int len,
struct DISASM_RESULT *w, int spam)
{
struct DISASMED s;
@ -1711,46 +1731,46 @@ const uint8_t* cli_disasm_one(const uint8_t* buff, unsigned int len,
w->adsize = s.adsize;
w->segment = s.segment;
for (i=0; i<3; i++) {
for (i = 0; i < 3; i++) {
w->arg[i][0] = s.args[i].access;
w->arg[i][1] = s.args[i].size;
switch(s.args[i].access) {
switch (s.args[i].access) {
case ACCESS_MEM:
w->arg[i][2]=s.args[i].arg.marg.r1;
w->arg[i][3]=s.args[i].arg.marg.r2;
w->arg[i][4]=s.args[i].arg.marg.scale;
w->arg[i][5]=0;
w->arg[i][2] = s.args[i].arg.marg.r1;
w->arg[i][3] = s.args[i].arg.marg.r2;
w->arg[i][4] = s.args[i].arg.marg.scale;
w->arg[i][5] = 0;
cli_writeint32(&w->arg[i][6], s.args[i].arg.marg.disp);
break;
case ACCESS_REG:
w->arg[i][1] = s.args[i].reg;
default:
cli_writeint32(&w->arg[i][2], s.args[i].arg.q);
cli_writeint32(&w->arg[i][6], s.args[i].arg.q>>32);
cli_writeint32(&w->arg[i][6], s.args[i].arg.q >> 32);
}
}
return buff;
}
int disasmbuf(const uint8_t *buff, unsigned int len, int fd) {
int disasmbuf(const uint8_t *buff, unsigned int len, int fd)
{
const uint8_t *next = buff;
unsigned int counter=0;
int gotsome=0;
unsigned int counter = 0;
int gotsome = 0;
struct DISASM_RESULT w;
memset(&w.extra[0], 0, sizeof(w.extra));
while(len && counter++<200) {
if(!(next = cli_disasm_one(next, len, &w, cli_debug_flag))) {
while (len && counter++ < 200) {
if (!(next = cli_disasm_one(next, len, &w, cli_debug_flag))) {
/* TODO: invd opcode or buff over */
return gotsome;
}
len -= next-buff;
buff=next;
len -= next - buff;
buff = next;
cli_writen(fd, &w, sizeof(w));
gotsome = 1;
}
return gotsome;
}

View file

@ -29,6 +29,6 @@
#include "others.h"
const uint8_t* cli_disasm_one(const uint8_t*, unsigned, struct DISASM_RESULT*, int);
int disasmbuf(const uint8_t *, unsigned int, int);
int disasmbuf(const uint8_t*, unsigned int, int);
#endif

View file

@ -119,7 +119,6 @@ static int ssn_max_group[MAX_AREA+1] = { 0,
};
*/
/*
Following is a table of payment card "issuer identification number" ranges
and additional info such as card number length.
@ -130,7 +129,7 @@ struct iin_map_struct {
uint32_t iin_end;
uint8_t card_len;
uint8_t luhn;
const char* iin_name;
const char *iin_name;
};
/* Maestro card range, 550000-699999, encompasses ranges
@ -150,12 +149,11 @@ static struct iin_map_struct iin_map[] = {
{500000, 509999, 16, 1, "Maestro"},
{510000, 559999, 16, 1, "Master Card"},
{560000, 699999, 16, 1, "Maestro/Discover/UnionPay/etc."},
{0}
};
{0}};
/* Fixme: some card ranges can have lengths other than 16 */
static const struct iin_map_struct * get_iin(char * digits)
static const struct iin_map_struct *get_iin(char *digits)
{
int iin = atoi(digits);
int i = 0;
@ -182,25 +180,25 @@ int dlp_is_valid_cc(const unsigned char *buffer, int length)
int digits = 0;
char cc_digits[20];
int pad_allowance = MAX_CC_BREAKS;
const struct iin_map_struct * iin;
const struct iin_map_struct *iin;
int need;
if(buffer == NULL || length < 13)
if (buffer == NULL || length < 13)
return 0;
/* if the first digit is greater than 6 it isn't one of the major
* credit cards
* reference => http://www.beachnet.com/~hstiles/cardtype.html
*/
if(!isdigit(buffer[0]) || buffer[0] > '6' || buffer[0] == 2)
if (!isdigit(buffer[0]) || buffer[0] > '6' || buffer[0] == 2)
return 0;
if(length > 19 + pad_allowance) /* max credit card length is 19, with allowance for punctuation */
if (length > 19 + pad_allowance) /* max credit card length is 19, with allowance for punctuation */
length = 19 + pad_allowance;
/* Look for possible 6 digit IIN */
for(i = 0; i < length && digits < IIN_SIZE; i++) {
if(isdigit(buffer[i]) == 0) {
if(buffer[i] == ' ' || buffer[i] == '-')
for (i = 0; i < length && digits < IIN_SIZE; i++) {
if (isdigit(buffer[i]) == 0) {
if (buffer[i] == ' ' || buffer[i] == '-')
if (pad_allowance-- > 0)
continue;
break;
@ -221,8 +219,8 @@ int dlp_is_valid_cc(const unsigned char *buffer, int length)
/* Look for the remaining needed digits. */
for (/*same 'i' from previous for-loop*/; i < length && digits < iin->card_len; i++) {
if(isdigit(buffer[i]) == 0) {
if(buffer[i] == ' ' || buffer[i] == '-')
if (isdigit(buffer[i]) == 0) {
if (buffer[i] == ' ' || buffer[i] == '-')
if (pad_allowance-- > 0)
continue;
break;
@ -232,22 +230,20 @@ int dlp_is_valid_cc(const unsigned char *buffer, int length)
}
// should be !isdigit(buffer[i]) ?
if(digits < 13 || (i < length && isdigit(buffer[i])))
if (digits < 13 || (i < length && isdigit(buffer[i])))
return 0;
//figure out luhn digits
for(i = digits - 1; i >= 0; i--)
{
for (i = digits - 1; i >= 0; i--) {
val = cc_digits[i] - '0';
if(mult)
{
if((val *= 2) > 9) val -= 9;
if (mult) {
if ((val *= 2) > 9) val -= 9;
}
mult = !mult;
sum += val;
}
if(sum % 10)
if (sum % 10)
return 0;
cli_dbgmsg("Luhn algorithm successful for %s\n", cc_digits);
@ -261,28 +257,23 @@ static int contains_cc(const unsigned char *buffer, int length, int detmode)
const unsigned char *end;
int count = 0;
if(buffer == NULL || length < 13)
{
if (buffer == NULL || length < 13) {
return 0;
}
end = buffer + length;
idx = buffer;
while(idx < end)
{
if(isdigit(*idx))
{
if((idx == buffer || !isdigit(idx[-1])) && dlp_is_valid_cc(idx, length - (idx - buffer)) == 1)
{
if(detmode == DETECT_MODE_DETECT)
while (idx < end) {
if (isdigit(*idx)) {
if ((idx == buffer || !isdigit(idx[-1])) && dlp_is_valid_cc(idx, length - (idx - buffer)) == 1) {
if (detmode == DETECT_MODE_DETECT)
return 1;
else
{
else {
count++;
/* if we got a valid match we should increment the idx ptr
* to gain a little performance
*/
idx += (length > 15?15:(length-1));
idx += (length > 15 ? 15 : (length - 1));
}
}
}
@ -311,46 +302,43 @@ int dlp_is_valid_ssn(const unsigned char *buffer, int length, int format)
int retval = 1;
char numbuf[12];
if(buffer == NULL)
if (buffer == NULL)
return 0;
minlength = (format==SSN_FORMAT_HYPHENS?11:9);
minlength = (format == SSN_FORMAT_HYPHENS ? 11 : 9);
if(length < minlength)
if (length < minlength)
return 0;
if((length > minlength) && isdigit(buffer[minlength]))
if ((length > minlength) && isdigit(buffer[minlength]))
return 0;
strncpy(numbuf, (const char*)buffer, minlength);
strncpy(numbuf, (const char *)buffer, minlength);
numbuf[minlength] = 0;
/* sscanf parses and (basically) validates the string for us */
switch(format)
{
switch (format) {
case SSN_FORMAT_HYPHENS:
if(numbuf[3] != '-' || numbuf[6] != '-')
if (numbuf[3] != '-' || numbuf[6] != '-')
return 0;
if(sscanf((const char *) numbuf,
if (sscanf((const char *)numbuf,
"%3d-%2d-%4d",
&area_number,
&group_number,
&serial_number) != 3)
{
&serial_number) != 3) {
return 0;
}
break;
case SSN_FORMAT_STRIPPED:
if(!cli_isnumber(numbuf))
if (!cli_isnumber(numbuf))
return 0;
if(sscanf((const char *) numbuf,
if (sscanf((const char *)numbuf,
"%3d%2d%4d",
&area_number,
&group_number,
&serial_number) != 3)
{
&serial_number) != 3) {
return 0;
}
break;
@ -363,7 +351,7 @@ int dlp_is_valid_ssn(const unsigned char *buffer, int length, int format)
/* validation data taken from
* http://en.wikipedia.org/wiki/Social_Security_number_%28United_States%29
*/
if(area_number > MAX_AREA ||
if (area_number > MAX_AREA ||
area_number == 666 ||
area_number <= 0 ||
group_number <= 0 ||
@ -372,9 +360,8 @@ int dlp_is_valid_ssn(const unsigned char *buffer, int length, int format)
serial_number > 9999)
retval = 0;
if(area_number == 987 && group_number == 65)
{
if(serial_number >= 4320 && serial_number <= 4329)
if (area_number == 987 && group_number == 65) {
if (serial_number >= 4320 && serial_number <= 4329)
retval = 0;
}
@ -382,7 +369,7 @@ int dlp_is_valid_ssn(const unsigned char *buffer, int length, int format)
if(group_number > ssn_max_group[area_number])
retval = 0;
*/
if(retval)
if (retval)
cli_dbgmsg("dlp_is_valid_ssn: SSN_%s: %s\n", format == SSN_FORMAT_HYPHENS ? "HYPHENS" : "STRIPPED", numbuf);
return retval;
@ -394,26 +381,20 @@ static int contains_ssn(const unsigned char *buffer, int length, int format, int
const unsigned char *end;
int count = 0;
if(buffer == NULL || length < 9)
if (buffer == NULL || length < 9)
return 0;
end = buffer + length;
idx = buffer;
while(idx < end)
{
if(isdigit(*idx))
{
while (idx < end) {
if (isdigit(*idx)) {
/* check for area number and the first hyphen */
if((idx == buffer || !isdigit(idx[-1])) && dlp_is_valid_ssn(idx, length - (idx - buffer), format) == 1)
{
if(detmode == DETECT_MODE_COUNT)
{
if ((idx == buffer || !isdigit(idx[-1])) && dlp_is_valid_ssn(idx, length - (idx - buffer), format) == 1) {
if (detmode == DETECT_MODE_COUNT) {
count++;
/* hop over the matched bytes if we found an SSN */
idx += ((format == SSN_FORMAT_HYPHENS)?11:9);
}
else
{
idx += ((format == SSN_FORMAT_HYPHENS) ? 11 : 9);
} else {
return 1;
}
}
@ -453,8 +434,8 @@ int dlp_has_ssn(const unsigned char *buffer, int length)
return (contains_ssn(buffer,
length,
SSN_FORMAT_HYPHENS,
DETECT_MODE_DETECT)
| contains_ssn(buffer,
DETECT_MODE_DETECT) |
contains_ssn(buffer,
length,
SSN_FORMAT_STRIPPED,
DETECT_MODE_DETECT));
@ -489,47 +470,82 @@ int dlp_has_normal_ssn(const unsigned char *buffer, int length)
/* numbers via the DLP module in ClamAV or the SDF pre- */
/* processor in the Snort IDS. */
/* Are first three or last three digits a valid bank code */
int is_bank_code_valid(int bank_code)
{
switch (bank_code) {
case 1: return 1; /* Bank of Montreal */
case 2: return 1; /* Bank of Nova Scotia */
case 3: return 1; /* Royal Bank of Canada */
case 4: return 1; /* Toronto-Dominion Bank */
case 6: return 1; /* National Bank of Canada */
case 10: return 1; /* Canadian Imperial Bank of Commerce */
case 16: return 1; /* HSBC Canada */
case 30: return 1; /* Canadian Western Bank */
case 39: return 1; /* Laurentian Bank of Canada */
case 117: return 1; /* Government of Canada */
case 127: return 1; /* Canada Post (Money Orders) */
case 177: return 1; /* Bank of Canada */
case 219: return 1; /* ATB Financial */
case 260: return 1; /* Citibank Canada */
case 290: return 1; /* UBS Bank (Canada) */
case 308: return 1; /* Bank of China (Canada) */
case 309: return 1; /* Citizens Bank of Canada */
case 326: return 1; /* Presidents Choice Financial */
case 338: return 1; /* Canadian Tire Bank */
case 340: return 1; /* ICICI Bank Canada */
case 509: return 1; /* Canada Trust */
case 540: return 1; /* Manulife Bank */
case 614: return 1; /* ING Direct Canada */
case 809: return 1; /* Central 1 [Credit Union] BC Region */
case 815: return 1; /* Caisses Desjardins du Québec */
case 819: return 1; /* Caisses populaires Desjardins du Manitoba */
case 828: return 1; /* Central 1 [Credit Union] ON Region */
case 829: return 1; /* Caisses populaires Desjardins de lOntario */
case 837: return 1; /* Meridian Credit Union */
case 839: return 1; /* Credit Union Heritage (Nova Scotia) */
case 865: return 1; /* Caisses populaires Desjardins acadiennes */
case 879: return 1; /* Credit Union Central of Manitoba */
case 889: return 1; /* Credit Union Central of Saskatchewan */
case 899: return 1; /* Credit Union Central Alberta */
case 900: return 1; /* Unknown??? */
default: return 0; /* NO MATCH...FAIL */
case 1:
return 1; /* Bank of Montreal */
case 2:
return 1; /* Bank of Nova Scotia */
case 3:
return 1; /* Royal Bank of Canada */
case 4:
return 1; /* Toronto-Dominion Bank */
case 6:
return 1; /* National Bank of Canada */
case 10:
return 1; /* Canadian Imperial Bank of Commerce */
case 16:
return 1; /* HSBC Canada */
case 30:
return 1; /* Canadian Western Bank */
case 39:
return 1; /* Laurentian Bank of Canada */
case 117:
return 1; /* Government of Canada */
case 127:
return 1; /* Canada Post (Money Orders) */
case 177:
return 1; /* Bank of Canada */
case 219:
return 1; /* ATB Financial */
case 260:
return 1; /* Citibank Canada */
case 290:
return 1; /* UBS Bank (Canada) */
case 308:
return 1; /* Bank of China (Canada) */
case 309:
return 1; /* Citizens Bank of Canada */
case 326:
return 1; /* Presidents Choice Financial */
case 338:
return 1; /* Canadian Tire Bank */
case 340:
return 1; /* ICICI Bank Canada */
case 509:
return 1; /* Canada Trust */
case 540:
return 1; /* Manulife Bank */
case 614:
return 1; /* ING Direct Canada */
case 809:
return 1; /* Central 1 [Credit Union] BC Region */
case 815:
return 1; /* Caisses Desjardins du Québec */
case 819:
return 1; /* Caisses populaires Desjardins du Manitoba */
case 828:
return 1; /* Central 1 [Credit Union] ON Region */
case 829:
return 1; /* Caisses populaires Desjardins de lOntario */
case 837:
return 1; /* Meridian Credit Union */
case 839:
return 1; /* Credit Union Heritage (Nova Scotia) */
case 865:
return 1; /* Caisses populaires Desjardins acadiennes */
case 879:
return 1; /* Credit Union Central of Manitoba */
case 889:
return 1; /* Credit Union Central of Saskatchewan */
case 899:
return 1; /* Credit Union Central Alberta */
case 900:
return 1; /* Unknown??? */
default:
return 0; /* NO MATCH...FAIL */
} /* end if switch(bank_code) */
return 0;
@ -570,7 +586,7 @@ int cdn_ctn_is_valid(const char *buffer, int length)
}
/* now have a switch sandwich for bank codes */
return(is_bank_code_valid(bank_code)); /* return 1 if valid, 0 if not */
return (is_bank_code_valid(bank_code)); /* return 1 if valid, 0 if not */
}
/* If the string is a canadian EFT (Electronic Fund */
@ -593,8 +609,7 @@ int cdn_eft_is_valid(const char *buffer, int length)
if (buffer[0] != '0') return 0; /* if the 1st char isn't a '0', not a valid EFT */
for (i = 1; i < 4; i++)
{
for (i = 1; i < 4; i++) {
if (isdigit(buffer[i]) == 0)
return 0;
bank_code = (bank_code * 10) + (buffer[i] - '0');
@ -605,7 +620,7 @@ int cdn_eft_is_valid(const char *buffer, int length)
if (!is_bank_code_valid(bank_code))
return 0;
for(i = 4; i < 9; i++)
for (i = 4; i < 9; i++)
if (isdigit(buffer[i]) == 0)
return 0;
@ -623,8 +638,7 @@ int us_micr_is_valid(const char *buffer, int length)
/* loop and make sure all the characters are actually digits */
for (i = 0; i < 9; i++)
{
for (i = 0; i < 9; i++) {
if (isdigit(buffer[i]) == 0)
return 0;
micr_digits[i] = buffer[i];

View file

@ -62,15 +62,15 @@
/* #define DEBUG_DMG_BZIP */
#ifdef DEBUG_DMG_PARSE
# define dmg_parsemsg(...) cli_dbgmsg( __VA_ARGS__)
#define dmg_parsemsg(...) cli_dbgmsg(__VA_ARGS__)
#else
# define dmg_parsemsg(...) ;
#define dmg_parsemsg(...) ;
#endif
#ifdef DEBUG_DMG_BZIP
# define dmg_bzipmsg(...) cli_dbgmsg( __VA_ARGS__)
#define dmg_bzipmsg(...) cli_dbgmsg(__VA_ARGS__)
#else
# define dmg_bzipmsg(...) ;
#define dmg_bzipmsg(...) ;
#endif
enum dmgReadState {
@ -89,7 +89,7 @@ static int dmg_extract_xml(cli_ctx *, char *, struct dmg_koly_block *);
#if HAVE_LIBXML2
static int dmg_decode_mish(cli_ctx *, unsigned int *, xmlChar *, struct dmg_mish_with_stripes *);
#endif
static int cmp_mish_stripes(const void * stripe_a, const void * stripe_b);
static int cmp_mish_stripes(const void *stripe_a, const void *stripe_b);
static int dmg_track_sectors(uint64_t *, uint8_t *, uint32_t, uint32_t, uint64_t);
static int dmg_handle_mish(cli_ctx *, unsigned int, char *, uint64_t, struct dmg_mish_with_stripes *);
@ -130,9 +130,8 @@ int cli_scandmg(cli_ctx *ctx)
/* Check magic */
hdr.magic = be32_to_host(hdr.magic);
if (hdr.magic == 0x6b6f6c79) {
cli_dbgmsg("cli_scandmg: Found koly block @ %ld\n", (long) pos);
}
else {
cli_dbgmsg("cli_scandmg: Found koly block @ %ld\n", (long)pos);
} else {
cli_dbgmsg("cli_scandmg: No koly magic, %8x\n", hdr.magic);
return CL_EFORMAT;
}
@ -147,8 +146,7 @@ int cli_scandmg(cli_ctx *ctx)
cli_dbgmsg("cli_scandmg: The embedded XML is way larger than necessary, and probably corrupt or tampered with.\n");
return CL_EFORMAT;
}
if ((hdr.xmlOffset > (uint64_t)maplen) || (hdr.xmlLength > (uint64_t)maplen)
|| (hdr.xmlOffset + hdr.xmlLength) > (uint64_t)maplen) {
if ((hdr.xmlOffset > (uint64_t)maplen) || (hdr.xmlLength > (uint64_t)maplen) || (hdr.xmlOffset + hdr.xmlLength) > (uint64_t)maplen) {
cli_dbgmsg("cli_scandmg: XML out of range for this file\n");
return CL_EFORMAT;
}
@ -249,9 +247,8 @@ int cli_scandmg(cli_ctx *ctx)
continue;
dmg_parsemsg("read: name %s depth %d\n", nodeName, depth);
if ((state == DMG_FIND_DATA_MISH)
&& (depth == stateDepth[state-1])) {
xmlChar * textValue;
if ((state == DMG_FIND_DATA_MISH) && (depth == stateDepth[state - 1])) {
xmlChar *textValue;
struct dmg_mish_with_stripes *mish_set;
/* Reset state early, for continue cases */
stateDepth[DMG_FIND_KEY_DATA] = -1;
@ -298,8 +295,7 @@ int cli_scandmg(cli_ctx *ctx)
free(mish_set);
xmlFree(nodeName);
continue;
}
else if (ret != CL_CLEAN) {
} else if (ret != CL_CLEAN) {
xmlFree(nodeName);
free(mish_set);
continue;
@ -308,17 +304,14 @@ int cli_scandmg(cli_ctx *ctx)
if (mish_list_tail != NULL) {
mish_list_tail->next = mish_set;
mish_list_tail = mish_set;
}
else {
} else {
mish_list = mish_set;
mish_list_tail = mish_set;
}
mish_list_tail->next = NULL;
}
if ((state == DMG_FIND_KEY_DATA)
&& (depth > stateDepth[state-1])
&& (xmlStrcmp(nodeName, (const xmlChar *)"key") == 0)) {
xmlChar * textValue;
if ((state == DMG_FIND_KEY_DATA) && (depth > stateDepth[state - 1]) && (xmlStrcmp(nodeName, (const xmlChar *)"key") == 0)) {
xmlChar *textValue;
dmg_parsemsg("read: Found key - checking for Data\n");
if (xmlTextReaderRead(reader) != 1) {
xmlFree(nodeName);
@ -339,34 +332,28 @@ int cli_scandmg(cli_ctx *ctx)
dmg_parsemsg("read: Matched data\n");
stateDepth[DMG_FIND_KEY_DATA] = depth;
state++;
}
else {
} else {
dmg_parsemsg("read: text value is %s\n", textValue);
}
xmlFree(textValue);
}
if ((state == DMG_FIND_BLKX_CONTAINER)
&& (depth == stateDepth[state-1])) {
if ((state == DMG_FIND_BLKX_CONTAINER) && (depth == stateDepth[state - 1])) {
if (xmlStrcmp(nodeName, (const xmlChar *)"array") == 0) {
dmg_parsemsg("read: Found array blkx\n");
stateDepth[DMG_FIND_BLKX_CONTAINER] = depth;
state++;
}
else if (xmlStrcmp(nodeName, (const xmlChar *)"dict") == 0) {
} else if (xmlStrcmp(nodeName, (const xmlChar *)"dict") == 0) {
dmg_parsemsg("read: Found dict blkx\n");
stateDepth[DMG_FIND_BLKX_CONTAINER] = depth;
state++;
}
else {
} else {
cli_dbgmsg("cli_scandmg: Bad blkx, not container\n");
stateDepth[DMG_FIND_KEY_BLKX] = -1;
state--;
}
}
if ((state == DMG_FIND_KEY_BLKX)
&& (depth == stateDepth[state-1] + 1)
&& (xmlStrcmp(nodeName, (const xmlChar *)"key") == 0)) {
xmlChar * textValue;
if ((state == DMG_FIND_KEY_BLKX) && (depth == stateDepth[state - 1] + 1) && (xmlStrcmp(nodeName, (const xmlChar *)"key") == 0)) {
xmlChar *textValue;
dmg_parsemsg("read: Found key - checking for blkx\n");
if (xmlTextReaderRead(reader) != 1) {
xmlFree(nodeName);
@ -387,35 +374,28 @@ int cli_scandmg(cli_ctx *ctx)
cli_dbgmsg("cli_scandmg: Matched blkx\n");
stateDepth[DMG_FIND_KEY_BLKX] = depth;
state++;
}
else {
} else {
cli_dbgmsg("cli_scandmg: wanted blkx, text value is %s\n", textValue);
}
xmlFree(textValue);
}
if ((state == DMG_FIND_DICT_RESOURCE_FORK)
&& (depth == stateDepth[state-1])) {
if ((state == DMG_FIND_DICT_RESOURCE_FORK) && (depth == stateDepth[state - 1])) {
if (xmlStrcmp(nodeName, (const xmlChar *)"dict") == 0) {
dmg_parsemsg("read: Found resource-fork dict\n");
stateDepth[DMG_FIND_DICT_RESOURCE_FORK] = depth;
state++;
}
else {
} else {
dmg_parsemsg("read: Not resource-fork dict\n");
stateDepth[DMG_FIND_KEY_RESOURCE_FORK] = -1;
state--;
}
}
if ((state == DMG_FIND_KEY_RESOURCE_FORK)
&& (depth == stateDepth[state-1] + 1)
&& (xmlStrcmp(nodeName, (const xmlChar *)"key") == 0)) {
if ((state == DMG_FIND_KEY_RESOURCE_FORK) && (depth == stateDepth[state - 1] + 1) && (xmlStrcmp(nodeName, (const xmlChar *)"key") == 0)) {
dmg_parsemsg("read: Found resource-fork key\n");
stateDepth[DMG_FIND_KEY_RESOURCE_FORK] = depth;
state++;
}
if ((state == DMG_FIND_BASE_DICT)
&& (depth == stateDepth[state-1] + 1)
&& (xmlStrcmp(nodeName, (const xmlChar *)"dict") == 0)) {
if ((state == DMG_FIND_BASE_DICT) && (depth == stateDepth[state - 1] + 1) && (xmlStrcmp(nodeName, (const xmlChar *)"dict") == 0)) {
dmg_parsemsg("read: Found dict start\n");
stateDepth[DMG_FIND_BASE_DICT] = depth;
state++;
@ -426,35 +406,29 @@ int cli_scandmg(cli_ctx *ctx)
state++;
}
xmlFree(nodeName);
}
else if ((nodeType == XML_READER_TYPE_END_ELEMENT) && (state > DMG_FIND_BASE_PLIST)) {
} else if ((nodeType == XML_READER_TYPE_END_ELEMENT) && (state > DMG_FIND_BASE_PLIST)) {
int significantEnd = 0;
int depth = xmlTextReaderDepth(reader);
if (depth < 0) {
break;
}
else if (depth < stateDepth[state-1]) {
} else if (depth < stateDepth[state - 1]) {
significantEnd = 1;
}
else if ((depth == stateDepth[state-1])
&& (state-1 == DMG_FIND_BLKX_CONTAINER)) {
} else if ((depth == stateDepth[state - 1]) && (state - 1 == DMG_FIND_BLKX_CONTAINER)) {
/* Special case, ending blkx container */
significantEnd = 1;
}
if (significantEnd) {
dmg_parsemsg("read: significant end tag, state %d\n", state);
stateDepth[state-1] = -1;
stateDepth[state - 1] = -1;
state--;
if ((state-1 == DMG_FIND_KEY_RESOURCE_FORK)
|| (state-1 == DMG_FIND_KEY_BLKX)) {
if ((state - 1 == DMG_FIND_KEY_RESOURCE_FORK) || (state - 1 == DMG_FIND_KEY_BLKX)) {
/* Keys end their own tag (validly) and the next state depends on the following tag */
// cli_dbgmsg("read: significant end tag ending prior key state\n");
stateDepth[state-1] = -1;
stateDepth[state - 1] = -1;
state--;
}
}
else {
dmg_parsemsg("read: not significant end tag, state %d depth %d prior depth %d\n", state, depth, stateDepth[state-1]);
} else {
dmg_parsemsg("read: not significant end tag, state %d depth %d prior depth %d\n", state, depth, stateDepth[state - 1]);
}
}
}
@ -501,7 +475,7 @@ static int dmg_decode_mish(cli_ctx *ctx, unsigned int *mishblocknum, xmlChar *mi
{
size_t base64_len, buff_size, decoded_len;
uint8_t *decoded;
const uint8_t mish_magic[4] = { 0x6d, 0x69, 0x73, 0x68 };
const uint8_t mish_magic[4] = {0x6d, 0x69, 0x73, 0x68};
UNUSEDPARAM(ctx);
@ -550,15 +524,12 @@ static int dmg_decode_mish(cli_ctx *ctx, unsigned int *mishblocknum, xmlChar *mi
mish_set->mish->dataOffset, mish_set->mish->blockDataCount);
/* decoded length should be mish block + blockDataCount * 40 */
if (decoded_len < (sizeof(struct dmg_mish_block)
+ mish_set->mish->blockDataCount * sizeof(struct dmg_block_data))) {
if (decoded_len < (sizeof(struct dmg_mish_block) + mish_set->mish->blockDataCount * sizeof(struct dmg_block_data))) {
cli_dbgmsg("dmg_decode_mish: mish block %u too small\n", *mishblocknum);
free(decoded);
mish_set->mish = NULL;
return CL_EFORMAT;
}
else if (decoded_len > (sizeof(struct dmg_mish_block)
+ mish_set->mish->blockDataCount * sizeof(struct dmg_block_data))) {
} else if (decoded_len > (sizeof(struct dmg_mish_block) + mish_set->mish->blockDataCount * sizeof(struct dmg_block_data))) {
cli_dbgmsg("dmg_decode_mish: mish block %u bigger than needed, continuing\n", *mishblocknum);
}
@ -568,7 +539,7 @@ static int dmg_decode_mish(cli_ctx *ctx, unsigned int *mishblocknum, xmlChar *mi
#endif
/* Comparator for stripe sorting */
static int cmp_mish_stripes(const void * stripe_a, const void * stripe_b)
static int cmp_mish_stripes(const void *stripe_a, const void *stripe_b)
{
const struct dmg_block_data *a = stripe_a, *b = stripe_b;
return a->startSector - b->startSector;
@ -620,8 +591,7 @@ static int dmg_track_sectors(uint64_t *total, uint8_t *data_to_write,
if (stripeCount) {
/* Continue for now */
cli_dbgmsg("dmg_track_sectors: unknown type on stripe " STDu32 ", will skip\n", stripeNum);
}
else {
} else {
/* Continue, no sectors missed */
cli_dbgmsg("dmg_track_sectors: unknown type on empty stripe " STDu32 "\n", stripeNum);
}
@ -632,12 +602,10 @@ static int dmg_track_sectors(uint64_t *total, uint8_t *data_to_write,
/* Check for wrap */
if (*total < (*total + stripeCount)) {
*total = *total + stripeCount;
}
else if (stripeCount) {
} else if (stripeCount) {
cli_dbgmsg("dmg_track_sectors: *total would wrap uint64, suspicious\n");
ret = CL_EFORMAT;
}
else {
} else {
/* Can continue */
cli_dbgmsg("dmg_track_sectors: unexpected zero sectorCount on stripe " STDu32 "\n", stripeNum);
}
@ -705,8 +673,7 @@ static int dmg_stripe_store(cli_ctx *ctx, int fd, uint32_t index, struct dmg_mis
if (written < 0) {
cli_errmsg("dmg_stripe_store: error writing bytes to file (out of disk space?)\n");
return CL_EWRITE;
}
else if ((size_t)written != len) {
} else if ((size_t)written != len) {
cli_errmsg("dmg_stripe_store: error writing bytes to file (out of disk space?)\n");
return CL_EWRITE;
}
@ -740,12 +707,12 @@ static int dmg_stripe_adc(cli_ctx *ctx, int fd, uint32_t index, struct dmg_mish_
strm.avail_out = sizeof(obuf);
adcret = adc_decompressInit(&strm);
if(adcret != ADC_OK) {
if (adcret != ADC_OK) {
cli_warnmsg("dmg_stripe_adc: adc_decompressInit failed\n");
return CL_EMEM;
}
while(adcret == ADC_OK) {
while (adcret == ADC_OK) {
int written;
if (size_so_far > expected_len) {
cli_warnmsg("dmg_stripe_adc: expected size exceeded!\n");
@ -753,10 +720,10 @@ static int dmg_stripe_adc(cli_ctx *ctx, int fd, uint32_t index, struct dmg_mish_
return CL_EFORMAT;
}
adcret = adc_decompress(&strm);
switch(adcret) {
switch (adcret) {
case ADC_OK:
if(strm.avail_out == 0) {
if ((written=cli_writen(fd, obuf, sizeof(obuf)))!=sizeof(obuf)) {
if (strm.avail_out == 0) {
if ((written = cli_writen(fd, obuf, sizeof(obuf))) != sizeof(obuf)) {
cli_errmsg("dmg_stripe_adc: failed write to output file\n");
adc_decompressEnd(&strm);
return CL_EWRITE;
@ -770,7 +737,7 @@ static int dmg_stripe_adc(cli_ctx *ctx, int fd, uint32_t index, struct dmg_mish_
default:
written = sizeof(obuf) - strm.avail_out;
if (written) {
if ((cli_writen(fd, obuf, written))!=written) {
if ((cli_writen(fd, obuf, written)) != written) {
cli_errmsg("dmg_stripe_adc: failed write to output file\n");
adc_decompressEnd(&strm);
return CL_EWRITE;
@ -812,7 +779,7 @@ static int dmg_stripe_inflate(cli_ctx *ctx, int fd, uint32_t index, struct dmg_m
return CL_CLEAN;
memset(&strm, 0, sizeof(strm));
strm.next_in = (void*)fmap_need_off_once(*ctx->fmap, off, len);
strm.next_in = (void *)fmap_need_off_once(*ctx->fmap, off, len);
if (!strm.next_in) {
cli_warnmsg("dmg_stripe_inflate: fmap need failed on stripe " STDu32 "\n", index);
return CL_EMAP;
@ -822,12 +789,12 @@ static int dmg_stripe_inflate(cli_ctx *ctx, int fd, uint32_t index, struct dmg_m
strm.avail_out = sizeof(obuf);
zstat = inflateInit(&strm);
if(zstat != Z_OK) {
if (zstat != Z_OK) {
cli_warnmsg("dmg_stripe_inflate: inflateInit failed\n");
return CL_EMEM;
}
while(strm.avail_in) {
while (strm.avail_in) {
int written;
if (size_so_far > expected_len) {
cli_warnmsg("dmg_stripe_inflate: expected size exceeded!\n");
@ -835,10 +802,10 @@ static int dmg_stripe_inflate(cli_ctx *ctx, int fd, uint32_t index, struct dmg_m
return CL_EFORMAT;
}
zstat = inflate(&strm, Z_NO_FLUSH); /* zlib */
switch(zstat) {
switch (zstat) {
case Z_OK:
if(strm.avail_out == 0) {
if ((written=cli_writen(fd, obuf, sizeof(obuf)))!=sizeof(obuf)) {
if (strm.avail_out == 0) {
if ((written = cli_writen(fd, obuf, sizeof(obuf))) != sizeof(obuf)) {
cli_errmsg("dmg_stripe_inflate: failed write to output file\n");
inflateEnd(&strm);
return CL_EWRITE;
@ -852,7 +819,7 @@ static int dmg_stripe_inflate(cli_ctx *ctx, int fd, uint32_t index, struct dmg_m
default:
written = sizeof(obuf) - strm.avail_out;
if (written) {
if ((cli_writen(fd, obuf, written))!=written) {
if ((cli_writen(fd, obuf, written)) != written) {
cli_errmsg("dmg_stripe_inflate: failed write to output file\n");
inflateEnd(&strm);
return CL_EWRITE;
@ -863,7 +830,7 @@ static int dmg_stripe_inflate(cli_ctx *ctx, int fd, uint32_t index, struct dmg_m
if (zstat == Z_STREAM_END)
break;
}
if(strm.msg)
if (strm.msg)
cli_dbgmsg("dmg_stripe_inflate: after writing " STDu64 " bytes, "
"got error \"%s\" inflating stripe " STDu32 "\n",
size_so_far, strm.msg, index);
@ -877,8 +844,8 @@ static int dmg_stripe_inflate(cli_ctx *ctx, int fd, uint32_t index, struct dmg_m
break;
}
if(strm.avail_out != sizeof(obuf)) {
if(cli_writen(fd, obuf, sizeof(obuf) - strm.avail_out) < 0) {
if (strm.avail_out != sizeof(obuf)) {
if (cli_writen(fd, obuf, sizeof(obuf) - strm.avail_out) < 0) {
cli_errmsg("dmg_stripe_inflate: failed write to output file\n");
inflateEnd(&strm);
return CL_EWRITE;
@ -924,7 +891,7 @@ static int dmg_stripe_bzip(cli_ctx *ctx, int fd, uint32_t index, struct dmg_mish
if (strm.avail_in == 0) {
size_t next_len = (len > sizeof(obuf)) ? sizeof(obuf) : len;
dmg_bzipmsg("dmg_stripe_bzip: off %lu len %lu next_len %lu\n", off, len, next_len);
strm.next_in = (void*)fmap_need_off_once(*ctx->fmap, off, next_len);
strm.next_in = (void *)fmap_need_off_once(*ctx->fmap, off, next_len);
if (strm.next_in == NULL) {
cli_dbgmsg("dmg_stripe_bzip: expected more stream\n");
ret = CL_EMAP;
@ -1043,7 +1010,7 @@ static int dmg_handle_mish(cli_ctx *ctx, unsigned int mishblocknum, char *dir,
cli_dbgmsg("dmg_handle_mish: invalid stripe offset and/or length\n");
return CL_EFORMAT;
}
if ((i > 0) && sorted && (blocklist[i].startSector < blocklist[i-1].startSector)) {
if ((i > 0) && sorted && (blocklist[i].startSector < blocklist[i - 1].startSector)) {
cli_dbgmsg("dmg_handle_mish: stripes not in order, will have to sort\n");
sorted = 0;
}
@ -1062,8 +1029,7 @@ static int dmg_handle_mish(cli_ctx *ctx, unsigned int mishblocknum, char *dir,
if ((writeable_data == 0) || (totalSectors == 0)) {
cli_dbgmsg("dmg_handle_mish: no data to output\n");
return CL_CLEAN;
}
else if (totalSectors > (ULONG_MAX / DMG_SECTOR_SIZE)) {
} else if (totalSectors > (ULONG_MAX / DMG_SECTOR_SIZE)) {
/* cli_checklimits only takes unsigned long for now */
cli_warnmsg("dmg_handle_mish: mish block %u too big to handle (for now)", mishblocknum);
return CL_CLEAN;
@ -1077,9 +1043,9 @@ static int dmg_handle_mish(cli_ctx *ctx, unsigned int mishblocknum, char *dir,
}
/* Prepare for file */
snprintf(outfile, sizeof(outfile)-1, "%s"PATHSEP"dmg%02u", dir, mishblocknum);
outfile[sizeof(outfile)-1] = '\0';
ofd = open(outfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
snprintf(outfile, sizeof(outfile) - 1, "%s" PATHSEP "dmg%02u", dir, mishblocknum);
outfile[sizeof(outfile) - 1] = '\0';
ofd = open(outfile, O_RDWR | O_CREAT | O_EXCL | O_TRUNC | O_BINARY, 0600);
if (ofd < 0) {
char err[128];
cli_errmsg("cli_scandmg: Can't create temporary file %s: %s\n",
@ -1089,7 +1055,7 @@ static int dmg_handle_mish(cli_ctx *ctx, unsigned int mishblocknum, char *dir,
cli_dbgmsg("dmg_handle_mish: extracting block %u to %s\n", mishblocknum, outfile);
/* Push data, stripe by stripe */
for(i=0; i < mish_set->mish->blockDataCount && ret == CL_CLEAN; i++) {
for (i = 0; i < mish_set->mish->blockDataCount && ret == CL_CLEAN; i++) {
switch (blocklist[i].type) {
case DMG_STRIPE_EMPTY:
case DMG_STRIPE_ZEROES:
@ -1129,7 +1095,7 @@ static int dmg_handle_mish(cli_ctx *ctx, unsigned int mishblocknum, char *dir,
static int dmg_extract_xml(cli_ctx *ctx, char *dir, struct dmg_koly_block *hdr)
{
char * xmlfile;
char *xmlfile;
const char *outdata;
size_t namelen, nread;
int ofd;
@ -1145,11 +1111,11 @@ static int dmg_extract_xml(cli_ctx *ctx, char *dir, struct dmg_koly_block *hdr)
if (!(xmlfile = cli_malloc(namelen))) {
return CL_EMEM;
}
snprintf(xmlfile, namelen, "%s"PATHSEP"toc.xml", dir);
snprintf(xmlfile, namelen, "%s" PATHSEP "toc.xml", dir);
cli_dbgmsg("cli_scandmg: Extracting XML as %s\n", xmlfile);
/* Write out TOC XML */
if ((ofd = open(xmlfile, O_CREAT|O_RDWR|O_EXCL|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
if ((ofd = open(xmlfile, O_CREAT | O_RDWR | O_EXCL | O_TRUNC | O_BINARY, S_IRWXU)) < 0) {
char err[128];
cli_errmsg("cli_scandmg: Can't create temporary file %s: %s\n",
xmlfile, cli_strerror(errno, err, sizeof(err)));
@ -1168,4 +1134,3 @@ static int dmg_extract_xml(cli_ctx *ctx, char *dir, struct dmg_koly_block *hdr)
free(xmlfile);
return CL_SUCCESS;
}

Some files were not shown because too many files have changed in this diff Show more