output-json: ensure string is json-encodable

Substitute json_string with SCJsonString custom function.
SCJsonString will ensure string passed is json-encodable (utf-8).
If it's not, the string will be converted in such a way that any
non-printable character will be encoded in its hex form.
The resulting json object will be returned.

rust modification will encode any non-printable character during its
conversion in to_cstring.
pull/3440/head
Maurizio Abba 8 years ago committed by Victor Julien
parent 4f32324fe4
commit bf4398b15d

@ -139,7 +139,7 @@ impl Json {
fn to_cstring(val: &[u8]) -> CString {
let mut safe = Vec::with_capacity(val.len());
for c in val {
if *c == 0 || *c > 0x7f {
if *c < 0x20 || *c > 0x7e {
safe.extend(format!("\\x{:02x}", *c).as_bytes());
} else {
safe.push(*c);

@ -328,9 +328,9 @@ void AlertJsonHeader(void *ctx, const Packet *p, const PacketAlert *pa, json_t *
json_object_set_new(ajs, "signature_id", json_integer(pa->s->id));
json_object_set_new(ajs, "rev", json_integer(pa->s->rev));
json_object_set_new(ajs, "signature",
json_string((pa->s->msg) ? pa->s->msg : ""));
SCJsonString((pa->s->msg) ? pa->s->msg : ""));
json_object_set_new(ajs, "category",
json_string((pa->s->class_msg) ? pa->s->class_msg : ""));
SCJsonString((pa->s->class_msg) ? pa->s->class_msg : ""));
json_object_set_new(ajs, "severity", json_integer(pa->s->prio));
if (p->tenant_id > 0)

@ -29,6 +29,7 @@
#include "app-layer-dnp3.h"
#include "app-layer-dnp3-objects.h"
#include "output-json-dnp3-objects.h"
#include "output-json.h"
#ifdef HAVE_LIBJANSSON
@ -2133,7 +2134,7 @@ void OutputJsonDNP3SetItem(json_t *js, DNP3Object *object,
char tmpbuf[data->filename_size + 1];
memcpy(tmpbuf, data->filename, data->filename_size);
tmpbuf[data->filename_size] = '\0';
json_object_set_new(js, "filename", json_string(tmpbuf));
json_object_set_new(js, "filename", SCJsonString(tmpbuf));
} else {
json_object_set_new(js, "filename", json_string(""));
}
@ -2145,7 +2146,7 @@ void OutputJsonDNP3SetItem(json_t *js, DNP3Object *object,
char tmpbuf[data->data_size + 1];
memcpy(tmpbuf, data->data, data->data_size);
tmpbuf[data->data_size] = '\0';
json_object_set_new(js, "data", json_string(tmpbuf));
json_object_set_new(js, "data", SCJsonString(tmpbuf));
} else {
json_object_set_new(js, "data", json_string(""));
}
@ -2169,7 +2170,7 @@ void OutputJsonDNP3SetItem(json_t *js, DNP3Object *object,
char tmpbuf[data->username_size + 1];
memcpy(tmpbuf, data->username, data->username_size);
tmpbuf[data->username_size] = '\0';
json_object_set_new(js, "username", json_string(tmpbuf));
json_object_set_new(js, "username", SCJsonString(tmpbuf));
} else {
json_object_set_new(js, "username", json_string(""));
}
@ -2179,7 +2180,7 @@ void OutputJsonDNP3SetItem(json_t *js, DNP3Object *object,
char tmpbuf[data->password_size + 1];
memcpy(tmpbuf, data->password, data->password_size);
tmpbuf[data->password_size] = '\0';
json_object_set_new(js, "password", json_string(tmpbuf));
json_object_set_new(js, "password", SCJsonString(tmpbuf));
} else {
json_object_set_new(js, "password", json_string(""));
}
@ -2211,7 +2212,7 @@ void OutputJsonDNP3SetItem(json_t *js, DNP3Object *object,
char tmpbuf[data->filename_size + 1];
memcpy(tmpbuf, data->filename, data->filename_size);
tmpbuf[data->filename_size] = '\0';
json_object_set_new(js, "filename", json_string(tmpbuf));
json_object_set_new(js, "filename", SCJsonString(tmpbuf));
} else {
json_object_set_new(js, "filename", json_string(""));
}
@ -2235,7 +2236,7 @@ void OutputJsonDNP3SetItem(json_t *js, DNP3Object *object,
char tmpbuf[data->optional_text_len + 1];
memcpy(tmpbuf, data->optional_text, data->optional_text_len);
tmpbuf[data->optional_text_len] = '\0';
json_object_set_new(js, "optional_text", json_string(tmpbuf));
json_object_set_new(js, "optional_text", SCJsonString(tmpbuf));
} else {
json_object_set_new(js, "optional_text", json_string(""));
}
@ -2253,7 +2254,7 @@ void OutputJsonDNP3SetItem(json_t *js, DNP3Object *object,
char tmpbuf[data->file_data_len + 1];
memcpy(tmpbuf, data->file_data, data->file_data_len);
tmpbuf[data->file_data_len] = '\0';
json_object_set_new(js, "file_data", json_string(tmpbuf));
json_object_set_new(js, "file_data", SCJsonString(tmpbuf));
} else {
json_object_set_new(js, "file_data", json_string(""));
}
@ -2273,7 +2274,7 @@ void OutputJsonDNP3SetItem(json_t *js, DNP3Object *object,
char tmpbuf[data->optional_text_len + 1];
memcpy(tmpbuf, data->optional_text, data->optional_text_len);
tmpbuf[data->optional_text_len] = '\0';
json_object_set_new(js, "optional_text", json_string(tmpbuf));
json_object_set_new(js, "optional_text", SCJsonString(tmpbuf));
} else {
json_object_set_new(js, "optional_text", json_string(""));
}
@ -2301,7 +2302,7 @@ void OutputJsonDNP3SetItem(json_t *js, DNP3Object *object,
char tmpbuf[data->filename_size + 1];
memcpy(tmpbuf, data->filename, data->filename_size);
tmpbuf[data->filename_size] = '\0';
json_object_set_new(js, "filename", json_string(tmpbuf));
json_object_set_new(js, "filename", SCJsonString(tmpbuf));
} else {
json_object_set_new(js, "filename", json_string(""));
}
@ -2315,7 +2316,7 @@ void OutputJsonDNP3SetItem(json_t *js, DNP3Object *object,
char tmpbuf[data->file_specification_len + 1];
memcpy(tmpbuf, data->file_specification, data->file_specification_len);
tmpbuf[data->file_specification_len] = '\0';
json_object_set_new(js, "file_specification", json_string(tmpbuf));
json_object_set_new(js, "file_specification", SCJsonString(tmpbuf));
} else {
json_object_set_new(js, "file_specification", json_string(""));
}
@ -2341,7 +2342,7 @@ void OutputJsonDNP3SetItem(json_t *js, DNP3Object *object,
}
case DNP3_OBJECT_CODE(83, 1): {
DNP3ObjectG83V1 *data = point->data;
json_object_set_new(js, "data->vendor_code", json_string(data->vendor_code));
json_object_set_new(js, "data->vendor_code", SCJsonString(data->vendor_code));
json_object_set_new(js, "object_id",
json_integer(data->object_id));
json_object_set_new(js, "length",
@ -2486,7 +2487,7 @@ void OutputJsonDNP3SetItem(json_t *js, DNP3Object *object,
char tmpbuf[data->error_text_len + 1];
memcpy(tmpbuf, data->error_text, data->error_text_len);
tmpbuf[data->error_text_len] = '\0';
json_object_set_new(js, "error_text", json_string(tmpbuf));
json_object_set_new(js, "error_text", SCJsonString(tmpbuf));
} else {
json_object_set_new(js, "error_text", json_string(""));
}
@ -2540,7 +2541,7 @@ void OutputJsonDNP3SetItem(json_t *js, DNP3Object *object,
char tmpbuf[data->username_len + 1];
memcpy(tmpbuf, data->username, data->username_len);
tmpbuf[data->username_len] = '\0';
json_object_set_new(js, "username", json_string(tmpbuf));
json_object_set_new(js, "username", SCJsonString(tmpbuf));
} else {
json_object_set_new(js, "username", json_string(""));
}
@ -2572,7 +2573,7 @@ void OutputJsonDNP3SetItem(json_t *js, DNP3Object *object,
char tmpbuf[data->username_len + 1];
memcpy(tmpbuf, data->username, data->username_len);
tmpbuf[data->username_len] = '\0';
json_object_set_new(js, "username", json_string(tmpbuf));
json_object_set_new(js, "username", SCJsonString(tmpbuf));
} else {
json_object_set_new(js, "username", json_string(""));
}

@ -429,7 +429,7 @@ static json_t *OutputQuery(DNSTransaction *tx, uint64_t tx_id, DNSQueryEntry *en
char *c;
c = BytesToString((uint8_t *)((uint8_t *)entry + sizeof(DNSQueryEntry)), entry->len);
if (c != NULL) {
json_object_set_new(djs, "rrname", json_string(c));
json_object_set_new(djs, "rrname", SCJsonString(c));
SCFree(c);
}
@ -766,7 +766,7 @@ static void OutputAnswerV1(LogDnsLogThread *aft, json_t *djs,
c = BytesToString((uint8_t *)((uint8_t *)entry + sizeof(DNSAnswerEntry)),
entry->fqdn_len);
if (c != NULL) {
json_object_set_new(js, "rrname", json_string(c));
json_object_set_new(js, "rrname", SCJsonString(c));
SCFree(c);
}
}
@ -799,7 +799,7 @@ static void OutputAnswerV1(LogDnsLogThread *aft, json_t *djs,
entry->data_len : sizeof(buffer) - 1;
memcpy(buffer, ptr, copy_len);
buffer[copy_len] = '\0';
json_object_set_new(js, "rdata", json_string(buffer));
json_object_set_new(js, "rdata", SCJsonString(buffer));
} else {
json_object_set_new(js, "rdata", json_string(""));
}
@ -959,7 +959,7 @@ static void OutputFailure(LogDnsLogThread *aft, json_t *djs,
char *c;
c = BytesToString((uint8_t *)((uint8_t *)entry + sizeof(DNSQueryEntry)), entry->len);
if (c != NULL) {
json_object_set_new(js, "rrname", json_string(c));
json_object_set_new(js, "rrname", SCJsonString(c));
SCFree(c);
}

@ -114,10 +114,10 @@ static json_t* JsonEmailJsonArrayFromCommaList(const uint8_t *val, size_t len)
return NULL;
}
sp = SkipWhiteSpaceTill(p, savep);
json_array_append_new(ajs, json_string(sp));
json_array_append_new(ajs, SCJsonString(sp));
while ((p = strtok_r(NULL, ",", &savep)) != NULL) {
sp = SkipWhiteSpaceTill(p, savep);
json_array_append_new(ajs, json_string(sp));
json_array_append_new(ajs, SCJsonString(sp));
}
} else {
json_decref(ajs);
@ -180,7 +180,7 @@ static int JsonEmailAddToJsonArray(const uint8_t *val, size_t len, void *data)
if (ajs == NULL)
return 0;
char *value = BytesToString((uint8_t *)val, len);
json_array_append_new(ajs, json_string(value));
json_array_append_new(ajs, SCJsonString(value));
SCFree(value);
return 1;
}
@ -223,7 +223,7 @@ static void JsonEmailLogJSONCustom(OutputJsonEmailCtx *email_ctx, json_t *js, SM
char *s = BytesToString((uint8_t *)field->value,
(size_t)field->value_len);
if (likely(s != NULL)) {
json_object_set_new(js, email_fields[f].config_field, json_string(s));
json_object_set_new(js, email_fields[f].config_field, SCJsonString(s));
SCFree(s);
}
}
@ -285,7 +285,7 @@ static json_t *JsonEmailLogJsonData(const Flow *f, void *state, void *vtx, uint6
if (likely(s != NULL)) {
//printf("From: \"%s\"\n", s);
char * sp = SkipWhiteSpaceTill(s, s + strlen(s));
json_object_set_new(sjs, "from", json_string(sp));
json_object_set_new(sjs, "from", SCJsonString(sp));
SCFree(s);
}
}
@ -325,7 +325,7 @@ static json_t *JsonEmailLogJsonData(const Flow *f, void *state, void *vtx, uint6
(size_t)url->url_len);
if (s != NULL) {
json_array_append_new(js_url,
json_string(s));
SCJsonString(s));
SCFree(s);
url_cnt += 1;
}
@ -337,7 +337,7 @@ static json_t *JsonEmailLogJsonData(const Flow *f, void *state, void *vtx, uint6
char *s = BytesToString((uint8_t *)entity->filename,
(size_t)entity->filename_len);
json_array_append_new(js_attch,
json_string(s));
SCJsonString(s));
SCFree(s);
attch_cnt += 1;
}
@ -348,7 +348,7 @@ static json_t *JsonEmailLogJsonData(const Flow *f, void *state, void *vtx, uint6
(size_t)url->url_len);
if (s != NULL) {
json_array_append_new(js_url,
json_string(s));
SCJsonString(s));
SCFree(s);
url_cnt += 1;
}

@ -146,7 +146,7 @@ json_t *JsonBuildFileInfoRecord(const Packet *p, const File *ff,
}
char *s = BytesToString(ff->name, ff->name_len);
json_object_set_new(fjs, "filename", json_string(s));
json_object_set_new(fjs, "filename", SCJsonString(s));
if (s != NULL)
SCFree(s);
#ifdef HAVE_MAGIC

@ -197,7 +197,7 @@ static void JsonHttpLogJSONBasic(json_t *js, htp_tx_t *tx)
{
c = bstr_util_strdup_to_c(tx->request_hostname);
if (c != NULL) {
json_object_set_new(js, "hostname", json_string(c));
json_object_set_new(js, "hostname", SCJsonString(c));
SCFree(c);
}
}
@ -207,7 +207,7 @@ static void JsonHttpLogJSONBasic(json_t *js, htp_tx_t *tx)
{
c = bstr_util_strdup_to_c(tx->request_uri);
if (c != NULL) {
json_object_set_new(js, "url", json_string(c));
json_object_set_new(js, "url", SCJsonString(c));
SCFree(c);
}
}
@ -220,7 +220,7 @@ static void JsonHttpLogJSONBasic(json_t *js, htp_tx_t *tx)
if (h_user_agent != NULL) {
c = bstr_util_strdup_to_c(h_user_agent->value);
if (c != NULL) {
json_object_set_new(js, "http_user_agent", json_string(c));
json_object_set_new(js, "http_user_agent", SCJsonString(c));
SCFree(c);
}
}
@ -250,7 +250,7 @@ static void JsonHttpLogJSONBasic(json_t *js, htp_tx_t *tx)
p = strchr(c, ';');
if (p != NULL)
*p = '\0';
json_object_set_new(js, "http_content_type", json_string(c));
json_object_set_new(js, "http_content_type", SCJsonString(c));
SCFree(c);
}
}
@ -289,7 +289,7 @@ static void JsonHttpLogJSONCustom(LogHttpFileCtx *http_ctx, json_t *js, htp_tx_t
if (c != NULL) {
json_object_set_new(js,
http_fields[f].config_field,
json_string(c));
SCJsonString(c));
SCFree(c);
}
}
@ -310,7 +310,7 @@ static void JsonHttpLogJSONExtended(json_t *js, htp_tx_t *tx)
if (h_referer != NULL) {
c = bstr_util_strdup_to_c(h_referer->value);
if (c != NULL) {
json_object_set_new(js, "http_refer", json_string(c));
json_object_set_new(js, "http_refer", SCJsonString(c));
SCFree(c);
}
}
@ -319,7 +319,7 @@ static void JsonHttpLogJSONExtended(json_t *js, htp_tx_t *tx)
if (tx->request_method != NULL) {
c = bstr_util_strdup_to_c(tx->request_method);
if (c != NULL) {
json_object_set_new(js, "http_method", json_string(c));
json_object_set_new(js, "http_method", SCJsonString(c));
SCFree(c);
}
}
@ -328,7 +328,7 @@ static void JsonHttpLogJSONExtended(json_t *js, htp_tx_t *tx)
if (tx->request_protocol != NULL) {
c = bstr_util_strdup_to_c(tx->request_protocol);
if (c != NULL) {
json_object_set_new(js, "protocol", json_string(c));
json_object_set_new(js, "protocol", SCJsonString(c));
SCFree(c);
}
}
@ -346,7 +346,7 @@ static void JsonHttpLogJSONExtended(json_t *js, htp_tx_t *tx)
if (h_location != NULL) {
c = bstr_util_strdup_to_c(h_location->value);
if (c != NULL) {
json_object_set_new(js, "redirect", json_string(c));
json_object_set_new(js, "redirect", SCJsonString(c));
SCFree(c);
}
}

