This is an automated email from the ASF dual-hosted git repository.
shinrich pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 2b31945 ja3: append to the last dub if X-JA3-Sig/X-JA3-RAW exist in
the client request headers
2b31945 is described below
commit 2b319457af8e9876cdbf2d31b29ee45fd4fa7348
Author: dyrock <[email protected]>
AuthorDate: Wed Jul 10 15:42:47 2019 -0500
ja3: append to the last dub if X-JA3-Sig/X-JA3-RAW exist in the client
request headers
---
doc/admin-guide/plugins/ja3_fingerprint.en.rst | 3 +-
.../ja3_fingerprint/ja3_fingerprint.cc | 43 +++++++++++++++-------
2 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/doc/admin-guide/plugins/ja3_fingerprint.en.rst
b/doc/admin-guide/plugins/ja3_fingerprint.en.rst
index 7387bca..351ef3b 100644
--- a/doc/admin-guide/plugins/ja3_fingerprint.en.rst
+++ b/doc/admin-guide/plugins/ja3_fingerprint.en.rst
@@ -36,7 +36,8 @@ effective way to detect malicious clients even when
superficial details are modi
JA3 is available `here <https://github.com/salesforce/ja3>`__.
The calculated JA3 fingerprints are then appended to upstream request in the
field ``X-JA3-Sig``
-(to be processed at upstream). The signatures can also be logged locally.
+(to be processed at upstream). If multiple dups exist for the field name, it
will append to the last
+occurrence; if none exists, it will add such a field to the headers. The
signatures can also be logged locally.
Plugin Configuration
====================
diff --git a/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc
b/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc
index 6feb51c..89088e8 100644
--- a/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc
+++ b/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc
@@ -61,7 +61,7 @@ static const std::unordered_set<uint16_t> GREASE_table =
{0x0a0a, 0x1a1a, 0x2a2a
struct ja3_data {
std::string ja3_string;
- char md5String[33];
+ char md5_string[33];
char ip_addr[INET6_ADDRSTRLEN];
};
@@ -265,6 +265,29 @@ custom_get_ja3(SSL *s)
#error OpenSSL cannot be 1.1.0
#endif
+// This function will append value to the last occurrence of field. If none
exists, it will
+// create a field and append to the headers
+static void
+append_to_field(TSMBuffer bufp, TSMLoc hdr_loc, const char *field, int
field_len, const char *value, int value_len)
+{
+ if (!bufp || !hdr_loc || !field || field_len <= 0)
+ return;
+
+ TSMLoc target = TSMimeHdrFieldFind(bufp, hdr_loc, field, field_len);
+ if (target == TS_NULL_MLOC) {
+ TSMimeHdrFieldCreateNamed(bufp, hdr_loc, field, field_len, &target);
+ TSMimeHdrFieldAppend(bufp, hdr_loc, target);
+ } else {
+ TSMLoc next = target;
+ while (next) {
+ target = next;
+ next = TSMimeHdrFieldNextDup(bufp, hdr_loc, target);
+ }
+ }
+ TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, target, -1, value, value_len);
+ TSHandleMLocRelease(bufp, hdr_loc, target);
+}
+
static int
client_hello_ja3_handler(TSCont contp, TSEvent event, void *edata)
{
@@ -295,9 +318,9 @@ client_hello_ja3_handler(TSCont contp, TSEvent event, void
*edata)
MD5((unsigned char *)data->ja3_string.c_str(), data->ja3_string.length(),
digest);
for (int i = 0; i < 16; i++) {
- sprintf(&(data->md5String[i * 2]), "%02x", (unsigned int)digest[i]);
+ sprintf(&(data->md5_string[i * 2]), "%02x", (unsigned int)digest[i]);
}
- TSDebug(PLUGIN_NAME, "Fingerprint: %s", data->md5String);
+ TSDebug(PLUGIN_NAME, "Fingerprint: %s", data->md5_string);
break;
}
case TS_EVENT_VCONN_CLOSE: {
@@ -347,28 +370,22 @@ req_hdr_ja3_handler(TSCont contp, TSEvent event, void
*edata)
// Get handle to headers
TSMBuffer bufp;
- TSMLoc hdr_loc, field_loc;
+ TSMLoc hdr_loc;
TSAssert(TS_SUCCESS == TSHttpTxnServerReqGet(txnp, &bufp, &hdr_loc));
// Add JA3 md5 fingerprints
- TSMimeHdrFieldCreateNamed(bufp, hdr_loc, "X-JA3-Sig", 9, &field_loc);
- TSMimeHdrFieldValueStringSet(bufp, hdr_loc, field_loc, -1,
data->md5String, 32);
- TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc);
- TSHandleMLocRelease(bufp, hdr_loc, field_loc);
+ append_to_field(bufp, hdr_loc, "X-JA3-Sig", 9, data->md5_string, 32);
// If raw string is configured, added JA3 raw string to header as well
if (raw_flag) {
- TSMimeHdrFieldCreateNamed(bufp, hdr_loc, "X-JA3-Raw", 9, &field_loc);
- TSMimeHdrFieldValueStringSet(bufp, hdr_loc, field_loc, -1,
data->ja3_string.data(), data->ja3_string.size());
- TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc);
- TSHandleMLocRelease(bufp, hdr_loc, field_loc);
+ append_to_field(bufp, hdr_loc, "x-JA3-RAW", 9, data->ja3_string.data(),
data->ja3_string.size());
}
TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
// Write to logfile
if (log_flag) {
TSTextLogObjectWrite(pluginlog, "Client IP: %s\tJA3: %.*s\tMD5: %.*s",
data->ip_addr,
- static_cast<int>(data->ja3_string.size()),
data->ja3_string.data(), 32, data->md5String);
+ static_cast<int>(data->ja3_string.size()),
data->ja3_string.data(), 32, data->md5_string);
}
} else {
TSDebug(PLUGIN_NAME, "req_hdr_ja3_handler(): ja3 data not set. Not SSL
vconn. Abort.");