core127: Ship updated wget
[ipfire-2.x.git] / src / patches / squid / 03_The_handshake_logformat_code_331.patch
CommitLineData
a2bcb413
MF
1commit 0022167d80725513d95b38aaebc90086fc0b6938 (tag: refs/tags/M-staged-PR331, refs/remotes/origin/v4)
2Author: Christos Tsantilas <christos@chtsanti.net>
3Date: 2018-11-14 15:17:06 +0000
4
5 The %>handshake logformat code (#331)
6
7 Logging client "handshake" bytes is useful in at least two contexts:
8
9 * Runtime traffic bypass and bumping/splicing decisions. Identifying
10 popular clients like Skype for Business (that uses a TLS handshake but
11 then may not speak TLS) is critical for handling their traffic
12 correctly. Squid does not have enough ACLs to interrogate most TLS
13 handshake aspects. Adding more ACLs may still be a good idea, but
14 initial sketches for SfB handshakes showed rather complex
15 ACLs/configurations, _and_ no reasonable ACLs would be able to handle
16 non-TLS handshakes. An external ACL receiving the handshake is in a
17 much better position to analyze/fingerprint it according to custom
18 admin needs.
19
20 * A logged handshake can be used to analyze new/unusual traffic or even
21 trigger security-related alarms.
22
23 The current support is limited to cases where Squid was saving handshake
24 for other reasons. With enough demand, this initial support can be
25 extended to all protocols and port configurations.
26
27 This is a Measurement Factory project.
28
29diff --git a/src/cf.data.pre b/src/cf.data.pre
30index fa8af56..a8ca587 100644
31--- a/src/cf.data.pre
32+++ b/src/cf.data.pre
33@@ -4394,6 +4394,37 @@ DOC_START
34 <qos Server connection TOS/DSCP value set by Squid
35 <nfmark Server connection netfilter mark set by Squid
36
37+ >handshake Raw client handshake
38+ Initial client bytes received by Squid on a newly
39+ accepted TCP connection or inside a just established
40+ CONNECT tunnel. Squid stops accumulating handshake
41+ bytes as soon as the handshake parser succeeds or
42+ fails (determining whether the client is using the
43+ expected protocol).
44+
45+ For HTTP clients, the handshake is the request line.
46+ For TLS clients, the handshake consists of all TLS
47+ records up to and including the TLS record that
48+ contains the last byte of the first ClientHello
49+ message. For clients using an unsupported protocol,
50+ this field contains the bytes received by Squid at the
51+ time of the handshake parsing failure.
52+
53+ See the on_unsupported_protocol directive for more
54+ information on Squid handshake traffic expectations.
55+
56+ Current support is limited to these contexts:
57+ - http_port connections, but only when the
58+ on_unsupported_protocol directive is in use.
59+ - https_port connections (and CONNECT tunnels) that
60+ are subject to the ssl_bump peek or stare action.
61+
62+ To protect binary handshake data, this field is always
63+ base64-encoded (RFC 4648 Section 4). If logformat
64+ field encoding is configured, that encoding is applied
65+ on top of base64. Otherwise, the computed base64 value
66+ is recorded as is.
67+
68 Time related format codes:
69
70 ts Seconds since epoch
71diff --git a/src/format/ByteCode.h b/src/format/ByteCode.h
72index ad230bb..a6f8fd9 100644
73--- a/src/format/ByteCode.h
74+++ b/src/format/ByteCode.h
75@@ -46,6 +46,8 @@ typedef enum {
76 LFT_CLIENT_LOCAL_TOS,
77 LFT_CLIENT_LOCAL_NFMARK,
78
79+ LFT_CLIENT_HANDSHAKE,
80+
81 /* client connection local squid.conf details */
82 LFT_LOCAL_LISTENING_IP,
83 LFT_LOCAL_LISTENING_PORT,
84diff --git a/src/format/Format.cc b/src/format/Format.cc
85index c1e19b4..8fd6720 100644
86--- a/src/format/Format.cc
87+++ b/src/format/Format.cc
88@@ -8,6 +8,7 @@
89
90 #include "squid.h"
91 #include "AccessLogEntry.h"
92+#include "base64.h"
93 #include "client_side.h"
94 #include "comm/Connection.h"
95 #include "err_detail_type.h"
96@@ -547,6 +548,24 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS
97 }
98 break;
99
100+ case LFT_CLIENT_HANDSHAKE:
101+ if (al->request && al->request->clientConnectionManager.valid()) {
102+ const auto &handshake = al->request->clientConnectionManager->preservedClientData;
103+ if (const auto rawLength = handshake.length()) {
104+ // add 1 byte to optimize the c_str() conversion below
105+ char *buf = sb.rawAppendStart(base64_encode_len(rawLength) + 1);
106+
107+ struct base64_encode_ctx ctx;
108+ base64_encode_init(&ctx);
109+ auto encLength = base64_encode_update(&ctx, buf, rawLength, reinterpret_cast<const uint8_t*>(handshake.rawContent()));
110+ encLength += base64_encode_final(&ctx, buf + encLength);
111+
112+ sb.rawAppendFinish(buf, encLength);
113+ out = sb.c_str();
114+ }
115+ }
116+ break;
117+
118 case LFT_TIME_SECONDS_SINCE_EPOCH:
119 // some platforms store time in 32-bit, some 64-bit...
120 outoff = static_cast<int64_t>(current_time.tv_sec);
121diff --git a/src/format/Token.cc b/src/format/Token.cc
122index 186ade5..06c60cf 100644
123--- a/src/format/Token.cc
124+++ b/src/format/Token.cc
125@@ -141,6 +141,7 @@ static TokenTableEntry TokenTableMisc[] = {
126 TokenTableEntry("<qos", LFT_SERVER_LOCAL_TOS),
127 TokenTableEntry(">nfmark", LFT_CLIENT_LOCAL_NFMARK),
128 TokenTableEntry("<nfmark", LFT_SERVER_LOCAL_NFMARK),
129+ TokenTableEntry(">handshake", LFT_CLIENT_HANDSHAKE),
130 TokenTableEntry("err_code", LFT_SQUID_ERROR ),
131 TokenTableEntry("err_detail", LFT_SQUID_ERROR_DETAIL ),
132 TokenTableEntry("note", LFT_NOTE ),