@ -64,17 +64,17 @@ static json_t *JsonSmtpDataLogger(const Flow *f, void *state, void *vtx, uint64_
}
if (((SMTPState *)state)->helo) {
json_object_set_new(sjs, "helo",
json_string((const char *)((SMTPState *)state)->helo));
SCJsonString((const char *)((SMTPState *)state)->helo));
}
if (tx->mail_from) {
json_object_set_new(sjs, "mail_from",
json_string((const char *)tx->mail_from));
SCJsonString((const char *)tx->mail_from));
}
if (!TAILQ_EMPTY(&tx->rcpt_to_list)) {
json_t *js_rcptto = json_array();
if (likely(js_rcptto != NULL)) {
TAILQ_FOREACH(rcptto_str, &tx->rcpt_to_list, next) {
json_array_append_new(js_rcptto, json_string((char *)rcptto_str->str));
json_array_append_new(js_rcptto, SCJsonString((char *)rcptto_str->str));
}
json_object_set_new(sjs, "rcpt_to", js_rcptto);
}

@ -72,20 +72,20 @@ void JsonSshLogJSON(json_t *tjs, SshState *ssh_state)
json_t *cjs = json_object();
if (cjs != NULL) {
json_object_set_new(cjs, "proto_version",
json_string((char *)ssh_state->cli_hdr.proto_version));
SCJsonString((char *)ssh_state->cli_hdr.proto_version));
json_object_set_new(cjs, "software_version",
json_string((char *)ssh_state->cli_hdr.software_version));
SCJsonString((char *)ssh_state->cli_hdr.software_version));
}
json_object_set_new(tjs, "client", cjs);
json_t *sjs = json_object();
if (sjs != NULL) {
json_object_set_new(sjs, "proto_version",
json_string((char *)ssh_state->srv_hdr.proto_version));
SCJsonString((char *)ssh_state->srv_hdr.proto_version));
json_object_set_new(sjs, "software_version",
json_string((char *)ssh_state->srv_hdr.software_version));
SCJsonString((char *)ssh_state->srv_hdr.software_version));
}
json_object_set_new(tjs, "server", sjs);

