2
* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2 as
8
* published by the Free Software Foundation.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
29
#include <sys/types.h>
37
#include <openssl/ssl.h>
38
#include <openssl/err.h>
39
#include "libclamav/crypto.h"
41
#include "libclamav/others.h"
42
#include "libclamav/clamav.h"
44
#define JSON_BUFSZ 512
45
#define SAMPLE_PREFIX "sample_"
47
char *hex_encode(char *buf, char *data, size_t len)
53
p = (buf != NULL) ? buf : calloc(1, (len*2)+1);
57
for (i=0; i<len; i++) {
59
sprintf(p+(i*2), "%02x", t);
65
char *ensure_bufsize(char *buf, size_t *oldsize, size_t used, size_t additional)
69
if (*oldsize - used < additional) {
70
p = realloc(buf, *oldsize + JSON_BUFSZ);
72
cli_errmsg("ensure_bufsize: Could not allocate more memory: %s (errno: %d)\n", strerror(errno), errno);
77
*oldsize += JSON_BUFSZ;
83
char *export_stats_to_json(struct cl_engine *engine, cli_intel_t *intel)
85
char *buf=NULL, *p, *hostid, md5[33];
86
cli_flagged_sample_t *sample;
87
size_t bufsz, curused, i, j;
90
if ((engine->cb_stats_get_hostid))
91
intel->hostid = engine->cb_stats_get_hostid(engine->stats_data);
93
hostid = (intel->hostid != NULL) ? intel->hostid : STATS_ANON_UUID;
95
buf = calloc(1, JSON_BUFSZ);
100
sprintf(buf, "{\n\t\"hostid\": \"%s\",\n", hostid);
101
if (intel->host_info)
102
sprintf(buf+strlen(buf), "\t\"host_info\": \"%s\",\n", intel->host_info);
104
sprintf(buf+strlen(buf), "\t\"samples\": [\n");
105
curused = strlen(buf);
107
for (sample = intel->samples; sample != NULL; sample = sample->next) {
108
if (sample->hits == 0)
111
memset(md5, 0x00, sizeof(md5));
112
hex_encode(md5, sample->md5, sizeof(sample->md5));
114
buf = ensure_bufsize(buf, &bufsz, curused, strlen(md5) + sizeof(SAMPLE_PREFIX) + 45);
118
snprintf(buf+curused, bufsz-curused, "\t\t\t{\n");
119
curused += strlen(buf+curused);
121
buf = ensure_bufsize(buf, &bufsz, curused, sizeof("\t\t\t\"hash\": \"\",\n") + strlen(md5) + 1);
125
snprintf(buf+curused, bufsz-curused, "\t\t\t\"hash\": \"%s\",\n", md5);
126
curused += strlen(buf+curused);
128
/* Reuse the md5 variable for serializing the number of hits */
129
snprintf(md5, sizeof(md5), "%u", sample->hits);
131
buf = ensure_bufsize(buf, &bufsz, curused, strlen(md5) + 20);
135
snprintf(buf+curused, bufsz-curused, "\t\t\t\"hits\": %s,\n", md5);
136
curused += strlen(buf+curused);
138
snprintf(md5, sizeof(md5), "%u", sample->size);
140
buf = ensure_bufsize(buf, &bufsz, curused, strlen(md5) + 20);
144
snprintf(buf+curused, bufsz-curused, "\t\t\t\"size\": %s,\n", md5);
145
curused += strlen(buf+curused);
147
buf = ensure_bufsize(buf, &bufsz, curused, 30);
151
if ((sample->sections) && (sample->sections->nsections)) {
152
buf = ensure_bufsize(buf, &bufsz, curused, 30);
156
snprintf(buf+curused, bufsz-curused, "\t\t\t\"sections\": [\n");
157
curused += strlen(buf+curused);
159
for (i=0; i < sample->sections->nsections; i++) {
160
buf = ensure_bufsize(buf, &bufsz, curused, 30);
164
snprintf(buf+curused, bufsz-curused, "\t\t\t\t%s{\n", (i > 0) ? "," : "");
165
curused += strlen(buf+curused);
167
buf = ensure_bufsize(buf, &bufsz, curused, 65);
171
memset(md5, 0x00, sizeof(md5));
172
for (j=0; j < 16; j++)
173
sprintf(md5+(j*2), "%02x", sample->sections->sections[i].md5[j]);
175
snprintf(buf+curused, bufsz-curused, "\t\t\t\t\t\"hash\": \"%s\",\n", md5);
176
curused += strlen(buf+curused);
178
buf = ensure_bufsize(buf, &bufsz, curused, 65);
182
snprintf(buf+curused, bufsz-curused, "\t\t\t\t\t\"size\": %u\n", sample->sections->sections[i].len);
183
curused += strlen(buf+curused);
185
buf = ensure_bufsize(buf, &bufsz, curused, 30);
189
snprintf(buf+curused, bufsz-curused, "\t\t\t\t}\n");
190
curused += strlen(buf+curused);
193
buf = ensure_bufsize(buf, &bufsz, curused, 20);
197
snprintf(buf+curused, bufsz-curused, "\t\t\t],\n");
198
curused += strlen(buf+curused);
201
snprintf(buf+curused, bufsz-curused, "\t\t\t\"virus_names\": [ ");
202
curused += strlen(buf+curused);
204
for (i=0; sample->virus_name[i] != NULL; i++) {
205
buf = ensure_bufsize(buf, &bufsz, curused, strlen(sample->virus_name[i]) + 5);
209
snprintf(buf+curused, bufsz-curused, "%s\"%s\"", (i > 0) ? ", " : "", sample->virus_name[i]);
210
curused += strlen(buf+curused);
213
buf = ensure_bufsize(buf, &bufsz, curused, 10);
217
snprintf(buf+curused, bufsz-curused, " ]\n\t\t}%s\n", (sample->next != NULL) ? "," : "");
218
curused += strlen(buf+curused);
221
buf = ensure_bufsize(buf, &bufsz, curused, 15);
225
snprintf(buf+curused, bufsz-curused, "\t]\n}\n");