@ -118,7 +118,7 @@ static void JsonTlsLogSubject(json_t *js, SSLState *ssl_state)
{
if (ssl_state->server_connp.cert0_subject) {
json_object_set_new(js, "subject",
json_string(ssl_state->server_connp.cert0_subject));
SCJsonString(ssl_state->server_connp.cert0_subject));
}
}
@ -126,7 +126,7 @@ static void JsonTlsLogIssuer(json_t *js, SSLState *ssl_state)
{
if (ssl_state->server_connp.cert0_issuerdn) {
json_object_set_new(js, "issuerdn",
json_string(ssl_state->server_connp.cert0_issuerdn));
SCJsonString(ssl_state->server_connp.cert0_issuerdn));
}
}
@ -141,7 +141,7 @@ static void JsonTlsLogFingerprint(json_t *js, SSLState *ssl_state)
{
if (ssl_state->server_connp.cert0_fingerprint) {
json_object_set_new(js, "fingerprint",
json_string(ssl_state->server_connp.cert0_fingerprint));
SCJsonString(ssl_state->server_connp.cert0_fingerprint));
}
}
@ -149,7 +149,7 @@ static void JsonTlsLogSni(json_t *js, SSLState *ssl_state)
{
if (ssl_state->client_connp.sni) {
json_object_set_new(js, "sni",
json_string(ssl_state->client_connp.sni));
SCJsonString(ssl_state->client_connp.sni));
}
}
@ -157,7 +157,7 @@ static void JsonTlsLogSerial(json_t *js, SSLState *ssl_state)
{
if (ssl_state->server_connp.cert0_serial) {
json_object_set_new(js, "serial",
json_string(ssl_state->server_connp.cert0_serial));
SCJsonString(ssl_state->server_connp.cert0_serial));
}
}

@ -87,6 +87,7 @@ void OutputJsonRegister (void)
#define MODULE_NAME "OutputJSON"
#define OUTPUT_BUFFER_SIZE 65536
#define MAX_JSON_SIZE 2048
static void OutputJsonDeInitCtx(OutputCtx *);
@ -117,6 +118,31 @@ void SCJsonDecref(json_t *json)
json_decref(json);
}
json_t *SCJsonString(const char *val)
{
if (val == NULL){
return NULL;
}
json_t * retval = json_string(val);
char retbuf[MAX_JSON_SIZE] = {0};
if (retval == NULL) {
uint32_t u = 0;
uint32_t offset = 0;
for (u = 0; u < strlen(val); u++) {
if (isprint(val[u])) {
PrintBufferData(retbuf, &offset, MAX_JSON_SIZE-1, "%c",
val[u]);
} else {
PrintBufferData(retbuf, &offset, MAX_JSON_SIZE-1,
"\\x%02X", val[u]);
}
}
retbuf[offset] = '\0';
retval = json_string(retbuf);
}
return retval;
}
/* Default Sensor ID value */
static int64_t sensor_id = -1; /* -1 = not defined */

@ -72,6 +72,7 @@ typedef struct OutputJsonCtx_ {
} OutputJsonCtx;
json_t *SCJsonBool(int val);
json_t *SCJsonString(const char *val);
void SCJsonDecref(json_t *js);
#endif /* HAVE_LIBJANSSON */

@ -21,6 +21,7 @@
#include "runmodes.h"
#include "runmode-pcap-file.h"
#include "output.h"
#include "output-json.h"
#include "util-debug.h"
#include "util-time.h"
@ -163,7 +164,7 @@ static TmEcode UnixSocketPcapFilesList(json_t *cmd, json_t* answer, void *data)
return TM_ECODE_FAILED;
}
TAILQ_FOREACH(file, &this->files, next) {
json_array_append_new(jarray, json_string(file->filename));
json_array_append_new(jarray, SCJsonString(file->filename));
i++;
}
json_object_set_new(jdata, "count", json_integer(i));

Loading…
Cancel
Save