From 3ea67a31096d57f23d31e25f6f8bb3d2fac439fb Mon Sep 17 00:00:00 2001 From: Theo Buehler Date: Fri, 12 Jul 2024 14:45:05 +0200 Subject: [PATCH 01/93] Use accessor to reach into X509_ALGOR Despite already having an accessor, X509_ALGOR wasn't made opaque during OpenSSL 1.1.0 development. It would be nice if this could be fixed at some point, so avoid reaching into that struct by using the accessor --- src/file_analysis/analyzer/x509/X509.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/file_analysis/analyzer/x509/X509.cc b/src/file_analysis/analyzer/x509/X509.cc index c32a00f2ba..aefdf2738c 100644 --- a/src/file_analysis/analyzer/x509/X509.cc +++ b/src/file_analysis/analyzer/x509/X509.cc @@ -161,8 +161,9 @@ RecordValPtr X509::ParseCertificate(X509Val* cert_val, file_analysis::File* f) { #if ( OPENSSL_VERSION_NUMBER < 0x10100000L ) i2a_ASN1_OBJECT(bio, ssl_cert->sig_alg->algorithm); #else - const X509_ALGOR* sigalg = X509_get0_tbs_sigalg(ssl_cert); - i2a_ASN1_OBJECT(bio, sigalg->algorithm); + const ASN1_OBJECT* alg; + X509_ALGOR_get0(&alg, NULL, NULL, X509_get0_tbs_sigalg(ssl_cert)); + i2a_ASN1_OBJECT(bio, alg); #endif len = BIO_gets(bio, buf, sizeof(buf)); pX509Cert->Assign(13, make_intrusive(len, buf)); From 09a48c7028b6239af9b3740783a1054fd695aaea Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Wed, 17 Jul 2024 17:00:53 +0200 Subject: [PATCH 02/93] ldap: Implement extended request/response and StartTLS support PCAP was produced with a local OpenLDAP server configured to support StartTLS. This puts the Zeek calls into a separate ldap_zeek.spicy file/module to separate it from LDAP. --- NEWS | 4 + scripts/base/protocols/ldap/consts.zeek | 7 ++ scripts/base/protocols/ldap/main.zeek | 3 + scripts/base/protocols/ldap/spicy-events.zeek | 41 ++++++++ src/analyzer/protocol/ldap/CMakeLists.txt | 4 +- src/analyzer/protocol/ldap/ldap.evt | 15 +++ src/analyzer/protocol/ldap/ldap.spicy | 96 ++++++++++++++---- src/analyzer/protocol/ldap/ldap_zeek.spicy | 12 +++ .../conn.log | 11 ++ .../ldap.log | 11 ++ .../scripts.base.protocols.ldap.starttls/out | 4 + .../ssl.log | 11 ++ .../conn.log | 11 ++ .../ldap.log | 13 +++ .../scripts.base.protocols.ldap.who-am-i/out | 3 + testing/btest/Traces/ldap/ldap-starttls.pcap | Bin 0 -> 6009 bytes testing/btest/Traces/ldap/ldap-who-am-i.pcap | Bin 0 -> 1248 bytes .../scripts/base/protocols/ldap/starttls.zeek | 25 +++++ .../scripts/base/protocols/ldap/who-am-i.zeek | 20 ++++ 19 files changed, 269 insertions(+), 22 deletions(-) create mode 100644 src/analyzer/protocol/ldap/ldap_zeek.spicy create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.starttls/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.starttls/out create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ssl.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/out create mode 100644 testing/btest/Traces/ldap/ldap-starttls.pcap create mode 100644 testing/btest/Traces/ldap/ldap-who-am-i.pcap create mode 100644 testing/btest/scripts/base/protocols/ldap/starttls.zeek create mode 100644 testing/btest/scripts/base/protocols/ldap/who-am-i.zeek diff --git a/NEWS b/NEWS index 02e9a035e4..c0bcac3a48 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,10 @@ New Functionality * The LDAP analyzer now supports handling of non-sealed GSS-API WRAP tokens. +* StartTLS support was added to the LDAP analyzer. The SSL analyzer is enabled + for connections where client and server negotiate to TLS through the extended + request/response mechanism. + Changed Functionality --------------------- diff --git a/scripts/base/protocols/ldap/consts.zeek b/scripts/base/protocols/ldap/consts.zeek index bbd378c7e8..5b29fd22e4 100644 --- a/scripts/base/protocols/ldap/consts.zeek +++ b/scripts/base/protocols/ldap/consts.zeek @@ -120,4 +120,11 @@ export { "searching", [ LDAP::SearchDerefAlias_DEREF_FINDING_BASE ] = "finding", [ LDAP::SearchDerefAlias_DEREF_ALWAYS ] = "always", } &default="unknown"; + + const EXTENDED_REQUESTS = { + # StartTLS, https://datatracker.ietf.org/doc/html/rfc4511#section-4.14.1 + [ "1.3.6.1.4.1.1466.20037" ] = "StartTLS", + # whoami, https://datatracker.ietf.org/doc/html/rfc4532#section-2 + [ "1.3.6.1.4.1.4203.1.11.3" ] = "whoami", + } &default="unknown" &redef; } diff --git a/scripts/base/protocols/ldap/main.zeek b/scripts/base/protocols/ldap/main.zeek index 93c301a65a..da4a21871c 100644 --- a/scripts/base/protocols/ldap/main.zeek +++ b/scripts/base/protocols/ldap/main.zeek @@ -258,6 +258,9 @@ event LDAP::message(c: connection, } m$object = object; + + if ( opcode == LDAP::ProtocolOpcode_EXTENDED_REQUEST ) + m$object += fmt(" (%s)", EXTENDED_REQUESTS[object]); } if ( argument != "" ) { diff --git a/scripts/base/protocols/ldap/spicy-events.zeek b/scripts/base/protocols/ldap/spicy-events.zeek index fa670f3456..baa00ba548 100644 --- a/scripts/base/protocols/ldap/spicy-events.zeek +++ b/scripts/base/protocols/ldap/spicy-events.zeek @@ -98,3 +98,44 @@ global LDAP::search_result_entry: event ( message_id: int, object_name: string ); + +## Event generated for each ExtendedRequest in LDAP messages. +## +## c: The connection. +## +## message_id: The messageID element. +## +## request_name: The name of the extended request. +## +## request_value: The value of the extended request (empty if missing). +global LDAP::extended_request: event ( + c: connection, + message_id: int, + request_name: string, + request_value: string +); + +## Event generated for each ExtendedResponse in LDAP messages. +## +## c: The connection. +## +## message_id: The messageID element. +## +## result: The result code of the response. +## +## response_name: The name of the extended response (empty if missing). +## +## response_value: The value of the extended response (empty if missing). +global LDAP::extended_response: event ( + c: connection, + message_id: int, + result: LDAP::ResultCode, + response_name: string, + response_value: string +); + +## Event generated when a plaintext LDAP connection switched to TLS. +## +## c: The connection. +## +global LDAP::starttls: event(c: connection); diff --git a/src/analyzer/protocol/ldap/CMakeLists.txt b/src/analyzer/protocol/ldap/CMakeLists.txt index a687e880ff..3f69e6543d 100644 --- a/src/analyzer/protocol/ldap/CMakeLists.txt +++ b/src/analyzer/protocol/ldap/CMakeLists.txt @@ -1,5 +1,5 @@ spicy_add_analyzer( NAME LDAP PACKAGE_NAME spicy-ldap - SOURCES ldap.spicy ldap.evt asn1.spicy - MODULES LDAP ASN1) + SOURCES ldap.spicy ldap.evt asn1.spicy ldap_zeek.spicy + MODULES LDAP ASN1 LDAP_Zeek) diff --git a/src/analyzer/protocol/ldap/ldap.evt b/src/analyzer/protocol/ldap/ldap.evt index 96baef6f98..77f34fb62e 100644 --- a/src/analyzer/protocol/ldap/ldap.evt +++ b/src/analyzer/protocol/ldap/ldap.evt @@ -41,3 +41,18 @@ on LDAP::SearchRequest -> event LDAP::search_request($conn, on LDAP::SearchResultEntry -> event LDAP::search_result_entry($conn, message.messageID, self.objectName); + +on LDAP::ExtendedRequest -> event LDAP::extended_request($conn, + message.messageID, + self.requestName, + self.requestValue); + +on LDAP::ExtendedResponse -> event LDAP::extended_response($conn, + message.messageID, + message.result_.code, + self.responseName, + self.responseValue); + +# Once switched into MessageMode::TLS, we won't parse messages anymore, +# so this is raised just once. +on LDAP::Message if (ctx.messageMode == LDAP::MessageMode::TLS) -> event LDAP::starttls($conn); diff --git a/src/analyzer/protocol/ldap/ldap.spicy b/src/analyzer/protocol/ldap/ldap.spicy index 2d4f821d78..75bbb23783 100644 --- a/src/analyzer/protocol/ldap/ldap.spicy +++ b/src/analyzer/protocol/ldap/ldap.spicy @@ -130,29 +130,38 @@ public type Result = unit { const GSSAPI_MECH_MS_KRB5 = "1.2.840.48018.1.2.2"; # Supported SASL stripping modes. -type SaslStripping = enum { - MS_KRB5 = 1, # Payload starts with a 4 byte length followed by a wrap token that may or may not be sealed. +type MessageMode = enum { + MS_KRB5 = 1, # Payload starts with a 4 byte length followed by a wrap token that may or may not be sealed. + TLS = 2, # Client/server used StartTLS, forward to SSL analyzer. }; type Ctx = struct { - saslStripping: SaslStripping; # Which mode of SASL stripping to use. + messageMode: MessageMode; # Message dispatching mode + startTlsRequested: bool; # Did the client use the StartTLS extended request? }; #----------------------------------------------------------------------------- public type Messages = unit { %context = Ctx; - : SASLStrip(self.context())[]; + : MessageDispatch(self.context())[]; }; #----------------------------------------------------------------------------- -public type SASLStrip = unit(ctx: Ctx&) { - switch( ctx.saslStripping ) { - SaslStripping::Undef -> : Message(ctx); - SaslStripping::MS_KRB5 -> : SaslMsKrb5Stripper(ctx); +public type MessageDispatch = unit(ctx: Ctx&) { + switch( ctx.messageMode ) { + MessageMode::Undef -> : Message(ctx); + MessageMode::MS_KRB5 -> : SaslMsKrb5Stripper(ctx); + MessageMode::TLS -> : TlsForward; }; }; +#----------------------------------------------------------------------------- +type TlsForward = unit { + # Just consume everything. This is hooked in ldap_zeek.spicy + chunk: bytes &chunked &eod; +}; + type KrbWrapToken = unit { # https://datatracker.ietf.org/doc/html/rfc4121#section-4.2.6.2 @@ -223,6 +232,7 @@ public type Message = unit(ctx: Ctx&) { var arg: string = ""; var seqHeaderLen: uint64; var msgLen: uint64; + var opLen: uint64; seqHeader: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Universal && $$.tag.type_ == ASN1::ASN1Type::Sequence) { self.msgLen = $$.len.len; @@ -241,6 +251,7 @@ public type Message = unit(ctx: Ctx&) { protocolOp: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Application) { self.opcode = cast(cast($$.tag.type_)); + self.opLen = $$.len.len; } switch ( self.opcode ) { @@ -263,12 +274,12 @@ public type Message = unit(ctx: Ctx&) { # just commenting this out, it will stop processing LDAP Messages in this connection ProtocolOpcode::ADD_REQUEST -> ADD_REQUEST: NotImplemented(self); ProtocolOpcode::COMPARE_REQUEST -> COMPARE_REQUEST: NotImplemented(self); - ProtocolOpcode::EXTENDED_REQUEST -> EXTENDED_REQUEST: NotImplemented(self); - ProtocolOpcode::EXTENDED_RESPONSE -> EXTENDED_RESPONSE: NotImplemented(self); + ProtocolOpcode::EXTENDED_REQUEST -> EXTENDED_REQUEST: ExtendedRequest(self, ctx); + ProtocolOpcode::EXTENDED_RESPONSE -> EXTENDED_RESPONSE: ExtendedResponse(self, ctx); ProtocolOpcode::INTERMEDIATE_RESPONSE -> INTERMEDIATE_RESPONSE: NotImplemented(self); ProtocolOpcode::MOD_DN_REQUEST -> MOD_DN_REQUEST: NotImplemented(self); ProtocolOpcode::SEARCH_RESULT_REFERENCE -> SEARCH_RESULT_REFERENCE: NotImplemented(self); - } &size=self.protocolOp.len.len; + } &size=self.opLen; # Ensure some invariants hold after parsing the command. : void &requires=(self.offset() >= self.seqHeaderLen); @@ -427,7 +438,7 @@ type BindResponse = unit(inout message: Message, ctx: Ctx&) { local token = self.serverSaslCreds[0].negTokenResp; if ( token.accepted && token?.supportedMechOid ) { if ( token.supportedMechOid == GSSAPI_MECH_MS_KRB5 ) { - ctx.saslStripping = SaslStripping::MS_KRB5; + ctx.messageMode = MessageMode::MS_KRB5; } } } @@ -980,16 +991,61 @@ type AbandonRequest = unit(inout message: Message) { #----------------------------------------------------------------------------- # Extended Operation # https://tools.ietf.org/html/rfc4511#section-4.12 +type ExtendedRequest = unit(inout message: Message, ctx: Ctx&) { + var requestValue: bytes; + header: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific); + requestName: bytes &size=self.header.len.len &convert=$$.decode(spicy::Charset::ASCII) { + message.obj = $$; + } -# TODO: implement ExtendedRequest -# type ExtendedRequest = unit(inout message: Message) { -# -# }; + # If there's more byte to parse, it's the requestValue. + : ASN1::ASN1Message(False) + &requires=($$.head.tag.class == ASN1::ASN1Class::ContextSpecific) + if ( message.opLen > self.offset() ) { -# TODO: implement ExtendedResponse -# type ExtendedResponse = unit(inout message: Message) { -# -# }; + self.requestValue = $$.application_data; + } + + on %done { + # Did the client request StartTLS? + # + # https://datatracker.ietf.org/doc/html/rfc4511#section-4.14.1 + if ( self.requestName == "1.3.6.1.4.1.1466.20037" ) + ctx.startTlsRequested = True; + } +}; + +#----------------------------------------------------------------------------- +type ExtendedResponseEntry = unit(inout r: ExtendedResponse) { + : ASN1::ASN1Message(False) &requires=($$.head.tag.class == ASN1::ASN1Class::ContextSpecific) { + if ( $$.head.tag.type_ == ASN1::ASN1Type(10) ) + r.responseName = $$.application_data; + else if ( $$.head.tag.type_ == ASN1::ASN1Type(11) ) + r.responseValue = $$.application_data; + else + throw "Unhandled extended response tag %s" % $$.head.tag; + } +}; + +#----------------------------------------------------------------------------- +type ExtendedResponse = unit(inout message: Message, ctx: Ctx&) { + var responseName: bytes; + var responseValue: bytes; + : Result { + message.result_ = $$; + } + + # Try to parse two ASN1 entries if there are bytes left in the unit. + # Both are optional and identified by context specific tagging. + : ExtendedResponseEntry(self) if ( message.opLen > self.offset() ); + : ExtendedResponseEntry(self) if ( message.opLen > self.offset() ); + + on %done { + # Client had requested StartTLS and it was successful? Switch to SSL. + if ( ctx.startTlsRequested && message.result_.code == ResultCode::SUCCESS ) + ctx.messageMode = MessageMode::TLS; + } +}; #----------------------------------------------------------------------------- # IntermediateResponse Message diff --git a/src/analyzer/protocol/ldap/ldap_zeek.spicy b/src/analyzer/protocol/ldap/ldap_zeek.spicy new file mode 100644 index 0000000000..3a6784589f --- /dev/null +++ b/src/analyzer/protocol/ldap/ldap_zeek.spicy @@ -0,0 +1,12 @@ +module LDAP_Zeek; + +import LDAP; +import zeek; + +on LDAP::TlsForward::%init { + zeek::protocol_begin("SSL"); +} + +on LDAP::TlsForward::chunk { + zeek::protocol_data_in(zeek::is_orig(), self.chunk); +} diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/conn.log new file mode 100644 index 0000000000..db789c02c1 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/conn.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 45936 127.0.1.1 389 tcp ldap_tcp,ssl 0.016922 683 3002 RSTO 0 ShADadFR 14 1407 14 3738 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ldap.log new file mode 100644 index 0000000000..95a084dab8 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ldap.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 45936 127.0.1.1 389 1 - extended success - 1.3.6.1.4.1.1466.20037 (StartTLS) - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/out b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/out new file mode 100644 index 0000000000..08e6ccc9f2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/out @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +CHhAvVGS1DHFjwGM9, extended_request, 1.3.6.1.4.1.1466.20037 (StartTLS), +CHhAvVGS1DHFjwGM9, extended_response, LDAP::ResultCode_SUCCESS, , +CHhAvVGS1DHFjwGM9, LDAP::starttls diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ssl.log new file mode 100644 index 0000000000..19fdd43528 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ssl.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert +#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 45936 127.0.1.1 389 TLSv13 TLS_AES_256_GCM_SHA384 secp256r1 ubuntu-01.example.com F - - T CsiI - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/conn.log new file mode 100644 index 0000000000..9914fbe2dc --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/conn.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 48122 127.0.1.1 389 tcp ldap_tcp 0.001192 83 59 SF 0 ShADadFf 8 507 5 327 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/ldap.log new file mode 100644 index 0000000000..80da834eba --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/ldap.log @@ -0,0 +1,13 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 48122 127.0.1.1 389 1 3 bind simple success - cn=admin,dc=example,dc=com REDACTED +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 48122 127.0.1.1 389 2 - extended success - 1.3.6.1.4.1.4203.1.11.3 (whoami) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 48122 127.0.1.1 389 3 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/out b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/out new file mode 100644 index 0000000000..c4dbc10489 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/out @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +CHhAvVGS1DHFjwGM9, extended_request, 1.3.6.1.4.1.4203.1.11.3 (whoami), +CHhAvVGS1DHFjwGM9, extended_response, LDAP::ResultCode_SUCCESS, , dn:cn=admin,dc=example,dc=com diff --git a/testing/btest/Traces/ldap/ldap-starttls.pcap b/testing/btest/Traces/ldap/ldap-starttls.pcap new file mode 100644 index 0000000000000000000000000000000000000000..0cb6035125efd4ca7094ea308e0aec2ef1f37e9f GIT binary patch literal 6009 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 DyIjjT literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/ldap/ldap-who-am-i.pcap b/testing/btest/Traces/ldap/ldap-who-am-i.pcap new file mode 100644 index 0000000000000000000000000000000000000000..75dae01d4e5c84bb150be922d14eef212fba067d GIT binary patch literal 1248 zcmaKr&ui0g7{=dknyq8(U?<`nY)nBBf0V>^Q`;3r!Gn64;8kqaBsjF~ytpzZi?FKL zZHF-sFEWcDDhL)~wmS&w#i0j_?hhEd<=jKpLw(|TbR@e z&Qq^F-cxU-M8uD;0VZ$|YG?60iQ*&^ueBxiLH&JwpSVo9D?K=m7VH*yhGaf9KalUU zf%BZ#6Hi_%xPcwsz`gyvHqrGmIgY*om_)18&SJ;c?F&qtYD>foENr`p%Ah2qnIqO= zH9Q<14Xfb@^*Lo2FDgDG#WE^pQHt7Gtf&=JoRR9uXa`d-S(wqSxGSSg(TrMZ~YZL_5YFA9_4i&|@#3 IpCPx$KS)1C6#xJL literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ldap/starttls.zeek b/testing/btest/scripts/base/protocols/ldap/starttls.zeek new file mode 100644 index 0000000000..df94315210 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/starttls.zeek @@ -0,0 +1,25 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/ldap-starttls.pcap %INPUT >out +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: btest-diff ssl.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: LDAP supports StartTLS through extendedRequest 1.3.6.1.4.1.1466.20037 + +event LDAP::extended_request(c: connection, message_id: int, request_name: string, request_value: string) { + print c$uid, "extended_request", fmt("%s (%s)", request_name, LDAP::EXTENDED_REQUESTS[request_name]), request_value; +} + +event LDAP::extended_response(c: connection, message_id: int, result: LDAP::ResultCode, response_name: string, response_value: string) { + print c$uid, "extended_response", result, response_name, response_value; +} + +event LDAP::starttls(c: connection) { + print c$uid, "LDAP::starttls"; +} diff --git a/testing/btest/scripts/base/protocols/ldap/who-am-i.zeek b/testing/btest/scripts/base/protocols/ldap/who-am-i.zeek new file mode 100644 index 0000000000..6026add5cc --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/who-am-i.zeek @@ -0,0 +1,20 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/ldap-who-am-i.pcap %INPUT >out +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: Testing OpenLDAP's ldapwhoami utility with simple authentication. + +event LDAP::extended_request(c: connection, message_id: int, request_name: string, request_value: string) { + print c$uid, "extended_request", fmt("%s (%s)", request_name, LDAP::EXTENDED_REQUESTS[request_name]), request_value; +} + +event LDAP::extended_response(c: connection, message_id: int, result: LDAP::ResultCode, response_name: string, response_value: string) { + print c$uid, "extended_response", result, response_name, response_value; +} From 724c08f2862dfe9ad5497e9808a821b4f3b9e97d Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 18 Jul 2024 15:45:31 +0200 Subject: [PATCH 03/93] ldap: Fix assuming GSS-SPNEGO for all bindResponses In retrospect that's an obvious bug. --- src/analyzer/protocol/ldap/ldap.spicy | 65 +++++++++--------- .../conn.log | 11 +++ .../ldap.log | 13 ++++ .../ldap_search.log | 11 +++ .../conn.log | 11 +++ .../ldap.log | 13 ++++ .../ldap_search.log | 11 +++ testing/btest/Traces/ldap/sasl-ntlm.pcap | Bin 0 -> 4052 bytes .../btest/Traces/ldap/sasl-scram-sha-512.pcap | Bin 0 -> 4297 bytes .../base/protocols/ldap/sasl-ntlm.zeek | 12 ++++ .../protocols/ldap/sasl-scram-sha-512.zeek | 12 ++++ 11 files changed, 125 insertions(+), 34 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap_search.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap_search.log create mode 100644 testing/btest/Traces/ldap/sasl-ntlm.pcap create mode 100644 testing/btest/Traces/ldap/sasl-scram-sha-512.pcap create mode 100644 testing/btest/scripts/base/protocols/ldap/sasl-ntlm.zeek create mode 100644 testing/btest/scripts/base/protocols/ldap/sasl-scram-sha-512.zeek diff --git a/src/analyzer/protocol/ldap/ldap.spicy b/src/analyzer/protocol/ldap/ldap.spicy index 75bbb23783..c8102c49c9 100644 --- a/src/analyzer/protocol/ldap/ldap.spicy +++ b/src/analyzer/protocol/ldap/ldap.spicy @@ -137,6 +137,7 @@ type MessageMode = enum { type Ctx = struct { messageMode: MessageMode; # Message dispatching mode + saslMechanism: string; # The SASL mechanism selected by the client. startTlsRequested: bool; # Did the client use the StartTLS extended request? }; @@ -255,7 +256,7 @@ public type Message = unit(ctx: Ctx&) { } switch ( self.opcode ) { - ProtocolOpcode::BIND_REQUEST -> BIND_REQUEST: BindRequest(self); + ProtocolOpcode::BIND_REQUEST -> BIND_REQUEST: BindRequest(self, ctx); ProtocolOpcode::BIND_RESPONSE -> BIND_RESPONSE: BindResponse(self, ctx); ProtocolOpcode::UNBIND_REQUEST -> UNBIND_REQUEST: UnbindRequest(self); ProtocolOpcode::SEARCH_REQUEST -> SEARCH_REQUEST: SearchRequest(self); @@ -307,7 +308,7 @@ type GSS_SPNEGO_negTokenInit = unit { }; # Peak into GSS-SPNEGO payload and ensure it is indeed GSS-SPNEGO. -type GSS_SPNEGO = unit { +type GSS_SPNEGO_Init = unit { # This is the optional octet string in SaslCredentials. credentialsHeader: ASN1::ASN1Header &requires=($$.tag.type_ == ASN1::ASN1Type::OctetString); @@ -333,12 +334,19 @@ type SaslCredentials = unit() { # Peak into GSS-SPNEGO payload if we have any. switch ( self.mechanism ) { - "GSS-SPNEGO" -> gss_spnego: GSS_SPNEGO; + "GSS-SPNEGO" -> gss_spnego: GSS_SPNEGO_Init; * -> : skip bytes &eod; }; }; -type NegTokenResp = unit { +type GSS_SPNEGO_Subsequent = unit { + token: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific); + switch ( self.token.tag.type_ ) { + ASN1::ASN1Type(1) -> negTokenResp: GSS_SPNEGO_negTokenResp; + }; +}; + +type GSS_SPNEGO_negTokenResp = unit { var accepted: bool; var supportedMech: ASN1::ASN1Message; @@ -366,34 +374,13 @@ type NegTokenResp = unit { } &parse-from=self.supportedMech.application_data; }; -type ServerSaslCreds = unit { - serverSaslCreds: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific && $$.tag.type_ == ASN1::ASN1Type(7)); - - # The PCAP missing_ldap_logs.pcapng has a1 81 b6 here for the GSS-SPNEGO response. - # - # This is context-specific ID 1, constructed, and a length of 182 as - # specified by in 4.2 of RFC4178. - # - # https://www.rfc-editor.org/rfc/rfc4178#section-4.2 - # - # TODO: This is only valid for a GSS-SPNEGO negTokenResp. - # If you want to support something else, remove the requires - # and add more to the switch below. - choice: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific); - - switch ( self.choice.tag.type_ ) { - ASN1::ASN1Type(1) -> negTokenResp: NegTokenResp; - # ... - } &size=self.choice.len.len; -}; - # TODO(fox-ds): A helper unit for requests for which no handling has been implemented. # Eventually all uses of this unit should be replaced with actual parsers so this unit can be removed. type NotImplemented = unit(inout message: Message) { : skip bytes &eod; }; -type BindRequest = unit(inout message: Message) { +type BindRequest = unit(inout message: Message, ctx: Ctx&) { version: ASN1::ASN1Message(True) &convert=$$.body.num_value; name: ASN1::ASN1Message(True) &convert=$$.body.str_value { message.obj = self.name; @@ -417,9 +404,15 @@ type BindRequest = unit(inout message: Message) { saslCreds: SaslCredentials() &parse-from=self.authData if ((self.authType == BindAuthType::BIND_AUTH_SASL) && (|self.authData| > 0)) { message.arg = self.saslCreds.mechanism; + ctx.saslMechanism = self.saslCreds.mechanism; } } &requires=(self?.authType && (self.authType != BindAuthType::Undef)); +type ServerSaslCreds = unit { + serverSaslCreds: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific && $$.tag.type_ == ASN1::ASN1Type(7)); + payload: bytes &size=self.serverSaslCreds.len.len; +}; + type BindResponse = unit(inout message: Message, ctx: Ctx&) { : Result { message.result_ = $$; @@ -432,14 +425,18 @@ type BindResponse = unit(inout message: Message, ctx: Ctx&) { # if the serverSaslCreds field exists or not. But, not sure we can # check if there's any bytes left at this point outside of passing # in the length and playing with offset(). - serverSaslCreds: ServerSaslCreds[] &eod { - if ( |self.serverSaslCreds| > 0 ) { - if ( self.serverSaslCreds[0]?.negTokenResp ) { - local token = self.serverSaslCreds[0].negTokenResp; - if ( token.accepted && token?.supportedMechOid ) { - if ( token.supportedMechOid == GSSAPI_MECH_MS_KRB5 ) { - ctx.messageMode = MessageMode::MS_KRB5; - } + serverSaslCreds: ServerSaslCreds[] &eod; + + # If the client requested GSS-SPNEGO, try to parse the server's response + # to switch message mode. + gss_spnego: GSS_SPNEGO_Subsequent &parse-from=self.serverSaslCreds[0].payload + if (ctx.saslMechanism == "GSS-SPNEGO" && |self.serverSaslCreds| > 0) { + + if ( $$?.negTokenResp ) { + local token = $$.negTokenResp; + if ( token.accepted && token?.supportedMechOid ) { + if ( token.supportedMechOid == GSSAPI_MECH_MS_KRB5 ) { + ctx.messageMode = MessageMode::MS_KRB5; } } } diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/conn.log new file mode 100644 index 0000000000..27c56bc33b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/conn.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60126 127.0.1.1 389 tcp ldap_tcp 2.290081 289 1509 SF 0 ShADadFf 12 921 15 2297 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap.log new file mode 100644 index 0000000000..cd94c49d5b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap.log @@ -0,0 +1,13 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60126 127.0.1.1 389 1 3 bind SASL SASL bind in progress SASL(0): successful result: - NTLM +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60126 127.0.1.1 389 2 3 bind SASL success - - NTLM +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60126 127.0.1.1 389 4 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap_search.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap_search.log new file mode 100644 index 0000000000..3ff2f3b1a6 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap_search.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap_search +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id scope deref_aliases base_object result_count result diagnostic_message filter attributes +#types time string addr port addr port int string string string count string string string vector[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60126 127.0.1.1 389 3 tree never dc=example,dc=com 9 success - (objectclass=*) - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/conn.log new file mode 100644 index 0000000000..5fcce64ab8 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/conn.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59552 127.0.1.1 389 tcp ldap_tcp 2.231680 353 1772 SF 0 ShADadFf 11 933 15 2560 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap.log new file mode 100644 index 0000000000..7c3478b262 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap.log @@ -0,0 +1,13 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59552 127.0.1.1 389 1 3 bind SASL SASL bind in progress SASL(0): successful result: user: sasladmin@slapd.ldap property: slapAuthzDN not found in sasldb - SCRAM-SHA-512 +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59552 127.0.1.1 389 2 3 bind SASL success - - SCRAM-SHA-512 +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59552 127.0.1.1 389 4 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap_search.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap_search.log new file mode 100644 index 0000000000..edcf38ced5 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap_search.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap_search +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id scope deref_aliases base_object result_count result diagnostic_message filter attributes +#types time string addr port addr port int string string string count string string string vector[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59552 127.0.1.1 389 3 tree never dc=example,dc=com 9 success - (objectclass=*) - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/ldap/sasl-ntlm.pcap b/testing/btest/Traces/ldap/sasl-ntlm.pcap new file mode 100644 index 0000000000000000000000000000000000000000..ef2fb91ab4e18be7df4fbe120116ef99178c1ce9 GIT binary patch literal 4052 zcmb7{e`phD7{}kczD;YJ^p{oZkJ_kotJB#_twXJ4ZJk&({ef+DbDMg(T+^$`UCbro zWKL6bGOC+Y9Tf$Cfj`Ek(+Q3t_=o;6VGIP(unifLfH>G6f-rTPd!F}_cz2Bf-}KFU zx#Yg@=lMR*``-2T^-CvsLP@$ke@+MoA1+lK?w_XeWF;J9H@8BvjF2UX!4}fukh*rj z1v?1GJ-o;5K0M5wz+WEcw{I;!PY6%*FH^p-=+1-p*W-CEFRuWV>vJj-g33)lpem|! zyC2?rTsyKD)K4C-_&EH}w=a~Pn}=qidRn;!l-pn??B>Rp8xxxt^BNoTNl|LL^*onH$*DR@JA1ty z)Q#^wJ>AUt0^XR#otg|sc<)*ql|diaa@Y%c>{@Au=&g#FbD&r}eb->KZ$LH|9@FidY=(nXe%R^lb?aMVM3nIp@9|K*M( zLM$`Aw#+0T*XLNSy_U?(x(trg{^%fo!MxbbjXCmrLPbU2nXHPC>uW30ivCsTvk*VW zbNt5mDI?qQBdK)9N7C`2`7_p5Q0~_Vev4$5=kP|`w091n5u?2qHfo?^{6C`(Z(DC)YvVyn63AYTCjc5`DSN0U{| zyH=ZbSHQcg=$-3W#=COx&MWi-iC@e@B6x+lG&TKFoZeGS^P*aq7W$N-6J`JmY9VDm?VC6UbpHvp$CWdU7%&2M^7A@qwB&`5z57 z^7vjvkAF(1YO&^SSxcE{^-~B4b=D{*8&Oo4*~MU=szikn%4;!CA$1sP!W>%cmvt$k zgfT$RG&*Ierbb0Yl_TzcE#i*pa3HJEh$8D4pbrB41nz0r%?(q-g_Bb-z`jkk0MDlb zl;_w29O4#YghQN%z8+Kj&0xB!%j(=*;SO($7jOM|Nn7`Dd!bCbQplp%VPBA3o`8F})6C)yermN`LN(Lv4r@W+kT(r1N^y%)@ z$yu~CDhK88fTqfwv5-%Wc*En0yz97NZMC-O6>81JYOR3gGcn}d0=y>y6uY@G-h;_$jCYxp_fUJ9_rIq$-u1}) z9$OsCBU&t+4S4Y@0B075p@ziUf%r6_VmCKNJesU##4R@BvuWbx4{gLgB>s?AgTo!7 zGyoNujd{r{Fqbiti)dk552<$n^%20uZf=ZvUvfI5UTLNN(wV0I6do^eD~B6{v4O5d z>eZ|+R`^3=I7?kL3bU+BvXW-oeljJ&bP)9mK)nl$*v*Zh-b~goRF@4^PNQD9Z$pib zAZvUtt(DZ~fD9XfjGM_z%R>^TTDhIHD6HwqR(1t0eOT(S^bIMY61NC{YJEdxdvKi! z)2*9mDRr@{-J&FEF*S-|9)d7)+^#ocm{Pax=6dyU?V+=9yZ(Fsej`k{opoSVQ1J{X zu7h0|ySbrpoHyx4#lFvM#yw3Nr{PpDa@-*dah2%Y5a*(`xD&td?qyp+{J!v-)w@Zw zAQduoG80=31IE}`YV5rhUtv#i&U!pkpGwkXS`^d* zirO-O3pO$nVTE+1QM zqi%eFT6-;{*ooC94W?L>F}D&HM<*(ZITaHz#^|*%-T=lK%+A6LV>bj}`9DG^6M6su literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/ldap/sasl-scram-sha-512.pcap b/testing/btest/Traces/ldap/sasl-scram-sha-512.pcap new file mode 100644 index 0000000000000000000000000000000000000000..70fd3d6b0d3659dec9bf9e97aa1d87ecce5a5af5 GIT binary patch literal 4297 zcmb7{4@?{P702()kMPI*OQBu*C!4i2BOL_JV8BUZ2?ORo1TX}LZB@?a!#--?S$Ajt zc-{D;wMbdIbXis9KXk34sp_ODTDP{_5@=Fsnc8Sm6Q)L6D=nKAG)3K{NmG|i-FrXV z^zP!)<%uWY;J){H-}iox0#!%F0iSANLe9-S9Q0G4dH7!|Y2Q zZf2Udtk%xL4YLf(-dbj#E-nAyQT)wi+qb6o|BYd6B=@JpmS4EG{_YT7XLEA$Q28gD zDl-f!KmI1FqB{HZt!1_H_^HLuv_O}js`*!;~y}KKnb!4AhT`hYwUW@Xfm?SsD=Xj_l8sg*Cs%Lbf zSDk548V<;^-d;a?V5Ca#AN0%Ja;G{t=57-aw)9G>^z7x^Uq@K3&|>U0Fm?{g|M-K( z6l{_DpR;T0*KeTWE040w*I*(rje+H}efBp{vF7ht6}K@TGmmU2zJ`k20((Cgz%Q^R zg=`67$RWSi-@A)@Y_CI02!g0-5)?jg6kz9-x#j*L#U`i6qTp-5e~ ziGhBlGd|f9j7NL>v?DzecJmSq<0N^n9H zbRo)X8poiEr{-AZ6+pl=1|>Od{{?k%$?W3EQE+hS!LdcjXKFO65TS#ygki2wxNd5+p z{|=BbjX}vT*?&pNr!3?bGvr?_u#nFmLG<}&$iqs)GaxEy6U}~dVQ!bXiU(6w+-GFx zqa(7Ub0x&4B%JwVOG=HaBKDA|391yw0-cYLhgua`=OtNGVdJTERXRjjS0z!y0^foH zVa91%3uNQ=UtxhYSIh;T>dzGTW4IHC1WtXbH4Cg8D_mfmq%t9eJYc%4iE{O3Mn%GLi#N#Qvop$~`~|!qTKD_wz9kueb1O zkXL#1Oq0>GZVJbh6PqAAi;2C34{DC|#T}$n7o%c4qR3)@A{G=?XBjEk<>K6rIT{)o zcGvHztAlCVHqHy06qBOj@Mgd5;vlvY662+)^L|pEMr=-Zz6OpFcH=U1W0TGP9Cl;X zX*sg9YUSy}xY^&|k?IBLNRy^y?ZWP+z#_0uOQhL+Qvvw9Yp;jp#B~hF^xe{uh`$Bs859$iHU8J z3U3XHI^!%MMYVXPHf`yHq%f+4CD|Vlqfw`w6x0SKxi-ja5pFBV4U2-J85*$NY&D2s z!A7V53{G#dWxtP3uX1;9*`@QiWv|~!Ic?ms>!3IQO~W(>9nlv1Wjdmke}0zEXL|RX zWa(WIbWY4mzb4{r9A03VE)d2v2GxH&d5jY8%0j$?FHlP_n2EVu8%tW~o7p)K-o%O@ zP~jSj@H1-V(#qUcu;MRfVMGmlXER0n+tiBxn#Xu)1*}-4iZ?f`xQYg&;x{){Og>K; UcUu@2fpL|#>rWeu_?mL{e?Fa+O8@`> literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ldap/sasl-ntlm.zeek b/testing/btest/scripts/base/protocols/ldap/sasl-ntlm.zeek new file mode 100644 index 0000000000..0504ba7a0a --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/sasl-ntlm.zeek @@ -0,0 +1,12 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/sasl-ntlm.pcap %INPUT +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: btest-diff ldap_search.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: This broke after #3826 got merged diff --git a/testing/btest/scripts/base/protocols/ldap/sasl-scram-sha-512.zeek b/testing/btest/scripts/base/protocols/ldap/sasl-scram-sha-512.zeek new file mode 100644 index 0000000000..9db41f96bc --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/sasl-scram-sha-512.zeek @@ -0,0 +1,12 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/sasl-scram-sha-512.pcap %INPUT +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: btest-diff ldap_search.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: This broke after #3826 got merged From 3846db6ccf07e49db059b9c2b038977a5e0a289b Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 18 Jul 2024 16:42:03 +0200 Subject: [PATCH 04/93] ldap: Reintroduce encryption after SASL heuristic @dopheide-esnet provided sample captures where SASL SRP is used as a SASL mechanism and the follow-up LDAP messages are encrypted. It's not clear how to determine whether encryption will or will not happen, so re-add a heuristic to determine this based on the first byte of the first message *after* the successful bindResponse handshake. If that byte is 0x30, assume cleartext. I haven't been able to produce such pcaps, unfortunately, but the cleartext path is tested via the existing sasl-ntlm.pcap. --- src/analyzer/protocol/ldap/ldap.spicy | 60 ++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/src/analyzer/protocol/ldap/ldap.spicy b/src/analyzer/protocol/ldap/ldap.spicy index c8102c49c9..a2878aad84 100644 --- a/src/analyzer/protocol/ldap/ldap.spicy +++ b/src/analyzer/protocol/ldap/ldap.spicy @@ -133,6 +133,9 @@ const GSSAPI_MECH_MS_KRB5 = "1.2.840.48018.1.2.2"; type MessageMode = enum { MS_KRB5 = 1, # Payload starts with a 4 byte length followed by a wrap token that may or may not be sealed. TLS = 2, # Client/server used StartTLS, forward to SSL analyzer. + MAYBE_ENCRYPTED = 3, # Use a heuristic to determine encrypted traffic. + CLEARTEXT = 4, # Assume cleartext. + ENCRYPTED = 5, # Assume encrypted. }; type Ctx = struct { @@ -152,11 +155,52 @@ public type MessageDispatch = unit(ctx: Ctx&) { switch( ctx.messageMode ) { MessageMode::Undef -> : Message(ctx); MessageMode::MS_KRB5 -> : SaslMsKrb5Stripper(ctx); - MessageMode::TLS -> : TlsForward; + MessageMode::TLS -> : TlsForward; # never returns + MessageMode::MAYBE_ENCRYPTED -> : MaybeEncrypted(ctx); + MessageMode::CLEARTEXT -> : Message(ctx); + MessageMode::ENCRYPTED -> : EncryptedMessage; }; }; +#----------------------------------------------------------------------------- +type MaybeEncrypted = unit(ctx: Ctx&) { + # A plaintext LDAP message always starts with at least 3 bytes and the first + # byte is 0x30 for the sequence. A SASL encrypted message starts with a 4 byte + # length field. The heuristic here is that if the first byte is a 0x30, + # assume it's unencrypted LDAP. This should be pretty good, if it was an + # encrypted/SASL wrapped message, it would have a size between 0x30000000 and + # 0x30FFFFFF, meaning at least a size of ~768MB, which seems unlikely. + var start: iterator; + on %init { + self.start = self.input(); + } + + first: uint8 { + if ( $$ == 0x30 ) { + ctx.messageMode = MessageMode::CLEARTEXT; + } else { + ctx.messageMode = MessageMode::ENCRYPTED; + } + } + + # Rewind the input. + : void { + # Prevent MessageDispatch from recursing endlessly. + assert ctx.messageMode != MessageMode::MAYBE_ENCRYPTED; + self.set_input(self.start); + } + + # One recursion to parse with the new ctx.messageMode setting. + : MessageDispatch(ctx); +}; + +#----------------------------------------------------------------------------- +type EncryptedMessage = unit { + len: uint32; + : skip bytes &size=self.len; +}; + #----------------------------------------------------------------------------- type TlsForward = unit { # Just consume everything. This is hooked in ldap_zeek.spicy @@ -416,6 +460,20 @@ type ServerSaslCreds = unit { type BindResponse = unit(inout message: Message, ctx: Ctx&) { : Result { message.result_ = $$; + + # The SASL authentication was successful. We do not actually + # know if the following messages are encrypted or not. This may be + # mechanism and parameter specific. For example SCRAM-SHA512 or NTLM + # will continue to be cleartext, while SRP or GSS-API would be encrypted. + # + # Switch messageMode into trial mode which is explored via MessageDispatch + # and the MaybeEncrypted unit. + # + # Note, messageMode may be changed to something more specific like + # MS_KRB5 below. + if ( |ctx.saslMechanism| > 0 && $$.code == ResultCode::SUCCESS ) { + ctx.messageMode = MessageMode::MAYBE_ENCRYPTED; + } } # Try to parse serverSaslCreds if there's any input remaining. This From a70ccc51abb321e6277b00f0414359df8e113788 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 18 Jul 2024 18:50:19 +0200 Subject: [PATCH 05/93] ldap: Add LDAP sample with SASL-SRP mechanism This is what @dopheide-esnet actually saw. Produced with a custom cyrus-sasl and openldap build :-( --- .../conn.log | 11 +++++++++++ .../ldap.log | 12 ++++++++++++ testing/btest/Traces/ldap/sasl-srp-who-am-i.pcap | Bin 0 -> 2838 bytes .../base/protocols/ldap/sasl-srp-who-am-i.zeek | 11 +++++++++++ 4 files changed, 34 insertions(+) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/ldap.log create mode 100644 testing/btest/Traces/ldap/sasl-srp-who-am-i.pcap create mode 100644 testing/btest/scripts/base/protocols/ldap/sasl-srp-who-am-i.zeek diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/conn.log new file mode 100644 index 0000000000..2638ca3cba --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/conn.log @@ -0,0 +1,11 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60648 127.0.1.1 389 tcp ldap_tcp 2.114467 548 1020 SF 0 ShADadFf 9 1024 6 1340 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/ldap.log new file mode 100644 index 0000000000..facaf46bc7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/ldap.log @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60648 127.0.1.1 389 1 3 bind SASL SASL bind in progress SASL(0): successful result: user: zeek@ubuntu-01.example.com property: slapAuthzDN not found in sasldb - SRP +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60648 127.0.1.1 389 2 3 bind SASL success - - SRP +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/ldap/sasl-srp-who-am-i.pcap b/testing/btest/Traces/ldap/sasl-srp-who-am-i.pcap new file mode 100644 index 0000000000000000000000000000000000000000..9e70f2d1b063516f418723540e8cc557d484e226 GIT binary patch literal 2838 zcmb7`3pkW%8^@n_W*n9aIfP1@$tqKr8KuNhidD+tGt$Xv@Q#LId~+bP)EJ}m_1UCa zBjvnHv<@Y^Y#XtZw6T>^)aszv(2*-tzULWRtJ${e`tIwx=bCx1XMXqpxu5&}zwfoC zllcTd0`FpS5&#VTF#j@(-Q5g;JN%AvdZ+_e0KVv1v7mfPv}dtG^EXPG8zB9tWCob%{S1|x(u>Foq1Jp4 z0*HVpl+!~&^zX4$5TiayGzJsleea0=0fk?G@2(uY_bKoaA4 zlNr^lSOq&EqY^F1Fg9V*xPZo$mLvewCE#i{- zxIn}e+LJ{BoNrG?n_MLd5k(6{R&<6nzJnDN!^N#bc~RsTJ}(C63*+IxxvUsxk#M`% z#giP(6O!3HQFIuY6HOMd1l+KYJyOD3I055uP)|g5JKMM)$$rMZ6R5v;Gp&MOgU{MC ztoE9bamev>uy>(=+E$&HHI#I)R}>eX@7QUkSGJzW(E4@P+T*uKZ@l}}S8#@Y2(N4p zK5TTv(Eb#Aw#r23cxgY?`1m(8&4WK~9E(3Vm>Kv-iIz~K`{kriu%*Mfv&pG=u7#;f zq(Pj+#ms7Zvk8e|?9XKJ8g5w9vn#b~dyKxEz3rII!_-%CYkghKPJdq6nHX3sUMRXU zI8L;j=pLb++QAB5m`>^wKdji}DIi{EQjcCDnS9lx-nGb2{-UI#N&4?{+gAhK6E%lU zUm$kniXYhCF^lpE@)c#{_xZ1{fBjsiSa)8I`=kJ1gc*FB;MaMrjD~2vas2k({&N^G zW&gHqpGW6jhEI05&^Ilx(eRR?dgJ$V36dm|QSt8}$!Kt%9hq*R&%FPVu@A^r6sSj? zbdPs3HU8`wCt&*{S+~Ed-S`TjUZ&$!i{%O0HD&SFqg?{yei%5mH2`G9TnKk-eN{_K zdah49CS3T%3HyV1f%RmXEV-iHLuS%Hcqs91y+y(U`LDZQbPVkOd@rZHvwhvVg&DP@ zk9UR^-P?cfMw!mOb)NFz2c?f!?sCyft}I%>8&I_iiqtIGRPwxoo4cxKUqncXZIPz+ z?ICTa=!^?uDBOadL$u~JaH(Rkqzb?lINcsZi6q~x;+4(4^sqFb^#g#Vh z0QfyBjOEB&>ukla_hIfCtfBdl>|`dTq; z>@1^LJ3>TkHqIAt#JJ-!TiYee(7nuo_wqlxLywihmkufU67*3YL*x!^WAA;51s%d1 z5mVy{;1M)`l+yz_9d@(F8W97AKT3q|FbHjI$~*lzh)9=W`2>s*EX9sYxt$a{Fy(hr zEEO)5VZce#PTxDF^{h^FCO2wz!)5Wzvy<&^<sqsZ|*Q{OU(F>O?Qs2 z+%9ZG)#`%qbic*bNAn3!>||P96#Fxrnu~Xn8*i?wy;Ue*qO#kO8Wby&Tse0?EA?e2 zPlx{MjJ2&zhR4pQ=QFwKPWH(ywT30~Z|kZ5U;%3#LczGac#EIwiKrgDN-UbCTh#;B1*Te~5D z)QGAc_a`FN(CP%3hIKfR`!Pl5%KLOiIgHloNcPqRyk~Ip9B%{ i584`ui1SlEsnJHEQR!W^tq*Fnu2oFiol>Y&A4anR8 literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ldap/sasl-srp-who-am-i.zeek b/testing/btest/scripts/base/protocols/ldap/sasl-srp-who-am-i.zeek new file mode 100644 index 0000000000..b467dbe484 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/sasl-srp-who-am-i.zeek @@ -0,0 +1,11 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/sasl-srp-who-am-i.pcap %INPUT +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: SASL authentication using SRP (Secure Remote Password) From ca25516e0330279ea9f6f8c7cde890beeb4756e2 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 19 Jul 2024 17:28:40 +0200 Subject: [PATCH 06/93] ldap: Ignore ec/rrc for sealed wrap tokens It shouldn't matter for the encrypted payload that we'll just consume and ignore. --- src/analyzer/protocol/ldap/ldap.spicy | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/analyzer/protocol/ldap/ldap.spicy b/src/analyzer/protocol/ldap/ldap.spicy index a2878aad84..3226b6e7cc 100644 --- a/src/analyzer/protocol/ldap/ldap.spicy +++ b/src/analyzer/protocol/ldap/ldap.spicy @@ -228,7 +228,10 @@ type KrbWrapToken = unit { } else if ( self.rrc == 0 ) { self.trailer_ec = self.ec; } else { - throw "Unhandled rc %s and ec %s" % (self.ec, self.rrc); + if ( ! self.ctx_flags.sealed ) + # If it's sealed, we'll consume until &eod anyhow + # and ec/rrc shouldn't apply, otherwise, bail. + throw "Unhandled rc %s and ec %s" % (self.ec, self.rrc); } } From d4778f451c6f7fc192f8ad6baedf34e35f6292c6 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 19 Jul 2024 19:48:04 +0200 Subject: [PATCH 07/93] ldap: Add heuristic for wrap tokens Instead of dissecting the GSSAPI handshake, add another heuristic into MaybeEncrypted to check for the WRAP token identifier. After this change, the pcap on the following ticket is processed nicely: https://gitlab.com/wireshark/migration-test/-/issues/9398 --- src/analyzer/protocol/ldap/ldap.spicy | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/analyzer/protocol/ldap/ldap.spicy b/src/analyzer/protocol/ldap/ldap.spicy index 3226b6e7cc..96f942d7a3 100644 --- a/src/analyzer/protocol/ldap/ldap.spicy +++ b/src/analyzer/protocol/ldap/ldap.spicy @@ -172,8 +172,14 @@ type MaybeEncrypted = unit(ctx: Ctx&) { # encrypted/SASL wrapped message, it would have a size between 0x30000000 and # 0x30FFFFFF, meaning at least a size of ~768MB, which seems unlikely. var start: iterator; + var saslLen: uint64; + var mech: bytes; + on %init { self.start = self.input(); + # Don't have starts_with() on string, work around that. + # https://github.com/zeek/spicy/issues/1807 + self.mech = ctx.saslMechanism.encode(spicy::Charset::UTF8); } first: uint8 { @@ -184,6 +190,21 @@ type MaybeEncrypted = unit(ctx: Ctx&) { } } + # As a further heuristic, if encrypted mode was decided and the client + # requested GSSAPI or GSS-SPNEGO (or we just didn't see it) peak a bit + # into the SASL payload and check if it starts with a 0504 (WRAP_TOKEN). + # If so, switch into KRB mode assuming that's what is being used and + # have a chance seeing some more plaintext LDAP in non-sealed tokens. + rem: uint8[3] if ( ctx.messageMode == MessageMode::ENCRYPTED && (|self.mech| == 0 || self.mech.starts_with(b"GSS")) ) { + self.saslLen = (self.first << 24) + ($$[0] << 16) + ($$[1] << 8) + $$[2]; + } + + : uint16 if ( self.saslLen >= 2 ) { + if ( $$ == 0x0504 ) { + ctx.messageMode = MessageMode::MS_KRB5; + } + } + # Rewind the input. : void { # Prevent MessageDispatch from recursing endlessly. From dc61cd7a54082398d3daa9254344caad032a43b5 Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Tue, 23 Jul 2024 11:43:01 +0200 Subject: [PATCH 08/93] Bump auxil/spicy to latest development snapshot --- auxil/spicy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/spicy b/auxil/spicy index 4a1b43ef07..04c5ed3c27 160000 --- a/auxil/spicy +++ b/auxil/spicy @@ -1 +1 @@ -Subproject commit 4a1b43ef07d1305a7e88a4f0866068dc49de9d06 +Subproject commit 04c5ed3c27879459de69d12efc417c6915f304b9 From da131fae60ca8e008fb6e60339ac67a6ddc1e16e Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 23 Jul 2024 16:05:30 +0100 Subject: [PATCH 09/93] Update Mozilla CA list and CT list --- scripts/base/protocols/ssl/ct-list.zeek | 21 +++++++++++++++---- .../base/protocols/ssl/mozilla-ca-list.zeek | 5 +++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/scripts/base/protocols/ssl/ct-list.zeek b/scripts/base/protocols/ssl/ct-list.zeek index c7c2a87ec9..036374d946 100644 --- a/scripts/base/protocols/ssl/ct-list.zeek +++ b/scripts/base/protocols/ssl/ct-list.zeek @@ -1,9 +1,9 @@ # # Do not edit this file. This file is automatically generated by gen-ct-list.pl -# File generated at Fri Feb 23 11:37:01 2024 +# File generated at Tue Jul 23 16:04:45 2024 # File generated from https://www.gstatic.com/ct/log_list/v3/log_list.json -# Source file generated at: 2024-02-22T12:56:21Z -# Source file version: 32.9 +# Source file generated at: 2024-07-23T13:06:08Z +# Source file version: 39.1 # @load base/protocols/ssl @@ -12,21 +12,32 @@ redef ct_logs += { ["\xee\xcd\xd0\x64\xd5\xdb\x1a\xce\xc5\x5c\xb7\x9d\xb4\xcd\x13\xa2\x32\x87\x46\x7c\xbc\xec\xde\xc3\x51\x48\x59\x46\x71\x1f\xb5\x9b"] = CTInfo($description="Google 'Argon2024' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2024/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x1d\xb9\x6c\xa9\xcb\x69\x94\xc5\x5c\xe6\xb6\xa6\x03\xbb\xd2\xb8\xdc\x54\x43\x17\x28\x99\x0c\x06\x01\x50\x1d\x9d\x64\xc0\x59\x46\x2b\xdc\xc8\x03\x1d\x05\xb4\x2d\xa8\x09\xf7\x99\x41\xed\x04\xfb\xe5\x57\xba\x26\x04\xf6\x11\x52\xce\x14\x65\x3b\x2f\x76\x2b\xc0"), ["\x4e\x75\xa3\x27\x5c\x9a\x10\xc3\x38\x5b\x6c\xd4\xdf\x3f\x52\xeb\x1d\xf0\xe0\x8e\x1b\x8d\x69\xc0\xb1\xfa\x64\xb1\x62\x9a\x39\xdf"] = CTInfo($description="Google 'Argon2025h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2025h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x20\x82\xa1\xf9\x67\x68\xa8\xe4\xdb\x94\x98\xe2\xe1\x68\x87\xe4\x09\x6d\x20\x35\x33\x38\x3c\xaf\x14\xaa\xd7\x08\x18\xf0\xfd\x16\x9b\xd3\xff\x7c\x27\x82\xd4\x87\xb7\x4e\x24\x46\x3b\xfb\xae\xbe\xc8\x23\x52\x20\x2b\xaa\x44\x05\xfe\x54\xf9\xd5\xf1\x1d\x45\x9a"), ["\x12\xf1\x4e\x34\xbd\x53\x72\x4c\x84\x06\x19\xc3\x8f\x3f\x7a\x13\xf8\xe7\xb5\x62\x87\x88\x9c\x6d\x30\x05\x84\xeb\xe5\x86\x26\x3a"] = CTInfo($description="Google 'Argon2025h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2025h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xaf\xe4\xf3\x94\x2c\xdf\xa6\x27\xb5\xfe\xb2\x61\x83\x19\xc8\x21\x3a\x23\xa8\xa9\x3d\x54\xaf\xbc\x31\x9a\x1c\xd3\xc1\xe3\xb6\xc2\xf3\x0f\xc7\xb9\xca\x3b\x1d\x79\x65\x61\x22\x25\x82\x56\x4e\x98\xe8\xaa\x26\x29\x36\x1e\x28\x60\x6f\xeb\x15\x6e\xf7\x7c\xd0\xba"), +["\x0e\x57\x94\xbc\xf3\xae\xa9\x3e\x33\x1b\x2c\x99\x07\xb3\xf7\x90\xdf\x9b\xc2\x3d\x71\x32\x25\xdd\x21\xa9\x25\xac\x61\xc5\x4e\x21"] = CTInfo($description="Google 'Argon2026h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2026h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xfc\x1e\xe8\x63\x8e\xff\x1c\x31\x8a\xfc\xb8\x1e\x19\x2b\x60\x50\x00\x3e\x8e\x9e\xda\x77\x37\xe3\xa5\xa8\xda\x8d\x94\xf8\x6b\xe8\x3d\x64\x8f\x27\x3f\x75\xb3\xfc\x6b\x12\xf0\x37\x06\x4f\x64\x58\x75\x14\x5d\x56\x52\xe6\x6a\x2b\x14\x4c\xec\x81\xd1\xea\x3e"), +["\xd7\x6d\x7d\x10\xd1\xa7\xf5\x77\xc2\xc7\xe9\x5f\xd7\x00\xbf\xf9\x82\xc9\x33\x5a\x65\xe1\xd0\xb3\x01\x73\x17\xc0\xc8\xc5\x69\x77"] = CTInfo($description="Google 'Argon2026h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/us1/argon2026h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x2a\x3a\x67\x8b\xfe\xba\x0c\x86\x2b\x4a\x51\x8a\xe9\x17\xfe\x7b\xa1\x76\x73\xfd\xbc\x65\x4b\xc3\x27\xbf\x4d\xf3\x5f\xa0\xca\x29\x80\x11\x20\x32\x78\xd6\x7e\xf9\x34\x60\x8c\x75\xa0\xf5\x35\x50\x9c\xa1\xd3\x49\x4d\x13\xd5\x3b\x6a\x0e\xea\x45\x9d\x24\x13\x22"), ["\x76\xff\x88\x3f\x0a\xb6\xfb\x95\x51\xc2\x61\xcc\xf5\x87\xba\x34\xb4\xa4\xcd\xbb\x29\xdc\x68\x42\x0a\x9f\xe6\x67\x4c\x5a\x3a\x74"] = CTInfo($description="Google 'Xenon2024' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2024/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xb9\x60\xe0\x34\x1e\x35\xe4\x65\x00\x93\x4f\x90\x09\xbd\x5a\xec\x44\xdd\x8c\x0f\xce\xed\x11\x3e\x2a\x59\x46\x9a\x31\xb6\xc7\x99\xf7\xdc\xef\x3d\xcd\x8f\x86\xc2\x35\xa5\x3e\xdc\x29\xba\xbb\xf2\x54\xe2\xa8\x0c\x83\x08\x51\x06\xde\x21\x6d\x36\x50\x8e\x38\x4d"), ["\xcf\x11\x56\xee\xd5\x2e\x7c\xaf\xf3\x87\x5b\xd9\x69\x2e\x9b\xe9\x1a\x71\x67\x4a\xb0\x17\xec\xac\x01\xd2\x5b\x77\xce\xcc\x3b\x08"] = CTInfo($description="Google 'Xenon2025h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2025h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x82\xe2\xce\x90\x40\x3f\x81\x0e\xdf\xea\xe1\x20\x2b\x5e\x2e\x30\x54\x46\x81\xb9\x58\xed\xaf\xbd\xff\x36\xa7\x9e\x0b\x5f\x6a\x6b\x91\xa5\xc1\x98\xe1\xf2\xcd\xeb\x17\x20\x70\xca\x2a\x12\xe6\x54\x78\x50\xdc\xff\x6d\xfd\x1c\xa7\xb6\x3a\x1f\xf9\x26\xa9\x1b\xbd"), ["\xdd\xdc\xca\x34\x95\xd7\xe1\x16\x05\xe7\x95\x32\xfa\xc7\x9f\xf8\x3d\x1c\x50\xdf\xdb\x00\x3a\x14\x12\x76\x0a\x2c\xac\xbb\xc8\x2a"] = CTInfo($description="Google 'Xenon2025h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2025h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x6b\xe0\xaf\xed\x06\x7c\x3d\xef\xd9\x0e\xe4\x58\x4b\x04\xd8\x2a\x47\x99\x90\x89\x7a\xb9\x36\xa5\x75\xc8\x04\xb8\xcb\xe2\xaa\x2b\xb5\x68\x9d\x88\x29\xa2\xa5\xcf\xce\x2b\x9a\x15\x9b\xa0\x3e\x9d\x94\x1c\xb2\xb7\x4a\xf2\x51\xec\x40\xed\x62\x47\xa4\x03\x49\x86"), +["\x96\x97\x64\xbf\x55\x58\x97\xad\xf7\x43\x87\x68\x37\x08\x42\x77\xe9\xf0\x3a\xd5\xf6\xa4\xf3\x36\x6e\x46\xa4\x3f\x0f\xca\xa9\xc6"] = CTInfo($description="Google 'Xenon2026h1' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2026h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x3a\x1f\xc8\xbb\xce\xd5\x90\x47\x34\xca\xca\x01\x04\x27\x21\x1c\xe2\x29\x3d\x92\xbb\x91\x45\xc7\x5a\x3e\xa5\xd4\xf2\x12\xe6\xe8\xe6\x43\xba\xf3\x7b\xc2\x38\xaf\xfc\x23\x8a\x05\x56\xeb\x03\x0a\x30\xcc\x63\x6c\xd9\x3c\xbe\xf5\x7b\x94\xba\x94\xd3\xbf\x88\x4c"), +["\xd8\x09\x55\x3b\x94\x4f\x7a\xff\xc8\x16\x19\x6f\x94\x4f\x85\xab\xb0\xf8\xfc\x5e\x87\x55\x26\x0f\x15\xd1\x2e\x72\xbb\x45\x4b\x14"] = CTInfo($description="Google 'Xenon2026h2' log", $operator="Google", $url="https://ct.googleapis.com/logs/eu1/xenon2026h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xe5\x77\x78\x95\x71\x28\xb3\x95\xc9\xa5\xcc\x7a\x4c\xe8\x32\x03\x96\x7b\xfc\x2e\x1d\xb9\xa4\xdb\x43\xa0\xbd\x69\x72\xf9\x45\xba\x9a\xc3\xe9\x96\xd5\x70\xe7\x0d\x7e\xc9\x95\x15\x27\x8a\x72\x30\x65\x86\x43\x53\xdc\x11\x44\x18\x49\x98\x25\x68\xa7\x3c\x05\xbf"), ["\xda\xb6\xbf\x6b\x3f\xb5\xb6\x22\x9f\x9b\xc2\xbb\x5c\x6b\xe8\x70\x91\x71\x6c\xbb\x51\x84\x85\x34\xbd\xa4\x3d\x30\x48\xd7\xfb\xab"] = CTInfo($description="Cloudflare 'Nimbus2024' Log", $operator="Cloudflare", $url="https://ct.cloudflare.com/logs/nimbus2024/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x77\xb1\x9b\x7b\x8f\xe6\x8b\x35\xfe\x3a\x92\x29\x2d\xac\x8a\x8d\x51\x8a\x25\xfc\x93\xb6\xd7\xa0\x8b\x29\x37\x71\x1d\x33\xca\xcc\x33\xea\x28\xb9\x1f\xe2\xac\xc3\xa9\x5d\xdd\x97\xbe\xf6\x9e\x94\x25\xdd\x36\x81\xd1\xeb\x5d\x29\xc3\x2b\x44\xf1\x5b\xca\x15\x48"), ["\xcc\xfb\x0f\x6a\x85\x71\x09\x65\xfe\x95\x9b\x53\xce\xe9\xb2\x7c\x22\xe9\x85\x5c\x0d\x97\x8d\xb6\xa9\x7e\x54\xc0\xfe\x4c\x0d\xb0"] = CTInfo($description="Cloudflare 'Nimbus2025'", $operator="Cloudflare", $url="https://ct.cloudflare.com/logs/nimbus2025/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x1a\x80\x1a\x15\x19\x19\x23\x79\xb4\xfa\xa0\x79\x8e\x8d\xd5\xc1\xdc\xc2\xb5\x96\x92\x7e\x94\xe0\xc3\x7e\x14\x7c\x0a\x0d\x2d\x46\xa8\x9d\x1b\xb1\x41\x65\x0c\x5f\x98\xc4\x5a\x17\x79\x81\x5b\x4a\x14\x41\xec\xaf\xa9\x5d\x0e\xab\x12\x19\x71\xcd\x43\xef\xbb\x97"), ["\x48\xb0\xe3\x6b\xda\xa6\x47\x34\x0f\xe5\x6a\x02\xfa\x9d\x30\xeb\x1c\x52\x01\xcb\x56\xdd\x2c\x81\xd9\xbb\xbf\xab\x39\xd8\x84\x73"] = CTInfo($description="DigiCert Yeti2024 Log", $operator="DigiCert", $url="https://yeti2024.ct.digicert.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x57\xb8\xc1\x6f\x30\xa4\x7f\x2e\xe4\xf0\xd0\xd9\x60\x62\x13\x95\xe3\x7a\xe3\x4e\x53\xc3\xb3\xb8\x73\x85\xc1\x18\x0d\x23\x0e\x58\x84\xd2\x78\xef\x9b\xb3\x1e\x2c\x1a\xde\xc1\x8f\x81\x1b\x19\x44\x58\xb7\x00\x77\x60\x20\x1a\x72\xd8\x82\xde\xae\x9e\xb1\xc6\x4b"), ["\x7d\x59\x1e\x12\xe1\x78\x2a\x7b\x1c\x61\x67\x7c\x5e\xfd\xf8\xd0\x87\x5c\x14\xa0\x4e\x95\x9e\xb9\x03\x2f\xd9\x0e\x8c\x2e\x79\xb8"] = CTInfo($description="DigiCert Yeti2025 Log", $operator="DigiCert", $url="https://yeti2025.ct.digicert.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xdf\x95\x00\x5e\x10\xc1\x01\xf7\x37\xe3\x10\x74\xd1\xff\xb2\xca\x90\xed\x32\x99\x5f\x0c\x39\xfe\xa1\xd1\x13\x11\xac\xd1\xb3\x73\x93\x20\xc2\x13\x3c\x4c\xb5\x7a\x52\x86\x86\x3d\xe3\x95\x24\x7c\xd8\x91\x98\x48\x3b\xf0\xf0\xdf\x21\xf1\xb0\x81\x5a\x59\x25\x43"), ["\x73\xd9\x9e\x89\x1b\x4c\x96\x78\xa0\x20\x7d\x47\x9d\xe6\xb2\xc6\x1c\xd0\x51\x5e\x71\x19\x2a\x8c\x6b\x80\x10\x7a\xc1\x77\x72\xb5"] = CTInfo($description="DigiCert Nessie2024 Log", $operator="DigiCert", $url="https://nessie2024.ct.digicert.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x2d\xfc\xa2\x7b\x36\xbf\x56\x91\xe9\xfe\x3f\xe8\x3d\xfc\xc3\xa7\xe0\x61\x52\xea\x2c\xe9\x05\xa3\x9f\x27\x17\x81\x05\x70\x6b\x81\x61\x44\x8a\xf8\x3b\x10\x80\x42\xed\x03\x2f\x00\x50\x21\xfc\x41\x54\x84\xa3\x54\xd5\x2e\xb2\x7a\x16\x4b\x2a\x1f\x2b\x66\x04\x2b"), ["\xe6\xd2\x31\x63\x40\x77\x8c\xc1\x10\x41\x06\xd7\x71\xb9\xce\xc1\xd2\x40\xf6\x96\x84\x86\xfb\xba\x87\x32\x1d\xfd\x1e\x37\x8e\x50"] = CTInfo($description="DigiCert Nessie2025 Log", $operator="DigiCert", $url="https://nessie2025.ct.digicert.com/log/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xf2\xf0\xf0\xa7\x8b\x81\x2e\x09\x39\x3b\x9f\x42\xda\x38\x44\x5f\xb4\xcc\xed\x36\xbb\xd8\x43\x7f\x16\x49\x57\x87\x04\x7f\xa5\x01\x34\xf7\xe8\x68\x3f\xb7\x78\x1f\x60\x66\x2d\x67\x9a\x75\x80\xb7\x53\xa7\x85\xd5\xbc\xab\x47\x06\x55\xdb\xb5\xdf\x88\xa1\x6f\x38"), +["\xb6\x9d\xdc\xbc\x3c\x1a\xbd\xef\x6f\x9f\xd6\x0c\x88\xb1\x06\x7b\x77\xf0\x82\x68\x8b\x2d\x78\x65\xd0\x4b\x39\xab\xe9\x27\xa5\x75"] = CTInfo($description="DigiCert 'Wyvern2024h1' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2024h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x68\xa6\x79\x14\xd1\x58\xe7\xab\xaa\x29\x69\x7f\x60\xed\x68\xe8\x10\xf6\x07\x84\xc0\xfb\x59\x04\x5a\x09\xc9\x1d\xe1\x4b\xfb\xcd\xdc\x03\xf3\xa8\x2a\x46\xb9\x84\x4d\x69\x30\xec\x23\x35\xc1\x8e\xfc\x9f\xb4\x20\x24\xd7\x15\xac\x87\xf7\x1e\xc1\x0b\x3c\x76\x1a"), +["\x0c\x2a\xef\x2c\x4a\x5b\x98\x83\xd4\xdd\xa3\x82\xfe\x50\xfb\x51\x88\xb3\xe9\x73\x33\xa1\xec\x53\xa0\x9d\xc9\xa7\x9d\x0d\x08\x20"] = CTInfo($description="DigiCert 'Wyvern2024h2' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2024h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa8\x73\x12\x9c\x54\xd0\x7a\x7d\xc5\xb5\x17\x2b\x71\x52\x89\x04\x90\xbb\x42\xf1\x9d\xf8\x1c\xde\x4c\xcf\x82\x3c\xbd\x37\x1b\x74\x4c\x3c\xc7\xa3\x13\x87\x01\x51\x13\x14\xda\xa2\x12\x98\x84\xce\x1c\xbe\xcf\x4f\x7a\xef\x15\xfa\xd0\xee\xed\xed\x07\xad\x71\x6d"), +["\x73\x20\x22\x0f\x08\x16\x8a\xf9\xf3\xc4\xa6\x8b\x0a\xb2\x6a\x9a\x4a\x00\xee\xf5\x77\x85\x8a\x08\x4d\x05\x00\xd4\xa5\x42\x44\x59"] = CTInfo($description="DigiCert 'Wyvern2025h1' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2025h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa7\xcb\x80\x61\x86\x1b\x1f\xb5\xab\x2b\x20\x76\x59\x83\x66\x0e\xce\xae\xb8\x6f\x3b\x88\x02\xeb\x43\xf4\x87\x90\xcb\x8b\xda\xac\x0e\x19\x50\xe0\xf9\x24\x0e\xab\x26\x93\x8c\x3f\x9e\x0d\x96\x58\x44\x9d\x3b\x8a\x80\xc5\xc8\xbe\xe1\x89\x46\x6b\x48\x4c\xd6\x09"), +["\xed\x3c\x4b\xd6\xe8\x06\xc2\xa4\xa2\x00\x57\xdb\xcb\x24\xe2\x38\x01\xdf\x51\x2f\xed\xc4\x86\xc5\x70\x0f\x20\xdd\xb7\x3e\x3f\xe0"] = CTInfo($description="DigiCert 'Wyvern2025h2' Log", $operator="DigiCert", $url="https://wyvern.ct.digicert.com/2025h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xe0\xdb\x41\xef\xe4\x04\xbd\xcb\x6b\x2e\x4c\xcc\xf1\x6c\xde\x41\x58\x7f\xfe\x94\xf6\x7a\xf6\x60\xed\x8b\x76\x72\xa3\xa2\x1c\x31\x13\x32\x35\xa1\xf2\x08\xd2\x68\xc5\x34\xa7\x56\x08\x1c\x63\xde\x95\xe2\x81\x69\x97\x8d\x1e\xa8\xb7\x66\x51\x25\x75\x4d\x78\x2e"), +["\xdb\x07\x6c\xde\x6a\x8b\x78\xec\x58\xd6\x05\x64\x96\xeb\x6a\x26\xa8\xc5\x9e\x72\x12\x93\xe8\xac\x03\x27\xdd\xde\x89\xdb\x5a\x2a"] = CTInfo($description="DigiCert 'Sphinx2024h1' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2024h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xc6\xe4\x29\x69\x98\xfe\x28\x92\x57\x12\x4d\x9e\xed\x0e\xe7\x32\xa2\xe6\x9c\x27\x78\xa4\x29\x7c\x99\xd5\xdb\xfa\x22\xc1\xdd\x5e\xa7\xf4\xd8\xea\xc8\xd7\x44\x8d\xe0\xf1\x8c\x0a\x01\x1d\xd8\x22\xa8\xd3\xeb\xc9\x22\x8e\x36\xfb\x4a\xb1\x70\x9c\x5d\xc1\xe8\x33"), +["\xdc\xc9\x5e\x6f\xa2\x99\xb9\xb0\xfd\xbd\x6c\xa6\xa3\x6e\x1d\x72\xc4\x21\x2f\xdd\x1e\x0f\x47\x55\x3a\x36\xd6\xcf\x1a\xd1\x1d\x8d"] = CTInfo($description="DigiCert 'Sphinx2024h2' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2024h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xdb\x09\x41\x84\xe7\xd1\xf1\x5b\x25\x09\x7b\xe8\xc6\x98\x51\x5e\x29\x85\xfd\x81\xde\x89\xd7\xd0\x86\xa4\xb0\xe5\x15\xec\x5d\x7b\x17\x55\x5f\xc9\x79\x8d\xe4\x22\x36\xe7\xe9\xbf\x38\x3f\xd1\xe9\xd4\x09\x84\x81\xbe\xb6\xc1\xed\x1b\x17\xea\x26\x97\xba\xe9\x9a"), +["\xde\x85\x81\xd7\x50\x24\x7c\x6b\xcd\xcb\xaf\x56\x37\xc5\xe7\x81\xc6\x4c\xe4\x6e\xd6\x17\x63\x9f\x8f\x34\xa7\x26\xc9\xe2\xbd\x37"] = CTInfo($description="DigiCert 'Sphinx2025h1' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2025h1/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xe3\x2f\x1f\x4d\x89\x05\x75\x29\x78\xbb\x22\x3d\x07\x62\x51\x14\x70\x94\xe7\x3c\xea\xf5\xee\xae\xa6\x48\x9a\x86\x52\x4e\x9e\x5c\xe3\x95\x97\x28\xbb\x52\x4b\x2a\xfd\xc8\xc9\x89\x4e\x45\x31\x17\xd3\x8d\xf2\xe7\xce\x18\x11\x58\x98\x2c\x60\x6f\x58\x20\x36\x6e"), +["\xa4\x42\xc5\x06\x49\x60\x61\x54\x8f\x0f\xd4\xea\x9c\xfb\x7a\x2d\x26\x45\x4d\x87\xa9\x7f\x2f\xdf\x45\x59\xf6\x27\x4f\x3a\x84\x54"] = CTInfo($description="DigiCert 'Sphinx2025h2' Log", $operator="DigiCert", $url="https://sphinx.ct.digicert.com/2025h2/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x41\x8c\x50\x13\x54\xb1\x19\x05\xb7\x7f\x4a\x20\x6e\xa3\x75\x63\xca\x34\xf4\xcc\x74\xea\x32\x3b\xb6\x8b\x03\x14\xa8\x52\x7f\x32\x87\x5e\x59\x9e\x0f\xab\x18\x9e\x29\x6c\xb5\x72\x77\x1a\x27\x54\x85\x5d\xc1\x7b\x24\xa8\x34\xe3\xcd\x88\xce\xd4\x50\x1b\xbe\x69"), ["\x55\x81\xd4\xc2\x16\x90\x36\x01\x4a\xea\x0b\x9b\x57\x3c\x53\xf0\xc0\xe4\x38\x78\x70\x25\x08\x17\x2f\xa3\xaa\x1d\x07\x13\xd3\x0c"] = CTInfo($description="Sectigo 'Sabre' CT log", $operator="Sectigo", $url="https://sabre.ct.comodo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xf2\x6f\xd2\x89\x0f\x3f\xc5\xf8\x87\x1e\xab\x65\xb3\xd9\xbb\x17\x23\x8c\x06\x0e\x09\x55\x96\x3d\x0a\x08\xa2\xc5\x71\xb3\xd1\xa9\x2f\x28\x3e\x83\x10\xbf\x12\xd0\x44\x66\x15\xef\x54\xe1\x98\x80\xd0\xce\x24\x6d\x3e\x67\x9a\xe9\x37\x23\xce\x52\x93\x86\xda\x80"), ["\xa2\xe2\xbf\xd6\x1e\xde\x2f\x2f\x07\xa0\xd6\x4e\x6d\x37\xa7\xdc\x65\x43\xb0\xc6\xb5\x2e\xa2\xda\xb7\x8a\xf8\x9a\x6d\xf5\x17\xd8"] = CTInfo($description="Sectigo 'Sabre2024h1'", $operator="Sectigo", $url="https://sabre2024h1.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x2c\x01\xf6\xce\x31\xbc\xaa\x14\x61\x51\xfe\x6b\x7a\x87\xae\xa6\xd3\x9b\xc7\x87\x2d\x0a\x5a\xc8\x4f\xb5\x54\xdc\xc9\x93\xa0\x00\xee\xca\x1c\xb9\xa7\xb6\x7b\x47\x3b\xe5\x4f\xaa\x6c\x16\x1c\x70\x2e\xc8\xec\x53\x5a\x4c\x21\x4c\x7e\x27\x0b\x13\x14\x5e\xfc\x85"), ["\x19\x98\x10\x71\x09\xf0\xd6\x52\x2e\x30\x80\xd2\x9e\x3f\x64\xbb\x83\x6e\x28\xcc\xf9\x0f\x52\x8e\xee\xdf\xce\x4a\x3f\x16\xb4\xca"] = CTInfo($description="Sectigo 'Sabre2024h2'", $operator="Sectigo", $url="https://sabre2024h2.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x7a\x10\x4c\x8a\xe7\x22\x7b\x6d\x2a\xba\x8e\xfa\x6b\x4a\x81\xd5\x85\xae\x03\xef\xff\x4b\xfc\x4d\x53\x3d\xb7\x8c\xbb\x75\x09\xc9\xea\x16\x7e\xc1\x77\x16\xd2\xc2\x45\x74\x6d\x8d\xc4\xe1\x88\x37\xdf\xd4\xf3\x60\x65\xfc\xa0\x75\xf0\x20\x66\x8e\x4a\xcc\x19\xda"), ["\xe0\x92\xb3\xfc\x0c\x1d\xc8\xe7\x68\x36\x1f\xde\x61\xb9\x96\x4d\x0a\x52\x78\x19\x8a\x72\xd6\x72\xc4\xb0\x4d\xa5\x6d\x6f\x54\x04"] = CTInfo($description="Sectigo 'Sabre2025h1'", $operator="Sectigo", $url="https://sabre2025h1.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x7e\x2f\x39\xf1\xe8\x23\x8e\xb3\x32\x04\xaf\x4d\x57\xf6\xdb\xc5\x74\xa4\x7a\x6d\x3b\x07\x51\x0c\x5a\xfb\x80\x30\x05\xc6\x5a\x0c\xc4\x76\xd6\x06\xa8\x57\x4d\xfb\xdf\xe4\x82\x90\xc2\x41\xae\x70\xb3\x31\xa2\xe3\xfa\x3d\x5f\x2c\x5d\x04\xcd\xb4\x9d\x55\xab\x41"), ["\x1a\x04\xff\x49\xd0\x54\x1d\x40\xaf\xf6\xa0\xc3\xbf\xf1\xd8\xc4\x67\x2f\x4e\xec\xee\x23\x40\x68\x98\x6b\x17\x40\x2e\xdc\x89\x7d"] = CTInfo($description="Sectigo 'Sabre2025h2'", $operator="Sectigo", $url="https://sabre2025h2.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x85\x13\x11\x2d\x7b\xf3\x93\x81\xe4\xb9\x7c\xd9\x64\x3b\xe7\xb5\x83\x99\x66\x79\x59\x47\x6a\x42\x5e\xd6\xbd\x63\x2e\xb7\x91\x4b\xae\xbc\x56\xc4\xc5\x6e\x09\xa0\xd7\x64\x1a\xc8\xc1\xaf\x89\x8b\xf5\x58\xd8\xba\xeb\x7b\x83\x52\xe9\xf4\xe0\xa5\xcd\xcd\x92\xcc"), -["\x6f\x53\x76\xac\x31\xf0\x31\x19\xd8\x99\x00\xa4\x51\x15\xff\x77\x15\x1c\x11\xd9\x02\xc1\x00\x29\x06\x8d\xb2\x08\x9a\x37\xd9\x13"] = CTInfo($description="Sectigo 'Mammoth' CT log", $operator="Sectigo", $url="https://mammoth.ct.comodo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xef\xe4\x7d\x74\x2e\x15\x15\xb6\xe9\xbb\x23\x8b\xfb\x2c\xb5\xe1\xc7\x80\x98\x47\xfb\x40\x69\x68\xfc\x49\xad\x61\x4e\x83\x47\x3c\x1a\xb7\x8d\xdf\xff\x7b\x30\xb4\xba\xff\x2f\xcb\xa0\x14\xe3\xad\xd5\x85\x3f\x44\x59\x8c\x8c\x60\x8b\xd7\xb8\xb1\xbf\xae\x8c\x67"), ["\x29\xd0\x3a\x1b\xb6\x74\xaa\x71\x1c\xd3\x03\x5b\x65\x57\xc1\x4f\x8a\xa7\x8b\x4f\xe8\x38\x94\x49\xec\xa4\x53\xf9\x44\xbd\x24\x68"] = CTInfo($description="Sectigo 'Mammoth2024h1'", $operator="Sectigo", $url="https://mammoth2024h1.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa4\x59\x90\xf3\x71\x24\x24\xf7\xc3\x55\x27\x56\x9c\xa3\x59\x1e\xf7\xb7\x9f\xce\xab\x4e\x19\x66\x4d\xd0\x8a\xfa\x9d\x62\xa4\x24\xf0\x3b\x20\xe4\x1d\x14\x67\xc8\xfc\xe4\x37\xf2\x4b\x38\x54\x5a\xcf\x9f\x6b\x07\x90\xd0\x0e\x7e\x3d\x4c\x87\xb2\xe8\x3f\x07\xcc"), ["\x50\x85\x01\x58\xdc\xb6\x05\x95\xc0\x0e\x92\xa8\x11\x02\xec\xcd\xfe\x3f\x6b\x78\x58\x42\x9f\x57\x98\x35\x38\xc9\xda\x52\x50\x63"] = CTInfo($description="Sectigo 'Mammoth2024h1b'", $operator="Sectigo", $url="https://mammoth2024h1b.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa3\xd5\x07\x28\x7a\x04\x34\xae\xca\xbe\x80\x79\x4f\x3e\xf6\x41\xf4\x24\x04\xe1\xd6\x36\x5a\x1a\x09\xf2\xd1\xba\x84\x17\xae\x1e\xa1\x7c\x00\x1d\x54\x73\x90\x75\x21\xa8\xd1\xda\x5e\x10\xe1\x8c\xec\xb2\x8a\x8c\xc8\xe7\xdd\xcd\xe2\x07\xf0\x4e\x16\x02\x57\x37"), ["\xdf\xe1\x56\xeb\xaa\x05\xaf\xb5\x9c\x0f\x86\x71\x8d\xa8\xc0\x32\x4e\xae\x56\xd9\x6e\xa7\xf5\xa5\x6a\x01\xd1\xc1\x3b\xbe\x52\x5c"] = CTInfo($description="Sectigo 'Mammoth2024h2'", $operator="Sectigo", $url="https://mammoth2024h2.ct.sectigo.com/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x85\x66\x22\x24\x6e\xbe\x52\x62\x0a\xa0\xaf\xc3\x25\x1a\x36\x2e\xa7\x60\x89\xa2\x65\xbf\xa4\x5f\xbd\x85\x6a\x94\x05\x81\x35\x90\x54\x31\x95\xe7\x11\x9e\xa3\x2e\x0f\x85\xef\xa7\x88\x57\x8b\x63\x1a\x81\xc1\x41\x9d\x7d\xec\x01\x3a\xdb\xb9\xc1\x27\xf4\x65\x1e"), @@ -39,4 +50,6 @@ redef ct_logs += { ["\x87\x4f\xb5\x0d\xc0\x29\xd9\x93\x1d\xe5\x73\xe9\xf2\x89\x9e\x8e\x45\x33\xb3\x92\xd3\x8b\x0a\x46\x25\x74\xbf\x0f\xee\xb2\xfc\x1e"] = CTInfo($description="Trust Asia Log2024-2", $operator="TrustAsia", $url="https://ct2024.trustasia.com/log2024/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa7\x64\xe2\x79\x81\x3f\x61\xd7\xec\xc6\xf8\x65\x28\x1d\xa0\xb4\x66\x33\xc3\x25\xd5\x0a\x95\x78\x9c\x8f\xfe\xa4\x2a\xd8\x8f\x7e\x72\xe0\xfe\xa8\x7f\xf8\xb1\x2d\x85\xc0\x8e\x12\x74\x0d\x2f\x8c\xab\xd7\x7f\x7a\x1e\xd9\x84\x33\x39\xe8\xfd\x89\x5f\x96\x48\x08"), ["\x28\xe2\x81\x38\xfd\x83\x21\x45\xe9\xa9\xd6\xaa\x75\x37\x6d\x83\x77\xa8\x85\x12\xb3\xc0\x7f\x72\x41\x48\x21\xdc\xbd\xe9\x8c\x66"] = CTInfo($description="TrustAsia Log2025a", $operator="TrustAsia", $url="https://ct2025-a.trustasia.com/log2025a/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x70\xe5\xb1\xa4\x09\x79\x2b\x9d\xf8\xa3\xa0\xdf\x18\xef\x95\x5d\x03\x6c\x7b\xa1\x91\xa9\xb8\x80\x7d\xec\x5c\x02\x08\xe2\x6e\x2f\x7c\x32\x70\xbd\x96\x84\x5f\xa6\x62\xe9\x65\xb5\x7c\x90\x58\xba\x22\xd5\xf9\xf5\x69\x54\xb7\xa8\x94\x4e\x32\x09\xae\x26\x11\x4d"), ["\x28\x2c\x8b\xdd\x81\x0f\xf9\x09\x12\x0a\xce\x16\xd6\xe0\xec\x20\x1b\xea\x82\xa3\xa4\xaf\x19\xd9\xef\xfb\x59\xe8\x3f\xdc\x42\x68"] = CTInfo($description="TrustAsia Log2025b", $operator="TrustAsia", $url="https://ct2025-b.trustasia.com/log2025b/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xaa\xa0\x8b\xdb\x67\x14\x5d\x97\x89\x1d\x08\x8d\x06\xd7\xc1\x94\x8e\xb0\xfa\x4c\x46\xd5\x53\x08\x78\x2b\x04\x53\x6c\xf3\xde\xb1\xd1\x53\x40\xda\x90\x57\xe6\x1a\x9e\x3c\xc7\x03\xb8\xbd\x2f\xa9\xcf\xe8\x7b\x5e\xe1\x4b\x60\xe5\x38\x43\x60\x97\xc1\x5b\x2f\x65"), +["\x74\xdb\x9d\x58\xf7\xd4\x7e\x9d\xfd\x78\x7a\x16\x2a\x99\x1c\x18\xcf\x69\x8d\xa7\xc7\x29\x91\x8c\x9a\x18\xb0\x45\x0d\xba\x44\xbc"] = CTInfo($description="TrustAsia 'log2026a'", $operator="TrustAsia", $url="https://ct2026-a.trustasia.com/log2026a/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\xa7\x4e\x7a\xc9\xa6\x07\xf9\xff\x74\xec\x98\xcb\x49\xe1\x00\x24\xb3\x59\x2e\x83\xfd\xc0\x70\x35\x33\x4c\x63\xca\x74\x83\xc0\x3c\x5b\x53\x40\x7c\x31\x1f\x35\xa4\x5f\x0f\xe4\xee\x4f\x89\x17\xe8\x5b\x2e\xc5\xac\x00\x05\xc9\x76\x37\x45\x97\x03\x15\xff\x60\x59"), +["\x25\xb7\xef\xde\xa1\x13\x01\x93\xed\x93\x07\x97\x70\xaa\x32\x2a\x26\x62\x0d\xe3\x5a\xc8\xaa\x7c\x75\x19\x7d\xe0\xb1\xa9\xe0\x65"] = CTInfo($description="TrustAsia 'log2026b'", $operator="TrustAsia", $url="https://ct2026-b.trustasia.com/log2026b/", $maximum_merge_delay=86400, $key="\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x0f\x12\x8c\xa9\xe6\xe3\xec\x62\xee\xdf\x58\xc8\x50\xe6\x26\x70\x76\x10\xb7\x04\x39\xb3\xa7\xf8\x4c\x73\x3b\xc3\x38\x5a\x12\x00\x4c\xe0\xda\x0e\x16\x8a\x45\x32\x0a\x31\xaa\x22\xc7\x9d\x7d\x05\x53\xc7\x9e\x94\xea\x9b\x57\x46\xbf\x4f\xa4\x7e\xfb\xdf\xfa\x85"), }; diff --git a/scripts/base/protocols/ssl/mozilla-ca-list.zeek b/scripts/base/protocols/ssl/mozilla-ca-list.zeek index 1206908a10..e308f1fb75 100644 --- a/scripts/base/protocols/ssl/mozilla-ca-list.zeek +++ b/scripts/base/protocols/ssl/mozilla-ca-list.zeek @@ -1,6 +1,6 @@ # Don't edit! This file is automatically generated. -# Generated at: 2024-02-23 11:28:07 +0000 -# Generated from: NSS 3.98 +# Generated at: 2024-07-23 16:04:06 +0100 +# Generated from: NSS 3.102 # # The original source file comes with this licensing statement: # @@ -158,4 +158,5 @@ redef root_certs += { ["CN=CommScope Public Trust RSA Root-02,O=CommScope,C=US"] = "\x30\x82\x05\x6C\x30\x82\x03\x54\xA0\x03\x02\x01\x02\x02\x14\x54\x16\xBF\x3B\x7E\x39\x95\x71\x8D\xD1\xAA\x00\xA5\x86\x0D\x2B\x8F\x7A\x05\x4E\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0B\x05\x00\x30\x4E\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x12\x30\x10\x06\x03\x55\x04\x0A\x0C\x09\x43\x6F\x6D\x6D\x53\x63\x6F\x70\x65\x31\x2B\x30\x29\x06\x03\x55\x04\x03\x0C\x22\x43\x6F\x6D\x6D\x53\x63\x6F\x70\x65\x20\x50\x75\x62\x6C\x69\x63\x20\x54\x72\x75\x73\x74\x20\x52\x53\x41\x20\x52\x6F\x6F\x74\x2D\x30\x32\x30\x1E\x17\x0D\x32\x31\x30\x34\x32\x38\x31\x37\x31\x36\x34\x33\x5A\x17\x0D\x34\x36\x30\x34\x32\x38\x31\x37\x31\x36\x34\x32\x5A\x30\x4E\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x12\x30\x10\x06\x03\x55\x04\x0A\x0C\x09\x43\x6F\x6D\x6D\x53\x63\x6F\x70\x65\x31\x2B\x30\x29\x06\x03\x55\x04\x03\x0C\x22\x43\x6F\x6D\x6D\x53\x63\x6F\x70\x65\x20\x50\x75\x62\x6C\x69\x63\x20\x54\x72\x75\x73\x74\x20\x52\x53\x41\x20\x52\x6F\x6F\x74\x2D\x30\x32\x30\x82\x02\x22\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x82\x02\x0F\x00\x30\x82\x02\x0A\x02\x82\x02\x01\x00\xE1\xFA\x0E\xFB\x68\x00\x12\xC8\x4D\xD5\xAC\x22\xC4\x35\x01\x3B\xC5\x54\xE5\x59\x76\x63\xA5\x7F\xEB\xC1\xC4\x6A\x98\xBD\x32\x8D\x17\x80\xEB\x5D\xBA\xD1\x62\x3D\x25\x23\x19\x35\x14\xE9\x7F\x89\xA7\x1B\x62\x3C\xD6\x50\xE7\x34\x95\x03\x32\xB1\xB4\x93\x22\x3D\xA7\xE2\xB1\xED\xE6\x7B\x4E\x2E\x87\x9B\x0D\x33\x75\x0A\xDE\xAA\x35\xE7\x7E\xE5\x36\x98\xA2\xAE\x25\x9E\x95\xB3\x32\x96\xA4\x2B\x58\x1E\xEF\x3F\xFE\x62\x34\x48\x51\xD1\xB4\x8D\x42\xAD\x60\xDA\x49\x6A\x95\x70\xDD\xD2\x00\xE2\xCC\x57\x63\x02\x7B\x96\xDD\x49\x97\x5B\x92\x4E\x95\xD3\xF9\xCB\x29\x1F\x18\x4A\xF8\x01\x2A\xD2\x63\x09\x6E\x24\xE9\x89\xD2\xE5\xC7\x22\x4C\xDC\x73\x86\x47\x00\xAA\x0D\x88\x8E\xAE\x85\x7D\x4A\xE9\xBB\x33\x4F\x0E\x52\x70\x9D\x95\xE3\x7C\x6D\x96\x5B\x2D\x3D\x5F\xA1\x83\x46\x5D\xB6\xE3\x25\xB8\x7C\xA7\x19\x80\x1C\xEA\x65\x43\xDC\x91\x79\x36\x2C\x74\x7C\xF2\x67\x06\xC9\x89\xC9\xDB\xBF\xDA\x68\xBF\x23\xED\xDC\x6B\xAD\x28\x83\x79\x2F\xEC\x38\xA5\x0D\x37\x01\x67\x27\x9A\xE9\x33\xD9\x33\x5F\x37\xA1\xC5\xF0\xAB\x3D\xFA\x78\xB0\xE7\x2C\x9F\xF6\x3E\x9F\x60\xE0\xEF\x48\xE9\x90\x45\x1E\x05\x51\x78\x1A\x2C\x12\x2C\x5C\x28\xAC\x0D\xA2\x23\x9E\x34\x8F\x05\xE6\xA2\x33\xCE\x11\x77\x13\xD4\x0E\xA4\x1E\x42\x1F\x86\xCD\x70\xFE\xD9\x2E\x15\x3D\x1D\xBB\xB8\xF2\x53\x57\xDB\xCC\xC6\x74\x29\x9C\x18\xB3\x36\x75\x38\x2E\x0F\x54\xA1\xF8\x92\x1F\x89\x96\x4F\xBB\xD4\xEE\x9D\xE9\x3B\x36\x42\xB5\x0A\x3B\x2A\xD4\x64\x79\x36\x10\xE1\xF9\x91\x03\x2B\x7B\x20\x54\xCD\x0D\x19\x1A\xC8\x41\x32\x34\xD1\xB0\x99\xE1\x90\x1E\x01\x40\x36\xB5\xB7\xFA\xA9\xE5\x77\x75\xA4\x22\x81\x5D\xB0\x8B\xE4\x27\x12\x0F\x54\x88\xC6\xDB\x85\x74\xE6\xB7\xC0\xD7\xA6\x29\xFA\xDB\xDE\xF3\x93\x97\x27\x04\x55\x2F\x0A\x6F\x37\xC5\x3D\x13\xAF\x0A\x00\xA9\x2C\x8B\x1C\x81\x28\xD7\xEF\x86\x31\xA9\xAE\xF2\x6E\xB8\xCA\x6A\x2C\x54\x47\xD8\x2A\x88\x2E\xAF\xC1\x07\x10\x78\xAC\x11\xA2\x2F\x42\xF0\x37\xC5\xF2\xB8\x56\xDD\x0E\x62\x2D\xCE\x2D\x56\x7E\x55\xF2\xA7\x44\xF6\x2B\x32\xF4\x23\xA8\x47\xE8\xD4\x2A\x01\x78\xCF\x6A\xC3\x37\xA8\x9E\x65\xD2\x2C\xE5\xFA\xBA\x33\xC1\x06\x44\xF6\xE6\xCF\xA5\x0D\xA7\x66\x08\x34\x8A\x2C\xF3\x02\x03\x01\x00\x01\xA3\x42\x30\x40\x30\x0F\x06\x03\x55\x1D\x13\x01\x01\xFF\x04\x05\x30\x03\x01\x01\xFF\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x01\x06\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16\x04\x14\x47\xD0\xE7\xB1\x22\xFF\x9D\x2C\xF5\xD9\x57\x60\xB3\xB1\xB1\x70\x95\xEF\x61\x7A\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0B\x05\x00\x03\x82\x02\x01\x00\x86\x69\xB1\x4D\x2F\xE9\x9F\x4F\x22\x93\x68\x8E\xE4\x21\x99\xA3\xCE\x45\x53\x1B\x73\x44\x53\x00\x81\x61\xCD\x31\xE3\x08\xBA\x81\x28\x28\x7A\x92\xB9\xB6\xA8\xC8\x43\x9E\xC7\x13\x26\x4D\xC2\xD8\xE5\x55\x9C\x92\x5D\x50\xD8\xC2\x2B\xDB\xFE\xE6\xA8\x97\xCF\x52\x3A\x24\xC3\x65\x64\x5C\x47\x31\xA3\x65\x35\x13\xC3\x93\xB9\xF7\xF9\x51\x97\xBB\xA4\xF0\x62\x87\xC5\xD6\x06\xD3\x97\x83\x20\xA9\x7E\xBB\xB6\x21\xC2\xA5\x0D\x84\x00\xE1\xF2\x27\x10\x83\xBA\xDD\x03\x81\xD5\xDD\x68\xC3\x66\x10\xC8\xD1\x76\xB4\xB3\x6F\x29\x9E\x00\xF9\xC2\x29\xF5\xB1\x93\x19\x52\x69\x1A\x2C\x4C\xA0\x8B\xE0\x15\x9A\x31\x2F\xD3\x88\x95\x59\x6E\xE5\xC4\xB3\x50\xC8\x14\x08\x4A\x9B\x8B\x13\x83\xB1\xA4\x72\xB2\x3B\x76\x33\x41\xDC\xDC\xAA\xA6\x07\x6F\x1D\x24\x12\x9F\xC8\x76\xBD\x2F\xD9\x8E\xF4\x2C\xEE\xB7\xD2\x38\x10\x24\x36\x51\x2F\xE3\x5C\x5D\x81\x21\xA7\xDA\xBB\x4E\xFF\xE6\x07\xA8\xFE\xB9\x0D\x27\x6C\xBB\x70\x5A\x55\x7A\x13\xE9\xF1\x2A\x49\x69\xC7\x5F\x87\x57\x4C\x43\x79\x6D\x3A\x65\xE9\x30\x5C\x41\xEE\xEB\x77\xA5\x73\x12\x88\xE8\xBF\x7D\xAE\xE5\xC4\xA8\x1F\x0D\x8E\x1C\x6D\x50\x02\x4F\x26\x18\x43\xDE\x8F\x55\x85\xB1\x0B\x37\x05\x60\xC9\x55\x39\x12\x04\xA1\x2A\xCF\x71\x16\x9F\x36\x51\x49\xBF\x70\x3B\x9E\x67\x9C\xFB\x7B\x79\xC9\x39\x1C\x78\xAC\x77\x91\x54\x9A\xB8\x75\x0A\x81\x52\x97\xE3\x66\x61\x6B\xED\x3E\x38\x1E\x96\x61\x55\xE1\x91\x54\x8C\xED\x8C\x24\x1F\x81\xC9\x10\x9A\x73\x99\x2B\x16\x4E\x72\x00\x3F\x54\x1B\xF8\x8D\xBA\x8B\xE7\x14\xD6\xB6\x45\x4F\x60\xEC\x96\xAE\xC3\x2F\x02\x4E\x5D\x9D\x96\x49\x72\x00\xB2\xAB\x75\x5C\x0F\x68\x5B\x1D\x65\xC2\x5F\x33\x0F\x1E\x0F\xF0\x3B\x86\xF5\xB0\x4E\xBB\x9C\xF7\xEA\x25\x05\xDC\xAD\xA2\x9B\x4B\x17\x01\xBE\x42\xDF\x35\x21\x1D\xAD\xAB\xAE\xF4\xBF\xAE\x1F\x1B\xD3\xE2\x3B\xFC\xB3\x72\x73\x1C\x9B\x28\x90\x89\x13\x3D\x1D\xC1\x00\x47\x09\x96\x9A\x38\x1B\xDD\xB1\xCF\x0D\xC2\xB4\x44\xF3\x96\x95\xCE\x32\x3A\x8F\x34\x9C\xE0\x17\xC7\x5E\xCE\xAE\x0D\xDB\x87\x38\xE5\x3F\x5B\xFD\x9B\x19\xE1\x31\x41\x7A\x70\xAA\x23\x6B\x01\xE1\x45\x4C\xCD\x94\xCE\x3B\x9E\x2D\xE7\x88\x02\x22\xF4\x6E\xE8\xC8\xEC\xD6\x3C\xF3\xB9\xB2\xD7\x77\x7A\xAC\x7B", ["CN=Telekom Security TLS ECC Root 2020,O=Deutsche Telekom Security GmbH,C=DE"] = "\x30\x82\x02\x42\x30\x82\x01\xC9\xA0\x03\x02\x01\x02\x02\x10\x36\x3A\x96\x8C\xC9\x5C\xB2\x58\xCD\xD0\x01\x5D\xC5\xE5\x57\x00\x30\x0A\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x03\x30\x63\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x27\x30\x25\x06\x03\x55\x04\x0A\x0C\x1E\x44\x65\x75\x74\x73\x63\x68\x65\x20\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x47\x6D\x62\x48\x31\x2B\x30\x29\x06\x03\x55\x04\x03\x0C\x22\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x54\x4C\x53\x20\x45\x43\x43\x20\x52\x6F\x6F\x74\x20\x32\x30\x32\x30\x30\x1E\x17\x0D\x32\x30\x30\x38\x32\x35\x30\x37\x34\x38\x32\x30\x5A\x17\x0D\x34\x35\x30\x38\x32\x35\x32\x33\x35\x39\x35\x39\x5A\x30\x63\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x27\x30\x25\x06\x03\x55\x04\x0A\x0C\x1E\x44\x65\x75\x74\x73\x63\x68\x65\x20\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x47\x6D\x62\x48\x31\x2B\x30\x29\x06\x03\x55\x04\x03\x0C\x22\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x54\x4C\x53\x20\x45\x43\x43\x20\x52\x6F\x6F\x74\x20\x32\x30\x32\x30\x30\x76\x30\x10\x06\x07\x2A\x86\x48\xCE\x3D\x02\x01\x06\x05\x2B\x81\x04\x00\x22\x03\x62\x00\x04\xCE\xBF\xFE\x57\xA8\xBF\xD5\xAA\xF7\x10\x9A\xCD\xBC\xD1\x11\xA2\xBD\x67\x42\xCC\x90\xEB\x15\x18\x90\xD9\xA2\xCD\x0C\x2A\x25\xEB\x3E\x4F\xCE\xB5\xD2\x8F\x0F\xF3\x35\xDA\x43\x8B\x02\x80\xBE\x6F\x51\x24\x1D\x0F\x6B\x2B\xCA\x9F\xC2\x6F\x50\x32\xE5\x37\x20\xB6\x20\xFF\x88\x0D\x0F\x6D\x49\xBB\xDB\x06\xA4\x87\x90\x92\x94\xF4\x09\xD0\xCF\x7F\xC8\x80\x0B\xC1\x97\xB3\xBB\x35\x27\xC9\xC2\x1B\xA3\x42\x30\x40\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16\x04\x14\xE3\x72\xCC\x6E\x95\x99\x47\xB1\xE6\xB3\x61\x4C\xD1\xCB\xAB\xE3\xBA\xCD\xDE\x9F\x30\x0F\x06\x03\x55\x1D\x13\x01\x01\xFF\x04\x05\x30\x03\x01\x01\xFF\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x01\x06\x30\x0A\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x03\x03\x67\x00\x30\x64\x02\x30\x75\x52\x8B\xB7\xA4\x10\x4F\xAE\x4A\x10\x8B\xB2\x84\x5B\x42\xE1\xE6\x2A\x36\x02\xDA\xA0\x6E\x19\x3F\x25\xBF\xDA\x59\x32\x8E\xE4\xFB\x90\xDC\x93\x64\xCE\xAD\xB4\x41\x47\x60\xE2\xCF\xA7\xCB\x1E\x02\x30\x37\x41\x8C\x66\xDF\x41\x6B\xD6\x83\x00\x41\xFD\x2F\x5A\xF7\x50\xB4\x67\xD1\x2C\xA8\x71\xD7\x43\xCA\x9C\x27\x24\x91\x83\x48\x0D\xCF\xCD\xF7\x54\x81\xAF\xEC\x7F\xE4\x67\xDB\xB8\x90\xEE\xDD\x25", ["CN=Telekom Security TLS RSA Root 2023,O=Deutsche Telekom Security GmbH,C=DE"] = "\x30\x82\x05\xB3\x30\x82\x03\x9B\xA0\x03\x02\x01\x02\x02\x10\x21\x9C\x54\x2D\xE8\xF6\xEC\x71\x77\xFA\x4E\xE8\xC3\x70\x57\x97\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0C\x05\x00\x30\x63\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x27\x30\x25\x06\x03\x55\x04\x0A\x0C\x1E\x44\x65\x75\x74\x73\x63\x68\x65\x20\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x47\x6D\x62\x48\x31\x2B\x30\x29\x06\x03\x55\x04\x03\x0C\x22\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x54\x4C\x53\x20\x52\x53\x41\x20\x52\x6F\x6F\x74\x20\x32\x30\x32\x33\x30\x1E\x17\x0D\x32\x33\x30\x33\x32\x38\x31\x32\x31\x36\x34\x35\x5A\x17\x0D\x34\x38\x30\x33\x32\x37\x32\x33\x35\x39\x35\x39\x5A\x30\x63\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x44\x45\x31\x27\x30\x25\x06\x03\x55\x04\x0A\x0C\x1E\x44\x65\x75\x74\x73\x63\x68\x65\x20\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x47\x6D\x62\x48\x31\x2B\x30\x29\x06\x03\x55\x04\x03\x0C\x22\x54\x65\x6C\x65\x6B\x6F\x6D\x20\x53\x65\x63\x75\x72\x69\x74\x79\x20\x54\x4C\x53\x20\x52\x53\x41\x20\x52\x6F\x6F\x74\x20\x32\x30\x32\x33\x30\x82\x02\x22\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x82\x02\x0F\x00\x30\x82\x02\x0A\x02\x82\x02\x01\x00\xED\x35\xA1\x81\x80\xF3\xCB\x4A\x69\x5B\xC2\xFB\x51\x83\xAE\x26\xFD\xE1\x6E\xF3\x81\x12\x7D\x71\x40\xFF\x87\x75\x42\x29\x21\xED\x81\x52\x2C\xDF\x12\xC1\x19\x84\x89\xC1\xBD\xC5\x28\xD5\xD5\x4B\x6C\x44\xD6\x4C\xDB\x07\x96\x4A\x55\x7A\xCA\x36\x82\x04\x36\xA8\xA5\xFC\x27\xF6\x49\xF1\xD5\x72\x9E\x91\xF9\x23\xD6\x70\x7B\xBB\xF5\x9B\xC1\xEC\x93\xCF\x19\xEA\x65\x7E\x88\x70\xA0\x73\xFC\xF6\xFF\xB5\x56\x62\xE1\x73\x6A\x34\x98\x3E\x82\xB8\xAC\x95\x53\xF4\x01\xA0\x27\x07\x72\xA3\x00\x53\xA0\xE4\xB2\xAB\x83\x38\x57\x33\x25\x94\x9F\xBE\x48\x1D\x98\xE1\xA3\xBA\x9E\x5C\xCD\x04\x71\x51\x7D\x75\x78\xAB\xF3\x59\xAA\xC4\xE0\x60\xBE\x8F\x83\x52\xB8\x75\x1A\x41\x35\xED\xBC\xF3\x3A\x63\xE9\xA9\x14\x45\xD7\xE6\x52\xD1\x6E\xD2\xDE\xBC\xE3\xF5\x0B\x3B\xE6\xE0\xC4\xBD\x43\x64\x13\xA6\xCE\xF4\x98\x37\x6C\x8A\x95\xA8\x97\xC8\x47\x0F\xF0\x5E\x10\x8B\xE7\x1D\x1C\xFE\xB1\x3B\xA0\x05\x33\x68\x05\x41\x82\xC1\x03\x2B\x01\xC8\xE7\x8F\x4D\xAB\xE8\xB5\xF6\xCD\x6B\x44\xB5\xE7\xDD\x8B\xEC\xEA\x25\xB4\x00\x22\x57\x4D\xB0\xB1\xB2\x31\xC1\x16\xCE\xFF\xFD\x14\x84\xB7\x47\xFA\xB2\xF1\x70\xDE\xDB\x8B\x6C\x36\x58\xA4\x7C\xB3\x11\xD1\xC3\x77\x7F\x5F\xB6\x25\xE0\x0D\xC5\xD2\xB3\xF9\xB8\xB8\x77\xDB\x37\x71\x71\x47\xE3\x60\x18\x4F\x24\xB6\x75\x37\x78\xB9\xA3\x62\xAF\xBD\xC9\x72\x8E\x2F\xCC\xBB\xAE\xDB\xE4\x15\x52\x19\x07\x33\xFB\x6A\xB7\x2D\x4B\x90\x28\x82\x73\xFE\x18\x8B\x35\x8D\xDB\xA7\x04\x6A\xBE\xEA\xC1\x4D\x36\x3B\x16\x36\x91\x32\xEF\xB6\x40\x89\x91\x43\xE0\xF2\xA2\xAB\x04\x2E\xE6\xF2\x4C\x0E\x16\x34\x20\xAC\x87\xC1\x2D\x7E\xC9\x66\x47\x17\x14\x11\xA4\xF3\xF7\xA1\x24\x89\xAB\xD8\x1A\xC8\xA1\x5C\xB1\xA3\xF7\x8C\x6D\xC8\x01\xC9\x4F\xC9\xEC\xC4\xFC\xAC\x51\x33\xD1\xC8\x83\xD1\xC9\x9F\x1D\xD4\x47\x34\x29\x3E\xCB\xB0\x0E\xFA\x83\x0B\x28\x58\xE5\x29\xDC\x3F\x7C\xA8\x9F\xC9\xB6\x0A\xBB\xA6\xE8\x46\x16\x0F\x96\xE5\x7B\xE4\x6A\x7A\x48\x6D\x76\x98\x05\xA5\xDC\x6D\x1E\x42\x1E\x42\xDA\x1A\xE0\x52\xF7\xB5\x83\xC0\x1A\x7B\x78\x35\x2C\x38\xF5\x1F\xFD\x49\xA3\x2E\xD2\x59\x63\xBF\x80\xB0\x8C\x93\x73\xCB\x35\xA6\x99\x95\x22\x61\x65\x03\x60\xFB\x2F\x93\x4B\xFA\x9A\x9C\x80\x3B\x02\x03\x01\x00\x01\xA3\x63\x30\x61\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x01\x06\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16\x04\x14\xB6\xA7\x97\x82\x3D\x74\x85\x9B\xF7\x3C\x9F\x93\x9A\x95\x79\x75\x52\x8C\x6D\x47\x30\x0F\x06\x03\x55\x1D\x13\x01\x01\xFF\x04\x05\x30\x03\x01\x01\xFF\x30\x1F\x06\x03\x55\x1D\x23\x04\x18\x30\x16\x80\x14\xB6\xA7\x97\x82\x3D\x74\x85\x9B\xF7\x3C\x9F\x93\x9A\x95\x79\x75\x52\x8C\x6D\x47\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0C\x05\x00\x03\x82\x02\x01\x00\xA8\xCC\x61\xA6\xBE\x75\x9E\x15\x50\xA4\x6B\xFB\xA8\x70\x45\x7C\xBA\x7E\xB1\x5A\xFC\x5B\x23\xFA\x0A\x77\xF8\x98\x71\x82\x0C\x6D\xE0\x5E\x46\xAA\x93\xF4\x1E\xA0\xC3\xE1\x93\xDB\x4B\xAD\xB2\xA6\x5D\xAB\xB0\xD4\x62\xCB\x5E\xBB\x66\xF5\x2D\xEE\x97\x40\x3C\x62\xEB\x5E\xD6\x14\xD6\x8C\xE2\x96\x8B\x41\x69\x93\x35\xE6\xB9\x99\x6B\x62\xB4\xA1\x17\x66\x34\xA6\x6B\x63\xC6\xB9\x4E\xF2\x22\xE9\x58\x0D\x56\x41\xD1\xFA\x0C\x4A\xF0\x33\xCD\x3B\xBB\x6D\x21\x3A\xAE\x8E\x72\xB5\xC3\x4A\xFB\xE9\x7D\xE5\xB1\x9B\x86\xEE\xE2\xE0\x7D\xB4\xF7\x32\xFD\x22\x84\xF1\x85\xC9\x37\x79\xE9\xB5\x3F\xBF\x5C\xE4\x74\xB2\x8F\x11\x62\x00\xDD\x18\x66\xA1\xD9\x7B\x23\x5F\xF1\x8E\xD5\x67\xE8\x54\xDA\x5B\x3A\x6B\x36\x6F\xF9\x81\xB1\x33\x47\x33\x77\x40\xF9\x52\xAA\xDD\xD4\x83\xCF\x85\x78\x99\x9A\x93\xB9\x73\x67\x42\x46\x11\x21\xEA\xFE\x0A\xA9\x1B\x1A\x65\x69\xB3\x8F\xAE\x16\xB6\xF6\x4B\x56\xB2\x2D\xF9\xA5\xC8\xEC\x3B\x62\xA3\xED\x6B\xD0\x4E\xD5\x40\x09\xA4\x1F\x98\xD7\x3A\xA5\x92\x59\x20\xE4\xB0\x7D\xCD\x5B\x73\x68\xBD\x6D\xC4\xA2\x13\x0E\x67\x19\xB8\x8D\x42\x7E\x6C\x0C\x9A\x6E\xA0\x24\x2D\xD5\x45\x1B\xDC\xC4\x02\x14\xFE\x85\x5B\x65\x97\xCA\x4E\x90\x50\x08\x7A\x42\x35\xF9\xEA\xC2\x66\xD4\xF8\x01\xAE\x1E\xB4\xBE\xC3\xA8\xEF\xFE\x76\x9A\xA2\xA6\x1F\x46\xF6\x84\xED\xFC\xDB\xCE\xC4\x02\xCE\x77\x48\x2C\x8C\xB2\xEC\xC3\x00\xA3\xEC\x2C\x55\x18\xC1\x7E\x19\xEE\xE1\x2F\xF2\xAD\x83\x9B\x9E\xAB\x19\xDF\xC6\x8A\x2F\x8C\x77\xE5\xB7\x05\xEC\x3B\xC1\xEC\xBE\x86\xB3\x86\xBC\xC0\xF7\xDC\xE7\xEA\x5B\xAE\xB2\xCC\xB5\x35\x86\x4B\xD0\xE2\x3F\xB6\xD8\xF8\x0E\x00\xEE\x5D\xE3\xF7\x8D\x58\xFF\xCF\x8B\x37\xE9\x63\x5F\x6E\xF7\x09\x71\x36\xC2\x12\x5D\x57\xF2\xC8\xB4\xCD\xF3\xEE\x02\xDF\x11\xDC\x6A\xB9\x57\x84\x1D\x59\x4D\x8C\xCE\xC8\x0E\x23\xC2\xB7\x26\x9A\x10\x14\x71\xFE\x93\xB2\x8A\xB8\x80\xF0\x0E\x10\x9E\xD3\xA8\x50\x0C\x37\x82\x2F\xEA\xE0\x8A\x9D\xE1\x2C\x39\xFF\xB5\xB4\x73\x00\xE4\xF7\x48\xA6\x73\xAC\xBF\xB2\xDE\x77\x04\x87\xB4\xA3\xCD\x9B\x35\x24\x37\xFA\x90\x93\x13\x81\x42\xC6\x98\x26\x75\x37\x66\x41\x10\xAC\xBB\xF5\x94\xE3\xC2\x31\x2B\xAD\xE7\x23\x56\xCC\x35\x25\x92\xB3\x50", + ["CN=FIRMAPROFESIONAL CA ROOT-A WEB,organizationIdentifier=VATES-A62634068,O=Firmaprofesional SA,C=ES"] = "\x30\x82\x02\x7A\x30\x82\x02\x00\xA0\x03\x02\x01\x02\x02\x10\x31\x97\x21\xED\xAF\x89\x42\x7F\x35\x41\x87\xA1\x67\x56\x4C\x6D\x30\x0A\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x03\x30\x6E\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x45\x53\x31\x1C\x30\x1A\x06\x03\x55\x04\x0A\x0C\x13\x46\x69\x72\x6D\x61\x70\x72\x6F\x66\x65\x73\x69\x6F\x6E\x61\x6C\x20\x53\x41\x31\x18\x30\x16\x06\x03\x55\x04\x61\x0C\x0F\x56\x41\x54\x45\x53\x2D\x41\x36\x32\x36\x33\x34\x30\x36\x38\x31\x27\x30\x25\x06\x03\x55\x04\x03\x0C\x1E\x46\x49\x52\x4D\x41\x50\x52\x4F\x46\x45\x53\x49\x4F\x4E\x41\x4C\x20\x43\x41\x20\x52\x4F\x4F\x54\x2D\x41\x20\x57\x45\x42\x30\x1E\x17\x0D\x32\x32\x30\x34\x30\x36\x30\x39\x30\x31\x33\x36\x5A\x17\x0D\x34\x37\x30\x33\x33\x31\x30\x39\x30\x31\x33\x36\x5A\x30\x6E\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x45\x53\x31\x1C\x30\x1A\x06\x03\x55\x04\x0A\x0C\x13\x46\x69\x72\x6D\x61\x70\x72\x6F\x66\x65\x73\x69\x6F\x6E\x61\x6C\x20\x53\x41\x31\x18\x30\x16\x06\x03\x55\x04\x61\x0C\x0F\x56\x41\x54\x45\x53\x2D\x41\x36\x32\x36\x33\x34\x30\x36\x38\x31\x27\x30\x25\x06\x03\x55\x04\x03\x0C\x1E\x46\x49\x52\x4D\x41\x50\x52\x4F\x46\x45\x53\x49\x4F\x4E\x41\x4C\x20\x43\x41\x20\x52\x4F\x4F\x54\x2D\x41\x20\x57\x45\x42\x30\x76\x30\x10\x06\x07\x2A\x86\x48\xCE\x3D\x02\x01\x06\x05\x2B\x81\x04\x00\x22\x03\x62\x00\x04\x47\x53\xEA\x2C\x11\xA4\x77\xC7\x2A\xEA\xF3\xD6\x5F\x7B\xD3\x04\x91\x5C\xFA\x88\xC6\x22\xB9\x83\x10\x62\x77\x84\x33\x2D\xE9\x03\x88\xD4\xE0\x33\xF7\xED\x77\x2C\x4A\x60\xEA\xE4\x6F\xAD\x6D\xB4\xF8\x4C\x8A\xA4\xE4\x1F\xCA\xEA\x4F\x38\x4A\x2E\x82\x73\x2B\xC7\x66\x9B\x0A\x8C\x40\x9C\x7C\x8A\xF6\xF2\x39\x60\xB2\xDE\xCB\xEC\xB8\xE4\x6F\xEA\x9B\x5D\xB7\x53\x90\x18\x32\x55\xC5\x20\xB7\x94\xA3\x63\x30\x61\x30\x0F\x06\x03\x55\x1D\x13\x01\x01\xFF\x04\x05\x30\x03\x01\x01\xFF\x30\x1F\x06\x03\x55\x1D\x23\x04\x18\x30\x16\x80\x14\x93\xE1\x43\x63\x5C\x3C\x9D\xD6\x27\xF3\x52\xEC\x17\xB2\xA9\xAF\x2C\xF7\x76\xF8\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16\x04\x14\x93\xE1\x43\x63\x5C\x3C\x9D\xD6\x27\xF3\x52\xEC\x17\xB2\xA9\xAF\x2C\xF7\x76\xF8\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x01\x06\x30\x0A\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x03\x03\x68\x00\x30\x65\x02\x30\x1D\x7C\xA4\x7B\xC3\x89\x75\x33\xE1\x3B\xA9\x45\xBF\x46\xE9\xE9\xA1\xDD\xC9\x22\x16\xB7\x47\x11\x0B\xD8\x9A\xBA\xF1\xC8\x0B\x70\x50\x53\x02\x91\x70\x85\x59\xA9\x1E\xA4\xE6\xEA\x23\x31\xA0\x00\x02\x31\x00\xFD\xE2\xF8\xB3\xAF\x16\xB9\x1E\x73\xC4\x96\xE3\xC1\x30\x19\xD8\x7E\xE6\xC3\x97\xDE\x1C\x4F\xB8\x89\x2F\x33\xEB\x48\x0F\x19\xF7\x87\x46\x5D\x26\x90\xA5\x85\xC5\xB9\x7A\x94\x3E\x87\xA8\xBD\x00", }; From e960c29acb9d81da69ced871ab5054c3e2152d3b Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 23 Jul 2024 15:18:21 -0700 Subject: [PATCH 10/93] fix & regression test for GH-3839 (spurious warnings for "when" constructs) --- src/Func.cc | 2 +- testing/btest/language/when.zeek | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Func.cc b/src/Func.cc index 87783a30a9..85d184295d 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -434,7 +434,7 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const { // Warn if the function returns something, but we returned from // the function without an explicit return, or without a value. - else if ( GetType()->Yield() && GetType()->Yield()->Tag() != TYPE_VOID && + else if ( GetType()->Yield() && GetType()->Yield()->Tag() != TYPE_VOID && ! GetType()->ExpressionlessReturnOkay() && (flow != FLOW_RETURN /* we fell off the end */ || ! result /* explicit return with no result */) && ! f->HasDelayed() ) reporter->Warning("non-void function returning without a value: %s", Name()); diff --git a/testing/btest/language/when.zeek b/testing/btest/language/when.zeek index d0d07b44fa..d8a447e8fd 100644 --- a/testing/btest/language/when.zeek +++ b/testing/btest/language/when.zeek @@ -26,6 +26,13 @@ event zeek_init() when [h] ( local hname3 = lookup_addr(h) ) {} timeout to + 2sec {} + # The following used to generate a spurious warning, so it's here + # as a regression test. + when ( local res = lookup_addr(127.0.0.1) ) + { + return; + } + print "done"; } From ff7466df6e54a548fa58303993cad8fcf9728a1b Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Tue, 23 Jul 2024 15:31:59 -0700 Subject: [PATCH 11/93] minor optimization of boolean comparisons --- src/script_opt/Expr.cc | 26 ++++++++++++++++++++++---- src/script_opt/Stmt.cc | 6 ++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/script_opt/Expr.cc b/src/script_opt/Expr.cc index 1ad24c5277..353604f1a7 100644 --- a/src/script_opt/Expr.cc +++ b/src/script_opt/Expr.cc @@ -1238,10 +1238,28 @@ ExprPtr EqExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { if ( IsHasElementsTest() ) return BuildHasElementsTest()->Reduce(c, red_stmt); - if ( GetType()->Tag() == TYPE_BOOL && same_singletons(op1, op2) ) { - bool t = Tag() == EXPR_EQ; - auto res = with_location_of(make_intrusive(val_mgr->Bool(t)), this); - return res->Reduce(c, red_stmt); + if ( GetType()->Tag() == TYPE_BOOL ) { + if ( same_singletons(op1, op2) ) { + bool t = Tag() == EXPR_EQ; + auto res = with_location_of(make_intrusive(val_mgr->Bool(t)), this); + return res->Reduce(c, red_stmt); + } + + if ( op1->GetType()->Tag() == TYPE_BOOL ) { + if ( op1->Tag() == EXPR_CONST ) + std::swap(op1, op2); + + if ( op2->Tag() == EXPR_CONST ) { + bool t = Tag() == EXPR_EQ; + if ( op2->AsConstExpr()->Value()->IsZero() ) + t = ! t; + if ( t ) + return op1->Reduce(c, red_stmt); + + auto res = with_location_of(make_intrusive(op1), this); + return res->Reduce(c, red_stmt); + } + } } return BinaryExpr::Reduce(c, red_stmt); diff --git a/src/script_opt/Stmt.cc b/src/script_opt/Stmt.cc index 618d52ebda..8ef72c60b4 100644 --- a/src/script_opt/Stmt.cc +++ b/src/script_opt/Stmt.cc @@ -245,6 +245,12 @@ StmtPtr IfStmt::DoReduce(Reducer* c) { red_e_stmt = cond_red_stmt; } + // Check again for negation given above reductions/replacements. + if ( e->Tag() == EXPR_NOT ) { + std::swap(s1, s2); + e = e->GetOp1(); + } + StmtPtr sl; if ( e->IsConst() ) { From 146cf99ff62d729705c155b44199a674911ade09 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Tue, 23 Jul 2024 16:58:52 -0700 Subject: [PATCH 12/93] Bump zeek-testing-cluster to reflect deprecation of prometheus.zeek --- testing/external/commit-hash.zeek-testing-cluster | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/external/commit-hash.zeek-testing-cluster b/testing/external/commit-hash.zeek-testing-cluster index 5d84d38106..b8df5d15d0 100644 --- a/testing/external/commit-hash.zeek-testing-cluster +++ b/testing/external/commit-hash.zeek-testing-cluster @@ -1 +1 @@ -ded009fb7a0cdee6f36d5b40a6394788b760fa06 +9f875d86000602661fbfc9bb471d1c598917ebc9 From 8526914e4ce82cad4e4fc181ddd72b805e5afe05 Mon Sep 17 00:00:00 2001 From: zeek-bot Date: Wed, 24 Jul 2024 00:19:23 +0000 Subject: [PATCH 13/93] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index f65820ff0f..8937245582 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit f65820ff0faf2887799fe691a443b5db39eeed54 +Subproject commit 893724558253c3c12b87eee031e4c68eb983868b From 2844d54f67a17282664c718c4d9633211164ea99 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 24 Jul 2024 12:44:46 -0700 Subject: [PATCH 14/93] Fix handling of zero-length SMB2 error responses --- src/analyzer/protocol/smb/smb2-protocol.pac | 2 +- .../out | 13 +++++++++++++ .../Traces/smb/smb2-zero-byte-error-ioctl.pcap | Bin 0 -> 29460 bytes .../smb/smb2-zero-byte-error-ioctl.test | 16 ++++++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.smb.smb2-zero-byte-error-ioctl/out create mode 100644 testing/btest/Traces/smb/smb2-zero-byte-error-ioctl.pcap create mode 100644 testing/btest/scripts/base/protocols/smb/smb2-zero-byte-error-ioctl.test diff --git a/src/analyzer/protocol/smb/smb2-protocol.pac b/src/analyzer/protocol/smb/smb2-protocol.pac index b922c62f2b..5e7bf673b1 100644 --- a/src/analyzer/protocol/smb/smb2-protocol.pac +++ b/src/analyzer/protocol/smb/smb2-protocol.pac @@ -413,7 +413,7 @@ type SMB2_error_response(header: SMB2_Header) = record { byte_count : uint32; # This is implemented incorrectly and is disabled for now. #error_data : SMB2_error_data(header, byte_count); - stuff : bytestring &restofdata &transient; + stuff : bytestring &length=byte_count &transient; } &byteorder = littleendian; type SMB2_logoff_request(header: SMB2_Header) = record { diff --git a/testing/btest/Baseline/scripts.base.protocols.smb.smb2-zero-byte-error-ioctl/out b/testing/btest/Baseline/scripts.base.protocols.smb.smb2-zero-byte-error-ioctl/out new file mode 100644 index 0000000000..f803db64f2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.smb.smb2-zero-byte-error-ioctl/out @@ -0,0 +1,13 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +smb2_close_request, [credit_charge=1, status=0, command=6, credits=256, flags=0, message_id=8, process_id=65279, tree_id=3905704575, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00] +smb2_close_response, [credit_charge=1, status=0, command=6, credits=256, flags=1, message_id=8, process_id=65279, tree_id=3905704575, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00], [alloc_size=0, eof=0, times=[modified=0.0, modified_raw=116444736000000000, accessed=0.0, accessed_raw=116444736000000000, created=0.0, created_raw=116444736000000000, changed=0.0, changed_raw=116444736000000000], attrs=[read_only=F, hidden=F, system=F, directory=F, archive=F, normal=F, temporary=F, sparse_file=F, reparse_point=F, compressed=F, offline=F, not_content_indexed=F, encrypted=F, integrity_stream=F, no_scrub_data=F]] +smb2_close_request, [credit_charge=1, status=0, command=6, credits=256, flags=0, message_id=21, process_id=65279, tree_id=900627714, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00] +smb2_close_response, [credit_charge=1, status=0, command=6, credits=256, flags=1, message_id=21, process_id=65279, tree_id=900627714, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00], [alloc_size=0, eof=0, times=[modified=0.0, modified_raw=116444736000000000, accessed=0.0, accessed_raw=116444736000000000, created=0.0, created_raw=116444736000000000, changed=0.0, changed_raw=116444736000000000], attrs=[read_only=F, hidden=F, system=F, directory=F, archive=F, normal=F, temporary=F, sparse_file=F, reparse_point=F, compressed=F, offline=F, not_content_indexed=F, encrypted=F, integrity_stream=F, no_scrub_data=F]] +smb2_close_request, [credit_charge=1, status=0, command=6, credits=256, flags=4, message_id=25, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00] +smb2_close_response, [credit_charge=1, status=0, command=6, credits=768, flags=5, message_id=25, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00], [alloc_size=0, eof=0, times=[modified=0.0, modified_raw=116444736000000000, accessed=0.0, accessed_raw=116444736000000000, created=0.0, created_raw=116444736000000000, changed=0.0, changed_raw=116444736000000000], attrs=[read_only=F, hidden=F, system=F, directory=F, archive=F, normal=F, temporary=F, sparse_file=F, reparse_point=F, compressed=F, offline=F, not_content_indexed=F, encrypted=F, integrity_stream=F, no_scrub_data=F]] +smb2_close_request, [credit_charge=1, status=0, command=6, credits=256, flags=4, message_id=28, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00] +smb2_close_response, [credit_charge=1, status=0, command=6, credits=768, flags=5, message_id=28, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00], [alloc_size=0, eof=0, times=[modified=0.0, modified_raw=116444736000000000, accessed=0.0, accessed_raw=116444736000000000, created=0.0, created_raw=116444736000000000, changed=0.0, changed_raw=116444736000000000], attrs=[read_only=F, hidden=F, system=F, directory=F, archive=F, normal=F, temporary=F, sparse_file=F, reparse_point=F, compressed=F, offline=F, not_content_indexed=F, encrypted=F, integrity_stream=F, no_scrub_data=F]] +smb2_close_request, [credit_charge=1, status=0, command=6, credits=256, flags=4, message_id=31, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00] +smb2_close_response, [credit_charge=1, status=0, command=6, credits=768, flags=5, message_id=31, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00], [alloc_size=0, eof=0, times=[modified=0.0, modified_raw=116444736000000000, accessed=0.0, accessed_raw=116444736000000000, created=0.0, created_raw=116444736000000000, changed=0.0, changed_raw=116444736000000000], attrs=[read_only=F, hidden=F, system=F, directory=F, archive=F, normal=F, temporary=F, sparse_file=F, reparse_point=F, compressed=F, offline=F, not_content_indexed=F, encrypted=F, integrity_stream=F, no_scrub_data=F]] +smb2_close_request, [credit_charge=1, status=0, command=6, credits=256, flags=4, message_id=34, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00] +smb2_close_response, [credit_charge=1, status=0, command=6, credits=768, flags=5, message_id=34, process_id=65279, tree_id=1248644238, session_id=66137014, signature=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00], [alloc_size=0, eof=0, times=[modified=0.0, modified_raw=116444736000000000, accessed=0.0, accessed_raw=116444736000000000, created=0.0, created_raw=116444736000000000, changed=0.0, changed_raw=116444736000000000], attrs=[read_only=F, hidden=F, system=F, directory=F, archive=F, normal=F, temporary=F, sparse_file=F, reparse_point=F, compressed=F, offline=F, not_content_indexed=F, encrypted=F, integrity_stream=F, no_scrub_data=F]] diff --git a/testing/btest/Traces/smb/smb2-zero-byte-error-ioctl.pcap b/testing/btest/Traces/smb/smb2-zero-byte-error-ioctl.pcap new file mode 100644 index 0000000000000000000000000000000000000000..3ffab0867ad80a375de55e06141ffe9dc358dc1e GIT binary patch literal 29460 zcmcg#31AdOx~`ri7$QPo5wn0A6xk6JBO4AC6%bfNj%ZNP$B2Oh0>qF7WI;ee5H|#( z5Q7{dmw4i8!X@IeW}~v8=)=VW6b}+qRNQraD)JC`-`7<&(^E5(%rGxgSW{g+-SyRf ze1BC}^~9ue&Pf_Bgc#hjQ)>(5X_ewd7tt?!+?3H-1*z`a$4$zaoSQXi!lkL{ox61I zmg=5rmzSqqKDJBN=o%Suf8dcu8E`CYt=pTr?v9xF)1JJtJH&p;eAOC*VE`cO@nb&H8L1@qm4n#2}X4HHFo#&$FIBIA#uzEnQ(vF=WdD-tNNW z#H3F;LxV~tV#&5m{Uxl}5Q+YZ#DZ`3Z{3Ry+4{?0=dZuvcMbcI-}&p$DU%0yXDCzi z#H54Ev`jP3_Lpe{VUcK~vsZ5Lz!ZWxz(#JRw?b_rvEYXy-U+$h&49a=?_!OKZJIXu z6m9GN2eh5O?j`zL^BuZvW&ho<|Cqw&)~TAtvj0P~KJW1Lgc)c1Y~s{W+sAzvVcUHS z?EWV0{_#ntjy~_;!*KFu%esi{KG)h&TK&NJ)Czgi^JcHz&!Uf&9sl@xe&=s@CvOfu zu^}?v%&pCR_zqxRK;Aq*QQ}G7eC{S*Xx?11J|g`|*)9OyorTFYXC3>i)E_ZmC-@6( zLqB+)A|lbphCRK(vjE4;0XCYYe5{j~n@)_BnzNdZ@nZCn7^2_l%)xyovH3*H>w&DE zK5Zf6;3DA~GAwn_;MBCvS9TFDT%Ovcb6T4B@cQdv1NPDM+1t=p?Xv-W4U8kQuVcOX zK&OzdUiJ8eu_R*!Docpm~fQlU4OtoeCX`BVFqEc}M!hY)uUXw;}vBP$`nwdT6Co@<(> zHEEQDdc0NC-Q`MpqGOtSO@}t^^CwOjnVmCcTz*dW$Z`22Z|Q$S`jy>#^eV{9$(o!q za@^SbiIZ}uC)4g%L0@NL_eE~-AmQgHyms#myL9x~#A)}wF~H~-1B{^!gpr|aPXApA zjLxVtn>@5qWz5)AY{U%k5cWu^Nm%)kX%BJ4-+$>*GAU4T`jkEsylgKLY@eTvulrut zf9KV!GGF*}yQ8D~ci2_N(IOt%BY`jc(D{qNCcSC2a9=gOCHuiXOglRb(PN$P&P@O~tS6#Mu}aTVr_oyC=+ zo9Ka($K7yF2KbB2u^WVj<_HdoZy(+HH{`8Hf|GD+sYd^l` zrN5XyL0y}6?E;-g8n@f^v~*`&I5 zxEf1Yt=qTPb&Pip88&EeW@d&Bd2UhhDAkC!Xk=BK-wZX%Z~EotoiBR*(u@U&H@SAa zY2qIX7WY8BIgWU9;$6gI84C_|FFSq^4o-h0MzIowy8iWs3eQ;7nN1Aq4)-`a-h3Gp zBgHyVI>3u@yTq{CX^-5 z%DOo_;^%DFilqrt@UI8TbBjtw{q5WP*EimG+o zf8^e{vm5@o&_<~5tUA7nw*`w+S7f2(Y_vKCIZL&CmPizZ$J*WRosd!grmg$;t?=49 zz~@8Endcp^%`NjF23g;iNjty>qlRW3y4`1MXAHVC1{irUz?j!S7}HcZATQp#ufj7N zb!O8ZE{w9hFb;3L%ZNeJ9w{}}ghO6? z7Fk=FYXnS#S}44{y+$x ze!n6Aa8iqpe%|ukjONGsCl+~w?9I#V=a<8`wBB+}$Kw6GyDk#eMc%ro8IN`wVa`ay zJ89Y&55J=!(HKZ}1!jlAXNgJBTBtN^%i1xg?|)}b`ez4jXqETn#ZR<|=VPR}rsv*- ze-C@@KfI6rX2yYYXZqrR8IKY3$J6f?Ci%zXGEZrBaWlmHWAEG}{SH2tgIJL7ivxR9 zN9o%K7gu;Tpw1kC@wj^eF&3-|ijiU+Yk9(pF{xX58HW$Io}%u;i_TsojobcKBC8d+A#pu(~=T zB$G!VVr7UMM0-J5Odq@WO`nei@Fm@yXLB;q;LA>Mat=B9cAl3n)8S`@J|El0?jwd9>pG!1DJR zmCq>o>e;^K$%0W)rf0>4IADKG-Q16U_rZDQ0DGq^d;9hb?6tn)IkmZuv@T3Obo#rd ze)hi4ryD2#9*hD596u)>wDe#y*U1i_xJTjT9;POzoan5 z`uU2ZQV-C<4EXvSG_uUpgYI*=v9KzGrOgMaFSX%4;YfH^zCT6xI^EhIYBBpw&LB#k4#B@M`{{V)8rQQ(W?G+uhAq zA4wFQk_X%^;{o-<-nNyu+GAAKdljDl#X05x-X3*Nw0S$&;O$oM_G|F=r#aV1J;7&Z zD&B53^`yYU*3*^fNiaR}*@lT_U;9XYB#0)qet3>pdt2>o^*tDSju=ret{`W`cr&qz0gg>oc_8tw>+Pm{${Au4fIk({RHRqj2K|di~^%Zd^0#4Ip#GG zMqgz%a{A_vD?AsW&TMkpYN@lX10%FYGWssp`KEC0TrV&>r9LdJSP)%N1v`xb?R_wT&3q>)R_bLKF3{P z^Zg}%zL)2hR+sE1-v^^PwfC3$I~F~gqrb1{{(iOE?5|aB*xdU(tNW?TQ2h-jKDAd8P|5`1 zvTd!;HBsNOU~VE@_{a4cS+=xmoRhgkTV&|7Fcqcl7t2hMi>1g(B1gUJgDJP2SUSH; z#X8MIynB?5EBRi4o;$JBPe;753qO!p%JZpchxbgyipgjkr3$yblp1U?G!?T(c`ZMA zWhQ!ej~Io|%TVu)9u(MXNjc(D`~!QD+uNTwuoG==#@`+A)kx!S$?n?RN3l0|=-02N zO54Lv7lQAY=8|nD#v3uf*ck(iJu$#|I|_^%@f93U&8h0J#|I6BQ6=5Xp7YcuReDyT z&TNh&Vv!KN5K}g%_>UvXuP~1M{E%0UQt4M>xHG0OL@F?B63A5F+>p;-Oy=BBh$@_= z&mKl*Voc0yQt7G2F|!#H#b);;_J2WGlEuhZw^@wEaIdOlDeXK)V^ z`$*q$_O-aFudf08nCYHu^W$ZMAN#xs1e(nlKjyIyifYFq$9`e`KerXQd9@8(Z z^lU?&Il#}KlYYMGl;P*n9`N(KuJB@%NenT`>E|?;j;Tosm442o=bICD7NlRhbYSPP zGu#in+~|v&=wky!$9mSfGjUCCaSPs9?<*(|IYAki=x6UdK4UqYiH_k!>&X(y8(e|h@xwiExp*U70Ha9jH+?ZHez3^6Yq*B1)TXfJ4W$I80) zf~MMh8fEb5HSp=U{e05K%cnBMr;vL=;p!pUy`aj{tUpt!yHB*FdHuRoW=4=~mS8?*iv1B|LDFlt0?`*7sg)j$}|y`bN9s*HFqXrZ(R zc)4hkDM#qNAiZ|WF{?gaa*xCGt7-750fvJC-8)lq?ge2k8L$^L?e_E*=`G&g@NZ#V z+;8ms4Qwj-en+sqpw5?9*0mS(C!4qYO``r?B7T3fY-DM5=??OC)>~3f^jYv0Pv9ct zUQoDt(rc}zo(d=!63f2!k^FG(1yMhGFQ|#y3(A|EHF+}5tDqf1H^KIT`a?I7a=LU! zZSL~($mv6Pa!}76b#Quc3^0a7fl(t4Jrj-`!x{*KzfWS~Si2b*O;KkypVN35eRb0_ z@KyPnUHcssWe;$=;0IF z@1ymlOFhSxeer$jwG-dI&mbiN`@0zZ?T9+FxrSr4bx*hZ`x~Rb*}A_Ah6nWbuwh^C zzK`ywE<^PfneBIM&U9XttJ?4tfialZ#3RdieOW{?7y<_* z3P8@f*is_DrvAv!L?s*fd91tdxzUVuV!!)7>T$ts{;_VwpwjAx?e*$Q2K&W2zHI9E z4k5=f1s1j*!-;ii6h|e!$IWxppVkF&Z@PBGp(R&s?(^{O!?!N^_Crp;kSMm${xb*g{(JWfoA=imy#KzmdeJz}$u8U{ z^$XoD#n`+QjchaZtMS9tZ#cXk03e+-?|F`TCI6Y^uW#frKiLn?dt@ok>-QKD5UQkJ z%y{5|ej=T>EE-pv``Gi02M4qK{15u!oXEr&6$6aCC@^Zo!I9y}k>5ZV`fVlp>uz9t z106D(@jx6@@nDaCJW%#PJlOD&DTi2Z`YRf?Q*%{DvyO6^YQt9q#sgkMk7%hbqJNt4 z03$d~^D5_oLt!h9Q~h*OgTc&$y-R!sK#tL4y%UjB9NoJhVMLP*x$!$PTr+| zo&26<^E=a@-zzh~@1Mx;xp-iqKftG#gWvG$&~x%|^%xDmsXxtcI?MWBryn?R@y?-7 z?QHhc>HY6@wN)E*PCf{Fh?w6$f!{xp-v>(k{Aqb`eh-TQ#%)nx)QAJc;mDEIKp1?F zn~D5B0E~-JXEw*+Q18Gmmi7R@7uR~_SWe$Wqaojc=X{qbnlYF&F8>tBZ(fs#JjlLK z&dE*xqym_^YQ~b|6%$M6x|w|vAG}5;>W)_xs8iJ8s2eLiLr`Zn=iOE>_xi!HcZKQ;&bx`txppc_ z9;b-b(3;DBzg({;b4?=DZ~xM_CO42Jl>Qe^gLeAtLyXst6uQm}cv z7!)~2ADIP?uID)a!BDSHtO(7~vtod8b`%&j;sdpoinv~f94#9Nqe|I}F>^jJR-w*p zj`N{@qoC{oj_$n9v`6UQC@{t|)#sPmugtx8A*ygU(P-ydte?!3W zF2Snx;MD>0Y9Thu)cpA|+5(M+{Eb4m{qJe_4Ilcq2%$=SonJ}W%rR#$WQ=rNd*ncE z?&|j7%<1?4=x3wHf{$x=#Q*GwkeI5Hq->Fj5B=)sW2KbFSv&nC3kr3p^CgV3qqXYq!IG+Skly2r<(=$Bu8tJHxBnmsXdzv!5Y;hYrg10Uh5${>J3Yd@Wl^O<$XW zzD63SmSAjOoyRz}?*Z9Y#9`%YY}<^555@qaBnk}tO^3PR$g!k>Ff_GjkKwoC{aDb5 z+4LQ2ue*r8Q)2A*uFfm1USiKVKU3TX?;od4AeH%ktj*DFuu{0(zXR8j*CnrgQgXxc z{nqmFucuzTcE6?Ty2K@ZiE)9+{jWiILr948uirS2kYYcl`u>It;t_uH z;p8ma;vUl7$X+hi6B`=iZAo5R_?M0Mvj2sx225aS$1!|3+lR--v3;g+V?uOu1{(^! zFu5`X_CFIou1y3Ve|`6e*N<1y2ZGNV?vDY+>?km5#Jh*Xkz;-XVSGMPknM=>`q9D*9gAS9AlmO0$aReciS*=yz#_K!6FE^S?>ox=v^{+wc>G-(1B~@iVAP0rUXgxWw;V4v5JnYv z$;9}ZG&1sMA!QH5-+2XIIaWz~gnkw}UxGGB{M9i?K`7qIn&zF8518+GpM@?6vtO4A zt3`Gc@$|wlakMN(I0eONH^$Qp%xjovzYj)NdOD-dY|dw0sqP2tcpC2?PuF3sXIT#8 z>GId4{b0Mb@I~;+QvXj1=^~u7@n{=zxb}-So;Lky5SL*^+Sec3oror$R-m15?aO#N z2G{HPcBpwcd?#qKJByF$y?tL7!V`7UM>O6DWT!vEs^0hRCq7d$(VzYW zf9iu{W^+Ck>hJ$9%c;#>zlibqE#JD@YWh_0_LW|kCiGym;njw|fwNn>{gFg*3pTPKNB1xIp7bYhzyxu#{y-0ptuiPp6 zIs+Kd5fJ3jUIj%ST|TSQ^8)J3W?Z(`xaZk%d9Ht4Ucaccdil$Y%ddWg4$3vEr|E;J z&1 >out +# @TEST-EXEC: ! test -f analyzer.log +# @TEST-EXEC: btest-diff out + +@load base/protocols/smb + +event smb2_close_request(c: connection, hdr: SMB2::Header, file_id: SMB2::GUID) +{ + print "smb2_close_request", hdr; +} + +event smb2_close_response(c: connection, hdr: SMB2::Header, response: SMB2::CloseResponse) +{ + print "smb2_close_response", hdr, response; +} From 73fd12a76e4c3523400e54a9ef27c094250e94fc Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 24 Jul 2024 12:52:36 -0700 Subject: [PATCH 15/93] Update 7.0 NEWS with blurb about multi-PDU parsing causing increased load [nomail] [skip ci] --- NEWS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index c0bcac3a48..ab80cd160c 100644 --- a/NEWS +++ b/NEWS @@ -113,7 +113,8 @@ New Functionality environment variable configures the addition. - SMB2 packets containing multiple PDUs now correctly parse all of the headers, - instead of just the first one and ignoring the rest. + instead of just the first one and ignoring the rest. This may cause increased + CPU load on SMB2-heavy networks. - The new built-in function ``lookup_connection_analyzer_id()`` retrieves the numeric identifier of an analyzer associated with a connection. This enables From c4907c3f77a91971a4917755dbc28308401d0ee5 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 24 Jul 2024 12:55:10 -0700 Subject: [PATCH 16/93] Update binpac submodule to better format output code [nomail] --- auxil/binpac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/binpac b/auxil/binpac index a5c8f19fb4..6e494ed5b3 160000 --- a/auxil/binpac +++ b/auxil/binpac @@ -1 +1 @@ -Subproject commit a5c8f19fb49c60171622536fa6d369fa168f19e0 +Subproject commit 6e494ed5b3d0a121cd1e1dd18b18e40d7e937675 From 9cb618c71819911b6c3aadf0a5b1448751a6ec1d Mon Sep 17 00:00:00 2001 From: Fupeng Zhao Date: Sun, 30 Jun 2024 15:59:13 +0800 Subject: [PATCH 17/93] Add support for parsing the "caching_sha2_password" auth plugin --- .../protocol/mysql/mysql-analyzer.pac | 6 +- .../protocol/mysql/mysql-protocol.pac | 97 +++++++++++++++++- .../mysql.log | 23 +++++ .../out | 39 +++++++ .../Traces/mysql/caching_sha2_password.trace | Bin 0 -> 7561 bytes .../mysql/caching_sha2_password.test | 35 +++++++ 6 files changed, 192 insertions(+), 8 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/mysql.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/out create mode 100644 testing/btest/Traces/mysql/caching_sha2_password.trace create mode 100644 testing/btest/scripts/base/protocols/mysql/caching_sha2_password.test diff --git a/src/analyzer/protocol/mysql/mysql-analyzer.pac b/src/analyzer/protocol/mysql/mysql-analyzer.pac index 31addd2518..ebc964a793 100644 --- a/src/analyzer/protocol/mysql/mysql-analyzer.pac +++ b/src/analyzer/protocol/mysql/mysql-analyzer.pac @@ -23,7 +23,7 @@ refine flow MySQL_Flow += { connection()->zeek_analyzer()->AnalyzerConfirmation(); // If the client requested SSL and didn't provide credentials, switch to SSL - if ( ${msg.version} == 10 && ( ${msg.v10_response.cap_flags} & CLIENT_SSL ) && ${msg.v10_response.credentials}->empty() ) + if ( ${msg.version} == 10 && ( ${msg.v10_response.cap_flags} & CLIENT_SSL )) { connection()->zeek_analyzer()->StartTLS(); return true; @@ -31,10 +31,10 @@ refine flow MySQL_Flow += { if ( mysql_handshake ) { - if ( ${msg.version} == 10 && ${msg.v10_response.credentials}->size() > 0 ) + if ( ${msg.version} == 10 ) zeek::BifEvent::enqueue_mysql_handshake(connection()->zeek_analyzer(), connection()->zeek_analyzer()->Conn(), - zeek::make_intrusive(c_str(${msg.v10_response.credentials[0].username}))); + zeek::make_intrusive(c_str(${msg.v10_response.plain.credentials.username}))); if ( ${msg.version} == 9 ) zeek::BifEvent::enqueue_mysql_handshake(connection()->zeek_analyzer(), connection()->zeek_analyzer()->Conn(), diff --git a/src/analyzer/protocol/mysql/mysql-protocol.pac b/src/analyzer/protocol/mysql/mysql-protocol.pac index e8415e3de0..ffc0c1fbc5 100644 --- a/src/analyzer/protocol/mysql/mysql-protocol.pac +++ b/src/analyzer/protocol/mysql/mysql-protocol.pac @@ -96,6 +96,11 @@ type LengthEncodedStringArg(first_byte: uint8) = record { }; %} +%code{ + const char* PLUGIN_CACHING_SHA2_PASSWORD = "caching_sha2_password"; +%} + +extern type PLUGIN_CACHING_SHA2_PASSWORD; extern type to_int; # Enums @@ -138,6 +143,9 @@ enum command_consts { enum state { CONNECTION_PHASE = 0, COMMAND_PHASE = 1, + SHA2_AUTH_PHASE = 2, + PUB_KEY_PHASE = 3, + SHA2_AUTH_RESP_PHASE = 4, }; enum Expected { @@ -158,12 +166,23 @@ enum EOFType { }; enum Client_Capabilities { + CLIENT_CONNECT_WITH_DB = 0x00000008, CLIENT_SSL = 0x00000800, + CLIENT_PLUGIN_AUTH = 0x00080000, + CLIENT_CONNECT_ATTRS = 0x00100000, # Expects an OK (instead of EOF) after the resultset rows of a Text Resultset. CLIENT_DEPRECATE_EOF = 0x01000000, + CLIENT_ZSTD_COMPRESSION_ALGORITHM = 0x04000000, +}; + +enum SHA2_Atuh_State { + REQUEST_PUBLIC_KEY = 2, + FAST_AUTH_SUCCESS = 3, + PERFORM_FULL_AUTHENTICATION = 4, }; type NUL_String = RE/[^\0]*\0/; +type EmptyOrNUL_String = RE/([^\0]*\0)?/; # MySQL PDU @@ -195,6 +214,9 @@ type Server_Message(seq_id: uint8, pkt_len: uint32) = case is_initial of { type Client_Message(state: int) = case state of { CONNECTION_PHASE -> connection_phase: Handshake_Response_Packet; COMMAND_PHASE -> command_phase : Command_Request_Packet; + SHA2_AUTH_PHASE -> sha2_auth_phase : SHA2_Auth_Packet; + PUB_KEY_PHASE -> pub_key_phase : Public_Key_Packet; + SHA2_AUTH_RESP_PHASE -> sha2_auth_resp_phase : SHA2_Auth_Response_Packet; }; # Handshake Request @@ -220,7 +242,12 @@ type Handshake_v10 = record { status_flags : uint16; capability_flags_2 : uint16; auth_plugin_data_len : uint8; - auth_plugin_name : NUL_String; + reserved : padding[10]; + auth_plugin_data_part_2: bytestring &length=13; + have_plugin : case ( ( capability_flags_2 << 4 ) & CLIENT_PLUGIN_AUTH ) of { + CLIENT_PLUGIN_AUTH -> auth_plugin_name: NUL_String; + 0x0 -> none : empty; + }; }; type Handshake_v9 = record { @@ -240,7 +267,40 @@ type Handshake_Response_Packet = case $context.connection.get_version() of { type Handshake_Credentials_v10 = record { username : NUL_String; - password : bytestring &restofdata; + password : LengthEncodedString; +}; + +type Connection_Attribute = record { + name : LengthEncodedString; + value : LengthEncodedString; +}; + +type Handshake_Connection_Attributes = record { + length : uint8; + attrs : Connection_Attribute[] &until($input.length() == 0); +} &length = length+1; + +type Handshake_Plain_v10(cap_flags: uint32) = record { + credentials: Handshake_Credentials_v10; + have_db : case ( cap_flags & CLIENT_CONNECT_WITH_DB ) of { + CLIENT_CONNECT_WITH_DB -> database: NUL_String; + 0x0 -> none_1 : empty; + }; + have_plugin : case ( cap_flags & CLIENT_PLUGIN_AUTH ) of { + CLIENT_PLUGIN_AUTH -> auth_plugin_name: EmptyOrNUL_String; + 0x0 -> none_2 : empty; + }; + have_attrs : case ( cap_flags & CLIENT_CONNECT_ATTRS ) of { + CLIENT_CONNECT_ATTRS -> conn_attrs: Handshake_Connection_Attributes; + 0x0 -> none_3 : empty; + }; + have_zstd : case ( cap_flags & CLIENT_ZSTD_COMPRESSION_ALGORITHM ) of { + CLIENT_ZSTD_COMPRESSION_ALGORITHM -> zstd_compression_level: uint8; + 0x0 -> none_4 : empty; + }; +} &let { + update_state: bool = $context.connection.update_state(SHA2_AUTH_PHASE) + &if(( cap_flags & CLIENT_PLUGIN_AUTH ) && auth_plugin_name==PLUGIN_CACHING_SHA2_PASSWORD); }; type Handshake_Response_Packet_v10 = record { @@ -248,7 +308,10 @@ type Handshake_Response_Packet_v10 = record { max_pkt_size: uint32; char_set : uint8; pad : padding[23]; - credentials : Handshake_Credentials_v10[] &until($input.length() == 0); + use_ssl : case ( cap_flags & CLIENT_SSL ) of { + CLIENT_SSL -> none : empty; + default -> plain: Handshake_Plain_v10(cap_flags); + }; } &let { deprecate_eof: bool = $context.connection.set_deprecate_eof(cap_flags & CLIENT_DEPRECATE_EOF); }; @@ -258,13 +321,37 @@ type Handshake_Response_Packet_v9 = record { max_pkt_size : uint24le; username : NUL_String; auth_response: NUL_String; - have_db : case ( cap_flags & 0x8 ) of { - 0x8 -> database: NUL_String; + have_db : case ( cap_flags & CLIENT_CONNECT_WITH_DB ) of { + CLIENT_CONNECT_WITH_DB -> database: NUL_String; 0x0 -> none : empty; }; password : bytestring &restofdata; }; +# SHA2 Auth + +type SHA2_Auth_Packet = record { + state: bytestring &restofdata; +} &let { + update_state_1: bool = $context.connection.update_state(COMMAND_PHASE) + &if(state[0] == FAST_AUTH_SUCCESS); + update_state_2: bool = $context.connection.update_state(PUB_KEY_PHASE) + &if(state[1] == REQUEST_PUBLIC_KEY); +}; + +type Public_Key_Packet = record { + pad : uint8; + pub_key: bytestring &restofdata; +} &let { + update_state: bool = $context.connection.update_state(SHA2_AUTH_RESP_PHASE); +}; + +type SHA2_Auth_Response_Packet = record { + data: bytestring &restofdata; +} &let { + update_state: bool = $context.connection.update_state(COMMAND_PHASE); +}; + # Command Request type Command_Request_Packet = record { diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/mysql.log b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/mysql.log new file mode 100644 index 0000000000..53fb4143f2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/mysql.log @@ -0,0 +1,23 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path mysql +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cmd arg success rows response +#types time string addr port addr port string string bool count string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 56494 127.0.0.1 3306 login root F - Got an error reading communication packets +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 login root T 0 - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 query \x00\x01show databases T 0 - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 query \x00\x01show tables T 0 - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 field_list t T 0 - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 query \x00\x01select @@version_comment limit 1 T 0 - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 quit (empty) - - - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 login root T 0 - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 query \x00\x01show databases T 0 - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 query \x00\x01show tables T 0 - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 field_list t T 0 - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 query \x00\x01select @@version_comment limit 1 T 0 - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 quit (empty) - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/out b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/out new file mode 100644 index 0000000000..6dd3801eba --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/out @@ -0,0 +1,39 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +mysql handshake, root +mysql error, 1158, Got an error reading communication packets +mysql handshake, root +mysql ok, 0 +mysql request, 3, \x00\x01show databases +mysql result row, [information_schema] +mysql result row, [mysql] +mysql result row, [performance_schema] +mysql result row, [sys] +mysql result row, [test] +mysql ok, 0 +mysql request, 3, \x00\x01show tables +mysql result row, [t] +mysql ok, 0 +mysql request, 4, t\x00 +mysql ok, 0 +mysql request, 3, \x00\x01select @@version_comment limit 1 +mysql result row, [MySQL Community Server - GPL] +mysql ok, 0 +mysql request, 1, +mysql handshake, root +mysql ok, 0 +mysql request, 3, \x00\x01show databases +mysql result row, [information_schema] +mysql result row, [mysql] +mysql result row, [performance_schema] +mysql result row, [sys] +mysql result row, [test] +mysql ok, 0 +mysql request, 3, \x00\x01show tables +mysql result row, [t] +mysql ok, 0 +mysql request, 4, t\x00 +mysql ok, 0 +mysql request, 3, \x00\x01select @@version_comment limit 1 +mysql result row, [MySQL Community Server - GPL] +mysql ok, 0 +mysql request, 1, diff --git a/testing/btest/Traces/mysql/caching_sha2_password.trace b/testing/btest/Traces/mysql/caching_sha2_password.trace new file mode 100644 index 0000000000000000000000000000000000000000..184ed83254a02fee3dd5614307debefdc7faa93b GIT binary patch literal 7561 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 H5!L?z3qPk) literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/mysql/caching_sha2_password.test b/testing/btest/scripts/base/protocols/mysql/caching_sha2_password.test new file mode 100644 index 0000000000..ba5c8a90b0 --- /dev/null +++ b/testing/btest/scripts/base/protocols/mysql/caching_sha2_password.test @@ -0,0 +1,35 @@ +# @TEST-EXEC: zeek -b -C -r $TRACES/mysql/caching_sha2_password.trace %INPUT >out +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff mysql.log + +@load base/protocols/mysql + +event mysql_ok(c: connection, affected_rows: count) + { + print "mysql ok", affected_rows; + } + +event mysql_eof(c: connection, is_intermediate: bool) + { + print "mysql eof", is_intermediate; + } + +event mysql_result_row(c: connection, row: string_vec) + { + print "mysql result row", row; + } + +event mysql_error(c: connection, code: count, msg: string) + { + print "mysql error", code, msg; + } + +event mysql_command_request(c: connection, command: count, arg: string) + { + print "mysql request", command, arg; + } + +event mysql_handshake(c: connection, username: string) + { + print "mysql handshake", username; + } From e8bdf149f22099a9a9cc84faa1964c23ea795fd3 Mon Sep 17 00:00:00 2001 From: Fupeng Zhao Date: Sun, 30 Jun 2024 21:52:31 +0800 Subject: [PATCH 18/93] Add support for "auth switch" and "query attrs" Also fix the issue where Resultset could not correctly distinguish between EOF_Packet and OK_Packet. --- .../protocol/mysql/mysql-analyzer.pac | 4 +- .../protocol/mysql/mysql-protocol.pac | 164 ++++++++++++++---- .../mysql.log | 16 ++ .../out | 14 ++ .../mysql.log | 12 +- .../out | 12 +- .../mysql.log | 14 ++ .../out | 12 ++ ...ing_sha2_password-after-auth-switch.pcapng | Bin 0 -> 4412 bytes testing/btest/Traces/mysql/query-attr.pcapng | Bin 0 -> 7696 bytes ...ching_sha2_password-after-auth-switch.test | 35 ++++ .../base/protocols/mysql/query-attr.test | 35 ++++ 12 files changed, 272 insertions(+), 46 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password-after-auth-switch/mysql.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password-after-auth-switch/out create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.query-attr/mysql.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.query-attr/out create mode 100644 testing/btest/Traces/mysql/caching_sha2_password-after-auth-switch.pcapng create mode 100644 testing/btest/Traces/mysql/query-attr.pcapng create mode 100644 testing/btest/scripts/base/protocols/mysql/caching_sha2_password-after-auth-switch.test create mode 100644 testing/btest/scripts/base/protocols/mysql/query-attr.test diff --git a/src/analyzer/protocol/mysql/mysql-analyzer.pac b/src/analyzer/protocol/mysql/mysql-analyzer.pac index ebc964a793..5f6782c4ff 100644 --- a/src/analyzer/protocol/mysql/mysql-analyzer.pac +++ b/src/analyzer/protocol/mysql/mysql-analyzer.pac @@ -83,8 +83,8 @@ refine flow MySQL_Flow += { function proc_resultset(msg: Resultset): bool %{ - if ( ${msg.is_eof} ) - return true; // Raised through proc_eof_packet() + if ( ${msg.is_eof_or_ok} ) + return true; // Raised through proc_eof_packet() or proc_ok_packet() if ( ! mysql_result_row ) return true; diff --git a/src/analyzer/protocol/mysql/mysql-protocol.pac b/src/analyzer/protocol/mysql/mysql-protocol.pac index ffc0c1fbc5..d482d23b10 100644 --- a/src/analyzer/protocol/mysql/mysql-protocol.pac +++ b/src/analyzer/protocol/mysql/mysql-protocol.pac @@ -96,11 +96,6 @@ type LengthEncodedStringArg(first_byte: uint8) = record { }; %} -%code{ - const char* PLUGIN_CACHING_SHA2_PASSWORD = "caching_sha2_password"; -%} - -extern type PLUGIN_CACHING_SHA2_PASSWORD; extern type to_int; # Enums @@ -141,11 +136,12 @@ enum command_consts { }; enum state { - CONNECTION_PHASE = 0, - COMMAND_PHASE = 1, - SHA2_AUTH_PHASE = 2, - PUB_KEY_PHASE = 3, - SHA2_AUTH_RESP_PHASE = 4, + CONNECTION_PHASE = 0, + COMMAND_PHASE = 1, + SHA2_AUTH_PHASE = 2, + PUB_KEY_PHASE = 3, + SHA2_AUTH_RESP_PHASE = 4, + AUTH_SWITCH_RESP_PHASE = 5, }; enum Expected { @@ -173,9 +169,10 @@ enum Client_Capabilities { # Expects an OK (instead of EOF) after the resultset rows of a Text Resultset. CLIENT_DEPRECATE_EOF = 0x01000000, CLIENT_ZSTD_COMPRESSION_ALGORITHM = 0x04000000, + CLIENT_QUERY_ATTRIBUTES = 0x08000000, }; -enum SHA2_Atuh_State { +enum SHA2_Auth_State { REQUEST_PUBLIC_KEY = 2, FAST_AUTH_SUCCESS = 3, PERFORM_FULL_AUTHENTICATION = 4, @@ -217,6 +214,7 @@ type Client_Message(state: int) = case state of { SHA2_AUTH_PHASE -> sha2_auth_phase : SHA2_Auth_Packet; PUB_KEY_PHASE -> pub_key_phase : Public_Key_Packet; SHA2_AUTH_RESP_PHASE -> sha2_auth_resp_phase : SHA2_Auth_Response_Packet; + AUTH_SWITCH_RESP_PHASE -> auth_switch_resp_phase : Auth_Switch_Response_Packet; }; # Handshake Request @@ -244,10 +242,14 @@ type Handshake_v10 = record { auth_plugin_data_len : uint8; reserved : padding[10]; auth_plugin_data_part_2: bytestring &length=13; - have_plugin : case ( ( capability_flags_2 << 4 ) & CLIENT_PLUGIN_AUTH ) of { - CLIENT_PLUGIN_AUTH -> auth_plugin_name: NUL_String; + have_plugin : case ( ( capability_flags_2 << 16 ) & CLIENT_PLUGIN_AUTH ) of { + CLIENT_PLUGIN_AUTH -> auth_plugin: NUL_String; 0x0 -> none : empty; }; +} &let { + update_auth_plugin: bool = $context.connection.set_auth_plugin(auth_plugin) + &if( ( capability_flags_2 << 16 ) & CLIENT_PLUGIN_AUTH ); + server_query_attrs: bool = $context.connection.set_server_query_attrs(( capability_flags_2 << 16 ) & CLIENT_QUERY_ATTRIBUTES); }; type Handshake_v9 = record { @@ -287,7 +289,7 @@ type Handshake_Plain_v10(cap_flags: uint32) = record { 0x0 -> none_1 : empty; }; have_plugin : case ( cap_flags & CLIENT_PLUGIN_AUTH ) of { - CLIENT_PLUGIN_AUTH -> auth_plugin_name: EmptyOrNUL_String; + CLIENT_PLUGIN_AUTH -> auth_plugin: EmptyOrNUL_String; 0x0 -> none_2 : empty; }; have_attrs : case ( cap_flags & CLIENT_CONNECT_ATTRS ) of { @@ -299,8 +301,10 @@ type Handshake_Plain_v10(cap_flags: uint32) = record { 0x0 -> none_4 : empty; }; } &let { - update_state: bool = $context.connection.update_state(SHA2_AUTH_PHASE) - &if(( cap_flags & CLIENT_PLUGIN_AUTH ) && auth_plugin_name==PLUGIN_CACHING_SHA2_PASSWORD); + update_auth_plugin: bool = $context.connection.set_auth_plugin(auth_plugin) + &if( cap_flags & CLIENT_PLUGIN_AUTH ); + update_state: bool = $context.connection.update_state_from_auth() + &if( cap_flags & CLIENT_PLUGIN_AUTH ); }; type Handshake_Response_Packet_v10 = record { @@ -314,6 +318,7 @@ type Handshake_Response_Packet_v10 = record { }; } &let { deprecate_eof: bool = $context.connection.set_deprecate_eof(cap_flags & CLIENT_DEPRECATE_EOF); + client_query_attrs: bool = $context.connection.set_client_query_attrs(cap_flags & CLIENT_QUERY_ATTRIBUTES); }; type Handshake_Response_Packet_v9 = record { @@ -352,10 +357,43 @@ type SHA2_Auth_Response_Packet = record { update_state: bool = $context.connection.update_state(COMMAND_PHASE); }; +# Auth Switch + +type Auth_Switch_Response_Packet = record { + data : bytestring &restofdata; +} &let { + update_state: bool = $context.connection.update_state_from_auth(); +}; + # Command Request +type AttributeTypeAndName = record { + type: uint16; + name: LengthEncodedString; +}; + +type Attributes(count: uint8) = record { + unused : uint8; + send_types_to_server: uint8; # Always 1. + names : AttributeTypeAndName[count]; + values : LengthEncodedString[count]; +}; + +type Query_Attributes = record { + count : uint8; + set_coun : uint8; + have_attr : case ( count > 0 ) of { + true -> attrs: Attributes(count); + false -> none: empty; + }; +}; + type Command_Request_Packet = record { command: uint8; + attrs : case ( command == COM_QUERY && $context.connection.get_client_query_attrs() && $context.connection.get_server_query_attrs() ) of { + true -> query_attrs: Query_Attributes; + false -> none: empty; + }; arg : bytestring &restofdata; } &let { update_expectation: bool = $context.connection.set_next_expected_from_command(command); @@ -413,22 +451,22 @@ type ColumnDefinition = record { }; # Only used to indicate the end of a result, no intermediate eofs here. -type EOFOrOK = case $context.connection.get_deprecate_eof() of { +# MySQL spec says "You must check whether the packet length is less than 9 +# to make sure that it is a EOF_Packet packet" so the value of 13 here +# comes from that 9, plus a 4-byte header. +type EOFOrOK(pkt_len: uint32) = case ( $context.connection.get_deprecate_eof() || pkt_len > 13 ) of { false -> eof: EOF_Packet(EOF_END); true -> ok: OK_Packet; }; type ColumnDefinitionOrEOF(pkt_len: uint32) = record { marker : uint8; - def_or_eof: case is_eof of { - true -> eof: EOFOrOK; + def_or_eof: case is_eof_or_ok of { + true -> eof: EOFOrOK(pkt_len); false -> def: ColumnDefinition41(marker); - } &requires(is_eof); + } &requires(is_eof_or_ok); } &let { - # MySQL spec says "You must check whether the packet length is less than 9 - # to make sure that it is a EOF_Packet packet" so the value of 13 here - # comes from that 9, plus a 4-byte header. - is_eof: bool = (marker == 0xfe && pkt_len < 13); + is_eof_or_ok: bool = (marker == 0xfe); }; @@ -442,17 +480,14 @@ type EOFIfLegacyThenResultset(pkt_len: uint32) = case $context.connection.get_de type Resultset(pkt_len: uint32) = record { marker : uint8; - row_or_eof: case is_eof of { - true -> eof: EOFOrOK; + row_or_eof: case is_eof_or_ok of { + true -> eof: EOFOrOK(pkt_len); false -> row: ResultsetRow(marker); - } &requires(is_eof); + } &requires(is_eof_or_ok); } &let { - # MySQL spec says "You must check whether the packet length is less than 9 - # to make sure that it is a EOF_Packet packet" so the value of 13 here - # comes from that 9, plus a 4-byte header. - is_eof : bool = (marker == 0xfe && pkt_len < 13); + is_eof_or_ok : bool = (marker == 0xfe); update_result_seen: bool = $context.connection.inc_results_seen(); - update_expectation: bool = $context.connection.set_next_expected(is_eof ? NO_EXPECTATION : EXPECT_RESULTSET); + update_expectation: bool = $context.connection.set_next_expected(is_eof_or_ok ? NO_EXPECTATION : EXPECT_RESULTSET); }; type ResultsetRow(first_byte: uint8) = record { @@ -480,6 +515,9 @@ type AuthSwitchRequest = record { status: uint8; name : NUL_String; data : bytestring &restofdata; +} &let { + update_auth_plugin: bool = $context.connection.set_auth_plugin(name); + update_state: bool = $context.connection.update_state(AUTH_SWITCH_RESP_PHASE); }; type ColumnDefinition320 = record { @@ -531,6 +569,9 @@ refine connection MySQL_Conn += { uint32 remaining_cols_; uint32 results_seen_; bool deprecate_eof_; + bool server_query_attrs_; + bool client_query_attrs_; + bytestring auth_plugin_; %} %init{ @@ -542,6 +583,13 @@ refine connection MySQL_Conn += { remaining_cols_ = 0; results_seen_ = 0; deprecate_eof_ = false; + server_query_attrs_ = false; + client_query_attrs_ = false; + auth_plugin_ = bytestring(); + %} + + %cleanup{ + auth_plugin_.free(); %} function get_version(): uint8 @@ -577,6 +625,18 @@ refine connection MySQL_Conn += { return true; %} + function update_state_from_auth(): bool + %{ + if ( auth_plugin_ == "caching_sha2_password" ) + { + state_ = SHA2_AUTH_PHASE; + if ( expected_ == EXPECT_AUTH_SWITCH ) + expected_ = EXPECT_STATUS; + } + + return true; + %} + function get_deprecate_eof(): bool %{ return deprecate_eof_; @@ -588,6 +648,46 @@ refine connection MySQL_Conn += { return true; %} + function get_server_query_attrs(): bool + %{ + return server_query_attrs_; + %} + + function set_server_query_attrs(q: bool): bool + %{ + server_query_attrs_ = q; + return true; + %} + + function get_client_query_attrs(): bool + %{ + return client_query_attrs_; + %} + + function set_client_query_attrs(q: bool): bool + %{ + client_query_attrs_ = q; + return true; + %} + + function get_auth_plugin(): bytestring + %{ + return auth_plugin_; + %} + + function set_auth_plugin(a: bytestring): bool + %{ + if ( auth_plugin_.length() > 0 && + strncmp(c_str(auth_plugin_), c_str(a), auth_plugin_.length()) != 0 ) + { + expected_ = EXPECT_AUTH_SWITCH; + } + + auth_plugin_.free(); + auth_plugin_.init(a.data(), a.length()); + return true; + %} + function get_expectation(): Expected %{ return expected_; diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password-after-auth-switch/mysql.log b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password-after-auth-switch/mysql.log new file mode 100644 index 0000000000..26e609fe2a --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password-after-auth-switch/mysql.log @@ -0,0 +1,16 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path mysql +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cmd arg success rows response +#types time string addr port addr port string string bool count string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 35928 127.0.0.1 3306 login root T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 35928 127.0.0.1 3306 query select @@version_comment limit 1 T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 35928 127.0.0.1 3306 query select DATABASE(), USER() limit 1 T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 35928 127.0.0.1 3306 query select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1 T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 35928 127.0.0.1 3306 statistics (empty) - - - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 35928 127.0.0.1 3306 quit (empty) - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password-after-auth-switch/out b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password-after-auth-switch/out new file mode 100644 index 0000000000..e8ead41d58 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password-after-auth-switch/out @@ -0,0 +1,14 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +mysql handshake, root +mysql ok, 0 +mysql request, 3, select @@version_comment limit 1 +mysql result row, [MySQL Community Server - GPL] +mysql ok, 0 +mysql request, 3, select DATABASE(), USER() limit 1 +mysql result row, [, root@localhost] +mysql ok, 0 +mysql request, 3, select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1 +mysql result row, [utf8mb4, utf8mb4, utf8mb4, utf8mb4] +mysql ok, 0 +mysql request, 9, +mysql request, 1, diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/mysql.log b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/mysql.log index 53fb4143f2..bb46a96482 100644 --- a/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/mysql.log +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/mysql.log @@ -9,15 +9,15 @@ #types time string addr port addr port string string bool count string XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 56494 127.0.0.1 3306 login root F - Got an error reading communication packets XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 login root T 0 - -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 query \x00\x01show databases T 0 - -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 query \x00\x01show tables T 0 - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 query show databases T 0 - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 query show tables T 0 - XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 field_list t T 0 - -XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 query \x00\x01select @@version_comment limit 1 T 0 - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 query select @@version_comment limit 1 T 0 - XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 127.0.0.1 49352 127.0.0.1 3306 quit (empty) - - - XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 login root T 0 - -XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 query \x00\x01show databases T 0 - -XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 query \x00\x01show tables T 0 - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 query show databases T 0 - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 query show tables T 0 - XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 field_list t T 0 - -XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 query \x00\x01select @@version_comment limit 1 T 0 - +XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 query select @@version_comment limit 1 T 0 - XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 127.0.0.1 40950 127.0.0.1 3306 quit (empty) - - - #close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/out b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/out index 6dd3801eba..f8855b38fc 100644 --- a/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/out +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/out @@ -3,37 +3,37 @@ mysql handshake, root mysql error, 1158, Got an error reading communication packets mysql handshake, root mysql ok, 0 -mysql request, 3, \x00\x01show databases +mysql request, 3, show databases mysql result row, [information_schema] mysql result row, [mysql] mysql result row, [performance_schema] mysql result row, [sys] mysql result row, [test] mysql ok, 0 -mysql request, 3, \x00\x01show tables +mysql request, 3, show tables mysql result row, [t] mysql ok, 0 mysql request, 4, t\x00 mysql ok, 0 -mysql request, 3, \x00\x01select @@version_comment limit 1 +mysql request, 3, select @@version_comment limit 1 mysql result row, [MySQL Community Server - GPL] mysql ok, 0 mysql request, 1, mysql handshake, root mysql ok, 0 -mysql request, 3, \x00\x01show databases +mysql request, 3, show databases mysql result row, [information_schema] mysql result row, [mysql] mysql result row, [performance_schema] mysql result row, [sys] mysql result row, [test] mysql ok, 0 -mysql request, 3, \x00\x01show tables +mysql request, 3, show tables mysql result row, [t] mysql ok, 0 mysql request, 4, t\x00 mysql ok, 0 -mysql request, 3, \x00\x01select @@version_comment limit 1 +mysql request, 3, select @@version_comment limit 1 mysql result row, [MySQL Community Server - GPL] mysql ok, 0 mysql request, 1, diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr/mysql.log b/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr/mysql.log new file mode 100644 index 0000000000..3fd06ec55f --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr/mysql.log @@ -0,0 +1,14 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path mysql +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cmd arg success rows response +#types time string addr port addr port string string bool count string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 51682 127.0.0.1 3306 login ykg T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 51682 127.0.0.1 3306 query select @@version_comment limit 1 T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 51682 127.0.0.1 3306 query select now() T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 51682 127.0.0.1 3306 query select now() T 0 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr/out b/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr/out new file mode 100644 index 0000000000..dce5524739 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr/out @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +mysql handshake, ykg +mysql ok, 0 +mysql request, 3, select @@version_comment limit 1 +mysql result row, [Source distribution] +mysql ok, 0 +mysql request, 3, select now() +mysql result row, [2022-07-13 10:45:41] +mysql ok, 0 +mysql request, 3, select now() +mysql result row, [2022-07-13 10:45:43] +mysql ok, 0 diff --git a/testing/btest/Traces/mysql/caching_sha2_password-after-auth-switch.pcapng b/testing/btest/Traces/mysql/caching_sha2_password-after-auth-switch.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..3f4407eb49c93a38b29b4fc7fcbcf2235bd912ec GIT binary patch literal 4412 zcmbVQZ)_Xo8Gp}q{*tmbf;P}rdj*qlNNk;*i~mGb<|Yj-EFpiKuxQ127vH5muzlw4 z?2t}lUZqLZln?tbBoI*8R<)`q7){j#6+#GYn$%7Ea#ESlM7IgbD9hLfq;0UqJkRU9 z_|7p#;)&ke``*3x{GR9cd*1gwxp&vD-q#2rGlz!mRr{0oD0Qq^St z;>;jbqJa=U8seAebOA3b)G`qvaAOOwedAs8McUb3G|D}~Y%G!hI4QG0BV3c*m2r~Wd#Y8gHd4)LMDiIq@{ zk3@u(2tN`Xgb)eFi?K@9m4HVN{N+>v*xh7WRf{WP=CK}_)dO>GA-#kYRn4FyBYcFA zzORT6USYmF;hMt%*oXU<_U#?|EcyWSu{o`qOc8P@_3Z>nbY468BM1)L#&X|{_~t8J zIP*nM?VT;25Rb3+j?dHGd$l^{!TX%o3(paw8SA+x+hGxcScfj#SbaA(md|e9elOs4 zzt~^r-tSssASZu!bMhM){^VTk z4)Da)obDWbO;rs-^6UEJxpYA^l(O7lVcnN5DpF@?Bsvo1d(y?6XsoJQzO%k)y=hhN zV2iphoyjS3!2kz&xjUzh61XOjg~! z4QufNTPM@*m?&(B|B;esmgV1Gy>Om>K6$QKz4rXX@rla$$|rqKO-#n`K2^uZIIe>dwrI|a{t>5QIYgYoxF?o^F*c_$ zoLO^%?F*8fuZ2_H#+ls4@#5aIkB|=V;z_{2TRVEX)0X+zs;j_V#CNW9q2!58z&&hE zWB5Yq2;=*QHonF8b>RC-(>iDPjdNqea)voR^{ywTz!;m;7{>9`6vJ3*iGg)C>(23R zaN#AKF6ZQoK@$mUd8IRIJ`c;1=9Ii*&=AbR7%<;|LPNt?9{jy8_DASra~g}~O_SAE z_ES3+i|;G(&FU_u>#tq0c!5@qy9WsOO7beW+p{Aa(pMvkOB}gL$TtZ&2%#UCSx?SS z!#71fUn(fZI!($Ntc;aw!%0DbvBOLdT2x2-bOem>S;iz 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 +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff mysql.log + +@load base/protocols/mysql + +event mysql_ok(c: connection, affected_rows: count) + { + print "mysql ok", affected_rows; + } + +event mysql_eof(c: connection, is_intermediate: bool) + { + print "mysql eof", is_intermediate; + } + +event mysql_result_row(c: connection, row: string_vec) + { + print "mysql result row", row; + } + +event mysql_error(c: connection, code: count, msg: string) + { + print "mysql error", code, msg; + } + +event mysql_command_request(c: connection, command: count, arg: string) + { + print "mysql request", command, arg; + } + +event mysql_handshake(c: connection, username: string) + { + print "mysql handshake", username; + } diff --git a/testing/btest/scripts/base/protocols/mysql/query-attr.test b/testing/btest/scripts/base/protocols/mysql/query-attr.test new file mode 100644 index 0000000000..d827ea97c0 --- /dev/null +++ b/testing/btest/scripts/base/protocols/mysql/query-attr.test @@ -0,0 +1,35 @@ +# @TEST-EXEC: zeek -b -C -r $TRACES/mysql/query-attr.pcapng %INPUT >out +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff mysql.log + +@load base/protocols/mysql + +event mysql_ok(c: connection, affected_rows: count) + { + print "mysql ok", affected_rows; + } + +event mysql_eof(c: connection, is_intermediate: bool) + { + print "mysql eof", is_intermediate; + } + +event mysql_result_row(c: connection, row: string_vec) + { + print "mysql result row", row; + } + +event mysql_error(c: connection, code: count, msg: string) + { + print "mysql error", code, msg; + } + +event mysql_command_request(c: connection, command: count, arg: string) + { + print "mysql request", command, arg; + } + +event mysql_handshake(c: connection, username: string) + { + print "mysql handshake", username; + } From c82756bda473e6c79b582773c45d66aef0ced787 Mon Sep 17 00:00:00 2001 From: Fupeng Zhao Date: Mon, 1 Jul 2024 14:55:47 +0800 Subject: [PATCH 19/93] Refactored connection phase state handling Added `ConnectionExpected` enum for expected packet types during the connection phase. --- .../protocol/mysql/mysql-protocol.pac | 68 +++++++++++++------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/src/analyzer/protocol/mysql/mysql-protocol.pac b/src/analyzer/protocol/mysql/mysql-protocol.pac index d482d23b10..76bdb5676f 100644 --- a/src/analyzer/protocol/mysql/mysql-protocol.pac +++ b/src/analyzer/protocol/mysql/mysql-protocol.pac @@ -136,12 +136,15 @@ enum command_consts { }; enum state { - CONNECTION_PHASE = 0, - COMMAND_PHASE = 1, - SHA2_AUTH_PHASE = 2, - PUB_KEY_PHASE = 3, - SHA2_AUTH_RESP_PHASE = 4, - AUTH_SWITCH_RESP_PHASE = 5, + CONNECTION_PHASE = 0, + COMMAND_PHASE = 1, +}; + +enum ConnectionExpected { + EXPECT_HANDSHAKE, + EXPECT_SHA2_AUTH, + EXPECT_PUB_KEY, + EXPECT_AUTH_SWITCH_RESP, }; enum Expected { @@ -154,6 +157,7 @@ enum Expected { EXPECT_RESULTSET, EXPECT_REST_OF_PACKET, EXPECT_AUTH_SWITCH, + EXPECT_SHA2_AUTH_RESP, }; enum EOFType { @@ -209,12 +213,8 @@ type Server_Message(seq_id: uint8, pkt_len: uint32) = case is_initial of { }; type Client_Message(state: int) = case state of { - CONNECTION_PHASE -> connection_phase: Handshake_Response_Packet; + CONNECTION_PHASE -> connection_phase: Connection_Phase_Packets; COMMAND_PHASE -> command_phase : Command_Request_Packet; - SHA2_AUTH_PHASE -> sha2_auth_phase : SHA2_Auth_Packet; - PUB_KEY_PHASE -> pub_key_phase : Public_Key_Packet; - SHA2_AUTH_RESP_PHASE -> sha2_auth_resp_phase : SHA2_Auth_Response_Packet; - AUTH_SWITCH_RESP_PHASE -> auth_switch_resp_phase : Auth_Switch_Response_Packet; }; # Handshake Request @@ -303,7 +303,7 @@ type Handshake_Plain_v10(cap_flags: uint32) = record { } &let { update_auth_plugin: bool = $context.connection.set_auth_plugin(auth_plugin) &if( cap_flags & CLIENT_PLUGIN_AUTH ); - update_state: bool = $context.connection.update_state_from_auth() + update_expected: bool = $context.connection.update_expected_from_auth() &if( cap_flags & CLIENT_PLUGIN_AUTH ); }; @@ -338,9 +338,9 @@ type Handshake_Response_Packet_v9 = record { type SHA2_Auth_Packet = record { state: bytestring &restofdata; } &let { - update_state_1: bool = $context.connection.update_state(COMMAND_PHASE) + update_state : bool = $context.connection.update_state(COMMAND_PHASE) &if(state[0] == FAST_AUTH_SUCCESS); - update_state_2: bool = $context.connection.update_state(PUB_KEY_PHASE) + update_conn_expectation: bool = $context.connection.set_next_conn_expected(EXPECT_PUB_KEY) &if(state[1] == REQUEST_PUBLIC_KEY); }; @@ -348,7 +348,7 @@ type Public_Key_Packet = record { pad : uint8; pub_key: bytestring &restofdata; } &let { - update_state: bool = $context.connection.update_state(SHA2_AUTH_RESP_PHASE); + update_expectation: bool = $context.connection.set_next_expected(EXPECT_SHA2_AUTH_RESP); }; type SHA2_Auth_Response_Packet = record { @@ -362,7 +362,17 @@ type SHA2_Auth_Response_Packet = record { type Auth_Switch_Response_Packet = record { data : bytestring &restofdata; } &let { - update_state: bool = $context.connection.update_state_from_auth(); + update_expected: bool = $context.connection.update_expected_from_auth(); +}; + +# Connection Phase + +type Connection_Phase_Packets = case $context.connection.get_conn_expectation() of { + EXPECT_HANDSHAKE -> handshake_resp : Handshake_Response_Packet; + EXPECT_SHA2_AUTH -> sha2_auth : SHA2_Auth_Packet; + EXPECT_PUB_KEY -> pub_key : Public_Key_Packet; + EXPECT_AUTH_SWITCH_RESP -> atuh_switch_resp : Auth_Switch_Response_Packet; + default -> unknown : empty; }; # Command Request @@ -409,6 +419,7 @@ type Command_Response(pkt_len: uint32) = case $context.connection.get_expectatio EXPECT_REST_OF_PACKET -> rest : bytestring &restofdata; EXPECT_STATUS -> status : Command_Response_Status; EXPECT_AUTH_SWITCH -> auth_switch : AuthSwitchRequest; + EXPECT_SHA2_AUTH_RESP -> sha2_auth_resp: SHA2_Auth_Response_Packet; EXPECT_EOF_THEN_RESULTSET -> eof : EOFIfLegacyThenResultset(pkt_len); default -> unknown : empty; }; @@ -516,8 +527,8 @@ type AuthSwitchRequest = record { name : NUL_String; data : bytestring &restofdata; } &let { - update_auth_plugin: bool = $context.connection.set_auth_plugin(name); - update_state: bool = $context.connection.update_state(AUTH_SWITCH_RESP_PHASE); + update_auth_plugin : bool = $context.connection.set_auth_plugin(name); + update_conn_expectation: bool = $context.connection.set_next_conn_expected(EXPECT_AUTH_SWITCH_RESP); }; type ColumnDefinition320 = record { @@ -565,6 +576,7 @@ refine connection MySQL_Conn += { uint8 previous_seq_id_; int state_; Expected expected_; + ConnectionExpected conn_expected_; uint32 col_count_; uint32 remaining_cols_; uint32 results_seen_; @@ -579,6 +591,7 @@ refine connection MySQL_Conn += { previous_seq_id_ = 0; state_ = CONNECTION_PHASE; expected_ = EXPECT_STATUS; + conn_expected_ = EXPECT_HANDSHAKE; col_count_ = 0; remaining_cols_ = 0; results_seen_ = 0; @@ -622,14 +635,18 @@ refine connection MySQL_Conn += { function update_state(s: state): bool %{ state_ = s; + + if ( s == COMMAND_PHASE ) + conn_expected_ = EXPECT_HANDSHAKE; // Reset connection phase expectation + return true; %} - function update_state_from_auth(): bool + function update_expected_from_auth(): bool %{ if ( auth_plugin_ == "caching_sha2_password" ) { - state_ = SHA2_AUTH_PHASE; + conn_expected_ = EXPECT_SHA2_AUTH; if ( expected_ == EXPECT_AUTH_SWITCH ) expected_ = EXPECT_STATUS; } @@ -699,6 +716,17 @@ refine connection MySQL_Conn += { return true; %} + function get_conn_expectation(): ConnectionExpected + %{ + return conn_expected_; + %} + + function set_next_conn_expected(c: ConnectionExpected): bool + %{ + conn_expected_ = c; + return true; + %} + function set_next_expected_from_command(cmd: uint8): bool %{ switch ( cmd ) { From e98b80d14073e1f060f8b8b0ba6703f3fc5f7df8 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 4 Jul 2024 10:24:20 +0200 Subject: [PATCH 20/93] mysql: Fix auth_plugin_data_part2 length computation --- src/analyzer/protocol/mysql/mysql-protocol.pac | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/analyzer/protocol/mysql/mysql-protocol.pac b/src/analyzer/protocol/mysql/mysql-protocol.pac index 76bdb5676f..ea81bb3398 100644 --- a/src/analyzer/protocol/mysql/mysql-protocol.pac +++ b/src/analyzer/protocol/mysql/mysql-protocol.pac @@ -240,13 +240,14 @@ type Handshake_v10 = record { status_flags : uint16; capability_flags_2 : uint16; auth_plugin_data_len : uint8; - reserved : padding[10]; - auth_plugin_data_part_2: bytestring &length=13; + reserved : padding[10]; + auth_plugin_data_part_2: bytestring &length=auth_plugin_data_part_2_len; have_plugin : case ( ( capability_flags_2 << 16 ) & CLIENT_PLUGIN_AUTH ) of { CLIENT_PLUGIN_AUTH -> auth_plugin: NUL_String; 0x0 -> none : empty; }; } &let { + auth_plugin_data_part_2_len = (auth_plugin_data_len > 8 && (auth_plugin_data_len - 8) > 13) ? auth_plugin_data_len - 8 : 13; update_auth_plugin: bool = $context.connection.set_auth_plugin(auth_plugin) &if( ( capability_flags_2 << 16 ) & CLIENT_PLUGIN_AUTH ); server_query_attrs: bool = $context.connection.set_server_query_attrs(( capability_flags_2 << 16 ) & CLIENT_QUERY_ATTRIBUTES); From 48e76f38cb3085785af24a45d6cd22d9e2762755 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 4 Jul 2024 10:25:56 +0200 Subject: [PATCH 21/93] mysql: Make auth_plugin_ a std::string --- .../protocol/mysql/mysql-protocol.pac | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/analyzer/protocol/mysql/mysql-protocol.pac b/src/analyzer/protocol/mysql/mysql-protocol.pac index ea81bb3398..2ea734cd56 100644 --- a/src/analyzer/protocol/mysql/mysql-protocol.pac +++ b/src/analyzer/protocol/mysql/mysql-protocol.pac @@ -584,7 +584,7 @@ refine connection MySQL_Conn += { bool deprecate_eof_; bool server_query_attrs_; bool client_query_attrs_; - bytestring auth_plugin_; + std::string auth_plugin_; %} %init{ @@ -599,11 +599,6 @@ refine connection MySQL_Conn += { deprecate_eof_ = false; server_query_attrs_ = false; client_query_attrs_ = false; - auth_plugin_ = bytestring(); - %} - - %cleanup{ - auth_plugin_.free(); %} function get_version(): uint8 @@ -688,21 +683,16 @@ refine connection MySQL_Conn += { return true; %} - function get_auth_plugin(): bytestring - %{ - return auth_plugin_; - %} - function set_auth_plugin(a: bytestring): bool %{ - if ( auth_plugin_.length() > 0 && - strncmp(c_str(auth_plugin_), c_str(a), auth_plugin_.length()) != 0 ) + // binpac::std_str() includes trailing \0 from parsing. + auto new_auth_plugin = std::string(binpac::c_str(a)); + if ( ! auth_plugin_.empty() && new_auth_plugin != auth_plugin_ ) { expected_ = EXPECT_AUTH_SWITCH; } - auth_plugin_.free(); - auth_plugin_.init(a.data(), a.length()); + auth_plugin_ = std::move(new_auth_plugin); return true; %} From 8a92945b0639fc1a814c519d9dbbf21f67b91053 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 5 Jul 2024 10:25:25 +0200 Subject: [PATCH 22/93] mysql: AuthSwitchRequest: &enforce a 0xfe / 254 status --- src/analyzer/protocol/mysql/mysql-protocol.pac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/analyzer/protocol/mysql/mysql-protocol.pac b/src/analyzer/protocol/mysql/mysql-protocol.pac index 2ea734cd56..7d427460ef 100644 --- a/src/analyzer/protocol/mysql/mysql-protocol.pac +++ b/src/analyzer/protocol/mysql/mysql-protocol.pac @@ -524,7 +524,7 @@ type ColumnDefinition41(first_byte: uint8) = record { }; type AuthSwitchRequest = record { - status: uint8; + status: uint8 &enforce(status==254); name : NUL_String; data : bytestring &restofdata; } &let { From 40f1c2cb6dbc2d3be9977ea8db3eb443f09515dc Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 5 Jul 2024 10:24:40 +0200 Subject: [PATCH 23/93] mysql: Add mysql_auth_plugin, mysql_auth_more_data and mysql_auth_switch_request events Remove caching_sha2_password parsing/state from the analyzer and implement the generic events. If we actually want to peak into the authentication mechanism, we could write a separate analyzer for it. For now, treat it as opaque values that are exposed to script land. The added tests show the --get-server-public-key in use where mysql_auth_more_data contains an RSA public key. --- src/analyzer/protocol/mysql/events.bif | 36 +++++++++ .../protocol/mysql/mysql-analyzer.pac | 49 +++++++++++ .../protocol/mysql/mysql-protocol.pac | 81 +++++-------------- .../out | 5 ++ .../out | 12 +++ ...ching_sha2_password-after-auth-switch.test | 15 ++++ .../mysql/caching_sha2_password.test | 15 ++++ 7 files changed, 151 insertions(+), 62 deletions(-) diff --git a/src/analyzer/protocol/mysql/events.bif b/src/analyzer/protocol/mysql/events.bif index ec5fa61ae6..68ff0e5720 100644 --- a/src/analyzer/protocol/mysql/events.bif +++ b/src/analyzer/protocol/mysql/events.bif @@ -87,3 +87,39 @@ event mysql_server_version%(c: connection, ver: string%); ## .. zeek:see:: mysql_command_request mysql_error mysql_ok mysql_server_version event mysql_handshake%(c: connection, username: string%); +## Generated for information about plugin authentication within handshake packets. +## +## c: The connection. +## +## is_orig: True if this is from the client, false if from the server. +## +## name: Name of the authentication plugin. +## +## .. zeek:see:: mysql_handshake mysql_auth_switch_request mysql_auth_more_data +event mysql_auth_plugin%(c: connection, is_orig: bool, name: string%); + +## Generated for a server packet with an auth switch request. +## +## c: The connection. +## +## name: The plugin name. +## +## data: Initial authentication data for the plugin. +## +## .. zeek:see:: mysql_handshake mysql_auth_more_data +event mysql_auth_switch_request%(c: connection, name: string, data: string%); + +## Generated for opaque authentication data exchanged between client and server +## after the client's handshake packet, but before the server replied with +## an OK_Packet +## +## Data is specific to the plugin auth mechanism used by client and server. +## +## c: The connection. +## +## is_orig: True if this is from the client, false if from the server. +## +## data: More authentication data. +## +## .. zeek:see:: mysql_handshake mysql_auth_switch_request +event mysql_auth_more_data%(c: connection, is_orig: bool, data: string%); diff --git a/src/analyzer/protocol/mysql/mysql-analyzer.pac b/src/analyzer/protocol/mysql/mysql-analyzer.pac index 5f6782c4ff..738e063fbb 100644 --- a/src/analyzer/protocol/mysql/mysql-analyzer.pac +++ b/src/analyzer/protocol/mysql/mysql-analyzer.pac @@ -14,6 +14,17 @@ refine flow MySQL_Flow += { connection()->zeek_analyzer()->Conn(), zeek::make_intrusive(c_str(${msg.handshake9.server_version}))); } + + if ( mysql_auth_plugin ) + { + if ( ${msg.version} == 10 && (${msg.handshake10.capability_flags_2} << 16) & CLIENT_PLUGIN_AUTH ) + { + zeek::BifEvent::enqueue_mysql_auth_plugin(connection()->zeek_analyzer(), + connection()->zeek_analyzer()->Conn(), + false /*is_orig*/, + zeek::make_intrusive(c_str(${msg.handshake10.auth_plugin}))); + } + } return true; %} @@ -40,6 +51,18 @@ refine flow MySQL_Flow += { connection()->zeek_analyzer()->Conn(), zeek::make_intrusive(c_str(${msg.v9_response.username}))); } + + if ( mysql_auth_plugin ) + { + if ( ${msg.version} == 10 && ${msg.v10_response.plain.cap_flags} & CLIENT_PLUGIN_AUTH ) + { + zeek::BifEvent::enqueue_mysql_auth_plugin(connection()->zeek_analyzer(), + connection()->zeek_analyzer()->Conn(), + true /*is_orig*/, + zeek::make_intrusive(c_str(${msg.v10_response.plain.auth_plugin}))); + } + } + return true; %} @@ -112,6 +135,24 @@ refine flow MySQL_Flow += { return true; %} + function proc_auth_switch_request(msg: AuthSwitchRequest): bool + %{ + zeek::BifEvent::enqueue_mysql_auth_switch_request(connection()->zeek_analyzer(), + connection()->zeek_analyzer()->Conn(), + zeek::make_intrusive(c_str(${msg.name})), + to_stringval(${msg.data})); + return true; + %} + + function proc_auth_more_data(msg: AuthMoreData): bool + %{ + zeek::BifEvent::enqueue_mysql_auth_more_data(connection()->zeek_analyzer(), + connection()->zeek_analyzer()->Conn(), + ${is_orig}, + to_stringval(${msg.data})); + return true; + %} + }; refine typeattr Initial_Handshake_Packet += &let { @@ -141,3 +182,11 @@ refine typeattr EOF_Packet += &let { refine typeattr Resultset += &let { proc = $context.flow.proc_resultset(this); }; + +refine typeattr AuthSwitchRequest += &let { + proc = $context.flow.proc_auth_switch_request(this); +}; + +refine typeattr AuthMoreData += &let { + proc = $context.flow.proc_auth_more_data(this); +}; diff --git a/src/analyzer/protocol/mysql/mysql-protocol.pac b/src/analyzer/protocol/mysql/mysql-protocol.pac index 7d427460ef..d415735fec 100644 --- a/src/analyzer/protocol/mysql/mysql-protocol.pac +++ b/src/analyzer/protocol/mysql/mysql-protocol.pac @@ -142,9 +142,7 @@ enum state { enum ConnectionExpected { EXPECT_HANDSHAKE, - EXPECT_SHA2_AUTH, - EXPECT_PUB_KEY, - EXPECT_AUTH_SWITCH_RESP, + EXPECT_AUTH_DATA, }; enum Expected { @@ -157,7 +155,6 @@ enum Expected { EXPECT_RESULTSET, EXPECT_REST_OF_PACKET, EXPECT_AUTH_SWITCH, - EXPECT_SHA2_AUTH_RESP, }; enum EOFType { @@ -176,12 +173,6 @@ enum Client_Capabilities { CLIENT_QUERY_ATTRIBUTES = 0x08000000, }; -enum SHA2_Auth_State { - REQUEST_PUBLIC_KEY = 2, - FAST_AUTH_SUCCESS = 3, - PERFORM_FULL_AUTHENTICATION = 4, -}; - type NUL_String = RE/[^\0]*\0/; type EmptyOrNUL_String = RE/([^\0]*\0)?/; @@ -304,7 +295,10 @@ type Handshake_Plain_v10(cap_flags: uint32) = record { } &let { update_auth_plugin: bool = $context.connection.set_auth_plugin(auth_plugin) &if( cap_flags & CLIENT_PLUGIN_AUTH ); - update_expected: bool = $context.connection.update_expected_from_auth() + + # Switch client state into expecting more auth data. If the server responds + # with an OK_Packet before, will switch into COMMAND_PHASE. + update_conn_expectation: bool = $context.connection.set_next_conn_expected(EXPECT_AUTH_DATA) &if( cap_flags & CLIENT_PLUGIN_AUTH ); }; @@ -334,46 +328,11 @@ type Handshake_Response_Packet_v9 = record { password : bytestring &restofdata; }; -# SHA2 Auth - -type SHA2_Auth_Packet = record { - state: bytestring &restofdata; -} &let { - update_state : bool = $context.connection.update_state(COMMAND_PHASE) - &if(state[0] == FAST_AUTH_SUCCESS); - update_conn_expectation: bool = $context.connection.set_next_conn_expected(EXPECT_PUB_KEY) - &if(state[1] == REQUEST_PUBLIC_KEY); -}; - -type Public_Key_Packet = record { - pad : uint8; - pub_key: bytestring &restofdata; -} &let { - update_expectation: bool = $context.connection.set_next_expected(EXPECT_SHA2_AUTH_RESP); -}; - -type SHA2_Auth_Response_Packet = record { - data: bytestring &restofdata; -} &let { - update_state: bool = $context.connection.update_state(COMMAND_PHASE); -}; - -# Auth Switch - -type Auth_Switch_Response_Packet = record { - data : bytestring &restofdata; -} &let { - update_expected: bool = $context.connection.update_expected_from_auth(); -}; - # Connection Phase type Connection_Phase_Packets = case $context.connection.get_conn_expectation() of { - EXPECT_HANDSHAKE -> handshake_resp : Handshake_Response_Packet; - EXPECT_SHA2_AUTH -> sha2_auth : SHA2_Auth_Packet; - EXPECT_PUB_KEY -> pub_key : Public_Key_Packet; - EXPECT_AUTH_SWITCH_RESP -> atuh_switch_resp : Auth_Switch_Response_Packet; - default -> unknown : empty; + EXPECT_HANDSHAKE -> handshake_resp: Handshake_Response_Packet; + EXPECT_AUTH_DATA -> auth_data: AuthMoreData(true); }; # Command Request @@ -420,7 +379,6 @@ type Command_Response(pkt_len: uint32) = case $context.connection.get_expectatio EXPECT_REST_OF_PACKET -> rest : bytestring &restofdata; EXPECT_STATUS -> status : Command_Response_Status; EXPECT_AUTH_SWITCH -> auth_switch : AuthSwitchRequest; - EXPECT_SHA2_AUTH_RESP -> sha2_auth_resp: SHA2_Auth_Response_Packet; EXPECT_EOF_THEN_RESULTSET -> eof : EOFIfLegacyThenResultset(pkt_len); default -> unknown : empty; }; @@ -429,6 +387,10 @@ type Command_Response_Status = record { pkt_type: uint8; response: case pkt_type of { 0x00 -> data_ok: OK_Packet; + # When still in the CONNECTION_PHASE, the server can reply + # with AuthMoreData which is 0x01 stuffed opaque payload. + # https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_packets_protocol_auth_more_data.html + 0x01 -> auth_more_data: AuthMoreData(false); 0xfe -> data_eof: EOF_Packet(EOF_END); 0xff -> data_err: ERR_Packet; default -> unknown: empty; @@ -523,13 +485,20 @@ type ColumnDefinition41(first_byte: uint8) = record { filler : padding[2]; }; +# Opaque auth data exchanged during the connection phase between client and server. +type AuthMoreData(is_orig: bool) = record { + data : bytestring &restofdata; +}; + type AuthSwitchRequest = record { status: uint8 &enforce(status==254); name : NUL_String; data : bytestring &restofdata; } &let { update_auth_plugin : bool = $context.connection.set_auth_plugin(name); - update_conn_expectation: bool = $context.connection.set_next_conn_expected(EXPECT_AUTH_SWITCH_RESP); + update_conn_expectation: bool = $context.connection.set_next_conn_expected(EXPECT_AUTH_DATA); + # After an AuthSwitchRequest, server replies with OK_Packet, ERR_Packet or AuthMoreData. + update_expectation: bool = $context.connection.set_next_expected(EXPECT_STATUS); }; type ColumnDefinition320 = record { @@ -638,18 +607,6 @@ refine connection MySQL_Conn += { return true; %} - function update_expected_from_auth(): bool - %{ - if ( auth_plugin_ == "caching_sha2_password" ) - { - conn_expected_ = EXPECT_SHA2_AUTH; - if ( expected_ == EXPECT_AUTH_SWITCH ) - expected_ = EXPECT_STATUS; - } - - return true; - %} - function get_deprecate_eof(): bool %{ return deprecate_eof_; diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password-after-auth-switch/out b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password-after-auth-switch/out index e8ead41d58..947e3add03 100644 --- a/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password-after-auth-switch/out +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password-after-auth-switch/out @@ -1,5 +1,10 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +mysql auth plugin, F, caching_sha2_password, Vz\x08w+^\x04p\x02Tv\x01"~\x114\x14RP6\x00, 21 mysql handshake, root +mysql auth plugin, T, mysql_native_password, , 0 +mysql auth switch request, caching_sha2_password, Vz\x08w+^\x04p\x02Tv\x01"~\x114\x14RP6\x00, 21 +mysql auth more data, T, \xf7dS\x9eXe\xc4\xd6\xa9\xa7 \xfbC\xa6p\xaf\xdf\x9dB[B\x80\xa7\x80\xef\x0c\x95BC9#\x82, 32 +mysql auth more data, F, \x03, 1 mysql ok, 0 mysql request, 3, select @@version_comment limit 1 mysql result row, [MySQL Community Server - GPL] diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/out b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/out index f8855b38fc..a9dd402e6c 100644 --- a/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/out +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.caching_sha2_password/out @@ -1,7 +1,16 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +mysql auth plugin, F, caching_sha2_password, s.\x13\x01>\x05m\x04~Lq)%\x0fLL\x01\x08Xj\x00, 21 mysql handshake, root +mysql auth plugin, T, caching_sha2_password, \x98\xa0Ex\x8a\xeb`\xf3\xc7)\xa6\xaf\xf1\xa4]-\xa0\xdf\x959\xa1\xc5\xd6\xb8\xf3\xd6}\xb2\xa8\x033~, 32 +mysql auth more data, F, \x04, 1 mysql error, 1158, Got an error reading communication packets +mysql auth plugin, F, caching_sha2_password, 4x`?e\x04i'k&-P%LID\x17/\x0f{\x00, 21 mysql handshake, root +mysql auth plugin, T, caching_sha2_password, y.\x91:\x11\x87i\x17\xdfI_\xd2\xec\x9a"\xc2%sB\x10\x90\xbd\x15C\xf4w\xc0\x09p}\x8eE, 32 +mysql auth more data, F, \x04, 1 +mysql auth more data, T, \x02, 1 +mysql auth more data, F, -----BEGIN PUBLIC KEY-----\x0aMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0VACy/bY60MRuPW6aCxZ\x0abi+o0EgCgxzFObbyzDfnTnVJegOXbrdcbu1qIlEjPyn7UMBfjQr+VueiJvPjz2M8\x0ad/6GX1h4fYuwW4bEXBVo4HGxM8N0IyO1BYjafOaoUeL/NI+bLifH70KorIcSUR+h\x0a879DAQ0zlKz5vwpDYN2LVxidjFvy5baSPi/csDMqi2jitBAzbNW992O/v9CPnh5f\x0akdRMa2lMPKxRaPeqAw9U7CAmRqAaHZAfdI5kYnj3vsOFvKL2dkE+ckY8sh5H2uto\x0a37+mg6oll5PsydMbSuvFHLc0JZm++oem5z2WsZBdxmohqJ8Foc43W8IOtxs+YAOw\x0avwIDAQAB\x0a-----END PUBLIC KEY-----\x0a, 451 +mysql auth more data, T, \xca3\x89.M\x9d\xc0\xcb\xd6'2Zo*\xda8\xd2\xba\xb1\xabI\xcb\x1es%R\x1fo\xd0\xa6\xb8\x90\xf56\x0e\xd9\xd8p\x9eX\x84K\xb5\x1a\xe5\xfa\x18\xc1*\xfc\xa9W\xd6p\x1a\xcfv\xe8%\xe0\xb9\xfe\x98\x1b\xb3\x938\x85\xf4O\xf0c2b\xae\x81F\x1e\xb9\x1f\xbd\xdf\x16C\x91\xd5\x08\xa6\x82\xb6y\xf7\xa3u Date: Fri, 5 Jul 2024 12:17:48 +0200 Subject: [PATCH 24/93] mysql: Add data parameter to mysql_auth_plugin This may contain salt from the server or a hashed password from the client. --- src/analyzer/protocol/mysql/events.bif | 6 +++++- src/analyzer/protocol/mysql/mysql-analyzer.pac | 17 +++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/analyzer/protocol/mysql/events.bif b/src/analyzer/protocol/mysql/events.bif index 68ff0e5720..8f5596e655 100644 --- a/src/analyzer/protocol/mysql/events.bif +++ b/src/analyzer/protocol/mysql/events.bif @@ -95,8 +95,12 @@ event mysql_handshake%(c: connection, username: string%); ## ## name: Name of the authentication plugin. ## +## data: The initial auth data. From the server, it is the concatenation of +## auth_plugin_data_part_1 and auth_plugin_data_part_2 in the handshake. +## For the client it is the auth_response in the handshake response. +## ## .. zeek:see:: mysql_handshake mysql_auth_switch_request mysql_auth_more_data -event mysql_auth_plugin%(c: connection, is_orig: bool, name: string%); +event mysql_auth_plugin%(c: connection, is_orig: bool, name: string, data: string%); ## Generated for a server packet with an auth switch request. ## diff --git a/src/analyzer/protocol/mysql/mysql-analyzer.pac b/src/analyzer/protocol/mysql/mysql-analyzer.pac index 738e063fbb..48cd0b6bd5 100644 --- a/src/analyzer/protocol/mysql/mysql-analyzer.pac +++ b/src/analyzer/protocol/mysql/mysql-analyzer.pac @@ -19,10 +19,20 @@ refine flow MySQL_Flow += { { if ( ${msg.version} == 10 && (${msg.handshake10.capability_flags_2} << 16) & CLIENT_PLUGIN_AUTH ) { + auto auth_plugin = zeek::make_intrusive(c_str(${msg.handshake10.auth_plugin})); + auto data_part_1 = ${msg.handshake10.auth_plugin_data_part_1}; + auto data_part_2 = ${msg.handshake10.auth_plugin_data_part_2}; + std::vector data_parts = { + zeek::data_chunk_t{data_part_1.length(), reinterpret_cast(data_part_1.begin())}, + zeek::data_chunk_t{data_part_2.length(), reinterpret_cast(data_part_2.begin())}, + }; + auto data = zeek::make_intrusive(zeek::concatenate(data_parts)); + zeek::BifEvent::enqueue_mysql_auth_plugin(connection()->zeek_analyzer(), connection()->zeek_analyzer()->Conn(), false /*is_orig*/, - zeek::make_intrusive(c_str(${msg.handshake10.auth_plugin}))); + std::move(auth_plugin), + std::move(data)); } } return true; @@ -56,10 +66,13 @@ refine flow MySQL_Flow += { { if ( ${msg.version} == 10 && ${msg.v10_response.plain.cap_flags} & CLIENT_PLUGIN_AUTH ) { + auto auth_plugin = zeek::make_intrusive(c_str(${msg.v10_response.plain.auth_plugin})); + auto data = to_stringval(${msg.v10_response.plain.credentials.password.val}); zeek::BifEvent::enqueue_mysql_auth_plugin(connection()->zeek_analyzer(), connection()->zeek_analyzer()->Conn(), true /*is_orig*/, - zeek::make_intrusive(c_str(${msg.v10_response.plain.auth_plugin}))); + std::move(auth_plugin), + std::move(data)); } } From 6ea1045245f2f07ac1c6262c00f75c20a52c6395 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 5 Jul 2024 13:56:44 +0200 Subject: [PATCH 25/93] mysql: Fix EOFIfLegacyThenResultSet Only expect a result next if an EOF was consumed. --- src/analyzer/protocol/mysql/mysql-protocol.pac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/analyzer/protocol/mysql/mysql-protocol.pac b/src/analyzer/protocol/mysql/mysql-protocol.pac index d415735fec..c992927b37 100644 --- a/src/analyzer/protocol/mysql/mysql-protocol.pac +++ b/src/analyzer/protocol/mysql/mysql-protocol.pac @@ -449,7 +449,7 @@ type EOFIfLegacyThenResultset(pkt_len: uint32) = case $context.connection.get_de true -> resultset: Resultset(pkt_len); } &let { update_result_seen: bool = $context.connection.set_results_seen(0); - update_expectation: bool = $context.connection.set_next_expected(EXPECT_RESULTSET); + update_expectation: bool = $context.connection.set_next_expected(EXPECT_RESULTSET) &if( ! $context.connection.get_deprecate_eof() ); }; type Resultset(pkt_len: uint32) = record { From 0a1568f1a10bb5d995dc573bad46987b91ec122b Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 9 Jul 2024 11:43:18 +0200 Subject: [PATCH 26/93] mysql: Introduce mysql_ssl_request event This should've been added with fa48c885 for completion. Do it now. The MySQL spec calls it SSLRequest packet, so keep SSL in the name for consistency. --- src/analyzer/protocol/mysql/events.bif | 13 ++++++++++++- src/analyzer/protocol/mysql/mysql-analyzer.pac | 4 ++++ .../tls-12.out | 2 ++ .../tls-13.out | 2 ++ .../scripts.base.protocols.mysql.encrypted/out | 2 ++ .../base/protocols/mysql/encrypted-aws-rds.test | 15 +++++++++++---- .../scripts/base/protocols/mysql/encrypted.test | 8 +++++++- 7 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.encrypted-aws-rds/tls-12.out create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.encrypted-aws-rds/tls-13.out create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.encrypted/out diff --git a/src/analyzer/protocol/mysql/events.bif b/src/analyzer/protocol/mysql/events.bif index 8f5596e655..a102842e05 100644 --- a/src/analyzer/protocol/mysql/events.bif +++ b/src/analyzer/protocol/mysql/events.bif @@ -84,9 +84,20 @@ event mysql_server_version%(c: connection, ver: string%); ## ## username: The username supplied by the client ## -## .. zeek:see:: mysql_command_request mysql_error mysql_ok mysql_server_version +## .. zeek:see:: mysql_command_request mysql_error mysql_ok mysql_server_version mysql_ssl_request event mysql_handshake%(c: connection, username: string%); +## Generated for a short client handshake response packet with the CLIENT_SSL +## flag set. Usually the client will initiate a TLS handshake afterwards. +# +## See the MySQL `documentation `__ +## for more information about the MySQL protocol. +## +## c: The connection. +## +## .. zeek:see:: mysql_handshake +event mysql_ssl_request%(c: connection%); + ## Generated for information about plugin authentication within handshake packets. ## ## c: The connection. diff --git a/src/analyzer/protocol/mysql/mysql-analyzer.pac b/src/analyzer/protocol/mysql/mysql-analyzer.pac index 48cd0b6bd5..28ce1e7d9e 100644 --- a/src/analyzer/protocol/mysql/mysql-analyzer.pac +++ b/src/analyzer/protocol/mysql/mysql-analyzer.pac @@ -47,6 +47,10 @@ refine flow MySQL_Flow += { if ( ${msg.version} == 10 && ( ${msg.v10_response.cap_flags} & CLIENT_SSL )) { connection()->zeek_analyzer()->StartTLS(); + + if ( mysql_ssl_request ) + zeek::BifEvent::enqueue_mysql_ssl_request(connection()->zeek_analyzer(), + connection()->zeek_analyzer()->Conn()); return true; } diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.encrypted-aws-rds/tls-12.out b/testing/btest/Baseline/scripts.base.protocols.mysql.encrypted-aws-rds/tls-12.out new file mode 100644 index 0000000000..dd294ea217 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.encrypted-aws-rds/tls-12.out @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +mysql ssl request, CHhAvVGS1DHFjwGM9 diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.encrypted-aws-rds/tls-13.out b/testing/btest/Baseline/scripts.base.protocols.mysql.encrypted-aws-rds/tls-13.out new file mode 100644 index 0000000000..dd294ea217 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.encrypted-aws-rds/tls-13.out @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +mysql ssl request, CHhAvVGS1DHFjwGM9 diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.encrypted/out b/testing/btest/Baseline/scripts.base.protocols.mysql.encrypted/out new file mode 100644 index 0000000000..dd294ea217 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.encrypted/out @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +mysql ssl request, CHhAvVGS1DHFjwGM9 diff --git a/testing/btest/scripts/base/protocols/mysql/encrypted-aws-rds.test b/testing/btest/scripts/base/protocols/mysql/encrypted-aws-rds.test index d653608aa4..7f336edf80 100644 --- a/testing/btest/scripts/base/protocols/mysql/encrypted-aws-rds.test +++ b/testing/btest/scripts/base/protocols/mysql/encrypted-aws-rds.test @@ -1,15 +1,17 @@ # Just two traces with MySQL running in Amazon RDS tls1.3 and tls1.2 -# @TEST-EXEC: zeek -b -r $TRACES/mysql/tls-12-amazon-rds.trace %INPUT -# @TEST-EXEC: mkdir tls-12 && mv *log tls-12 +# @TEST-EXEC: zeek -b -r $TRACES/mysql/tls-12-amazon-rds.trace %INPUT >out +# @TEST-EXEC: mkdir tls-12 && mv *log out tls-12 # -# @TEST-EXEC: zeek -b -r $TRACES/mysql/tls-13-amazon-rds.trace %INPUT -# @TEST-EXEC: mkdir tls-13 && mv *log tls-13 +# @TEST-EXEC: zeek -b -r $TRACES/mysql/tls-13-amazon-rds.trace %INPUT >out +# @TEST-EXEC: mkdir tls-13 && mv *log out tls-13 # +# @TEST-EXEC: btest-diff tls-12/out # @TEST-EXEC: btest-diff tls-12/conn.log # @TEST-EXEC: btest-diff tls-12/ssl.log # @TEST-EXEC: btest-diff tls-12/x509.log # +# @TEST-EXEC: btest-diff tls-13/out # @TEST-EXEC: btest-diff tls-13/conn.log # @TEST-EXEC: btest-diff tls-13/ssl.log # @TEST-EXEC: ! test -f tls-13/x509.log @@ -17,3 +19,8 @@ @load base/protocols/conn @load base/protocols/mysql @load base/protocols/ssl + +event mysql_ssl_request(c: connection) + { + print "mysql ssl request", c$uid; + } diff --git a/testing/btest/scripts/base/protocols/mysql/encrypted.test b/testing/btest/scripts/base/protocols/mysql/encrypted.test index 1f43ec7da6..808bed3cfb 100644 --- a/testing/btest/scripts/base/protocols/mysql/encrypted.test +++ b/testing/btest/scripts/base/protocols/mysql/encrypted.test @@ -3,8 +3,9 @@ # empty mysql.log file. # @TEST-EXEC: touch mysql.log -# @TEST-EXEC: zeek -b -r $TRACES/mysql/encrypted.trace %INPUT +# @TEST-EXEC: zeek -b -r $TRACES/mysql/encrypted.trace %INPUT >out # @TEST-EXEC: btest-diff mysql.log +# @TEST-EXEC: btest-diff out # # Ensure the connection was handed off by peaking into some other logs. # @TEST-EXEC: btest-diff conn.log @@ -14,3 +15,8 @@ @load base/protocols/conn @load base/protocols/mysql @load base/protocols/ssl + +event mysql_ssl_request(c: connection) + { + print "mysql ssl request", c$uid; + } From 93f5813be365bd6de27d741f8aeb757de7a9dafe Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 9 Jul 2024 13:28:43 +0200 Subject: [PATCH 27/93] btest/mysql: Add pcap with non-string query attributes Pcap was generated as follows. Doesn't seem wireshark even parses this properly right now. with common.get_connection() as c: with c.cursor() as cur: date1 = datetime.date(1987, 10, 18) datetime1 = datetime.datetime(1990, 9, 26, 12, 13, 14) cur.add_attribute("number1", 42) cur.add_attribute("string1", "a string") cur.add_attribute("date1", date1) cur.add_attribute("datetime1", datetime1) cur.execute("SELECT version()") result = cur.fetchall() print("result", result) --- .../mysql/mysql-9.0.0-query-attributes.pcap | Bin 0 -> 2034 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 testing/btest/Traces/mysql/mysql-9.0.0-query-attributes.pcap diff --git a/testing/btest/Traces/mysql/mysql-9.0.0-query-attributes.pcap b/testing/btest/Traces/mysql/mysql-9.0.0-query-attributes.pcap new file mode 100644 index 0000000000000000000000000000000000000000..684dbcad3811dba656df87c10d9ee67e5a5d2168 GIT binary patch literal 2034 zcmaKtZ)g*D7{{MqE|+U-;?(`IbD$YAvASeQ*40L|7LU?ST6NCS?$wcAuO>6OOYbh) z!q_5$R1nG(^P+p>Ht@BM3F4b|W(;8t#u$tho!jV(;TR0Yirw(C=lLbqUP7A(9`5dU z$LGG!_j!JIKa@ZF*av=C4L>lvSl&7_(eo37BX~~fjTYzwI3TBcp*OJn)&~HL^87;Z zacJ(#Z|KQuzJLF6VgNqB__^QL(sn!X6@LX21c}H)P00X6K5)k+2Opnb7+XB}1=8F4Rf3~=}(l`q~LdX!6UA`)q;CM>lJ+C0fQvY z0HrsmV76C2O~fb4n#6XtRM}Bq@ZWeD`sAf{B=uIjIM2Ch7&e4o-Z?A$_Ivi$xAuIu z{@t+`FMYacbn(V}H~&$G4?Xz)$B))A;i_NBXT}5ForyQP_O&YcY|5T6%v@lqyG!Zn z3@VmUFjY-S8sgp-b_I;tl;oiLAMK$1U}VClXC}+T)#D?y?k;?u94Nr z=?R7A?v}ANPuH5o%MTe0pmCJm;Ip{D^eQLLu1Rc1Vsxc7B2BjsHz*TGY46Vrh7d^U z4bDAOig5152JW+5DREz~=SlzqQV`E4^a{e)w?WPle0kV~S10std2F#~d&7j1Xp!Uw z9x>=gI;A(b+@zf2#A9m`aYCI)om`Q|d?R5;5!=LtD0gAT#n$?@9bLGGJH62b5nUj% z>%t!hpTlcPZ*a|*WS!to{&V3q7w(}89SC1?iuIaLB0}&p{8$wwy^tHz%(w%RWt;es zh_`__p0c%g5L)SIXL4G6PfIFXz3necZCj+TrPgi1(8jm>2K(fb;o2&m+zSb^toz2NEXBBeAG$(o_T|vNUB%6HyPk*vB91gA%9C8 Date: Tue, 9 Jul 2024 13:23:44 +0200 Subject: [PATCH 28/93] mysql: Support non-string query attributes The query attributes aren't exposed to script layer right now, but this should at least parse over them once encountered and some fixups. --- .../protocol/mysql/mysql-protocol.pac | 144 ++++++++++++++++-- .../mysql.log | 54 +++++++ .../out | 132 ++++++++++++++++ .../mysql.log | 14 ++ .../out | 10 ++ .../btest/Traces/mysql/many-query-attrs.pcap | Bin 0 -> 37064 bytes .../base/protocols/mysql/many-query-attr.test | 35 +++++ .../mysql/query-attr-non-string.test | 35 +++++ 8 files changed, 412 insertions(+), 12 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/mysql.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/out create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/mysql.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/out create mode 100644 testing/btest/Traces/mysql/many-query-attrs.pcap create mode 100644 testing/btest/scripts/base/protocols/mysql/many-query-attr.test create mode 100644 testing/btest/scripts/base/protocols/mysql/query-attr-non-string.test diff --git a/src/analyzer/protocol/mysql/mysql-protocol.pac b/src/analyzer/protocol/mysql/mysql-protocol.pac index c992927b37..bc350c747c 100644 --- a/src/analyzer/protocol/mysql/mysql-protocol.pac +++ b/src/analyzer/protocol/mysql/mysql-protocol.pac @@ -173,6 +173,85 @@ enum Client_Capabilities { CLIENT_QUERY_ATTRIBUTES = 0x08000000, }; +# Binary Protocol Resultset encoding. +# +# https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_binary_resultset.html +# +# Values taken from here: https://dev.mysql.com/doc/dev/mysql-server/latest/namespaceclassic__protocol_1_1field__type.html +enum field_types { + TYPE_DECIMAL = 0x00, + TYPE_TINY = 0x01, + TYPE_SHORT = 0x02, + TYPE_LONG = 0x03, + TYPE_FLOAT = 0x04, + TYPE_DOUBLE = 0x05, + TYPE_NULL = 0x06, + TYPE_TIMESTAMP = 0x07, + TYPE_LONGLONG = 0x08, + TYPE_INT24 = 0x09, + TYPE_DATE = 0x0a, + TYPE_TIME = 0x0b, + TYPE_DATETIME = 0x0c, + TYPE_YEAR = 0x0d, + TYPE_VARCHAR = 0x0f, + TYPE_BIT = 0x10, + TYPE_TIMESTAMP2 = 0x11, + TYPE_JSON = 0xf5, + TYPE_NEWDECIMAL = 0xf6, + TYPE_ENUM = 0xf7, + TYPE_SET = 0xf8, + TYPE_TINYBLOB = 0xf9, + TYPE_MEDIUMBLOB = 0xfa, + TYPE_LONGBLOB = 0xfb, + TYPE_BLOB = 0xfc, + TYPE_VARSTRING = 0xfd, + TYPE_STRING = 0xfe, + TYPE_GEOMETRY = 0xff, +}; + +type BinaryDate = record { + len: uint8 &enforce(len == 0 || len == 4 || len == 7 || len == 11); + not_implemented: bytestring &length=len; +}; + +type BinaryTime = record { + len: uint8 &enforce(len == 0 || len == 8 || len == 12); + not_implemented: bytestring &length=len; +}; + +type BinaryValue(type: uint16) = record { + value: case ( type ) of { + TYPE_DECIMAL -> decimal_val: LengthEncodedInteger; + TYPE_TINY -> tiny_val: int8; + TYPE_SHORT -> short_val: int16; + TYPE_LONG -> long_val: int32; + TYPE_FLOAT -> float_val: bytestring &length=4; + TYPE_DOUBLE -> double_val: bytestring &length=8; + TYPE_NULL -> null_val: empty; # in null_bitmap + TYPE_TIMESTAMP -> timestamp_val: BinaryDate; + TYPE_LONGLONG -> longlong_val: int64; + TYPE_INT24 -> int24_val: int32; + TYPE_DATE -> date_val: BinaryDate; + TYPE_TIME -> time_val: BinaryTime; + TYPE_DATETIME -> datetime_val: BinaryDate; + TYPE_YEAR -> year_val: int16; + TYPE_VARCHAR -> varchar_val: LengthEncodedString; + TYPE_BIT -> bit_val: LengthEncodedString; + TYPE_TIMESTAMP2 -> timestamp2_val: BinaryDate; + TYPE_JSON -> json_val: LengthEncodedString; + TYPE_NEWDECIMAL -> newdecimal_val: LengthEncodedString; + TYPE_ENUM -> enum_val: LengthEncodedString; + TYPE_SET -> set_val: LengthEncodedString; + TYPE_TINYBLOB -> tinyblob_val: LengthEncodedString; + TYPE_MEDIUMBLOB -> mediumblob_val: LengthEncodedString; + TYPE_LONGBLOB -> longblob_val: LengthEncodedString; + TYPE_BLOB -> blob_val: LengthEncodedString; + TYPE_VARSTRING -> varstring_val: LengthEncodedString; + TYPE_STRING -> string_val: LengthEncodedString; + TYPE_GEOMETRY -> geometry_val: LengthEncodedString; + }; +}; + type NUL_String = RE/[^\0]*\0/; type EmptyOrNUL_String = RE/([^\0]*\0)?/; @@ -335,29 +414,51 @@ type Connection_Phase_Packets = case $context.connection.get_conn_expectation() EXPECT_AUTH_DATA -> auth_data: AuthMoreData(true); }; -# Command Request - +# Query attribute handling for COM_QUERY +# type AttributeTypeAndName = record { - type: uint16; + type: uint8; + unsigned_flag: uint8; name: LengthEncodedString; }; -type Attributes(count: uint8) = record { - unused : uint8; - send_types_to_server: uint8; # Always 1. +type AttributeValue(is_null: bool, type: uint8) = record { + null: case is_null of { + false -> val: BinaryValue(type); + true -> null_val: empty; + }; +} &let { + # Move parsing the next query attribute. + done = $context.connection.next_query_attr(); +}; + +type Attributes(count: int) = record { + null_bitmap : bytestring &length=(count + 7) / 8; + send_types_to_server: uint8 &enforce(send_types_to_server == 1); names : AttributeTypeAndName[count]; - values : LengthEncodedString[count]; + values : AttributeValue( + # Check if null_bitmap contains this attribute index. This + # will pass true if the attribute value is NULL and parsing + # skipped in AttributeValue above. + (null_bitmap[$context.connection.query_attr_idx() / 8] >> ($context.connection.query_attr_idx() % 8)) & 0x01, + names[$context.connection.query_attr_idx()].type + )[] &until($context.connection.query_attr_idx() >= count); }; type Query_Attributes = record { - count : uint8; - set_coun : uint8; - have_attr : case ( count > 0 ) of { - true -> attrs: Attributes(count); + count : LengthEncodedInteger; + set_count: LengthEncodedInteger; + have_attr: case ( attr_count > 0 ) of { + true -> attrs: Attributes(attr_count); false -> none: empty; - }; + } &requires(new_query_attrs); +} &let { + attr_count: int = to_int()(count); + new_query_attrs = $context.connection.new_query_attrs(); }; +# Command Request + type Command_Request_Packet = record { command: uint8; attrs : case ( command == COM_QUERY && $context.connection.get_client_query_attrs() && $context.connection.get_server_query_attrs() ) of { @@ -554,6 +655,7 @@ refine connection MySQL_Conn += { bool server_query_attrs_; bool client_query_attrs_; std::string auth_plugin_; + int query_attr_idx_; %} %init{ @@ -568,6 +670,7 @@ refine connection MySQL_Conn += { deprecate_eof_ = false; server_query_attrs_ = false; client_query_attrs_ = false; + query_attr_idx_ = 0; %} function get_version(): uint8 @@ -825,4 +928,21 @@ refine connection MySQL_Conn += { ++results_seen_; return true; %} + + function query_attr_idx(): int + %{ + return query_attr_idx_; + %} + + function new_query_attrs(): bool + %{ + query_attr_idx_ = 0; + return true; + %} + + function next_query_attr(): bool + %{ + query_attr_idx_++; + return true; + %} }; diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/mysql.log b/testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/mysql.log new file mode 100644 index 0000000000..1f6d2899e8 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/mysql.log @@ -0,0 +1,54 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path mysql +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cmd arg success rows response +#types time string addr port addr port string string bool count string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 login root T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 query show databases T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 query show tables T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list columns_priv T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list component T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list db T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list default_roles T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list engine_cost T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list func T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list general_log T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list global_grants T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list gtid_executed T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list help_category T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list help_keyword T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list help_relation T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list help_topic T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list innodb_index_stats T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list innodb_table_stats T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list ndb_binlog_index T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list password_history T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list plugin T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list procs_priv T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list proxies_priv T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list replication_asynchronous_connection_failover T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list replication_asynchronous_connection_failover_managed T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list replication_group_configuration_version T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list replication_group_member_actions T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list role_edges T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list server_cost T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list servers T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list slave_master_info T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list slave_relay_log_info T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list slave_worker_info T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list slow_log T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list tables_priv T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list time_zone T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list time_zone_leap_second T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list time_zone_name T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list time_zone_transition T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list time_zone_transition_type T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list user T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 query select @@version_comment limit 1 T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 query SELECT mysql_query_attribute_string('n1'), mysql_query_attribute_string('n2') T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 quit (empty) - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/out b/testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/out new file mode 100644 index 0000000000..a064e5f357 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/out @@ -0,0 +1,132 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +mysql handshake, root +mysql ok, 0 +mysql request, 3, show databases +mysql result row, [information_schema] +mysql result row, [mysql] +mysql result row, [performance_schema] +mysql result row, [sys] +mysql ok, 0 +mysql request, 3, show tables +mysql result row, [columns_priv] +mysql result row, [component] +mysql result row, [db] +mysql result row, [default_roles] +mysql result row, [engine_cost] +mysql result row, [func] +mysql result row, [general_log] +mysql result row, [global_grants] +mysql result row, [gtid_executed] +mysql result row, [help_category] +mysql result row, [help_keyword] +mysql result row, [help_relation] +mysql result row, [help_topic] +mysql result row, [innodb_index_stats] +mysql result row, [innodb_table_stats] +mysql result row, [ndb_binlog_index] +mysql result row, [password_history] +mysql result row, [plugin] +mysql result row, [procs_priv] +mysql result row, [proxies_priv] +mysql result row, [replication_asynchronous_connection_failover] +mysql result row, [replication_asynchronous_connection_failover_managed] +mysql result row, [replication_group_configuration_version] +mysql result row, [replication_group_member_actions] +mysql result row, [role_edges] +mysql result row, [server_cost] +mysql result row, [servers] +mysql result row, [slave_master_info] +mysql result row, [slave_relay_log_info] +mysql result row, [slave_worker_info] +mysql result row, [slow_log] +mysql result row, [tables_priv] +mysql result row, [time_zone] +mysql result row, [time_zone_leap_second] +mysql result row, [time_zone_name] +mysql result row, [time_zone_transition] +mysql result row, [time_zone_transition_type] +mysql result row, [user] +mysql ok, 0 +mysql request, 4, columns_priv\x00 +mysql ok, 0 +mysql request, 4, component\x00 +mysql ok, 0 +mysql request, 4, db\x00 +mysql ok, 0 +mysql request, 4, default_roles\x00 +mysql ok, 0 +mysql request, 4, engine_cost\x00 +mysql ok, 0 +mysql request, 4, func\x00 +mysql ok, 0 +mysql request, 4, general_log\x00 +mysql ok, 0 +mysql request, 4, global_grants\x00 +mysql ok, 0 +mysql request, 4, gtid_executed\x00 +mysql ok, 0 +mysql request, 4, help_category\x00 +mysql ok, 0 +mysql request, 4, help_keyword\x00 +mysql ok, 0 +mysql request, 4, help_relation\x00 +mysql ok, 0 +mysql request, 4, help_topic\x00 +mysql ok, 0 +mysql request, 4, innodb_index_stats\x00 +mysql ok, 0 +mysql request, 4, innodb_table_stats\x00 +mysql ok, 0 +mysql request, 4, ndb_binlog_index\x00 +mysql ok, 0 +mysql request, 4, password_history\x00 +mysql ok, 0 +mysql request, 4, plugin\x00 +mysql ok, 0 +mysql request, 4, procs_priv\x00 +mysql ok, 0 +mysql request, 4, proxies_priv\x00 +mysql ok, 0 +mysql request, 4, replication_asynchronous_connection_failover\x00 +mysql ok, 0 +mysql request, 4, replication_asynchronous_connection_failover_managed\x00 +mysql ok, 0 +mysql request, 4, replication_group_configuration_version\x00 +mysql ok, 0 +mysql request, 4, replication_group_member_actions\x00 +mysql ok, 0 +mysql request, 4, role_edges\x00 +mysql ok, 0 +mysql request, 4, server_cost\x00 +mysql ok, 0 +mysql request, 4, servers\x00 +mysql ok, 0 +mysql request, 4, slave_master_info\x00 +mysql ok, 0 +mysql request, 4, slave_relay_log_info\x00 +mysql ok, 0 +mysql request, 4, slave_worker_info\x00 +mysql ok, 0 +mysql request, 4, slow_log\x00 +mysql ok, 0 +mysql request, 4, tables_priv\x00 +mysql ok, 0 +mysql request, 4, time_zone\x00 +mysql ok, 0 +mysql request, 4, time_zone_leap_second\x00 +mysql ok, 0 +mysql request, 4, time_zone_name\x00 +mysql ok, 0 +mysql request, 4, time_zone_transition\x00 +mysql ok, 0 +mysql request, 4, time_zone_transition_type\x00 +mysql ok, 0 +mysql request, 4, user\x00 +mysql ok, 0 +mysql request, 3, select @@version_comment limit 1 +mysql result row, [MySQL Community Server - GPL] +mysql ok, 0 +mysql request, 3, SELECT mysql_query_attribute_string('n1'), mysql_query_attribute_string('n2') +mysql result row, [42, v2] +mysql ok, 0 +mysql request, 1, diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/mysql.log b/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/mysql.log new file mode 100644 index 0000000000..8ae14a6dc2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/mysql.log @@ -0,0 +1,14 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path mysql +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cmd arg success rows response +#types time string addr port addr port string string bool count string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33754 127.0.0.1 3306 login root T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33754 127.0.0.1 3306 ping (empty) T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33754 127.0.0.1 3306 query SELECT version() T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33754 127.0.0.1 3306 quit (empty) - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/out b/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/out new file mode 100644 index 0000000000..0924f49140 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/out @@ -0,0 +1,10 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +mysql handshake, root +mysql ok, 0 +mysql request, 14, +mysql ok, 0 +mysql request, 3, SELECT version() +mysql eof, T +mysql result row, [9.0.0] +mysql eof, F +mysql request, 1, diff --git a/testing/btest/Traces/mysql/many-query-attrs.pcap b/testing/btest/Traces/mysql/many-query-attrs.pcap new file mode 100644 index 0000000000000000000000000000000000000000..175e5a9644a21ad189cec7b03f14385249267f02 GIT binary patch literal 37064 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≈0df` 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 H`0D=vR>j^i literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/mysql/many-query-attr.test b/testing/btest/scripts/base/protocols/mysql/many-query-attr.test new file mode 100644 index 0000000000..5ff2e4cb92 --- /dev/null +++ b/testing/btest/scripts/base/protocols/mysql/many-query-attr.test @@ -0,0 +1,35 @@ +# @TEST-EXEC: zeek -b -C -r $TRACES/mysql/many-query-attrs.pcap %INPUT >out +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff mysql.log + +@load base/protocols/mysql + +event mysql_ok(c: connection, affected_rows: count) + { + print "mysql ok", affected_rows; + } + +event mysql_eof(c: connection, is_intermediate: bool) + { + print "mysql eof", is_intermediate; + } + +event mysql_result_row(c: connection, row: string_vec) + { + print "mysql result row", row; + } + +event mysql_error(c: connection, code: count, msg: string) + { + print "mysql error", code, msg; + } + +event mysql_command_request(c: connection, command: count, arg: string) + { + print "mysql request", command, arg; + } + +event mysql_handshake(c: connection, username: string) + { + print "mysql handshake", username; + } diff --git a/testing/btest/scripts/base/protocols/mysql/query-attr-non-string.test b/testing/btest/scripts/base/protocols/mysql/query-attr-non-string.test new file mode 100644 index 0000000000..ef6ef4d8b7 --- /dev/null +++ b/testing/btest/scripts/base/protocols/mysql/query-attr-non-string.test @@ -0,0 +1,35 @@ +# @TEST-EXEC: zeek -b -C -r $TRACES/mysql/mysql-9.0.0-query-attributes.pcap %INPUT >out +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff mysql.log + +@load base/protocols/mysql + +event mysql_ok(c: connection, affected_rows: count) + { + print "mysql ok", affected_rows; + } + +event mysql_eof(c: connection, is_intermediate: bool) + { + print "mysql eof", is_intermediate; + } + +event mysql_result_row(c: connection, row: string_vec) + { + print "mysql result row", row; + } + +event mysql_error(c: connection, code: count, msg: string) + { + print "mysql error", code, msg; + } + +event mysql_command_request(c: connection, command: count, arg: string) + { + print "mysql request", command, arg; + } + +event mysql_handshake(c: connection, username: string) + { + print "mysql handshake", username; + } From 7b8bbc6d001ae6e478257406ef001d41cb75237a Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 9 Jul 2024 16:32:21 +0200 Subject: [PATCH 29/93] btest/mysql: Clean query-attr.pcapng It contained some unrelated IntelliJ traffic. --- testing/btest/Traces/mysql/query-attr.pcap | Bin 0 -> 2557 bytes testing/btest/Traces/mysql/query-attr.pcapng | Bin 7696 -> 0 bytes .../scripts/base/protocols/mysql/query-attr.test | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 testing/btest/Traces/mysql/query-attr.pcap delete mode 100644 testing/btest/Traces/mysql/query-attr.pcapng diff --git a/testing/btest/Traces/mysql/query-attr.pcap b/testing/btest/Traces/mysql/query-attr.pcap new file mode 100644 index 0000000000000000000000000000000000000000..144134b89c42149c9eb828ead53b9b093ea19f8f GIT binary patch literal 2557 zcmbuBOKcle6o$_{>^Nbf2EwZ}5=JbV2ol*&;-pEXScs}Xf*1i=G%PGXCeEm1k2_Q-{nPeu|-f*N7 z*;f4B|3Ck^ll<`Y#rJp+VW&jk@XfX8a{Agm5*%hd9Z)F zYv-Uy_jv2EK)EOJ(4o_iNo8i#LM~~}q+-cp$~2GbMwVsu4ytV8TV%dJcU5|PR~z~6 zyHA2UaTTb&MZUS993bLv>vf6bd(-cG8Q;FRXzxW5XM1s;*C&tWAUvA>^RV#RcjC`? zzxt~_xzO{$D_yU5J^j~5Z9iTbo40!Zs6PTjOcvE_;J|P!HrSdhYN^t+Zsda}hU3Zj zfRNP9z=T>TpOBInO;rk|WFeJTLYkV+pEQqYExMU3n~EWzfIaSS%qoVd>V;q}E2(Jc zIU|*4UktEs(QXXlj2ch9!n57@(w&jB8`bdn___HG&aSs@my!4w&V<@qY}-aEY=5n# zxv;YW5LBVXDI}qM@uyPBNyZwOh$i2`=?lclrq*Hr~$$d@^ zG2&TQu8&A^pYqFn5D@}!rlKjCQaF)twk4U-^LgB_u%_nKQaDO;(wbVSuzO^E<{s?K z=>pDarID3)yCirM1yFm7S$V0#vb1LE63NObzZJaR9Je1wFJzTz#NGZMHz3*Y>?8;O z0Njty19aZ`j9xY}N;s>UB|}Y@OL$W-L2+v*!77Sul3**F_x2(?^Io~Jq>1%xuizlx z_&5ML6iDqYX8VZTRyV;Kk!<6h)*kIsbF{(_AVT0d;I@D-MCnJ2pN;afF(=c4e!RPf zj{OjiZEU2%R?*sC#ae!vi1}^$jnJ`Eb3`;Q2jFEqp4wZ?$f*ijMa%H#=Mc$=?lm$s z$MV~^lV5--2WbpC5iY$zC$P+7kyxxZGSnOG4@V;-1A`+2QBP(hYypKewkqGoCVa&e z=47^snT^-8x{AcnZv>b`0o2}NRu9V(BfejkNLKN0V=c4PG7WDJB6e;a^GSys!9yC$ zuCP_x{mj(xzlouCzic`rwM@i?Z-r(Fu~oB*u52gs8qt?f>N*ksM?(Fcgh<%iD6Fwn Xxt-1Pk}Is1&`>)jbat0j5_bJxw0wPw literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/mysql/query-attr.pcapng b/testing/btest/Traces/mysql/query-attr.pcapng deleted file mode 100644 index 15b6d479c14aae8bd679678e1ea0bdb06cabdadb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7696 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 +# @TEST-EXEC: zeek -b -C -r $TRACES/mysql/query-attr.pcap %INPUT >out # @TEST-EXEC: btest-diff out # @TEST-EXEC: btest-diff mysql.log From 4adea7978c14204bbe9c5edd7374cd2ee20e70e8 Mon Sep 17 00:00:00 2001 From: Fupeng Zhao Date: Fri, 12 Jul 2024 11:21:44 +0200 Subject: [PATCH 30/93] mysql: Improve date and time parsing --- .../protocol/mysql/mysql-protocol.pac | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/analyzer/protocol/mysql/mysql-protocol.pac b/src/analyzer/protocol/mysql/mysql-protocol.pac index bc350c747c..3ab7830d8f 100644 --- a/src/analyzer/protocol/mysql/mysql-protocol.pac +++ b/src/analyzer/protocol/mysql/mysql-protocol.pac @@ -209,14 +209,50 @@ enum field_types { TYPE_GEOMETRY = 0xff, }; +type Date = record { + year : int16; + month: int8; + day : int8; +}; + +type Time = record { + hour : int8; + minute: int8; + second: int8; +}; + type BinaryDate = record { len: uint8 &enforce(len == 0 || len == 4 || len == 7 || len == 11); - not_implemented: bytestring &length=len; + have_date: case ( len > 0 ) of { + true -> date : Date; + false -> none_1: empty; + }; + have_time: case ( len > 4 ) of { + true -> time : Time; + false -> none_2: empty; + }; + have_micros: case ( len > 7 ) of { + true -> micros: int32; + false -> none_3: empty; + }; +}; + +type DurationTime = record { + is_negative: int8 &enforce(is_negative == 0 || is_negative == 1); + days : int32; + time : Time; }; type BinaryTime = record { len: uint8 &enforce(len == 0 || len == 8 || len == 12); - not_implemented: bytestring &length=len; + have_time: case ( len > 0 ) of { + true -> time : DurationTime; + false -> none_1: empty; + }; + have_micros: case ( len > 8 ) of { + true -> micros: int32; + false -> none_2: empty; + }; }; type BinaryValue(type: uint16) = record { From 2e1e57033d6ee42275ec1cf3cb71857a25d32776 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 25 Jul 2024 11:45:13 +0200 Subject: [PATCH 31/93] mysql: Simplify length computation Thanks Tim! --- src/analyzer/protocol/mysql/mysql-protocol.pac | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/analyzer/protocol/mysql/mysql-protocol.pac b/src/analyzer/protocol/mysql/mysql-protocol.pac index 3ab7830d8f..aeee595887 100644 --- a/src/analyzer/protocol/mysql/mysql-protocol.pac +++ b/src/analyzer/protocol/mysql/mysql-protocol.pac @@ -345,7 +345,7 @@ type Handshake_v10 = record { character_set : uint8; status_flags : uint16; capability_flags_2 : uint16; - auth_plugin_data_len : uint8; + auth_plugin_data_len : uint8 &enforce( auth_plugin_data_len==0 || auth_plugin_data_len >= 21); reserved : padding[10]; auth_plugin_data_part_2: bytestring &length=auth_plugin_data_part_2_len; have_plugin : case ( ( capability_flags_2 << 16 ) & CLIENT_PLUGIN_AUTH ) of { @@ -353,7 +353,13 @@ type Handshake_v10 = record { 0x0 -> none : empty; }; } &let { - auth_plugin_data_part_2_len = (auth_plugin_data_len > 8 && (auth_plugin_data_len - 8) > 13) ? auth_plugin_data_len - 8 : 13; + # The length of auth_plugin_data_part_2 is at least 13 bytes, + # or auth_plugin_data_len - 8 if that is larger, check for + # auth_plugin_data_len > 21 (8 + 13) to prevent underflow for + # when subtracting 8. + # + # https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_packets_protocol_handshake_v10.html + auth_plugin_data_part_2_len = auth_plugin_data_len > 21 ? auth_plugin_data_len - 8 : 13; update_auth_plugin: bool = $context.connection.set_auth_plugin(auth_plugin) &if( ( capability_flags_2 << 16 ) & CLIENT_PLUGIN_AUTH ); server_query_attrs: bool = $context.connection.set_server_query_attrs(( capability_flags_2 << 16 ) & CLIENT_QUERY_ATTRIBUTES); From 7afb9b2afb48ac909b6e5727aa171e91656d776f Mon Sep 17 00:00:00 2001 From: zeek-bot Date: Fri, 26 Jul 2024 00:10:24 +0000 Subject: [PATCH 32/93] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 8937245582..7c810aa123 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 893724558253c3c12b87eee031e4c68eb983868b +Subproject commit 7c810aa123898d2303b87703442c76c9ce77219c From 666341fcbb71ca8653669a56dcbf18108ed65752 Mon Sep 17 00:00:00 2001 From: Benjamin Bannier Date: Fri, 26 Jul 2024 13:28:31 +0200 Subject: [PATCH 33/93] Bump auxil/spicy to latest development snapshot This in particular pulls in a fix for zeek/spicy#1808. --- auxil/spicy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/spicy b/auxil/spicy index 04c5ed3c27..4c5c26bf34 160000 --- a/auxil/spicy +++ b/auxil/spicy @@ -1 +1 @@ -Subproject commit 04c5ed3c27879459de69d12efc417c6915f304b9 +Subproject commit 4c5c26bf34c2cf2cedf56270e84f1271fcf94465 From 02e3d302277a01fa3cdd4eb9ae51a2408145c9c4 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 26 Jul 2024 12:31:53 +0200 Subject: [PATCH 34/93] ldap: Recognize SASL+SPNEGO+NTLMSSP The ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap file was harvested from the CTU-SME-11 (Experiment-VM-Microsoft-Windows7AD-1) dataset at https://zenodo.org/records/7958259 (DOI 10.5281/zenodo.7958258). Closes #3853 --- src/analyzer/protocol/ldap/ldap.spicy | 34 ++++++++++-------- .../conn.log | 12 +++++++ .../ldap.log | 14 ++++++++ testing/btest/Traces/README | 3 ++ .../ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap | Bin 0 -> 2084 bytes .../base/protocols/ldap/spnego-ntlmssp.zeek | 15 ++++++++ 6 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/ldap.log create mode 100644 testing/btest/Traces/ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap create mode 100644 testing/btest/scripts/base/protocols/ldap/spnego-ntlmssp.zeek diff --git a/src/analyzer/protocol/ldap/ldap.spicy b/src/analyzer/protocol/ldap/ldap.spicy index 96f942d7a3..52ab0e6160 100644 --- a/src/analyzer/protocol/ldap/ldap.spicy +++ b/src/analyzer/protocol/ldap/ldap.spicy @@ -375,26 +375,29 @@ type GSS_SPNEGO_negTokenInit = unit { : skip bytes &eod; }; -# Peak into GSS-SPNEGO payload and ensure it is indeed GSS-SPNEGO. +# Peak into GSS-SPNEGO payload and ensure it is indeed GSS-SPNEGO, +# or GSS-SPNEGO with a NTMLSSP payload that starts with NTLMSSP. type GSS_SPNEGO_Init = unit { # This is the optional octet string in SaslCredentials. credentialsHeader: ASN1::ASN1Header &requires=($$.tag.type_ == ASN1::ASN1Type::OctetString); # Now we either have the initial message as specified in RFC2743 or - # a continuation from RFC4178 + # a continuation from RFC4178, or a "NTMLSSP" signature. # - # 60 -> APPLICATION [0] https://datatracker.ietf.org/doc/html/rfc2743#page-81) + # 60 -> APPLICATION [0] https://datatracker.ietf.org/doc/html/rfc2743#page-81 # a1 -> CHOICE [1] https://www.rfc-editor.org/rfc/rfc4178#section-4.2 + # "NTMLSSP" https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/907f519d-6217-45b1-b421-dca10fc8af0d # - gssapiHeader: ASN1::ASN1Header &requires=( - $$.tag.class == ASN1::ASN1Class::Application && $$.tag.type_ == ASN1::ASN1Type(0) - || $$.tag.class == ASN1::ASN1Class::ContextSpecific && $$.tag.type_ == ASN1::ASN1Type(1) - ); + switch { + -> spnegoInitByte: uint8(0x60); + -> spnegoChoiceByte: uint8(0xa1); + -> ntlmSignature: skip b"NTLMSSP"; # Unsupported, should forward to child analyzer! + }; - switch ( self.gssapiHeader.tag.type_ ) { - ASN1::ASN1Type(0) -> initial: GSS_SPNEGO_negTokenInit; - * -> : skip bytes &eod; - } &size=self.gssapiHeader.len.len; + spnegoLen: skip ASN1::LengthType if (self?.spnegoInitByte || self?.spnegoChoiceByte); + + # Peak into the SPNEGO_negTokenInit + spnegoInitial: skip GSS_SPNEGO_negTokenInit if (self?.spnegoInitByte); }; type SaslCredentials = unit() { @@ -408,10 +411,13 @@ type SaslCredentials = unit() { }; type GSS_SPNEGO_Subsequent = unit { - token: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific); - switch ( self.token.tag.type_ ) { - ASN1::ASN1Type(1) -> negTokenResp: GSS_SPNEGO_negTokenResp; + switch { + -> spnegoChoiceByte: uint8(0xa1); + -> ntmlSignature: skip b"NTLMSSP"; # Unsupported, should forward to NTLM! }; + + spnegoChoiceLen: skip ASN1::LengthType if (self?.spnegoChoiceByte); + negTokenResp: GSS_SPNEGO_negTokenResp if (self?.spnegoChoiceByte); }; type GSS_SPNEGO_negTokenResp = unit { diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/conn.log new file mode 100644 index 0000000000..84a495d3fb --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/conn.log @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.1.105 50041 192.168.1.108 389 tcp ldap_tcp 0.004745 93 283 RSTR 0 ShADdFar 5 305 4 455 - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.168.1.107 50041 192.168.1.108 389 tcp ldap_tcp 0.005883 93 283 RSTR 0 ShADdFar 5 305 4 455 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/ldap.log new file mode 100644 index 0000000000..07355e0e78 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/ldap.log @@ -0,0 +1,14 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ldap +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument +#types time string addr port addr port int int string string string string string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.1.105 50041 192.168.1.108 389 160 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.1.105 50041 192.168.1.108 389 161 - unbind - - - - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.168.1.107 50041 192.168.1.108 389 427 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.168.1.107 50041 192.168.1.108 389 428 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/README b/testing/btest/Traces/README index bc5a304436..43942584f2 100644 --- a/testing/btest/Traces/README +++ b/testing/btest/Traces/README @@ -18,3 +18,6 @@ Trace Index/Sources: - one `\x30` byte in the ciphertext changed to `\x00` - ldap/issue-32.pcapng: Provided by GH user martinvanhensbergen, +- ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap: Harvested from CTU-SME-11 + (Experiment-VM-Microsoft-Windows7AD-1) dataset, filtering on tcp port 389 and port 50041. + https://zenodo.org/records/7958259 (DOI 10.5281/zenodo.7958258). diff --git a/testing/btest/Traces/ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap b/testing/btest/Traces/ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap new file mode 100644 index 0000000000000000000000000000000000000000..dd2b34ce4add5cef82f592fb7a64421f6153fcf4 GIT binary patch literal 2084 zcmds%Uq}>D6voe;9rurtyDOOzY#36mq9U=16hW@3P@8V84+*wv24-tS=F39rwrC;= zAwBqq3N@2*?ZFTUdZ`ww$AU6ae9-Elf7l1)xifcWc7F5Cch3D@ zgzpYYAjA451H+SG+?U!GI|C=qX&52xnIQ-F=lhn8Pz2zxHSdFfzGC}>TdW>OL)g#S z)1OaYB2qv~0d^Tcl4B;APG@9HmWcQyT_AFn!X=`shlm*lq7jv~hyC8FMGI290tqQF zzA2LUIfFqSzL7?RM!T(rYs}PW>_V#5ZDC-UQ@*s)!Jq>PG$JT|TPsnHPDiCAGq`pU zAg2uqP))M}iRomxLDM`rw#4Jf^0-TjO3Gw=X}Rl=$K&QE_XLge_zz*zvvC_< zFq2*5xeN|tHE5{Tt9G$MS1-x3f794yMZ0F*DC=vzB8w%GtQyq9;$m663^H^C8K^=e zd|Lwk^6{7$?3_Q{oZOc7F@CSAY7!>l0G{Y|fgN}-d!QVSKmqQ{z=cOANceQ*RR+mX zu4ci0C`1KY@m>=&LJjWEAg2b7LpIJDp$>H55biecyULTb4Y0KT&CwY|qo zSYu5Jc>70`6p-hLa`rw_d_wZsD_mw2u%mSrA_QZM$urViJGYRK5 z?8kSU7#4}6CQif@7+zBP@s&ss3J-Sg3Q>|mV&P{NQin!ksjG(<70Q(+L5r61i&I9U LQZNN>eggOn=p^s( literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ldap/spnego-ntlmssp.zeek b/testing/btest/scripts/base/protocols/ldap/spnego-ntlmssp.zeek new file mode 100644 index 0000000000..e936332b47 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/spnego-ntlmssp.zeek @@ -0,0 +1,15 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. +# +# The ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap file was harvested +# from the CTU-SME-11 (Experiment-VM-Microsoft-Windows7AD-1) dataset +# at https://zenodo.org/records/7958259 (DOI 10.5281/zenodo.7958258). + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: SASL bindRequest with SPNEGO NTLMSSP. From e9adb8e46284173558927c785f0cad8022ac46b4 Mon Sep 17 00:00:00 2001 From: zeek-bot Date: Tue, 30 Jul 2024 00:10:33 +0000 Subject: [PATCH 35/93] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 7c810aa123..9eeee6bd64 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 7c810aa123898d2303b87703442c76c9ce77219c +Subproject commit 9eeee6bd64be928c730ef799cb448816cb1f4c1d From ed4acd2437646c55eddefad3ae1b4011d8635247 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Wed, 31 Jul 2024 12:22:08 +0200 Subject: [PATCH 36/93] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 9eeee6bd64..20e7d06fcc 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 9eeee6bd64be928c730ef799cb448816cb1f4c1d +Subproject commit 20e7d06fcc5ed135ddebdd94073cf06a62af4908 From af65c29a3eb399863b3d017d130e4c043eb4ee78 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 31 Jul 2024 10:19:11 -0700 Subject: [PATCH 37/93] CI: Use 16GB of memory for FreeBSD builds --- .cirrus.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index b96146f230..88ffb16c76 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -35,8 +35,7 @@ macos_environment: &MACOS_ENVIRONMENT freebsd_resources_template: &FREEBSD_RESOURCES_TEMPLATE cpu: 8 - # Not allowed to request less than 8GB for an 8 CPU FreeBSD VM. - memory: 8GB + memory: *MEMORY # For greediness, see https://medium.com/cirruslabs/introducing-greedy-container-instances-29aad06dc2b4 greedy: true From 7ac7ce1d2bf3d863846d034504c83718b8850f5c Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 26 Jul 2024 11:12:54 -0700 Subject: [PATCH 38/93] Process metric callbacks from the main-loop thread This avoids the callbacks from being processed on the worker thread spawned by Civetweb. It fixes data race issues with lookups involving global variables, amongst other threading issues. --- auxil/prometheus-cpp | 2 +- scripts/base/init-bare.zeek | 7 ++ src/telemetry/CMakeLists.txt | 1 + src/telemetry/Manager.cc | 79 ++++++++++++++++++- src/telemetry/Manager.h | 40 ++++++++-- src/telemetry/consts.bif | 2 + src/zeek-setup.cc | 2 + .../canonified_loaded_scripts.log | 1 + .../canonified_loaded_scripts.log | 1 + testing/btest/Baseline/plugins.hooks/output | 6 ++ 10 files changed, 130 insertions(+), 11 deletions(-) create mode 100644 src/telemetry/consts.bif diff --git a/auxil/prometheus-cpp b/auxil/prometheus-cpp index 2fec7205d1..4649065e2a 160000 --- a/auxil/prometheus-cpp +++ b/auxil/prometheus-cpp @@ -1 +1 @@ -Subproject commit 2fec7205d1a9cb4829b86c943d599696d53de85c +Subproject commit 4649065e2a1dd21c81e41cd6007dce5486b77fc0 diff --git a/scripts/base/init-bare.zeek b/scripts/base/init-bare.zeek index 30b49def26..85a1dc0f20 100644 --- a/scripts/base/init-bare.zeek +++ b/scripts/base/init-bare.zeek @@ -5883,6 +5883,13 @@ export { type MetricVector : vector of Metric; type HistogramMetricVector : vector of HistogramMetric; + + ## Maximum amount of time for CivetWeb HTTP threads to + ## wait for metric callbacks to complete on the IO loop. + const callback_timeout: interval = 5sec &redef; + + ## Number of CivetWeb threads to use. + const civetweb_threads: count = 2 &redef; } module GLOBAL; diff --git a/src/telemetry/CMakeLists.txt b/src/telemetry/CMakeLists.txt index d61cbdb671..a760dcd13c 100644 --- a/src/telemetry/CMakeLists.txt +++ b/src/telemetry/CMakeLists.txt @@ -9,6 +9,7 @@ zeek_add_subdir_library( ProcessStats.cc Utils.cc BIFS + consts.bif telemetry.bif) # We don't need to include the civetweb headers across the whole project, only diff --git a/src/telemetry/Manager.cc b/src/telemetry/Manager.cc index 04c47ba3ef..6ae4e06ec6 100644 --- a/src/telemetry/Manager.cc +++ b/src/telemetry/Manager.cc @@ -6,6 +6,7 @@ // CivetServer is from the civetweb submodule in prometheus-cpp #include +#include #include #include #include @@ -16,19 +17,32 @@ #include "zeek/3rdparty/doctest.h" #include "zeek/ID.h" +#include "zeek/RunState.h" #include "zeek/ZeekString.h" #include "zeek/broker/Manager.h" +#include "zeek/iosource/Manager.h" #include "zeek/telemetry/ProcessStats.h" #include "zeek/telemetry/Timer.h" +#include "zeek/telemetry/consts.bif.h" #include "zeek/telemetry/telemetry.bif.h" #include "zeek/threading/formatters/detail/json.h" namespace zeek::telemetry { -Manager::Manager() { prometheus_registry = std::make_shared(); } +/** + * Prometheus Collectable interface used to insert Zeek callback processing + * before the Prometheus registry's collection of metric data. + */ +class ZeekCollectable : public prometheus::Collectable { +public: + std::vector Collect() const override { + telemetry_mgr->WaitForPrometheusCallbacks(); + return {}; + } +}; + +Manager::Manager() : IOSource(true) { prometheus_registry = std::make_shared(); } -// This can't be defined as =default because of the use of unique_ptr with a forward-declared type -// in Manager.h Manager::~Manager() {} void Manager::InitPostScript() { @@ -75,7 +89,9 @@ void Manager::InitPostScript() { if ( ! getenv("ZEEKCTL_CHECK_CONFIG") ) { try { - prometheus_exposer = std::make_unique(prometheus_url, 2, callbacks); + prometheus_exposer = + std::make_unique(prometheus_url, BifConst::Telemetry::civetweb_threads, + callbacks); // CivetWeb stores a copy of the callbacks, so we're safe to delete the pointer here delete callbacks; @@ -84,6 +100,13 @@ void Manager::InitPostScript() { prometheus_url.c_str()); } + // This has to be inserted before the registry below. The exposer + // processes the collectors in order of insertion. We want to make + // sure that the callbacks get called and the values in the metrics + // are updated before prometheus-cpp scrapes them. + zeek_collectable = std::make_shared(); + prometheus_exposer->RegisterCollectable(zeek_collectable); + prometheus_exposer->RegisterCollectable(prometheus_registry); } } @@ -130,6 +153,21 @@ void Manager::InitPostScript() { return metric; }); #endif + + iosource_mgr->RegisterFd(collector_flare.FD(), this); +} + +void Manager::Terminate() { + // Notify the collector condition so that it doesn't hang waiting for + // a collector request to complete. + collector_cv.notify_all(); + + // Shut down the exposer first of all so we stop getting requests for + // data. This keeps us from getting a request on another thread while + // we're shutting down. + prometheus_exposer.reset(); + + iosource_mgr->UnregisterFd(collector_flare.FD(), this); } // -- collect metric stuff ----------------------------------------------------- @@ -545,6 +583,39 @@ HistogramPtr Manager::HistogramInstance(std::string_view prefix, std::string_vie return HistogramInstance(prefix, name, lbls, bounds_span, helptext, unit); } +void Manager::ProcessFd(int fd, int flags) { + std::unique_lock lk(collector_cv_mtx); + + collector_flare.Extinguish(); + + prometheus_registry->UpdateViaCallbacks(); + collector_response_idx = collector_request_idx; + + lk.unlock(); + collector_cv.notify_all(); +} + +void Manager::WaitForPrometheusCallbacks() { + std::unique_lock lk(collector_cv_mtx); + + ++collector_request_idx; + uint64_t expected_idx = collector_request_idx; + collector_flare.Fire(); + + // It should *not* take 5 seconds to go through all of the callbacks, but + // set this to have a timeout anyways just to avoid a deadlock. + bool res = collector_cv.wait_for(lk, + std::chrono::microseconds( + static_cast(BifConst::Telemetry::callback_timeout * 1000000)), + [expected_idx]() { + return telemetry_mgr->collector_response_idx >= expected_idx || + zeek::run_state::terminating; + }); + + if ( ! res ) + fprintf(stderr, "Timeout waiting for prometheus callbacks\n"); +} + } // namespace zeek::telemetry // -- unit tests --------------------------------------------------------------- diff --git a/src/telemetry/Manager.h b/src/telemetry/Manager.h index c4c2537f1a..d967fe43c0 100644 --- a/src/telemetry/Manager.h +++ b/src/telemetry/Manager.h @@ -9,8 +9,10 @@ #include #include +#include "zeek/Flare.h" #include "zeek/IntrusivePtr.h" #include "zeek/Span.h" +#include "zeek/iosource/IOSource.h" #include "zeek/telemetry/Counter.h" #include "zeek/telemetry/Gauge.h" #include "zeek/telemetry/Histogram.h" @@ -29,15 +31,16 @@ class Registry; namespace zeek::telemetry { +class ZeekCollectable; + /** * Manages a collection of metric families. */ -class Manager final { +class Manager final : public iosource::IOSource { public: Manager(); Manager(const Manager&) = delete; - Manager& operator=(const Manager&) = delete; ~Manager(); @@ -50,6 +53,8 @@ public: */ void InitPostScript(); + void Terminate(); + /** * @return A VectorVal containing all counter and gauge metrics and their values matching prefix and name. * @param prefix The prefix pattern to use for filtering. Supports globbing. @@ -88,8 +93,8 @@ public: * @param labels Values for all label dimensions of the metric. * @param helptext Short explanation of the metric. * @param unit Unit of measurement. - * @param callback Passing a callback method will enable asynchronous mode. The callback method will be called by - * the metrics subsystem whenever data is requested. + * @param callback Passing a callback method will enable asynchronous mode. The callback method will be called + * by the metrics subsystem whenever data is requested. */ CounterPtr CounterInstance(std::string_view prefix, std::string_view name, Span labels, std::string_view helptext, std::string_view unit = "", @@ -124,8 +129,8 @@ public: * @param labels Values for all label dimensions of the metric. * @param helptext Short explanation of the metric. * @param unit Unit of measurement. - * @param callback Passing a callback method will enable asynchronous mode. The callback method will be called by - * the metrics subsystem whenever data is requested. + * @param callback Passing a callback method will enable asynchronous mode. The callback method will be called + * by the metrics subsystem whenever data is requested. */ GaugePtr GaugeInstance(std::string_view prefix, std::string_view name, Span labels, std::string_view helptext, std::string_view unit = "", @@ -212,6 +217,12 @@ public: */ std::shared_ptr GetRegistry() const { return prometheus_registry; } + // IOSource interface + double GetNextTimeout() override { return -1.0; } + void Process() override {} + const char* Tag() override { return "Telemetry::Manager"; } + void ProcessFd(int fd, int flags) override; + protected: template static auto WithLabelNames(Span xs, F continuation) { @@ -231,6 +242,15 @@ protected: } } + friend class ZeekCollectable; + + /** + * Fires the flare for prometheus-cpp callback handling and waits for it to complete. + * This can be called from other threads to ensure the callback handling happens on + * the main thread. + */ + void WaitForPrometheusCallbacks(); + private: RecordValPtr GetMetricOptsRecord(const prometheus::MetricFamily& metric_family); void BuildClusterJson(); @@ -250,6 +270,14 @@ private: std::unique_ptr prometheus_exposer; std::string cluster_json; + + std::shared_ptr zeek_collectable; + zeek::detail::Flare collector_flare; + std::condition_variable collector_cv; + std::mutex collector_cv_mtx; + // Only modified under collector_cv_mtx! + uint64_t collector_request_idx = 0; + uint64_t collector_response_idx = 0; }; } // namespace zeek::telemetry diff --git a/src/telemetry/consts.bif b/src/telemetry/consts.bif new file mode 100644 index 0000000000..76c256dfa1 --- /dev/null +++ b/src/telemetry/consts.bif @@ -0,0 +1,2 @@ +const Telemetry::callback_timeout: interval; +const Telemetry::civetweb_threads: count; diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index b05af74f20..3f5549b78a 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -376,6 +376,7 @@ static void terminate_zeek() { input_mgr->Terminate(); thread_mgr->Terminate(); broker_mgr->Terminate(); + telemetry_mgr->Terminate(); event_mgr.Drain(); @@ -716,6 +717,7 @@ SetupResult setup(int argc, char** argv, Options* zopts) { // when that variable is defined. auto early_shutdown = [] { broker_mgr->Terminate(); + telemetry_mgr->Terminate(); delete iosource_mgr; delete telemetry_mgr; }; diff --git a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log index aee483157a..5466f0ea13 100644 --- a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log @@ -146,6 +146,7 @@ scripts/base/init-frameworks-and-bifs.zeek scripts/base/frameworks/files/magic/__load__.zeek scripts/base/frameworks/telemetry/options.zeek build/scripts/base/bif/__load__.zeek + build/scripts/base/bif/consts.bif.zeek build/scripts/base/bif/telemetry.bif.zeek build/scripts/base/bif/zeekygen.bif.zeek build/scripts/base/bif/pcap.bif.zeek diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index 40a1c5b84c..07dc32da6d 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -146,6 +146,7 @@ scripts/base/init-frameworks-and-bifs.zeek scripts/base/frameworks/files/magic/__load__.zeek scripts/base/frameworks/telemetry/options.zeek build/scripts/base/bif/__load__.zeek + build/scripts/base/bif/consts.bif.zeek build/scripts/base/bif/telemetry.bif.zeek build/scripts/base/bif/zeekygen.bif.zeek build/scripts/base/bif/pcap.bif.zeek diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index c3b551dc84..2514d98015 100644 --- a/testing/btest/Baseline/plugins.hooks/output +++ b/testing/btest/Baseline/plugins.hooks/output @@ -464,6 +464,7 @@ 0.000000 MetaHookPost LoadFile(0, ./comm.bif.zeek, <...>/comm.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./communityid.bif.zeek, <...>/communityid.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./const.bif.zeek, <...>/const.bif.zeek) -> -1 +0.000000 MetaHookPost LoadFile(0, ./consts.bif.zeek, <...>/consts.bif.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./contents, <...>/contents.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./control, <...>/control.zeek) -> -1 0.000000 MetaHookPost LoadFile(0, ./data.bif.zeek, <...>/data.bif.zeek) -> -1 @@ -758,6 +759,7 @@ 0.000000 MetaHookPost LoadFileExtended(0, ./comm.bif.zeek, <...>/comm.bif.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./communityid.bif.zeek, <...>/communityid.bif.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./const.bif.zeek, <...>/const.bif.zeek) -> (-1, ) +0.000000 MetaHookPost LoadFileExtended(0, ./consts.bif.zeek, <...>/consts.bif.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./contents, <...>/contents.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./control, <...>/control.zeek) -> (-1, ) 0.000000 MetaHookPost LoadFileExtended(0, ./data.bif.zeek, <...>/data.bif.zeek) -> (-1, ) @@ -1384,6 +1386,7 @@ 0.000000 MetaHookPre LoadFile(0, ./comm.bif.zeek, <...>/comm.bif.zeek) 0.000000 MetaHookPre LoadFile(0, ./communityid.bif.zeek, <...>/communityid.bif.zeek) 0.000000 MetaHookPre LoadFile(0, ./const.bif.zeek, <...>/const.bif.zeek) +0.000000 MetaHookPre LoadFile(0, ./consts.bif.zeek, <...>/consts.bif.zeek) 0.000000 MetaHookPre LoadFile(0, ./contents, <...>/contents.zeek) 0.000000 MetaHookPre LoadFile(0, ./control, <...>/control.zeek) 0.000000 MetaHookPre LoadFile(0, ./data.bif.zeek, <...>/data.bif.zeek) @@ -1678,6 +1681,7 @@ 0.000000 MetaHookPre LoadFileExtended(0, ./comm.bif.zeek, <...>/comm.bif.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./communityid.bif.zeek, <...>/communityid.bif.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./const.bif.zeek, <...>/const.bif.zeek) +0.000000 MetaHookPre LoadFileExtended(0, ./consts.bif.zeek, <...>/consts.bif.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./contents, <...>/contents.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./control, <...>/control.zeek) 0.000000 MetaHookPre LoadFileExtended(0, ./data.bif.zeek, <...>/data.bif.zeek) @@ -2305,6 +2309,7 @@ 0.000000 | HookLoadFile ./comm.bif.zeek <...>/comm.bif.zeek 0.000000 | HookLoadFile ./communityid.bif.zeek <...>/communityid.bif.zeek 0.000000 | HookLoadFile ./const.bif.zeek <...>/const.bif.zeek +0.000000 | HookLoadFile ./consts.bif.zeek <...>/consts.bif.zeek 0.000000 | HookLoadFile ./contents <...>/contents.zeek 0.000000 | HookLoadFile ./control <...>/control.zeek 0.000000 | HookLoadFile ./data.bif.zeek <...>/data.bif.zeek @@ -2599,6 +2604,7 @@ 0.000000 | HookLoadFileExtended ./comm.bif.zeek <...>/comm.bif.zeek 0.000000 | HookLoadFileExtended ./communityid.bif.zeek <...>/communityid.bif.zeek 0.000000 | HookLoadFileExtended ./const.bif.zeek <...>/const.bif.zeek +0.000000 | HookLoadFileExtended ./consts.bif.zeek <...>/consts.bif.zeek 0.000000 | HookLoadFileExtended ./contents <...>/contents.zeek 0.000000 | HookLoadFileExtended ./control <...>/control.zeek 0.000000 | HookLoadFileExtended ./data.bif.zeek <...>/data.bif.zeek From 8acc5ae15ec4b756a01fac033e6021dd5a8c2266 Mon Sep 17 00:00:00 2001 From: zeek-bot Date: Sat, 3 Aug 2024 00:12:18 +0000 Subject: [PATCH 39/93] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 20e7d06fcc..2d35a0d90c 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 20e7d06fcc5ed135ddebdd94073cf06a62af4908 +Subproject commit 2d35a0d90c249dc60ecdeb77b25754381f876e57 From 77c05357b5dc45381e90edb0b17a3acdab55bfb5 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 30 May 2024 16:00:41 -0700 Subject: [PATCH 40/93] Move pulling of global state inside 'expensive' check for stats --- src/Stats.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Stats.cc b/src/Stats.cc index 7f49585121..fb7766eaac 100644 --- a/src/Stats.cc +++ b/src/Stats.cc @@ -213,14 +213,12 @@ void ProfileLogger::Log() { cs.num_events_outgoing, cs.num_logs_incoming, cs.num_logs_outgoing, cs.num_ids_incoming, cs.num_ids_outgoing)); - // Script-level state. - const auto& globals = global_scope()->Vars(); - if ( expensive ) { + // Script-level state. int total_table_entries = 0; int total_table_rentries = 0; - for ( const auto& global : globals ) { + for ( const auto& global : global_scope()->Vars() ) { auto& id = global.second; // We don't show/count internal globals as they are always From 8b4af064840f32e88f030d8fa9f4d707440792d3 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 28 May 2024 16:53:10 -0700 Subject: [PATCH 41/93] Move trigger stats to telemetry instruments --- src/Trigger.cc | 19 ++++++++++++++++--- src/Trigger.h | 10 +++++++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/Trigger.cc b/src/Trigger.cc index dae99bab37..3dfe76e2dc 100644 --- a/src/Trigger.cc +++ b/src/Trigger.cc @@ -13,6 +13,7 @@ #include "zeek/Traverse.h" #include "zeek/Val.h" #include "zeek/iosource/Manager.h" +#include "zeek/telemetry/Manager.h" using namespace zeek::detail; using namespace zeek::detail::trigger; @@ -437,7 +438,19 @@ Manager::Manager() : iosource::IOSource() { pending = new TriggerList(); } Manager::~Manager() { delete pending; } -void Manager::InitPostScript() { iosource_mgr->Register(this, true); } +void Manager::InitPostScript() { + trigger_count = telemetry_mgr->CounterInstance("zeek", "triggers", {}, "Total number of triggers scheduled"); + trigger_pending = + telemetry_mgr->GaugeInstance("zeek", "pending_triggers", {}, "Pending number of triggers", "", + []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + metric.gauge.value = + trigger_mgr ? static_cast(trigger_mgr->pending->size()) : 0.0; + return metric; + }); + + iosource_mgr->Register(this, true); +} double Manager::GetNextTimeout() { return pending->empty() ? -1 : run_state::network_time + 0.100; } @@ -468,13 +481,13 @@ void Manager::Queue(Trigger* trigger) { if ( std::find(pending->begin(), pending->end(), trigger) == pending->end() ) { Ref(trigger); pending->push_back(trigger); - total_triggers++; + trigger_count->Inc(); iosource_mgr->Wakeup(Tag()); } } void Manager::GetStats(Stats* stats) { - stats->total = total_triggers; + stats->total = static_cast(trigger_count->Value()); stats->pending = pending->size(); } diff --git a/src/Trigger.h b/src/Trigger.h index 6c4fade3be..5955cc25b4 100644 --- a/src/Trigger.h +++ b/src/Trigger.h @@ -18,6 +18,13 @@ class Val; using ValPtr = IntrusivePtr; +namespace telemetry { +class Gauge; +class Counter; +using GaugePtr = std::shared_ptr; +using CounterPtr = std::shared_ptr; +} // namespace telemetry + namespace detail { class Frame; @@ -187,7 +194,8 @@ public: private: using TriggerList = std::list; TriggerList* pending; - unsigned long total_triggers = 0; + telemetry::CounterPtr trigger_count; + telemetry::GaugePtr trigger_pending; }; } // namespace trigger From d1f7999f61137bae6070c352e421969d97d1a26f Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 28 May 2024 19:52:49 -0700 Subject: [PATCH 42/93] Move dns_mgr stats to telemetry instruments --- src/DNS_Mgr.cc | 111 ++++++++++++++++++++++++++++++++++++++----------- src/DNS_Mgr.h | 38 +++++++++++++---- src/Stats.cc | 2 +- src/stats.bif | 8 ++-- 4 files changed, 122 insertions(+), 37 deletions(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index a707d8ead0..33da7dd0ae 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -45,6 +45,7 @@ using ztd::out_ptr::out_ptr; #include "zeek/Val.h" #include "zeek/ZeekString.h" #include "zeek/iosource/Manager.h" +#include "zeek/telemetry/Manager.h" // Number of seconds we'll wait for a reply. constexpr int DNS_TIMEOUT = 5; @@ -545,6 +546,55 @@ void DNS_Mgr::InitSource() { } void DNS_Mgr::InitPostScript() { + num_requests_metric = + telemetry_mgr->CounterInstance("zeek", "dnsmgr_requests", {}, "Total number of requests through DNS_Mgr"); + successful_metric = telemetry_mgr->CounterInstance("zeek", "dnsmgr_successful_requests", {}, + "Total number of successful requests through DNS_Mgr"); + failed_metric = telemetry_mgr->CounterInstance("zeek", "dnsmgr_failed_requests", {}, + "Total number of failed requests through DNS_Mgr"); + asyncs_pending_metric = telemetry_mgr->GaugeInstance("zeek", "dnsmgr_pending_asyncs_requests", {}, + "Number of pending async requests through DNS_Mgr"); + + cached_hosts_metric = + telemetry_mgr->GaugeInstance("zeek", "dnsmgr_cache_entries", {{"type", "host"}}, + "Number of cached hosts in DNS_Mgr", "", []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + metric.gauge.value = 0; + + if ( dns_mgr ) { + dns_mgr->UpdateCachedStats(false); + metric.gauge.value = static_cast(dns_mgr->last_cached_stats.hosts); + } + return metric; + }); + + cached_addresses_metric = + telemetry_mgr->GaugeInstance("zeek", "dnsmgr_cache_entries", {{"type", "address"}}, + "Number of cached addresses in DNS_Mgr", "", []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + metric.gauge.value = 0; + + if ( dns_mgr ) { + dns_mgr->UpdateCachedStats(false); + metric.gauge.value = + static_cast(dns_mgr->last_cached_stats.addresses); + } + return metric; + }); + + cached_texts_metric = + telemetry_mgr->GaugeInstance("zeek", "dnsmgr_cache_entries", {{"type", "text"}}, + "Number of cached texts in DNS_Mgr", "", []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + metric.gauge.value = 0; + + if ( dns_mgr ) { + dns_mgr->UpdateCachedStats(false); + metric.gauge.value = static_cast(dns_mgr->last_cached_stats.texts); + } + return metric; + }); + if ( ! doctest::is_running_in_test ) { dm_rec = id::find_type("dns_mapping"); @@ -1158,7 +1208,7 @@ void DNS_Mgr::IssueAsyncRequests() { AsyncRequest* req = asyncs_queued.front(); asyncs_queued.pop_front(); - ++num_requests; + num_requests_metric->Inc(); req->time = util::current_time(); if ( req->type == T_PTR ) @@ -1173,6 +1223,7 @@ void DNS_Mgr::IssueAsyncRequests() { dns_req->MakeRequest(channel, this); ++asyncs_pending; + asyncs_pending_metric->Inc(); } } @@ -1182,11 +1233,11 @@ void DNS_Mgr::CheckAsyncHostRequest(const std::string& host, bool timeout) { if ( i != asyncs.end() ) { if ( timeout ) { - ++failed; + failed_metric->Inc(); i->second->Timeout(); } else if ( auto addrs = LookupNameInCache(host, true, false) ) { - ++successful; + successful_metric->Inc(); i->second->Resolved(addrs); } else @@ -1195,6 +1246,7 @@ void DNS_Mgr::CheckAsyncHostRequest(const std::string& host, bool timeout) { delete i->second; asyncs.erase(i); --asyncs_pending; + asyncs_pending_metric->Dec(); } } @@ -1207,11 +1259,11 @@ void DNS_Mgr::CheckAsyncAddrRequest(const IPAddr& addr, bool timeout) { if ( i != asyncs.end() ) { if ( timeout ) { - ++failed; + failed_metric->Inc(); i->second->Timeout(); } else if ( auto name = LookupAddrInCache(addr, true, false) ) { - ++successful; + successful_metric->Inc(); i->second->Resolved(name->CheckString()); } else @@ -1220,6 +1272,7 @@ void DNS_Mgr::CheckAsyncAddrRequest(const IPAddr& addr, bool timeout) { delete i->second; asyncs.erase(i); --asyncs_pending; + asyncs_pending_metric->Dec(); } } @@ -1229,11 +1282,11 @@ void DNS_Mgr::CheckAsyncOtherRequest(const std::string& host, bool timeout, int auto i = asyncs.find(std::make_pair(request_type, host)); if ( i != asyncs.end() ) { if ( timeout ) { - ++failed; + failed_metric->Inc(); i->second->Timeout(); } else if ( auto name = LookupOtherInCache(host, request_type, true) ) { - ++successful; + successful_metric->Inc(); i->second->Resolved(name->CheckString()); } else @@ -1242,6 +1295,7 @@ void DNS_Mgr::CheckAsyncOtherRequest(const std::string& host, bool timeout, int delete i->second; asyncs.erase(i); --asyncs_pending; + asyncs_pending_metric->Dec(); } } @@ -1293,26 +1347,35 @@ void DNS_Mgr::Process() { ares_process_fd(channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); } +void DNS_Mgr::UpdateCachedStats(bool force) { + double now = util::current_time(); + if ( force || last_cached_stats_update < now - 0.01 ) { + last_cached_stats.hosts = 0; + last_cached_stats.addresses = 0; + last_cached_stats.texts = 0; + last_cached_stats.total = all_mappings.size(); + + for ( const auto& [key, mapping] : all_mappings ) { + if ( mapping->ReqType() == T_PTR ) + last_cached_stats.addresses++; + else if ( mapping->ReqType() == T_A ) + last_cached_stats.hosts++; + else + last_cached_stats.texts++; + } + + last_cached_stats_update = now; + } +} + void DNS_Mgr::GetStats(Stats* stats) { - // TODO: can this use the telemetry framework? - stats->requests = num_requests; - stats->successful = successful; - stats->failed = failed; + stats->requests = static_cast(num_requests_metric->Value()); + stats->successful = static_cast(successful_metric->Value()); + stats->failed = static_cast(failed_metric->Value()); stats->pending = asyncs_pending; - stats->cached_hosts = 0; - stats->cached_addresses = 0; - stats->cached_texts = 0; - stats->cached_total = all_mappings.size(); - - for ( const auto& [key, mapping] : all_mappings ) { - if ( mapping->ReqType() == T_PTR ) - stats->cached_addresses++; - else if ( mapping->ReqType() == T_A ) - stats->cached_hosts++; - else - stats->cached_texts++; - } + UpdateCachedStats(true); + stats->cached = last_cached_stats; } void DNS_Mgr::AsyncRequest::Resolved(const std::string& name) { diff --git a/src/DNS_Mgr.h b/src/DNS_Mgr.h index 5d0f9a84b7..7e063b28a3 100644 --- a/src/DNS_Mgr.h +++ b/src/DNS_Mgr.h @@ -42,6 +42,13 @@ using TableValPtr = IntrusivePtr; using StringValPtr = IntrusivePtr; using RecordValPtr = IntrusivePtr; +namespace telemetry { +class Gauge; +class Counter; +using GaugePtr = std::shared_ptr; +using CounterPtr = std::shared_ptr; +} // namespace telemetry + } // namespace zeek namespace zeek::detail { @@ -198,15 +205,19 @@ public: */ bool Save(); + struct CachedStats { + unsigned long hosts; + unsigned long addresses; + unsigned long texts; + unsigned long total; + }; + struct Stats { unsigned long requests; // These count only async requests. unsigned long successful; unsigned long failed; unsigned long pending; - unsigned long cached_hosts; - unsigned long cached_addresses; - unsigned long cached_texts; - unsigned long cached_total; + CachedStats cached; }; /** @@ -285,6 +296,8 @@ protected: const char* Tag() override { return "DNS_Mgr"; } double GetNextTimeout() override; + void UpdateCachedStats(bool force); + DNS_MgrMode mode; MappingMap all_mappings; @@ -293,7 +306,6 @@ protected: std::string dir; // directory in which cache_name resides bool did_init = false; - int asyncs_pending = 0; RecordTypePtr dm_rec; @@ -327,9 +339,19 @@ protected: using QueuedList = std::list; QueuedList asyncs_queued; - unsigned long num_requests = 0; - unsigned long successful = 0; - unsigned long failed = 0; + telemetry::CounterPtr num_requests_metric; + telemetry::CounterPtr successful_metric; + telemetry::CounterPtr failed_metric; + telemetry::GaugePtr asyncs_pending_metric; + + telemetry::GaugePtr cached_hosts_metric; + telemetry::GaugePtr cached_addresses_metric; + telemetry::GaugePtr cached_texts_metric; + + double last_cached_stats_update = 0; + CachedStats last_cached_stats; + + int asyncs_pending = 0; std::set socket_fds; std::set write_socket_fds; diff --git a/src/Stats.cc b/src/Stats.cc index fb7766eaac..3742c42528 100644 --- a/src/Stats.cc +++ b/src/Stats.cc @@ -173,7 +173,7 @@ void ProfileLogger::Log() { util::fmt("%.06f DNS_Mgr: requests=%lu successful=%lu failed=%lu pending=%lu " "cached_hosts=%lu cached_addrs=%lu\n", run_state::network_time, dstats.requests, dstats.successful, dstats.failed, dstats.pending, - dstats.cached_hosts, dstats.cached_addresses)); + dstats.cached.hosts, dstats.cached.addresses)); trigger::Manager::Stats tstats; trigger_mgr->GetStats(&tstats); diff --git a/src/stats.bif b/src/stats.bif index 50dcc5685f..4763eedea2 100644 --- a/src/stats.bif +++ b/src/stats.bif @@ -252,10 +252,10 @@ function get_dns_stats%(%): DNSStats r->Assign(n++, static_cast(dstats.successful)); r->Assign(n++, static_cast(dstats.failed)); r->Assign(n++, static_cast(dstats.pending)); - r->Assign(n++, static_cast(dstats.cached_hosts)); - r->Assign(n++, static_cast(dstats.cached_addresses)); - r->Assign(n++, static_cast(dstats.cached_texts)); - r->Assign(n++, static_cast(dstats.cached_total)); + r->Assign(n++, static_cast(dstats.cached.hosts)); + r->Assign(n++, static_cast(dstats.cached.addresses)); + r->Assign(n++, static_cast(dstats.cached.texts)); + r->Assign(n++, static_cast(dstats.cached.total)); return std::move(r); %} From a81f6ab9a6a0b4f176080198d1c49ff44c70d2ed Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 29 May 2024 17:28:11 -0700 Subject: [PATCH 43/93] Add extra metrics to session_mgr - Sessions killed by activity - Current number of sessions across all types --- src/Stats.cc | 2 +- src/session/Manager.cc | 16 +++++++++++++--- src/session/Manager.h | 11 ++++++++++- src/stats.bif | 2 +- .../scripts.base.frameworks.telemetry.basic/out | 3 ++- .../telemetry.log.filtered | 2 ++ 6 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/Stats.cc b/src/Stats.cc index 3742c42528..d223002294 100644 --- a/src/Stats.cc +++ b/src/Stats.cc @@ -119,7 +119,7 @@ void ProfileLogger::Log() { // TODO: This previously output the number of connections, but now that we're storing // sessions as well as connections, this might need to be renamed. - file->Write(util::fmt("%.06f Conns: total=%" PRIu64 " current=%" PRIu64 "/%u\n", run_state::network_time, + file->Write(util::fmt("%.06f Conns: total=%" PRIu64 " current=%" PRIu64 "/%zu\n", run_state::network_time, Connection::TotalConnections(), Connection::CurrentConnections(), session_mgr->CurrentSessions())); diff --git a/src/session/Manager.cc b/src/session/Manager.cc index 8f2fbc6881..d33182a705 100644 --- a/src/session/Manager.cc +++ b/src/session/Manager.cc @@ -46,9 +46,9 @@ public: ProtocolMap::iterator InitCounters(const std::string& protocol) { auto active_family = - telemetry_mgr->GaugeFamily("zeek", "active-sessions", {"protocol"}, "Active Zeek Sessions"); + telemetry_mgr->GaugeFamily("zeek", "active_sessions", {"protocol"}, "Active Zeek Sessions"); auto total_family = - telemetry_mgr->CounterFamily("zeek", "total-sessions", {"protocol"}, "Total number of sessions"); + telemetry_mgr->CounterFamily("zeek", "total_sessions", {"protocol"}, "Total number of sessions"); auto [it, inserted] = entries.insert({protocol, Protocol{active_family, total_family, protocol}}); @@ -75,7 +75,17 @@ private: } // namespace detail -Manager::Manager() { stats = new detail::ProtocolStats(); } +Manager::Manager() { + stats = new detail::ProtocolStats(); + ended_sessions_metric_family = telemetry_mgr->CounterFamily("zeek", "ended_sessions", {"reason"}, + "Number of sessions ended for specific reasons"); + ended_by_inactivity_metric = + ended_sessions_metric_family->GetOrAdd({{"reason", "inactivity"}}, []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + metric.counter.value = static_cast(zeek::detail::killed_by_inactivity); + return metric; + }); +} Manager::~Manager() { Clear(); diff --git a/src/session/Manager.h b/src/session/Manager.h index 6bbb128d95..eb02e87498 100644 --- a/src/session/Manager.h +++ b/src/session/Manager.h @@ -13,6 +13,13 @@ namespace zeek { +namespace telemetry { +class CounterFamily; +using CounterFamilyPtr = std::shared_ptr; +class Counter; +using CounterPtr = std::shared_ptr; +} // namespace telemetry + namespace detail { class PacketFilter; } @@ -82,7 +89,7 @@ public: void Weird(const char* name, const Packet* pkt, const char* addl = "", const char* source = ""); void Weird(const char* name, const IP_Hdr* ip, const char* addl = ""); - unsigned int CurrentSessions() { return session_map.size(); } + size_t CurrentSessions() { return session_map.size(); } private: using SessionMap = std::unordered_map; @@ -96,6 +103,8 @@ private: SessionMap session_map; detail::ProtocolStats* stats; + telemetry::CounterFamilyPtr ended_sessions_metric_family; + telemetry::CounterPtr ended_by_inactivity_metric; }; } // namespace session diff --git a/src/stats.bif b/src/stats.bif index 4763eedea2..295cb7e9d1 100644 --- a/src/stats.bif +++ b/src/stats.bif @@ -83,7 +83,7 @@ function get_conn_stats%(%): ConnStats r->Assign(n++, Connection::TotalConnections()); r->Assign(n++, Connection::CurrentConnections()); - r->Assign(n++, session_mgr->CurrentSessions()); + r->Assign(n++, static_cast(session_mgr->CurrentSessions())); session::Stats s; if ( session_mgr ) diff --git a/testing/btest/Baseline/scripts.base.frameworks.telemetry.basic/out b/testing/btest/Baseline/scripts.base.frameworks.telemetry.basic/out index d35b64e3d4..fdde7d52ff 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.telemetry.basic/out +++ b/testing/btest/Baseline/scripts.base.frameworks.telemetry.basic/out @@ -1,5 +1,6 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -### zeek_session_metrics |2| +### zeek_session_metrics |3| +Telemetry::COUNTER, zeek, zeek_ended_sessions_total, [reason], [inactivity], 0.0 Telemetry::COUNTER, zeek, zeek_total_sessions_total, [protocol], [tcp], 500.0 Telemetry::GAUGE, zeek, zeek_active_sessions, [protocol], [tcp], 500.0 ### bt* metrics |5| diff --git a/testing/btest/Baseline/scripts.policy.frameworks.telemetry.log/telemetry.log.filtered b/testing/btest/Baseline/scripts.policy.frameworks.telemetry.log/telemetry.log.filtered index c7b26a1f28..b5c04c3f44 100644 --- a/testing/btest/Baseline/scripts.policy.frameworks.telemetry.log/telemetry.log.filtered +++ b/testing/btest/Baseline/scripts.policy.frameworks.telemetry.log/telemetry.log.filtered @@ -1,5 +1,7 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +XXXXXXXXXX.XXXXXX zeek counter zeek_ended_sessions_total reason inactivity 0.0 XXXXXXXXXX.XXXXXX zeek counter zeek_total_sessions_total protocol tcp 1.0 XXXXXXXXXX.XXXXXX zeek gauge zeek_active_sessions protocol tcp 1.0 +XXXXXXXXXX.XXXXXX zeek counter zeek_ended_sessions_total reason inactivity 0.0 XXXXXXXXXX.XXXXXX zeek counter zeek_total_sessions_total protocol tcp 500.0 XXXXXXXXXX.XXXXXX zeek gauge zeek_active_sessions protocol tcp 500.0 From 4face43462704e43b1121eb43106701b988233fc Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 30 May 2024 11:26:59 -0700 Subject: [PATCH 44/93] Move thread manager stats to telemetry metric --- src/Stats.cc | 2 +- src/stats.bif | 2 +- src/threading/Manager.cc | 12 ++++++ src/threading/Manager.h | 14 ++++++- src/threading/MsgThread.cc | 77 ++++++++++++++++++++++++++++++++++++++ src/zeek-setup.cc | 1 + 6 files changed, 105 insertions(+), 3 deletions(-) diff --git a/src/Stats.cc b/src/Stats.cc index d223002294..7b776b0138 100644 --- a/src/Stats.cc +++ b/src/Stats.cc @@ -188,7 +188,7 @@ void ProfileLogger::Log() { timer_type_to_string(static_cast(i)), current_timers[i])); } - file->Write(util::fmt("%0.6f Threads: current=%d\n", run_state::network_time, thread_mgr->NumThreads())); + file->Write(util::fmt("%0.6f Threads: current=%zu\n", run_state::network_time, thread_mgr->NumThreads())); const threading::Manager::msg_stats_list& thread_stats = thread_mgr->GetMsgThreadStats(); for ( threading::Manager::msg_stats_list::const_iterator i = thread_stats.begin(); i != thread_stats.end(); ++i ) { diff --git a/src/stats.bif b/src/stats.bif index 295cb7e9d1..5d410bc9bf 100644 --- a/src/stats.bif +++ b/src/stats.bif @@ -337,7 +337,7 @@ function get_thread_stats%(%): ThreadStats auto r = zeek::make_intrusive(ThreadStats); int n = 0; - r->Assign(n++, zeek::thread_mgr->NumThreads()); + r->Assign(n++, static_cast(zeek::thread_mgr->NumThreads())); return std::move(r); %} diff --git a/src/threading/Manager.cc b/src/threading/Manager.cc index 5620a0bf80..36a4ced939 100644 --- a/src/threading/Manager.cc +++ b/src/threading/Manager.cc @@ -8,6 +8,7 @@ #include "zeek/NetVar.h" #include "zeek/RunState.h" #include "zeek/iosource/Manager.h" +#include "zeek/telemetry/Manager.h" namespace zeek::threading { namespace detail { @@ -36,6 +37,17 @@ Manager::~Manager() { Terminate(); } +void Manager::InitPostScript() { + num_threads_metric = + telemetry_mgr->GaugeInstance("zeek", "active_threads", {}, "Number of active threads", "", + []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + metric.gauge.value = + thread_mgr ? static_cast(thread_mgr->all_threads.size()) : 0.0; + return metric; + }); +} + void Manager::Terminate() { DBG_LOG(DBG_THREADING, "Terminating thread manager ..."); terminating = true; diff --git a/src/threading/Manager.h b/src/threading/Manager.h index b075e6a70d..306063081f 100644 --- a/src/threading/Manager.h +++ b/src/threading/Manager.h @@ -7,6 +7,11 @@ #include "zeek/threading/MsgThread.h" namespace zeek { + +namespace telemetry { +class Gauge; +} + namespace threading { namespace detail { @@ -46,6 +51,12 @@ public: */ ~Manager(); + /** + * Performs initialization that can only happen after script parsing has + * completed. + */ + void InitPostScript(); + /** * Terminates the manager's processor. The method signals all threads * to terminates and wait for them to do so. It then joins them and @@ -77,7 +88,7 @@ public: * threads that are not yet joined, including any potentially in * Terminating() state. */ - int NumThreads() const { return all_threads.size(); } + size_t NumThreads() const { return all_threads.size(); } /** * Signals a specific threads to terminate immediately. @@ -151,6 +162,7 @@ private: msg_stats_list stats; bool heartbeat_timer_running = false; + std::shared_ptr num_threads_metric; }; } // namespace threading diff --git a/src/threading/MsgThread.cc b/src/threading/MsgThread.cc index 022a8ce2b4..c33c9d5bd7 100644 --- a/src/threading/MsgThread.cc +++ b/src/threading/MsgThread.cc @@ -229,6 +229,83 @@ MsgThread::MsgThread() : BasicThread(), queue_in(this, nullptr), queue_out(nullp // Register IOSource as non-counting lifetime managed IO source. iosource_mgr->Register(io_source, true); + + cnt_sent_in_metric = telemetry_mgr->CounterInstance("zeek", "msg_thread_msgs_sent_in", {{"thread_name", Name()}}, + "Number of messages sent into thread"); + cnt_sent_out_metric = telemetry_mgr->CounterInstance("zeek", "msg_thread_msgs_sent_out", {{"thread_name", Name()}}, + "Number of messages sent from thread"); + pending_in_metric = telemetry_mgr->GaugeInstance("zeek", "msg_thread_msgs_pending_in", {{"thread_name", Name()}}, + "Number of pending messages sent into thread", "", + [this]() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + metric.gauge.value = static_cast(queue_in.Size()); + return metric; + }); + pending_out_metric = telemetry_mgr->GaugeInstance("zeek", "msg_thread_msgs_pending_in", {{"thread_name", Name()}}, + "Number of pending messages sent from thread", "", + [this]() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + metric.gauge.value = static_cast(queue_out.Size()); + return metric; + }); + + static auto get_queue_in_stats = [this]() -> const Queue::Stats { + double now = util::current_time(); + if ( this->queue_in_stats_last_updated < now - 0.01 ) { + queue_in.GetStats(&queue_in_last_stats); + this->queue_in_stats_last_updated = now; + } + + return queue_in_last_stats; + }; + + queue_in_num_reads_metric = + telemetry_mgr->CounterInstance("zeek", "msg_thread_queue_in_reads", {{"thread_name", Name()}}, + "Number of reads from msg thread input queue", "", + []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + auto stats = get_queue_in_stats(); + metric.gauge.value = static_cast(stats.num_reads); + return metric; + }); + queue_in_num_writes_metric = + telemetry_mgr->CounterInstance("zeek", "msg_thread_queue_in_writes", {{"thread_name", Name()}}, + "Number of writes from msg thread input queue", "", + []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + auto stats = get_queue_in_stats(); + metric.gauge.value = static_cast(stats.num_writes); + return metric; + }); + + static auto get_queue_out_stats = [this]() -> const Queue::Stats { + double now = util::current_time(); + if ( this->queue_out_stats_last_updated < now - 0.01 ) { + queue_out.GetStats(&queue_out_last_stats); + this->queue_out_stats_last_updated = now; + } + + return queue_out_last_stats; + }; + + queue_out_num_reads_metric = + telemetry_mgr->CounterInstance("zeek", "msg_thread_queue_out_reads", {{"thread_name", Name()}}, + "Number of reads from msg thread input queue", "", + []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + auto stats = get_queue_out_stats(); + metric.gauge.value = static_cast(stats.num_reads); + return metric; + }); + queue_out_num_writes_metric = + telemetry_mgr->CounterInstance("zeek", "msg_thread_queue_out_writes", {{"thread_name", Name()}}, + "Number of writes from msg thread input queue", "", + []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + auto stats = get_queue_out_stats(); + metric.gauge.value = static_cast(stats.num_writes); + return metric; + }); } MsgThread::~MsgThread() { diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index 3f5549b78a..c97458984c 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -802,6 +802,7 @@ SetupResult setup(int argc, char** argv, Options* zopts) { RecordType::InitPostScript(); telemetry_mgr->InitPostScript(); + thread_mgr->InitPostScript(); iosource_mgr->InitPostScript(); log_mgr->InitPostScript(); plugin_mgr->InitPostScript(); From 44860676a281815c44c0b7423634f0dc2aa44778 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 30 May 2024 15:22:35 -0700 Subject: [PATCH 45/93] Add timer counts as telemetry metrics --- src/Timer.cc | 29 +++++++++++++++++++++++++++++ src/Timer.h | 17 +++++++++++++---- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/Timer.cc b/src/Timer.cc index ef2763071a..191d9c9e6e 100644 --- a/src/Timer.cc +++ b/src/Timer.cc @@ -10,6 +10,7 @@ #include "zeek/broker/Manager.h" #include "zeek/iosource/Manager.h" #include "zeek/iosource/PktSrc.h" +#include "zeek/telemetry/Manager.h" #include "zeek/util.h" namespace zeek::detail { @@ -97,6 +98,34 @@ void TimerMgr::InitPostScript() { iosource_mgr->Register(this, true); dispatch_all_expired = zeek::detail::max_timer_expires == 0; + + cumulative_num_metric = telemetry_mgr->CounterInstance("zeek", "timers", {}, "Cumulative number of timers", "", + []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + metric.counter.value = + static_cast(timer_mgr->CumulativeNum()); + return metric; + }); + + lag_time_metric = telemetry_mgr->GaugeInstance("zeek", "timers_lag_time", {}, + "Lag between current network time and last expired timer", "seconds", + []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + metric.gauge.value = + run_state::network_time - timer_mgr->last_timestamp; + return metric; + }); + + std::shared_ptr family = + telemetry_mgr->GaugeFamily("zeek", "timers_pending", {"type"}, "Number of timers for a certain type"); + for ( int i = 0; i < NUM_TIMER_TYPES; i++ ) { + current_timer_metrics[i] = family->GetOrAdd({{"type", timer_type_to_string(static_cast(i))}}, + [i]() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + metric.gauge.value = TimerMgr::CurrentTimers()[i]; + return metric; + }); + } } void TimerMgr::Add(Timer* timer) { diff --git a/src/Timer.h b/src/Timer.h index ff535f64e1..45ba50314e 100644 --- a/src/Timer.h +++ b/src/Timer.h @@ -10,7 +10,14 @@ namespace zeek { class ODesc; -} + +namespace telemetry { +class Gauge; +class Counter; +using GaugePtr = std::shared_ptr; +using CounterPtr = std::shared_ptr; +} // namespace telemetry +} // namespace zeek namespace zeek::detail { @@ -153,10 +160,12 @@ private: // for the max_timer_expires=0 case. bool dispatch_all_expired = false; - size_t peak_size = 0; - size_t cumulative_num = 0; - static unsigned int current_timers[NUM_TIMER_TYPES]; + + telemetry::CounterPtr cumulative_num_metric; + telemetry::GaugePtr lag_time_metric; + telemetry::GaugePtr current_timer_metrics[NUM_TIMER_TYPES]; + std::unique_ptr q; }; From 206f5cd52282a0f049b00bd78618998946da42b4 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 6 Jun 2024 14:51:09 -0700 Subject: [PATCH 46/93] Move broker statistics to be telemetry metrics --- src/broker/Manager.cc | 63 ++++++++++++++++++++++++++++++++++++------- src/broker/Manager.h | 17 ++++++++++-- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index 015f53d10e..dec03afb8e 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -340,6 +340,43 @@ void Manager::InitPostScript() { bstate->subscriber.add_topic(broker::topic::store_events(), true); InitializeBrokerStoreForwarding(); + + num_peers_metric = + telemetry_mgr->GaugeInstance("zeek", "broker_peers", {}, "Current number of peers connected via broker", "", + []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + metric.gauge.value = static_cast(broker_mgr->peer_count); + return metric; + }); + + num_stores_metric = + telemetry_mgr->GaugeInstance("zeek", "broker_stores", {}, "Current number of stores connected via broker", "", + []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + metric.gauge.value = static_cast(broker_mgr->data_stores.size()); + return metric; + }); + + num_pending_queries_metric = + telemetry_mgr->GaugeInstance("zeek", "broker_pending_queries", {}, "Current number of pending broker queries", + "", []() -> prometheus::ClientMetric { + prometheus::ClientMetric metric; + metric.gauge.value = static_cast(broker_mgr->pending_queries.size()); + return metric; + }); + + num_events_incoming_metric = telemetry_mgr->CounterInstance("zeek", "broker_incoming_events", {}, + "Total number of incoming events via broker"); + num_events_outgoing_metric = telemetry_mgr->CounterInstance("zeek", "broker_outgoing_events", {}, + "Total number of outgoing events via broker"); + num_logs_incoming_metric = + telemetry_mgr->CounterInstance("zeek", "broker_incoming_logs", {}, "Total number of incoming logs via broker"); + num_logs_outgoing_metric = + telemetry_mgr->CounterInstance("zeek", "broker_outgoing_logs", {}, "Total number of outgoing logs via broker"); + num_ids_incoming_metric = + telemetry_mgr->CounterInstance("zeek", "broker_incoming_ids", {}, "Total number of incoming ids via broker"); + num_ids_outgoing_metric = + telemetry_mgr->CounterInstance("zeek", "broker_outgoing_ids", {}, "Total number of outgoing ids via broker"); } void Manager::InitializeBrokerStoreForwarding() { @@ -528,7 +565,7 @@ bool Manager::PublishEvent(string topic, std::string name, broker::vector args, DBG_LOG(DBG_BROKER, "Publishing event: %s", RenderEvent(topic, name, args).c_str()); broker::zeek::Event ev(std::move(name), std::move(args), broker::to_timestamp(ts)); bstate->endpoint.publish(std::move(topic), ev.move_data()); - ++statistics.num_events_outgoing; + num_events_outgoing_metric->Inc(); return true; } @@ -588,7 +625,7 @@ bool Manager::PublishIdentifier(std::string topic, std::string id) { broker::zeek::IdentifierUpdate msg(std::move(id), std::move(data.value_)); DBG_LOG(DBG_BROKER, "Publishing id-update: %s", RenderMessage(topic, msg.as_data()).c_str()); bstate->endpoint.publish(std::move(topic), msg.move_data()); - ++statistics.num_ids_outgoing; + num_ids_outgoing_metric->Inc(); return true; } @@ -715,8 +752,10 @@ bool Manager::PublishLogWrite(EnumVal* stream, EnumVal* writer, string path, int ++lb.message_count; lb.msgs[topic].add(std::move(msg)); - if ( lb.message_count >= log_batch_size ) - statistics.num_logs_outgoing += lb.Flush(bstate->endpoint, log_batch_size); + if ( lb.message_count >= log_batch_size ) { + auto outgoing_logs = static_cast(lb.Flush(bstate->endpoint, log_batch_size)); + num_logs_outgoing_metric->Inc(outgoing_logs); + } return true; } @@ -746,7 +785,8 @@ size_t Manager::FlushLogBuffers() { for ( auto& lb : log_buffers ) rval += lb.Flush(bstate->endpoint, log_batch_size); - statistics.num_logs_outgoing += rval; + num_logs_outgoing_metric->Inc(rval); + return rval; } @@ -1141,7 +1181,7 @@ void Manager::ProcessMessage(std::string_view topic, broker::zeek::Event& ev) { ts = run_state::network_time; DBG_LOG(DBG_BROKER, "Process event: %s (%.6f) %s", c_str_safe(name).c_str(), ts, RenderMessage(args).c_str()); - ++statistics.num_events_incoming; + num_events_incoming_metric->Inc(); auto handler = event_registry->Lookup(name); if ( ! handler ) @@ -1286,7 +1326,7 @@ bool Manager::ProcessMessage(std::string_view, broker::zeek::LogWrite& lw) { return false; } - ++statistics.num_logs_incoming; + num_logs_incoming_metric->Inc(); auto&& stream_id_name = lw.stream_id().name; // Get stream ID. @@ -1352,7 +1392,7 @@ bool Manager::ProcessMessage(std::string_view, broker::zeek::IdentifierUpdate& i return false; } - ++statistics.num_ids_incoming; + num_ids_incoming_metric->Inc(); auto id_name = c_str_safe(iu.id_name()); auto id_value = convert_if_broker_variant_or_move(iu.id_value()); const auto& id = zeek::detail::global_scope()->Find(id_name); @@ -1706,7 +1746,12 @@ const Stats& Manager::GetStatistics() { statistics.num_stores = data_stores.size(); statistics.num_pending_queries = pending_queries.size(); - // The other attributes are set as activity happens. + statistics.num_events_incoming = static_cast(num_events_incoming_metric->Value()); + statistics.num_events_outgoing = static_cast(num_events_outgoing_metric->Value()); + statistics.num_logs_incoming = static_cast(num_logs_incoming_metric->Value()); + statistics.num_logs_outgoing = static_cast(num_logs_outgoing_metric->Value()); + statistics.num_ids_incoming = static_cast(num_ids_incoming_metric->Value()); + statistics.num_ids_outgoing = static_cast(num_ids_outgoing_metric->Value()); return statistics; } diff --git a/src/broker/Manager.h b/src/broker/Manager.h index d373d8883e..43bd00fbc9 100644 --- a/src/broker/Manager.h +++ b/src/broker/Manager.h @@ -27,8 +27,11 @@ using VectorTypePtr = IntrusivePtr; using TableValPtr = IntrusivePtr; namespace telemetry { -class Manager; -} +class Gauge; +class Counter; +using GaugePtr = std::shared_ptr; +using CounterPtr = std::shared_ptr; +} // namespace telemetry namespace detail { class Frame; @@ -451,6 +454,16 @@ private: std::string zeek_table_db_directory; static int script_scope; + + telemetry::GaugePtr num_peers_metric; + telemetry::GaugePtr num_stores_metric; + telemetry::GaugePtr num_pending_queries_metric; + telemetry::CounterPtr num_events_incoming_metric; + telemetry::CounterPtr num_events_outgoing_metric; + telemetry::CounterPtr num_logs_incoming_metric; + telemetry::CounterPtr num_logs_outgoing_metric; + telemetry::CounterPtr num_ids_incoming_metric; + telemetry::CounterPtr num_ids_outgoing_metric; }; } // namespace Broker From a6843067e9157ad0a7ca6dd1abb6d969cc770e31 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 5 Aug 2024 13:06:49 -0700 Subject: [PATCH 47/93] Split cpu time metric into user/system components like prof.log The total can be calculated from the two parts via Prometheus/Grafana if desired, so it's more informative to pass them as separate parts. --- src/telemetry/Manager.cc | 34 +++++++++++++++------------------- src/telemetry/Manager.h | 3 ++- src/telemetry/ProcessStats.cc | 16 ++++++++++------ src/telemetry/ProcessStats.h | 3 ++- 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/telemetry/Manager.cc b/src/telemetry/Manager.cc index 6ae4e06ec6..6bfcdc71a9 100644 --- a/src/telemetry/Manager.cc +++ b/src/telemetry/Manager.cc @@ -137,13 +137,21 @@ void Manager::InitPostScript() { return metric; }); - cpu_gauge = GaugeInstance("process", "cpu", {}, "Total user and system CPU time spent", "seconds", - []() -> prometheus::ClientMetric { - auto* s = get_stats(); - prometheus::ClientMetric metric; - metric.gauge.value = s->cpu; - return metric; - }); + cpu_user_counter = CounterInstance("process", "cpu_user", {}, "Total user CPU time spent", "seconds", + []() -> prometheus::ClientMetric { + auto* s = get_stats(); + prometheus::ClientMetric metric; + metric.gauge.value = s->cpu_user; + return metric; + }); + + cpu_system_counter = CounterInstance("process", "cpu_system", {}, "Total system CPU time spent", "seconds", + []() -> prometheus::ClientMetric { + auto* s = get_stats(); + prometheus::ClientMetric metric; + metric.gauge.value = s->cpu_system; + return metric; + }); fds_gauge = GaugeInstance("process", "open_fds", {}, "Number of open file descriptors", "", []() -> prometheus::ClientMetric { @@ -623,18 +631,6 @@ void Manager::WaitForPrometheusCallbacks() { using namespace std::literals; using namespace zeek::telemetry; -namespace { - -template -auto toVector(zeek::Span xs) { - std::vector> result; - for ( auto&& x : xs ) - result.emplace_back(x); - return result; -} - -} // namespace - SCENARIO("telemetry managers provide access to counter families") { GIVEN("a telemetry manager") { Manager mgr; diff --git a/src/telemetry/Manager.h b/src/telemetry/Manager.h index d967fe43c0..26647b7cf7 100644 --- a/src/telemetry/Manager.h +++ b/src/telemetry/Manager.h @@ -263,7 +263,8 @@ private: GaugePtr rss_gauge; GaugePtr vms_gauge; - GaugePtr cpu_gauge; + CounterPtr cpu_user_counter; + CounterPtr cpu_system_counter; GaugePtr fds_gauge; std::shared_ptr prometheus_registry; diff --git a/src/telemetry/ProcessStats.cc b/src/telemetry/ProcessStats.cc index f2a0447b63..476efd4487 100644 --- a/src/telemetry/ProcessStats.cc +++ b/src/telemetry/ProcessStats.cc @@ -34,10 +34,10 @@ process_stats get_process_stats() { if ( task_info(mach_task_self(), TASK_THREAD_TIMES_INFO, reinterpret_cast(&info), &count) == KERN_SUCCESS ) { // Round to milliseconds. - result.cpu += info.user_time.seconds; - result.cpu += ceil(info.user_time.microseconds / 1000.0) / 1000.0; - result.cpu += info.system_time.seconds; - result.cpu += ceil(info.system_time.microseconds / 1000.0) / 1000.0; + result.cpu_user += info.user_time.seconds; + result.cpu_user += ceil(info.user_time.microseconds / 1000.0) / 1000.0; + result.cpu_system += info.system_time.seconds; + result.cpu_system += ceil(info.system_time.microseconds / 1000.0) / 1000.0; } } // Fetch open file handles. @@ -154,7 +154,8 @@ process_stats get_process_stats() { result.rss = rss_pages * page_size; result.vms = vmsize_bytes; - result.cpu = static_cast(utime_ticks + stime_ticks) / ticks_per_second; + result.cpu_user = static_cast(utime_ticks) / ticks_per_second; + result.cpu_system = static_cast(stime_ticks) / ticks_per_second; result.fds = count_entries_in_directory("/proc/self/fd"); } @@ -187,7 +188,10 @@ process_stats get_process_stats() { if ( kp ) { result.vms = kp->ki_size; result.rss = kp->ki_rssize * getpagesize(); - result.cpu = static_cast(kp->ki_runtime) / 1000000.0; + result.cpu_user = static_cast(kp->ki_rusage.ru_utime.tv_sec) + + (static_cast(kp->ki_rusage.ru_utime.tv_usec) / 1e6); + result.cpu_system = static_cast(kp->ki_rusage.ru_stime.tv_sec) + + (static_cast(kp->ki_rusage.ru_stime.tv_usec) / 1e6); struct procstat* procstat = procstat_open_sysctl(); struct filestat_list* files = procstat_getfiles(procstat, kp, 0); diff --git a/src/telemetry/ProcessStats.h b/src/telemetry/ProcessStats.h index 02581362cc..d79bb2cb5f 100644 --- a/src/telemetry/ProcessStats.h +++ b/src/telemetry/ProcessStats.h @@ -9,7 +9,8 @@ namespace zeek::telemetry::detail { struct process_stats { int64_t rss = 0; int64_t vms = 0; - double cpu = 0.0; + double cpu_user = 0.0; + double cpu_system = 0.0; int64_t fds = 0; }; From 73f71e652d0da37f016652983225a789c1c81e69 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 5 Aug 2024 13:06:55 -0700 Subject: [PATCH 48/93] Make telemetry metrics out of MsgThread statistics --- src/telemetry/Counter.cc | 2 +- src/telemetry/Counter.h | 1 + src/telemetry/Gauge.cc | 2 +- src/telemetry/Gauge.h | 1 + src/threading/Manager.cc | 121 ++++++++++++++++++++++++++++++++++++- src/threading/Manager.h | 32 +++++++++- src/threading/MsgThread.cc | 78 +----------------------- 7 files changed, 155 insertions(+), 82 deletions(-) diff --git a/src/telemetry/Counter.cc b/src/telemetry/Counter.cc index 8b34624254..ef3679329e 100644 --- a/src/telemetry/Counter.cc +++ b/src/telemetry/Counter.cc @@ -3,7 +3,7 @@ using namespace zeek::telemetry; Counter::Counter(FamilyType* family, const prometheus::Labels& labels, prometheus::CollectCallbackPtr callback) noexcept - : handle(family->Add(labels)), labels(labels) { + : family(family), handle(family->Add(labels)), labels(labels) { if ( callback ) { handle.AddCollectCallback(std::move(callback)); has_callback = true; diff --git a/src/telemetry/Counter.h b/src/telemetry/Counter.h index f6c49315b7..a0186ad219 100644 --- a/src/telemetry/Counter.h +++ b/src/telemetry/Counter.h @@ -56,6 +56,7 @@ public: bool CompareLabels(const prometheus::Labels& lbls) const { return labels == lbls; } private: + FamilyType* family = nullptr; Handle& handle; prometheus::Labels labels; bool has_callback = false; diff --git a/src/telemetry/Gauge.cc b/src/telemetry/Gauge.cc index 273c9a57bf..114ada3811 100644 --- a/src/telemetry/Gauge.cc +++ b/src/telemetry/Gauge.cc @@ -15,7 +15,7 @@ double Gauge::Value() const noexcept { Gauge::Gauge(FamilyType* family, const prometheus::Labels& labels, prometheus::CollectCallbackPtr callback) noexcept - : handle(family->Add(labels)), labels(labels) { + : family(family), handle(family->Add(labels)), labels(labels) { if ( callback ) { handle.AddCollectCallback(std::move(callback)); has_callback = true; diff --git a/src/telemetry/Gauge.h b/src/telemetry/Gauge.h index 900cb7b784..652ff72667 100644 --- a/src/telemetry/Gauge.h +++ b/src/telemetry/Gauge.h @@ -74,6 +74,7 @@ public: bool CompareLabels(const prometheus::Labels& lbls) const { return labels == lbls; } private: + FamilyType* family = nullptr; Handle& handle; prometheus::Labels labels; bool has_callback = false; diff --git a/src/threading/Manager.cc b/src/threading/Manager.cc index 36a4ced939..f97427b08c 100644 --- a/src/threading/Manager.cc +++ b/src/threading/Manager.cc @@ -23,6 +23,9 @@ void HeartbeatTimer::Dispatch(double t, bool is_expire) { } // namespace detail +static std::vector pending_bucket_brackets = {1, 10, 100, + 1000, 10000, std::numeric_limits::infinity()}; + Manager::Manager() { DBG_LOG(DBG_THREADING, "Creating thread manager ..."); @@ -38,14 +41,128 @@ Manager::~Manager() { } void Manager::InitPostScript() { + static auto get_message_thread_stats = []() -> const BucketedMessages* { + if ( ! thread_mgr->terminating ) { + double now = util::current_time(); + if ( thread_mgr->bucketed_messages_last_updated < now - 1 ) { + thread_mgr->current_bucketed_messages.pending_in_total = 0; + thread_mgr->current_bucketed_messages.pending_out_total = 0; + for ( auto& m : thread_mgr->current_bucketed_messages.pending_in ) + m.second = 0; + for ( auto& m : thread_mgr->current_bucketed_messages.pending_out ) + m.second = 0; + + MsgThread::Stats thread_stats; + for ( const auto& t : thread_mgr->msg_threads ) { + t->GetStats(&thread_stats); + + thread_mgr->current_bucketed_messages.sent_in_total += thread_stats.sent_in; + thread_mgr->current_bucketed_messages.sent_out_total += thread_stats.sent_out; + thread_mgr->current_bucketed_messages.pending_in_total += thread_stats.pending_in; + thread_mgr->current_bucketed_messages.pending_out_total += thread_stats.pending_out; + + for ( auto upper_limit : pending_bucket_brackets ) { + if ( thread_stats.pending_in < upper_limit ) { + thread_mgr->current_bucketed_messages.pending_in[upper_limit]++; + break; + } + } + for ( auto upper_limit : pending_bucket_brackets ) { + if ( thread_stats.pending_out < upper_limit ) { + thread_mgr->current_bucketed_messages.pending_out[upper_limit]++; + break; + } + } + } + + thread_mgr->bucketed_messages_last_updated = now; + } + } + + return &thread_mgr->current_bucketed_messages; + }; + num_threads_metric = - telemetry_mgr->GaugeInstance("zeek", "active_threads", {}, "Number of active threads", "", + telemetry_mgr->GaugeInstance("zeek", "msgthread_active_threads", {}, "Number of active threads", "", []() -> prometheus::ClientMetric { prometheus::ClientMetric metric; metric.gauge.value = thread_mgr ? static_cast(thread_mgr->all_threads.size()) : 0.0; return metric; }); + + total_threads_metric = telemetry_mgr->CounterInstance("zeek", "msgthread_threads", {}, "Total number of threads"); + total_messages_in_metric = + telemetry_mgr->CounterInstance("zeek", "msgthread_in_messages", {}, "Number of inbound messages received", "", + []() -> prometheus::ClientMetric { + auto* s = get_message_thread_stats(); + prometheus::ClientMetric metric; + metric.gauge.value = static_cast(s->sent_in_total); + return metric; + }); + + total_messages_in_metric = + telemetry_mgr->CounterInstance("zeek", "msgthread_out_messages", {}, "Number of outbound messages sent", "", + []() -> prometheus::ClientMetric { + auto* s = get_message_thread_stats(); + prometheus::ClientMetric metric; + metric.gauge.value = static_cast(s->sent_out_total); + return metric; + }); + + pending_messages_in_metric = + telemetry_mgr->GaugeInstance("zeek", "msgthread_pending_in_messages", {}, "Pending number of inbound messages", + "", []() -> prometheus::ClientMetric { + auto* s = get_message_thread_stats(); + prometheus::ClientMetric metric; + metric.gauge.value = static_cast(s->pending_in_total); + return metric; + }); + pending_messages_out_metric = + telemetry_mgr->GaugeInstance("zeek", "msgthread_pending_out_messages", {}, + "Pending number of outbound messages", "", []() -> prometheus::ClientMetric { + auto* s = get_message_thread_stats(); + prometheus::ClientMetric metric; + metric.gauge.value = static_cast(s->pending_out_total); + return metric; + }); + + pending_message_in_buckets_fam = + telemetry_mgr->GaugeFamily("zeek", "msgthread_pending_messages_in_buckets", {"lt"}, + "Number of threads with pending inbound messages split into buckets"); + pending_message_out_buckets_fam = + telemetry_mgr->GaugeFamily("zeek", "msgthread_pending_messages_out_buckets", {"lt"}, + "Number of threads with pending outbound messages split into buckets"); + + for ( auto upper_limit : pending_bucket_brackets ) { + std::string upper_limit_str; + if ( upper_limit == std::numeric_limits::infinity() ) + upper_limit_str = "inf"; + else + upper_limit_str = std::to_string(upper_limit); + + current_bucketed_messages.pending_in[upper_limit] = 0; + current_bucketed_messages.pending_out[upper_limit] = 0; + + pending_message_in_buckets[upper_limit] = + pending_message_in_buckets_fam->GetOrAdd({{"lt", upper_limit_str}}, + [upper_limit]() -> prometheus::ClientMetric { + auto* s = get_message_thread_stats(); + prometheus::ClientMetric metric; + metric.gauge.value = + static_cast(s->pending_in.at(upper_limit)); + return metric; + }); + pending_message_out_buckets[upper_limit] = + pending_message_out_buckets_fam->GetOrAdd({{"lt", upper_limit_str}}, + [upper_limit]() -> prometheus::ClientMetric { + auto* s = get_message_thread_stats(); + prometheus::ClientMetric metric; + metric.gauge.value = + static_cast(s->pending_out.at(upper_limit)); + return metric; + }); + } } void Manager::Terminate() { @@ -90,6 +207,8 @@ void Manager::AddThread(BasicThread* thread) { if ( ! heartbeat_timer_running ) StartHeartbeatTimer(); + + total_threads_metric->Inc(); } void Manager::AddMsgThread(MsgThread* thread) { diff --git a/src/threading/Manager.h b/src/threading/Manager.h index 306063081f..3b4763a497 100644 --- a/src/threading/Manager.h +++ b/src/threading/Manager.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include "zeek/Timer.h" @@ -10,7 +11,12 @@ namespace zeek { namespace telemetry { class Gauge; -} +using GaugePtr = std::shared_ptr; +class GaugeFamily; +using GaugeFamilyPtr = std::shared_ptr; +class Counter; +using CounterPtr = std::shared_ptr; +} // namespace telemetry namespace threading { namespace detail { @@ -162,7 +168,29 @@ private: msg_stats_list stats; bool heartbeat_timer_running = false; - std::shared_ptr num_threads_metric; + telemetry::GaugePtr num_threads_metric; + telemetry::CounterPtr total_threads_metric; + telemetry::CounterPtr total_messages_in_metric; + telemetry::CounterPtr total_messages_out_metric; + telemetry::GaugePtr pending_messages_in_metric; + telemetry::GaugePtr pending_messages_out_metric; + + telemetry::GaugeFamilyPtr pending_message_in_buckets_fam; + telemetry::GaugeFamilyPtr pending_message_out_buckets_fam; + std::map pending_message_in_buckets; + std::map pending_message_out_buckets; + + struct BucketedMessages { + uint64_t sent_in_total; + uint64_t sent_out_total; + uint64_t pending_in_total; + uint64_t pending_out_total; + std::map pending_in; + std::map pending_out; + }; + + BucketedMessages current_bucketed_messages; + double bucketed_messages_last_updated = 0.0; }; } // namespace threading diff --git a/src/threading/MsgThread.cc b/src/threading/MsgThread.cc index c33c9d5bd7..6854f5f188 100644 --- a/src/threading/MsgThread.cc +++ b/src/threading/MsgThread.cc @@ -9,6 +9,7 @@ #include "zeek/Obj.h" #include "zeek/RunState.h" #include "zeek/iosource/Manager.h" +#include "zeek/telemetry/Manager.h" #include "zeek/threading/Manager.h" // Set by Zeek's main signal handler. @@ -229,83 +230,6 @@ MsgThread::MsgThread() : BasicThread(), queue_in(this, nullptr), queue_out(nullp // Register IOSource as non-counting lifetime managed IO source. iosource_mgr->Register(io_source, true); - - cnt_sent_in_metric = telemetry_mgr->CounterInstance("zeek", "msg_thread_msgs_sent_in", {{"thread_name", Name()}}, - "Number of messages sent into thread"); - cnt_sent_out_metric = telemetry_mgr->CounterInstance("zeek", "msg_thread_msgs_sent_out", {{"thread_name", Name()}}, - "Number of messages sent from thread"); - pending_in_metric = telemetry_mgr->GaugeInstance("zeek", "msg_thread_msgs_pending_in", {{"thread_name", Name()}}, - "Number of pending messages sent into thread", "", - [this]() -> prometheus::ClientMetric { - prometheus::ClientMetric metric; - metric.gauge.value = static_cast(queue_in.Size()); - return metric; - }); - pending_out_metric = telemetry_mgr->GaugeInstance("zeek", "msg_thread_msgs_pending_in", {{"thread_name", Name()}}, - "Number of pending messages sent from thread", "", - [this]() -> prometheus::ClientMetric { - prometheus::ClientMetric metric; - metric.gauge.value = static_cast(queue_out.Size()); - return metric; - }); - - static auto get_queue_in_stats = [this]() -> const Queue::Stats { - double now = util::current_time(); - if ( this->queue_in_stats_last_updated < now - 0.01 ) { - queue_in.GetStats(&queue_in_last_stats); - this->queue_in_stats_last_updated = now; - } - - return queue_in_last_stats; - }; - - queue_in_num_reads_metric = - telemetry_mgr->CounterInstance("zeek", "msg_thread_queue_in_reads", {{"thread_name", Name()}}, - "Number of reads from msg thread input queue", "", - []() -> prometheus::ClientMetric { - prometheus::ClientMetric metric; - auto stats = get_queue_in_stats(); - metric.gauge.value = static_cast(stats.num_reads); - return metric; - }); - queue_in_num_writes_metric = - telemetry_mgr->CounterInstance("zeek", "msg_thread_queue_in_writes", {{"thread_name", Name()}}, - "Number of writes from msg thread input queue", "", - []() -> prometheus::ClientMetric { - prometheus::ClientMetric metric; - auto stats = get_queue_in_stats(); - metric.gauge.value = static_cast(stats.num_writes); - return metric; - }); - - static auto get_queue_out_stats = [this]() -> const Queue::Stats { - double now = util::current_time(); - if ( this->queue_out_stats_last_updated < now - 0.01 ) { - queue_out.GetStats(&queue_out_last_stats); - this->queue_out_stats_last_updated = now; - } - - return queue_out_last_stats; - }; - - queue_out_num_reads_metric = - telemetry_mgr->CounterInstance("zeek", "msg_thread_queue_out_reads", {{"thread_name", Name()}}, - "Number of reads from msg thread input queue", "", - []() -> prometheus::ClientMetric { - prometheus::ClientMetric metric; - auto stats = get_queue_out_stats(); - metric.gauge.value = static_cast(stats.num_reads); - return metric; - }); - queue_out_num_writes_metric = - telemetry_mgr->CounterInstance("zeek", "msg_thread_queue_out_writes", {{"thread_name", Name()}}, - "Number of writes from msg thread input queue", "", - []() -> prometheus::ClientMetric { - prometheus::ClientMetric metric; - auto stats = get_queue_out_stats(); - metric.gauge.value = static_cast(stats.num_writes); - return metric; - }); } MsgThread::~MsgThread() { From 7a1eb78b672183ee49a25ef9bb74027b42ff168b Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 2 Aug 2024 16:58:57 -0700 Subject: [PATCH 49/93] Avoid capturing 'this' for callback in telemetry::Manager --- src/telemetry/Manager.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/telemetry/Manager.cc b/src/telemetry/Manager.cc index 6bfcdc71a9..69b4ed485a 100644 --- a/src/telemetry/Manager.cc +++ b/src/telemetry/Manager.cc @@ -112,14 +112,14 @@ void Manager::InitPostScript() { } #ifdef HAVE_PROCESS_STAT_METRICS - static auto get_stats = [this]() -> const detail::process_stats* { + static auto get_stats = []() -> const detail::process_stats* { double now = util::current_time(); - if ( this->process_stats_last_updated < now - 0.01 ) { - this->current_process_stats = detail::get_process_stats(); - this->process_stats_last_updated = now; + if ( telemetry_mgr->process_stats_last_updated < now - 0.01 ) { + telemetry_mgr->current_process_stats = detail::get_process_stats(); + telemetry_mgr->process_stats_last_updated = now; } - return &this->current_process_stats; + return &telemetry_mgr->current_process_stats; }; rss_gauge = GaugeInstance("process", "resident_memory", {}, "Resident memory size", "bytes", []() -> prometheus::ClientMetric { From 1325e16a0d30f3a514b5d229302c2294090c73da Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 10 Jul 2024 15:07:46 -0700 Subject: [PATCH 50/93] Remove some unnecessary #includes --- src/Timer.cc | 1 - src/threading/Manager.cc | 1 - src/threading/MsgThread.h | 2 -- 3 files changed, 4 deletions(-) diff --git a/src/Timer.cc b/src/Timer.cc index 191d9c9e6e..f348731c73 100644 --- a/src/Timer.cc +++ b/src/Timer.cc @@ -9,7 +9,6 @@ #include "zeek/RunState.h" #include "zeek/broker/Manager.h" #include "zeek/iosource/Manager.h" -#include "zeek/iosource/PktSrc.h" #include "zeek/telemetry/Manager.h" #include "zeek/util.h" diff --git a/src/threading/Manager.cc b/src/threading/Manager.cc index f97427b08c..5499cbb8ed 100644 --- a/src/threading/Manager.cc +++ b/src/threading/Manager.cc @@ -7,7 +7,6 @@ #include "zeek/IPAddr.h" #include "zeek/NetVar.h" #include "zeek/RunState.h" -#include "zeek/iosource/Manager.h" #include "zeek/telemetry/Manager.h" namespace zeek::threading { diff --git a/src/threading/MsgThread.h b/src/threading/MsgThread.h index 259e64b11f..0bb3dbaec4 100644 --- a/src/threading/MsgThread.h +++ b/src/threading/MsgThread.h @@ -3,8 +3,6 @@ #include #include "zeek/DebugLogger.h" -#include "zeek/Flare.h" -#include "zeek/iosource/IOSource.h" #include "zeek/threading/BasicThread.h" #include "zeek/threading/Queue.h" From 25f65a705f3c0ac43679c5edbb3829af13db431d Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 5 Aug 2024 14:40:31 -0700 Subject: [PATCH 51/93] Updating CHANGES and VERSION. --- CHANGES | 30 ++++++++++++++++++++++++++++++ VERSION | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 14cf860494..92f9c50e06 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,33 @@ +7.1.0-dev.87 | 2024-08-05 14:39:56 -0700 + + * Remove some unnecessary #includes (Tim Wojtulewicz, Corelight) + + * Avoid capturing 'this' for callback in telemetry::Manager (Tim Wojtulewicz, Corelight) + + * Make telemetry metrics out of MsgThread statistics (Tim Wojtulewicz, Corelight) + + * Split cpu time metric into user/system components like prof.log (Tim Wojtulewicz, Corelight) + + The total can be calculated from the two parts via Prometheus/Grafana + if desired, so it's more informative to pass them as separate parts. + + * Move broker statistics to be telemetry metrics (Tim Wojtulewicz, Corelight) + + * Add timer counts as telemetry metrics (Tim Wojtulewicz, Corelight) + + * Move thread manager stats to telemetry metric (Tim Wojtulewicz, Corelight) + + * Add extra metrics to session_mgr (Tim Wojtulewicz, Corelight) + + - Sessions killed by activity + - Current number of sessions across all types + + * Move dns_mgr stats to telemetry instruments (Tim Wojtulewicz, Corelight) + + * Move trigger stats to telemetry instruments (Tim Wojtulewicz, Corelight) + + * Move pulling of global state inside 'expensive' check for stats (Tim Wojtulewicz, Corelight) + 7.1.0-dev.74 | 2024-08-02 15:49:40 -0700 * Process metric callbacks from the main-loop thread (Tim Wojtulewicz, Corelight) diff --git a/VERSION b/VERSION index 23ab27973f..6a8a0039ab 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.1.0-dev.74 +7.1.0-dev.87 From 2f8733e08d982717db94044ef8233d43af688426 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 5 Aug 2024 16:23:03 -0700 Subject: [PATCH 52/93] Don't install empty ZAM directories --- src/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c7ae4f183c..6920e42a01 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -636,6 +636,8 @@ install( # https://gitlab.kitware.com/cmake/cmake/-/issues/17122 Exclude the ones that # this affects explicitly. PATTERN "script_opt/CPP/maint" EXCLUDE + PATTERN "script_opt/ZAM/maint" EXCLUDE + PATTERN "script_opt/ZAM/OPs" EXCLUDE PATTERN "fuzzers/corpora" EXCLUDE) install( From 98480cf3393d3cf2b72411c41c53f5e70ff129e1 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 6 Aug 2024 09:30:29 +0200 Subject: [PATCH 53/93] threading/Manager: "lt" to "le" and do not break The buckets are specified as lower-equal (changed from lower-than now), which means we shouldn't break: The larger "le" bucket contains all previous buckets, too. The "inf" bucket represents the current number of threads. For example, with a total of 10 threads, 5 threads with 0 messages pending, another 4 threads with 50 messages, and on with 2000 messages, the metrics would end end up as follows: pending_buckets{le=1} = 5 pending_buckets{le=10} = 5 pending_buckets{le=100} = 9 pending_buckets{le=1000} = 9 pending_buckets{le=10000} = 10 pending_buckets{le=inf} = 10 This might be strange initially, but aligns with the Prometheus histogram approach (though we're using gauges here). --- src/threading/Manager.cc | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/threading/Manager.cc b/src/threading/Manager.cc index 5499cbb8ed..de6e7008b9 100644 --- a/src/threading/Manager.cc +++ b/src/threading/Manager.cc @@ -61,16 +61,11 @@ void Manager::InitPostScript() { thread_mgr->current_bucketed_messages.pending_out_total += thread_stats.pending_out; for ( auto upper_limit : pending_bucket_brackets ) { - if ( thread_stats.pending_in < upper_limit ) { + if ( thread_stats.pending_in <= upper_limit ) thread_mgr->current_bucketed_messages.pending_in[upper_limit]++; - break; - } - } - for ( auto upper_limit : pending_bucket_brackets ) { - if ( thread_stats.pending_out < upper_limit ) { + + if ( thread_stats.pending_out <= upper_limit ) thread_mgr->current_bucketed_messages.pending_out[upper_limit]++; - break; - } } } @@ -127,10 +122,10 @@ void Manager::InitPostScript() { }); pending_message_in_buckets_fam = - telemetry_mgr->GaugeFamily("zeek", "msgthread_pending_messages_in_buckets", {"lt"}, + telemetry_mgr->GaugeFamily("zeek", "msgthread_pending_messages_in_buckets", {"le"}, "Number of threads with pending inbound messages split into buckets"); pending_message_out_buckets_fam = - telemetry_mgr->GaugeFamily("zeek", "msgthread_pending_messages_out_buckets", {"lt"}, + telemetry_mgr->GaugeFamily("zeek", "msgthread_pending_messages_out_buckets", {"le"}, "Number of threads with pending outbound messages split into buckets"); for ( auto upper_limit : pending_bucket_brackets ) { @@ -144,7 +139,7 @@ void Manager::InitPostScript() { current_bucketed_messages.pending_out[upper_limit] = 0; pending_message_in_buckets[upper_limit] = - pending_message_in_buckets_fam->GetOrAdd({{"lt", upper_limit_str}}, + pending_message_in_buckets_fam->GetOrAdd({{"le", upper_limit_str}}, [upper_limit]() -> prometheus::ClientMetric { auto* s = get_message_thread_stats(); prometheus::ClientMetric metric; @@ -153,7 +148,7 @@ void Manager::InitPostScript() { return metric; }); pending_message_out_buckets[upper_limit] = - pending_message_out_buckets_fam->GetOrAdd({{"lt", upper_limit_str}}, + pending_message_out_buckets_fam->GetOrAdd({{"le", upper_limit_str}}, [upper_limit]() -> prometheus::ClientMetric { auto* s = get_message_thread_stats(); prometheus::ClientMetric metric; From c55b2ece8f47107de4ec88e973e63d1f667ce430 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 6 Aug 2024 10:38:18 +0200 Subject: [PATCH 54/93] threading/Manager: Switch inf bucket from infinity() to max() For uint64_t, std::numeric_limits::has_infinity is false and infinity() actually returns 0. Use uint64_t's max() instead. We could cast to double and use the double infinity, but this seems reasonable, too. This was found while trying to provoke some pending messages and being confused why all but the "inf" bucket increased. --- src/threading/Manager.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/threading/Manager.cc b/src/threading/Manager.cc index de6e7008b9..beafba7758 100644 --- a/src/threading/Manager.cc +++ b/src/threading/Manager.cc @@ -2,6 +2,8 @@ #include #include +#include +#include #include "zeek/Event.h" #include "zeek/IPAddr.h" @@ -22,8 +24,7 @@ void HeartbeatTimer::Dispatch(double t, bool is_expire) { } // namespace detail -static std::vector pending_bucket_brackets = {1, 10, 100, - 1000, 10000, std::numeric_limits::infinity()}; +static std::vector pending_bucket_brackets = {1, 10, 100, 1000, 10000, std::numeric_limits::max()}; Manager::Manager() { DBG_LOG(DBG_THREADING, "Creating thread manager ..."); @@ -130,7 +131,7 @@ void Manager::InitPostScript() { for ( auto upper_limit : pending_bucket_brackets ) { std::string upper_limit_str; - if ( upper_limit == std::numeric_limits::infinity() ) + if ( upper_limit == std::numeric_limits::max() ) upper_limit_str = "inf"; else upper_limit_str = std::to_string(upper_limit); From 351f16c160d8a4ae548b08fe9ccb05fa3225ca89 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 6 Aug 2024 10:56:07 +0200 Subject: [PATCH 55/93] telemetry/Manager: Track sent_in and sent_out totals without callback For terminated threads, the totals would go down once the threads are removed, which isn't great. Move tracking of sent in and sent out messages from callback to explicit `Inc()` calls. Also fixes total_messages_in_metric being initialized twice rather than total_messages_out_metric. --- src/threading/Manager.cc | 24 +++++++----------------- src/threading/Manager.h | 12 ++++++++++-- src/threading/MsgThread.cc | 4 ++++ 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/threading/Manager.cc b/src/threading/Manager.cc index beafba7758..8e67676643 100644 --- a/src/threading/Manager.cc +++ b/src/threading/Manager.cc @@ -56,8 +56,6 @@ void Manager::InitPostScript() { for ( const auto& t : thread_mgr->msg_threads ) { t->GetStats(&thread_stats); - thread_mgr->current_bucketed_messages.sent_in_total += thread_stats.sent_in; - thread_mgr->current_bucketed_messages.sent_out_total += thread_stats.sent_out; thread_mgr->current_bucketed_messages.pending_in_total += thread_stats.pending_in; thread_mgr->current_bucketed_messages.pending_out_total += thread_stats.pending_out; @@ -88,22 +86,10 @@ void Manager::InitPostScript() { total_threads_metric = telemetry_mgr->CounterInstance("zeek", "msgthread_threads", {}, "Total number of threads"); total_messages_in_metric = - telemetry_mgr->CounterInstance("zeek", "msgthread_in_messages", {}, "Number of inbound messages received", "", - []() -> prometheus::ClientMetric { - auto* s = get_message_thread_stats(); - prometheus::ClientMetric metric; - metric.gauge.value = static_cast(s->sent_in_total); - return metric; - }); + telemetry_mgr->CounterInstance("zeek", "msgthread_in_messages", {}, "Number of inbound messages received", ""); - total_messages_in_metric = - telemetry_mgr->CounterInstance("zeek", "msgthread_out_messages", {}, "Number of outbound messages sent", "", - []() -> prometheus::ClientMetric { - auto* s = get_message_thread_stats(); - prometheus::ClientMetric metric; - metric.gauge.value = static_cast(s->sent_out_total); - return metric; - }); + total_messages_out_metric = + telemetry_mgr->CounterInstance("zeek", "msgthread_out_messages", {}, "Number of outbound messages sent", ""); pending_messages_in_metric = telemetry_mgr->GaugeInstance("zeek", "msgthread_pending_in_messages", {}, "Pending number of inbound messages", @@ -259,6 +245,10 @@ void Manager::StartHeartbeatTimer() { new detail::HeartbeatTimer(run_state::network_time + BifConst::Threading::heartbeat_interval)); } +void Manager::MessageIn() { total_messages_in_metric->Inc(); } + +void Manager::MessageOut() { total_messages_out_metric->Inc(); } + // Raise everything in here as warnings so it is passed to scriptland without // looking "fatal". In addition to these warnings, ReaderBackend will queue // one reporter message. diff --git a/src/threading/Manager.h b/src/threading/Manager.h index 3b4763a497..897068bee5 100644 --- a/src/threading/Manager.h +++ b/src/threading/Manager.h @@ -153,6 +153,16 @@ protected: */ void StartHeartbeatTimer(); + /** + * Called by MsgThread::SendIn() to update metrics. + */ + void MessageIn(); + + /** + * Called by MsgThread::SendOut() to update metrics. + */ + void MessageOut(); + private: using all_thread_list = std::list; all_thread_list all_threads; @@ -181,8 +191,6 @@ private: std::map pending_message_out_buckets; struct BucketedMessages { - uint64_t sent_in_total; - uint64_t sent_out_total; uint64_t pending_in_total; uint64_t pending_out_total; std::map pending_in; diff --git a/src/threading/MsgThread.cc b/src/threading/MsgThread.cc index 6854f5f188..5bfb8ebeb4 100644 --- a/src/threading/MsgThread.cc +++ b/src/threading/MsgThread.cc @@ -388,6 +388,8 @@ void MsgThread::SendIn(BasicInputMessage* msg, bool force) { queue_in.Put(msg); ++cnt_sent_in; + + zeek::thread_mgr->MessageIn(); } void MsgThread::SendOut(BasicOutputMessage* msg, bool force) { @@ -400,6 +402,8 @@ void MsgThread::SendOut(BasicOutputMessage* msg, bool force) { ++cnt_sent_out; + zeek::thread_mgr->MessageOut(); + if ( io_source ) io_source->Fire(); } From bae15230bb9137e5485d8a70539f1494b7cf502e Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 6 Aug 2024 11:45:41 +0200 Subject: [PATCH 56/93] btest/spicy: Make replaces-conflicts trigger replaces code path The current test attempts to instantiate two spicy::SSH_1 protocol analyzers in the .evt file. The intention likely was to use two distinct protocol analyzer both trying to replace the builtin SSH analyzer. Coincidentally, fixing this happens to workaround TSAN errors tickled by the FatalError() call while loading the .hlto with two identically named analyzers. $ cat .tmp/spicy.replaces-conflicts/output error: redefinition of protocol analyzer spicy::SSH_1 ThreadSanitizer: main thread finished with ignores enabled One of the following ignores was not ended (in order of probability) Ignore was enabled at: #0 __llvm_gcov_init __linker___d192e45c25d5ee23-484d3e0fc2caf5b4.cc (ssh.hlto+0x34036) (BuildId: 091934ca4da885e7) #1 __llvm_gcov_init __linker___d192e45c25d5ee23-484d3e0fc2caf5b4.cc (ssh.hlto+0x34036) (BuildId: 091934ca4da885e7) ... I was tempted to replace FatalError() with Error() and rely on zeek-setup.cc's early exiting on any reporter errors, but this seems easier for now. Relates to #3865. --- testing/btest/Baseline/spicy.replaces-conflicts/output | 2 +- testing/btest/spicy/replaces-conflicts.evt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/btest/Baseline/spicy.replaces-conflicts/output b/testing/btest/Baseline/spicy.replaces-conflicts/output index 8cf95b5195..e5e9334522 100644 --- a/testing/btest/Baseline/spicy.replaces-conflicts/output +++ b/testing/btest/Baseline/spicy.replaces-conflicts/output @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -fatal error: redefinition of protocol analyzer spicy::SSH_1 +fatal error: spicy::SSH_2: protocol analyzer SSH is already mapped to a different analyzer; cannot replace an analyzer multiple times diff --git a/testing/btest/spicy/replaces-conflicts.evt b/testing/btest/spicy/replaces-conflicts.evt index dbca6d637e..5ca7610503 100644 --- a/testing/btest/spicy/replaces-conflicts.evt +++ b/testing/btest/spicy/replaces-conflicts.evt @@ -16,7 +16,7 @@ protocol analyzer spicy::SSH_1 over TCP: parse with SSH::Banner, replaces SSH; -protocol analyzer spicy::SSH_1 over UDP: +protocol analyzer spicy::SSH_2 over UDP: parse with SSH::Banner, replaces SSH; From 92d4e50b4855fc714d5b88cb9832fd61853f0390 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 1 Aug 2024 20:29:26 +0200 Subject: [PATCH 57/93] fuzzers: Add LDAP fuzzing LDAP supports both, UDP and TCP as separate analyzers. The corpus is identical, however. Started to hit the TLS analyzer fairly quickly, too. Closes #3860 --- src/fuzzers/CMakeLists.txt | 2 ++ src/fuzzers/corpora/ldap_tcp-corpus.zip | Bin 0 -> 13047 bytes src/fuzzers/corpora/ldap_udp-corpus.zip | Bin 0 -> 13047 bytes 3 files changed, 2 insertions(+) create mode 100644 src/fuzzers/corpora/ldap_tcp-corpus.zip create mode 100644 src/fuzzers/corpora/ldap_udp-corpus.zip diff --git a/src/fuzzers/CMakeLists.txt b/src/fuzzers/CMakeLists.txt index 41a46dc64a..5a4b13f888 100644 --- a/src/fuzzers/CMakeLists.txt +++ b/src/fuzzers/CMakeLists.txt @@ -107,6 +107,8 @@ add_generic_analyzer_fuzz_target(dhcp udp) add_generic_analyzer_fuzz_target(dnp3_tcp) add_generic_analyzer_fuzz_target(dtls udp) add_generic_analyzer_fuzz_target(irc) +add_generic_analyzer_fuzz_target(ldap_udp udp) +add_generic_analyzer_fuzz_target(ldap_tcp tcp) add_generic_analyzer_fuzz_target(modbus) add_generic_analyzer_fuzz_target(mqtt) add_generic_analyzer_fuzz_target(mysql) diff --git a/src/fuzzers/corpora/ldap_tcp-corpus.zip b/src/fuzzers/corpora/ldap_tcp-corpus.zip new file mode 100644 index 0000000000000000000000000000000000000000..e95f0c4b5360a75e72bb526f1d6e582fbf7bd7db GIT binary patch literal 13047 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 literal 0 HcmV?d00001 diff --git a/src/fuzzers/corpora/ldap_udp-corpus.zip b/src/fuzzers/corpora/ldap_udp-corpus.zip new file mode 100644 index 0000000000000000000000000000000000000000..e95f0c4b5360a75e72bb526f1d6e582fbf7bd7db GIT binary patch literal 13047 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 literal 0 HcmV?d00001 From 83a2eb366500ea78d7c7a1392df4cdb501d33943 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 1 Aug 2024 21:11:38 +0200 Subject: [PATCH 58/93] ldap: Avoid unset m$opcode Initial fuzzing caused a bind response to arrive before a bind request, resulting in an unset field expression error: expression error in base/protocols/ldap/main.zeek, line 270: field value missing (LDAP::m$opcode) Prevent this by ensuring m$opcode is set and raising instead. --- scripts/base/protocols/ldap/main.zeek | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/base/protocols/ldap/main.zeek b/scripts/base/protocols/ldap/main.zeek index da4a21871c..1e23c7bf84 100644 --- a/scripts/base/protocols/ldap/main.zeek +++ b/scripts/base/protocols/ldap/main.zeek @@ -229,6 +229,10 @@ event LDAP::message(c: connection, fmt("%s: %s -> %s", message_id, m$opcode, opcode_str), "LDAP"); } + m$opcode = opcode_str; + } else if ( ! m?$opcode ) { + # This can happen if we see a bind response before the bind request. + Reporter::conn_weird("LDAP_bind_without_opcode", c, fmt("%s: %s", message_id, opcode_str), "LDAP"); m$opcode = opcode_str; } From f1167fc87fe00977c8ad9f32b14038ebfb03dabc Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 2 Aug 2024 09:15:05 +0200 Subject: [PATCH 59/93] cirrus: Do not disable Spicy for sanitizer builds --- .cirrus.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 88ffb16c76..446116bb5b 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -14,9 +14,9 @@ config: &CONFIG --build-type=release --disable-broker-tests --prefix=$CIRRUS_WOR no_spicy_config: &NO_SPICY_CONFIG --build-type=release --disable-broker-tests --disable-spicy --prefix=$CIRRUS_WORKING_DIR/install --ccache --enable-werror static_config: &STATIC_CONFIG --build-type=release --disable-broker-tests --enable-static-broker --enable-static-binpac --prefix=$CIRRUS_WORKING_DIR/install --ccache --enable-werror binary_config: &BINARY_CONFIG --prefix=$CIRRUS_WORKING_DIR/install --libdir=$CIRRUS_WORKING_DIR/install/lib --binary-package --enable-static-broker --enable-static-binpac --disable-broker-tests --build-type=Release --ccache --enable-werror -asan_sanitizer_config: &ASAN_SANITIZER_CONFIG --build-type=debug --disable-broker-tests --sanitizers=address --enable-fuzzers --enable-coverage --disable-spicy --ccache -ubsan_sanitizer_config: &UBSAN_SANITIZER_CONFIG --build-type=debug --disable-broker-tests --sanitizers=undefined --enable-fuzzers --disable-spicy --ccache --enable-werror -tsan_sanitizer_config: &TSAN_SANITIZER_CONFIG --build-type=debug --disable-broker-tests --sanitizers=thread --enable-fuzzers --disable-spicy --ccache --enable-werror +asan_sanitizer_config: &ASAN_SANITIZER_CONFIG --build-type=debug --disable-broker-tests --sanitizers=address --enable-fuzzers --enable-coverage --ccache --enable-werror +ubsan_sanitizer_config: &UBSAN_SANITIZER_CONFIG --build-type=debug --disable-broker-tests --sanitizers=undefined --enable-fuzzers --ccache --enable-werror +tsan_sanitizer_config: &TSAN_SANITIZER_CONFIG --build-type=debug --disable-broker-tests --sanitizers=thread --enable-fuzzers --ccache --enable-werror resources_template: &RESOURCES_TEMPLATE cpu: *CPUS From 11bc233f45e102fa06fba576eacd400506098fb1 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 2 Aug 2024 17:18:02 +0200 Subject: [PATCH 60/93] coverage/lcov_html: Ignore testing/btest/.tmp gcda/gcno files in the btest/.tmp directory are from .htlo files referencing ephemeral cc files. No need to include these. --- testing/coverage/lcov_html.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/coverage/lcov_html.sh b/testing/coverage/lcov_html.sh index ba8c8a37df..be65e4add4 100755 --- a/testing/coverage/lcov_html.sh +++ b/testing/coverage/lcov_html.sh @@ -116,7 +116,7 @@ verify_run "which lcov" \ # 4. Create a "tracefile" through lcov, which is necessary to create output later on. echo -n "Creating tracefile for output generation... " -verify_run "lcov --no-external --capture --directory . --output-file $COVERAGE_FILE" +verify_run "lcov --no-external --capture --directory . --exclude 'testing/btest/.tmp/*' --output-file $COVERAGE_FILE" # 5. Remove a number of 3rdparty and "extra" files that shouldn't be included in the # Zeek coverage numbers. From 9f5f8b809a96708e1cad0c6def5d45f26b03e7ff Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 6 Aug 2024 17:45:58 +0200 Subject: [PATCH 61/93] spicy/runtime-support: Switch ParameterMismatch::_fmt to static UBSAN's vptr sanitize isn't happy with the call to _fmt() in its member initializer list. $ zeek -r Traces/ssh/single-conn.trace .tmp/spicy.event-args-mismatch/test.hlto .tmp/spicy.event-args-mismatch/event-args-mismatch.zeek <...>/src/include/zeek/spicy/runtime-support.h:80:29: runtime error: member call on address 0x511000369540 which does not point to an object of type 'zeek::spicy::rt::ParameterMismatch' 0x511000369540: note: object has invalid vptr 00 00 00 00 be be be be be be be be be be be be be be be be be be be be be be be be be be be be ^~~~~~~~~~~~~~~~~~~~~~~ invalid vptr #0 0x7f9c9977b019 in zeek::spicy::rt::ParameterMismatch::ParameterMismatch(std::basic_string_view>, zeek::IntrusivePtr const&, std::basic_string_view>) <...>/src/include/zeek/spicy/runtime-support.h:80:29 #1 0x7f9c9977a6a2 in zeek::spicy::rt::to_val(hilti::rt::Bytes const&, zeek::IntrusivePtr const&) <...>/src/include/zeek/spicy/runtime-support.h:562:15 --- src/spicy/runtime-support.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spicy/runtime-support.h b/src/spicy/runtime-support.h index 9ffef2d9d0..0397dc86cc 100644 --- a/src/spicy/runtime-support.h +++ b/src/spicy/runtime-support.h @@ -80,7 +80,7 @@ public: : ParameterMismatch(_fmt(have, want)) {} private: - std::string _fmt(const std::string_view& have, const TypePtr& want) { + static std::string _fmt(const std::string_view& have, const TypePtr& want) { ODesc d; want->Describe(&d); return hilti::rt::fmt("cannot convert Spicy value of type '%s' to Zeek value of type '%s'", have, From 821d460c2e99042327adc097e7daec40ea77678f Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 6 Aug 2024 13:50:22 +0200 Subject: [PATCH 62/93] Bump auxil/spicy to latest development snapshot --- auxil/spicy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/spicy b/auxil/spicy index 4c5c26bf34..7cddc357ff 160000 --- a/auxil/spicy +++ b/auxil/spicy @@ -1 +1 @@ -Subproject commit 4c5c26bf34c2cf2cedf56270e84f1271fcf94465 +Subproject commit 7cddc357ff83175984e19037f1f8062a69cf2030 From 60bdaffe0b2c00fe0d22b8bb8702c88b2ba4f12a Mon Sep 17 00:00:00 2001 From: zeek-bot Date: Wed, 7 Aug 2024 00:20:16 +0000 Subject: [PATCH 63/93] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 2d35a0d90c..25c0805d35 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 2d35a0d90c249dc60ecdeb77b25754381f876e57 +Subproject commit 25c0805d35e063403e9a4de5db89d59a4ef02c88 From 4fe9580a7ee7665757b50f513af0d2752a2da1db Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Wed, 7 Aug 2024 09:35:37 +0200 Subject: [PATCH 64/93] telemetry/Manager: Check RegisterFd() return value Please coverity. --- src/telemetry/Manager.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/telemetry/Manager.cc b/src/telemetry/Manager.cc index 69b4ed485a..7b19affc82 100644 --- a/src/telemetry/Manager.cc +++ b/src/telemetry/Manager.cc @@ -162,7 +162,9 @@ void Manager::InitPostScript() { }); #endif - iosource_mgr->RegisterFd(collector_flare.FD(), this); + if ( ! iosource_mgr->RegisterFd(collector_flare.FD(), this) ) { + reporter->FatalError("Failed to register telemetry collector descriptor"); + } } void Manager::Terminate() { From 84c9daafd12becfc65f4917edd86e52a0b89fb3e Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Wed, 7 Aug 2024 10:31:31 +0200 Subject: [PATCH 65/93] ci/ubuntu-24.04: Use ccache 4.10.2 The ccache version shipped with Ubuntu 24.04 does not yet recognize --fprofile-update=atomic, install one that does. Now that the asan_sanitizer build also includes building Spicy and running the spicyz test suite, ccache is quite important. Reference ccache/ccache#1408 and zeek/zeek#3777. --- ci/ubuntu-24.04/Dockerfile | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/ci/ubuntu-24.04/Dockerfile b/ci/ubuntu-24.04/Dockerfile index ab7ad2cf25..f4f98fa272 100644 --- a/ci/ubuntu-24.04/Dockerfile +++ b/ci/ubuntu-24.04/Dockerfile @@ -4,7 +4,7 @@ ENV DEBIAN_FRONTEND="noninteractive" TZ="America/Los_Angeles" # A version field to invalidate Cirrus's build cache when needed, as suggested in # https://github.com/cirruslabs/cirrus-ci-docs/issues/544#issuecomment-566066822 -ENV DOCKERFILE_VERSION 20240528 +ENV DOCKERFILE_VERSION 20240807 RUN apt-get update && apt-get -y install \ bc \ @@ -41,3 +41,25 @@ RUN apt-get update && apt-get -y install \ RUN pip3 install --break-system-packages junit2html RUN gem install coveralls-lcov + +# Download a newer pre-built ccache version that recognizes -fprofile-update=atomic +# which is used when building with --coverage. +# +# This extracts the tarball into /opt/ccache-- and +# symlinks the executable to /usr/local/bin/ccache. +# +# See: https://ccache.dev/download.html +ENV CCACHE_VERSION=4.10.2 +ENV CCACHE_PLATFORM=linux-x86_64 +ENV CCACHE_URL=https://github.com/ccache/ccache/releases/download/v${CCACHE_VERSION}/ccache-${CCACHE_VERSION}-${CCACHE_PLATFORM}.tar.xz +ENV CCACHE_SHA256=80cab87bd510eca796467aee8e663c398239e0df1c4800a0b5dff11dca0b4f18 +RUN cd /opt \ + && if [ "$(uname -p)" != "x86_64" ]; then echo "cannot use ccache pre-built for x86_64!" >&2; exit 1 ; fi \ + && curl -L --fail --max-time 30 $CCACHE_URL -o ccache.tar.xz \ + && sha256sum ./ccache.tar.xz >&2 \ + && echo "${CCACHE_SHA256} ccache.tar.xz" | sha256sum -c - \ + && tar xvf ./ccache.tar.xz \ + && ln -s $(pwd)/ccache-${CCACHE_VERSION}-${CCACHE_PLATFORM}/ccache /usr/local/bin/ccache \ + && test "$(command -v ccache)" = "/usr/local/bin/ccache" \ + && test "$(ccache --print-version)" = "${CCACHE_VERSION}" \ + && rm ./ccache.tar.xz From 2be39cf0d011221d3ead9ec40ae2304ac214f590 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Wed, 7 Aug 2024 13:04:16 +0200 Subject: [PATCH 66/93] ldap: Promote uint8 to uint64 before shifting Relates to zeek/spicy#1829 --- src/analyzer/protocol/ldap/ldap.spicy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/analyzer/protocol/ldap/ldap.spicy b/src/analyzer/protocol/ldap/ldap.spicy index 52ab0e6160..0816e6afe9 100644 --- a/src/analyzer/protocol/ldap/ldap.spicy +++ b/src/analyzer/protocol/ldap/ldap.spicy @@ -196,7 +196,7 @@ type MaybeEncrypted = unit(ctx: Ctx&) { # If so, switch into KRB mode assuming that's what is being used and # have a chance seeing some more plaintext LDAP in non-sealed tokens. rem: uint8[3] if ( ctx.messageMode == MessageMode::ENCRYPTED && (|self.mech| == 0 || self.mech.starts_with(b"GSS")) ) { - self.saslLen = (self.first << 24) + ($$[0] << 16) + ($$[1] << 8) + $$[2]; + self.saslLen = (uint64(self.first) << 24) + (uint64($$[0]) << 16) + (uint64($$[1]) << 8) + uint64($$[2]); } : uint16 if ( self.saslLen >= 2 ) { From e2b03681d10ea57faf81ee132b4dc2e3d4e5b295 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 2 Aug 2024 11:05:56 -0700 Subject: [PATCH 67/93] Remove EventRegistry::Used and EventRegistry::SetUsed --- scripts/base/init-bare.zeek | 3 -- src/EventHandler.h | 7 ---- src/EventRegistry.cc | 41 ------------------- src/EventRegistry.h | 2 - src/Expr.cc | 12 ------ src/NetVar.cc | 3 -- src/NetVar.h | 2 - src/script_opt/CPP/RuntimeInitSupport.cc | 18 ++------ src/script_opt/ScriptOpt.cc | 9 +--- src/zeek-setup.cc | 10 ----- .../core/check-unused-event-handlers.test | 10 ----- 11 files changed, 6 insertions(+), 111 deletions(-) delete mode 100644 testing/btest/core/check-unused-event-handlers.test diff --git a/scripts/base/init-bare.zeek b/scripts/base/init-bare.zeek index 85a1dc0f20..1d04c2ee09 100644 --- a/scripts/base/init-bare.zeek +++ b/scripts/base/init-bare.zeek @@ -5259,9 +5259,6 @@ const likely_server_ports: set[port] &redef; ## If true, output profiling for Time-Machine queries. const time_machine_profiling = F &redef &deprecated="Remove in v7.1. Unused."; -## If true, warns about unused event handlers at startup. -const check_for_unused_event_handlers = F &redef &deprecated="Remove in v7.1. This has been replaced by usage analyzer functionality."; - ## Holds the filename of the trace file given with ``-w`` (empty if none). ## ## .. zeek:see:: record_all_packets diff --git a/src/EventHandler.h b/src/EventHandler.h index ef647a7c6e..0fbd5c1282 100644 --- a/src/EventHandler.h +++ b/src/EventHandler.h @@ -44,13 +44,6 @@ public: // Returns true if there is at least one local or remote handler. explicit operator bool() const; - [[deprecated("Remove in v7.1 - Unused event handlers are now found via UsageAnalyzer.")]] void SetUsed() { - used = true; - } - [[deprecated("Remove in v7.1 - Unused event handlers are now found via UsageAnalyzer.")]] bool Used() const { - return used; - } - // Handlers marked as error handlers will not be called recursively to // avoid infinite loops if they trigger a similar error themselves. void SetErrorHandler() { error_handler = true; } diff --git a/src/EventRegistry.cc b/src/EventRegistry.cc index 93a5844331..b166546276 100644 --- a/src/EventRegistry.cc +++ b/src/EventRegistry.cc @@ -21,23 +21,12 @@ EventHandlerPtr EventRegistry::Register(std::string_view name, bool is_from_scri if ( ! is_from_script ) not_only_from_script.insert(std::string(name)); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - // Remove in v7.1 - h->SetUsed(); -#pragma GCC diagnostic pop return h; } h = new EventHandler(std::string(name)); event_registry->Register(h, is_from_script); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - // Remove in v7.1 - h->SetUsed(); -#pragma GCC diagnostic pop - return h; } @@ -74,36 +63,6 @@ EventRegistry::string_list EventRegistry::Match(RE_Matcher* pattern) { return names; } -EventRegistry::string_list EventRegistry::UnusedHandlers() { - string_list names; - - for ( const auto& entry : handlers ) { - EventHandler* v = entry.second.get(); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - if ( v->GetFunc() && ! v->Used() ) - names.push_back(entry.first); -#pragma GCC diagnostic pop - } - - return names; -} - -EventRegistry::string_list EventRegistry::UsedHandlers() { - string_list names; - - for ( const auto& entry : handlers ) { - EventHandler* v = entry.second.get(); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - if ( v->GetFunc() && v->Used() ) - names.push_back(entry.first); -#pragma GCC diagnostic pop - } - - return names; -} - EventRegistry::string_list EventRegistry::AllHandlers() { string_list names; diff --git a/src/EventRegistry.h b/src/EventRegistry.h index eb9b9b0026..cbe9c622bf 100644 --- a/src/EventRegistry.h +++ b/src/EventRegistry.h @@ -69,8 +69,6 @@ public: // themselves. void SetErrorHandler(std::string_view name); - [[deprecated("Remove in v7.1 - Unused handlers are now found via UsageAnalyzer.")]] string_list UnusedHandlers(); - [[deprecated("Remove in v7.1 - UsedHandlers() is unreliable - use AllHandlers().")]] string_list UsedHandlers(); string_list AllHandlers(); void PrintDebug(); diff --git a/src/Expr.cc b/src/Expr.cc index abbb07a3d4..3147906b92 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -414,13 +414,6 @@ NameExpr::NameExpr(IDPtr arg_id, bool const_init) : Expr(EXPR_NAME), id(std::mov SetType(make_intrusive(id->GetType())); else SetType(id->GetType()); - - EventHandler* h = event_registry->Lookup(id->Name()); - if ( h ) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - h->SetUsed(); -#pragma GCC diagnostic pop } bool NameExpr::CanDel() const { @@ -4417,11 +4410,6 @@ EventExpr::EventExpr(const char* arg_name, ListExprPtr arg_args) event_registry->Register(h, true); } -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - h->SetUsed(); -#pragma GCC diagnostic pop - handler = h; if ( args->IsError() ) { diff --git a/src/NetVar.cc b/src/NetVar.cc index 67e078e4d6..1b97300858 100644 --- a/src/NetVar.cc +++ b/src/NetVar.cc @@ -182,8 +182,6 @@ int dpd_match_only_beginning; int dpd_late_match_stop; int dpd_ignore_ports; -int check_for_unused_event_handlers; - int record_all_packets; zeek_uint_t bits_per_uid; @@ -229,7 +227,6 @@ void init_general_global_var() { table_incremental_step = id::find_val("table_incremental_step")->AsCount(); packet_filter_default = id::find_val("packet_filter_default")->AsBool(); sig_max_group_size = id::find_val("sig_max_group_size")->AsCount(); - check_for_unused_event_handlers = id::find_val("check_for_unused_event_handlers")->AsBool(); record_all_packets = id::find_val("record_all_packets")->AsBool(); bits_per_uid = id::find_val("bits_per_uid")->AsCount(); } diff --git a/src/NetVar.h b/src/NetVar.h index 8d628c1ff9..8f7319f30f 100644 --- a/src/NetVar.h +++ b/src/NetVar.h @@ -85,8 +85,6 @@ extern int dpd_match_only_beginning; extern int dpd_late_match_stop; extern int dpd_ignore_ports; -extern int check_for_unused_event_handlers; - extern int record_all_packets; extern zeek_uint_t bits_per_uid; diff --git a/src/script_opt/CPP/RuntimeInitSupport.cc b/src/script_opt/CPP/RuntimeInitSupport.cc index f3ab29295a..3674d7605d 100644 --- a/src/script_opt/CPP/RuntimeInitSupport.cc +++ b/src/script_opt/CPP/RuntimeInitSupport.cc @@ -131,13 +131,8 @@ void activate_bodies__CPP(const char* fn, const char* module, bool exported, Typ events.insert(cs.events.begin(), cs.events.end()); } - for ( const auto& e : events ) { - auto eh = event_registry->Register(e); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - eh->SetUsed(); -#pragma GCC diagnostic pop - } + for ( const auto& e : events ) + event_registry->Register(e); } IDPtr lookup_global__CPP(const char* g, const TypePtr& t, bool exported) { @@ -191,13 +186,8 @@ FuncValPtr lookup_func__CPP(string name, int num_bodies, vector has // This might register the same event more than once, // if it's used in multiple bodies, but that's okay as // the semantics for Register explicitly allow it. - for ( auto& e : f.events ) { - auto eh = event_registry->Register(e); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - eh->SetUsed(); -#pragma GCC diagnostic pop - } + for ( auto& e : f.events ) + event_registry->Register(e); } auto sf = make_intrusive(std::move(name), std::move(ft), std::move(bodies), std::move(priorities)); diff --git a/src/script_opt/ScriptOpt.cc b/src/script_opt/ScriptOpt.cc index c41e6cf429..d09e9dd25b 100644 --- a/src/script_opt/ScriptOpt.cc +++ b/src/script_opt/ScriptOpt.cc @@ -417,13 +417,8 @@ static void use_CPP() { f.SetBody(b); } - for ( auto& e : s->second.events ) { - auto h = event_registry->Register(e); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - h->SetUsed(); -#pragma GCC diagnostic pop - } + for ( auto& e : s->second.events ) + event_registry->Register(e); auto finish = s->second.finish_init_func; if ( finish ) diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index c97458984c..8b740a27d8 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -996,16 +996,6 @@ SetupResult setup(int argc, char** argv, Options* zopts) { if ( zeek_init ) event_mgr.Enqueue(zeek_init, Args{}); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - EventRegistry::string_list dead_handlers = event_registry->UnusedHandlers(); -#pragma GCC diagnostic pop - - if ( ! dead_handlers.empty() && check_for_unused_event_handlers ) { - for ( const string& handler : dead_handlers ) - reporter->Warning("event handler never invoked: %s", handler.c_str()); - } - // Enable LeakSanitizer before zeek_init() and even before executing // top-level statements. Even though it's not bad if a leak happens only // once at initialization, we have to assume that script-layer code causing diff --git a/testing/btest/core/check-unused-event-handlers.test b/testing/btest/core/check-unused-event-handlers.test deleted file mode 100644 index b5f9cf4aae..0000000000 --- a/testing/btest/core/check-unused-event-handlers.test +++ /dev/null @@ -1,10 +0,0 @@ -# This test should print a warning that the event handler is never invoked. -# @TEST-REQUIRES: test "${ZEEK_USE_CPP}" != "1" -# @TEST-REQUIRES: $SCRIPTS/have-spicy # This test logs uninvoked event handlers, so disable it if Spicy and its plugin is unavailable. -# @TEST-EXEC: zeek -b %INPUT check_for_unused_event_handlers=T -# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort-and-remove-abspath btest-diff .stderr - -event this_is_never_used() - { - print "not even once"; - } From 1d4bd2c70a9c0852e7d84ffbd6bb3bdad6c1df3b Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 2 Aug 2024 11:06:12 -0700 Subject: [PATCH 68/93] Remove STMT_ANY statement type --- src/Stmt.cc | 6 ------ src/StmtEnums.h | 1 - 2 files changed, 7 deletions(-) diff --git a/src/Stmt.cc b/src/Stmt.cc index a1edb51ee0..cd84febe8e 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -54,12 +54,6 @@ const char* stmt_name(StmtTag t) { "std-function", }; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - if ( int(t) == STMT_ANY ) - return "any"; -#pragma GCC diagnostic pop - return stmt_names[int(t)]; } diff --git a/src/StmtEnums.h b/src/StmtEnums.h index 04bbfcb189..b5a3030088 100644 --- a/src/StmtEnums.h +++ b/src/StmtEnums.h @@ -6,7 +6,6 @@ namespace zeek::detail { // These are in a separate file to break circular dependences enum StmtTag { - STMT_ANY [[deprecated("Remove in v7.1 - Unused and plugins should use STMT_EXTERN.")]] = -1, STMT_ALARM, // Does no longer exist but kept to create enums consistent. STMT_PRINT, STMT_EVENT, From 6bb00f9e017f013ce874afde8a307521ecd6cd89 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 2 Aug 2024 11:06:25 -0700 Subject: [PATCH 69/93] Remove Connection::AppendAddl --- src/Conn.cc | 9 --------- src/Conn.h | 6 ------ 2 files changed, 15 deletions(-) diff --git a/src/Conn.cc b/src/Conn.cc index 8510dc192b..2e53c8184f 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -258,15 +258,6 @@ analyzer::Analyzer* Connection::FindAnalyzer(const zeek::Tag& tag) { analyzer::Analyzer* Connection::FindAnalyzer(const char* name) { return adapter->FindChild(name); } -void Connection::AppendAddl(const char* str) { - const auto& cv = GetVal(); - - const char* old = cv->GetFieldAs(6)->CheckString(); - const char* format = *old ? "%s %s" : "%s%s"; - - cv->Assign(6, util::fmt(format, old, str)); -} - void Connection::Match(detail::Rule::PatternType type, const u_char* data, int len, bool is_orig, bool bol, bool eol, bool clear_state) { if ( primary_PIA ) diff --git a/src/Conn.h b/src/Conn.h index f6ec77e59a..67f41dc68d 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -145,12 +145,6 @@ public: */ const RecordValPtr& GetVal() override; - /** - * Append additional entries to the history field in the connection record. - */ - [[deprecated("Remove in v7.1 - Appears unused and named rough. Use CheckHistory() or AddHistory() instead.")]] void - AppendAddl(const char* str); - void Match(detail::Rule::PatternType type, const u_char* data, int len, bool is_orig, bool bol, bool eol, bool clear_state); From 401a07403628f32c09eb03c57dba5e93fa35681b Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 2 Aug 2024 11:07:30 -0700 Subject: [PATCH 70/93] Remove deprecated modbus event definitions --- src/analyzer/protocol/modbus/events.bif | 4 ---- .../scripts.base.protocols.modbus.coil_parsing_big/coverage | 2 +- .../scripts.base.protocols.modbus.coil_parsing_small/coverage | 2 +- .../Baseline/scripts.base.protocols.modbus.events/coverage | 2 +- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/analyzer/protocol/modbus/events.bif b/src/analyzer/protocol/modbus/events.bif index ecd47379c5..6ec72fe4e5 100644 --- a/src/analyzer/protocol/modbus/events.bif +++ b/src/analyzer/protocol/modbus/events.bif @@ -195,7 +195,6 @@ event modbus_write_multiple_registers_response%(c: connection, headers: ModbusHe ## ## refs: A vector of reference records. event modbus_read_file_record_request%(c: connection, headers: ModbusHeaders, byte_count: count, refs: ModbusFileRecordRequests%); -event modbus_read_file_record_request%(c: connection, headers: ModbusHeaders%) &deprecated="Remove in v7.1. Use the version that takes a byte_count and vector of references"; ## Generated for a Modbus read file record response. ## @@ -207,7 +206,6 @@ event modbus_read_file_record_request%(c: connection, headers: ModbusHeaders%) & ## ## refs: A vector of reference records. event modbus_read_file_record_response%(c: connection, headers: ModbusHeaders, byte_count: count, refs: ModbusFileRecordResponses%); -event modbus_read_file_record_response%(c: connection, headers: ModbusHeaders%) &deprecated="Remove in v7.1. Use the version that takes a byte_count and vector of references"; ## Generated for a Modbus write file record request. ## @@ -219,7 +217,6 @@ event modbus_read_file_record_response%(c: connection, headers: ModbusHeaders%) ## ## refs: A vector of reference records. event modbus_write_file_record_request%(c: connection, headers: ModbusHeaders, byte_count: count, refs: ModbusFileReferences%); -event modbus_write_file_record_request%(c: connection, headers: ModbusHeaders%) &deprecated="Remove in v7.1. Use the version that takes a byte_count and vector of references"; ## Generated for a Modbus write file record response. ## @@ -231,7 +228,6 @@ event modbus_write_file_record_request%(c: connection, headers: ModbusHeaders%) ## ## refs: A vector of reference records. event modbus_write_file_record_response%(c: connection, headers: ModbusHeaders, byte_count: count, refs: ModbusFileReferences%); -event modbus_write_file_record_response%(c: connection, headers: ModbusHeaders%) &deprecated="Remove in v7.1. Use the version that takes a byte_count and vector of references"; ## Generated for a Modbus mask write register request. ## diff --git a/testing/btest/Baseline/scripts.base.protocols.modbus.coil_parsing_big/coverage b/testing/btest/Baseline/scripts.base.protocols.modbus.coil_parsing_big/coverage index c9dd1e6e71..f8af25eb8c 100644 --- a/testing/btest/Baseline/scripts.base.protocols.modbus.coil_parsing_big/coverage +++ b/testing/btest/Baseline/scripts.base.protocols.modbus.coil_parsing_big/coverage @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -5 of 36 events triggered by trace +5 of 32 events triggered by trace diff --git a/testing/btest/Baseline/scripts.base.protocols.modbus.coil_parsing_small/coverage b/testing/btest/Baseline/scripts.base.protocols.modbus.coil_parsing_small/coverage index c9dd1e6e71..f8af25eb8c 100644 --- a/testing/btest/Baseline/scripts.base.protocols.modbus.coil_parsing_small/coverage +++ b/testing/btest/Baseline/scripts.base.protocols.modbus.coil_parsing_small/coverage @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -5 of 36 events triggered by trace +5 of 32 events triggered by trace diff --git a/testing/btest/Baseline/scripts.base.protocols.modbus.events/coverage b/testing/btest/Baseline/scripts.base.protocols.modbus.events/coverage index eb747a6f71..e7693345ad 100644 --- a/testing/btest/Baseline/scripts.base.protocols.modbus.events/coverage +++ b/testing/btest/Baseline/scripts.base.protocols.modbus.events/coverage @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -22 of 36 events triggered by trace +22 of 32 events triggered by trace From aba1f431cf78ed6c0d05a8ca8f217da0a969506b Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 2 Aug 2024 11:08:59 -0700 Subject: [PATCH 71/93] Remove deprecated json NullDoubleWriter class --- CMakeLists.txt | 8 -------- src/threading/formatters/JSON.cc | 8 ++------ src/threading/formatters/JSON.h | 16 ---------------- 3 files changed, 2 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c4c7aa9990..42dc4f0a63 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -340,7 +340,6 @@ add_zeek_dynamic_plugin_build_interface_include_directories( ${PROJECT_SOURCE_DIR}/auxil/binpac/lib ${PROJECT_SOURCE_DIR}/auxil/broker/libbroker ${PROJECT_SOURCE_DIR}/auxil/paraglob/include - ${PROJECT_SOURCE_DIR}/auxil/rapidjson/include ${PROJECT_SOURCE_DIR}/auxil/prometheus-cpp/core/include ${CMAKE_BINARY_DIR}/src ${CMAKE_BINARY_DIR}/src/include @@ -348,10 +347,6 @@ add_zeek_dynamic_plugin_build_interface_include_directories( ${CMAKE_BINARY_DIR}/auxil/broker/libbroker ${CMAKE_BINARY_DIR}/auxil/prometheus-cpp/core/include) -# threading/formatters/JSON.h includes rapidjson headers and may be used -# by external plugins, extend the include path. -target_include_directories(zeek_dynamic_plugin_base SYSTEM - INTERFACE $) target_include_directories( zeek_dynamic_plugin_base SYSTEM INTERFACE $) @@ -1010,9 +1005,6 @@ include(BuiltInSpicyAnalyzer) include_directories(BEFORE ${PCAP_INCLUDE_DIR} ${BIND_INCLUDE_DIR} ${BinPAC_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ${JEMALLOC_INCLUDE_DIR}) -install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/auxil/rapidjson/include/rapidjson - DESTINATION include/zeek/3rdparty/rapidjson/include) - install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/auxil/filesystem/include/ghc DESTINATION include/zeek/3rdparty/) diff --git a/src/threading/formatters/JSON.cc b/src/threading/formatters/JSON.cc index 3231adfead..08a2c2a703 100644 --- a/src/threading/formatters/JSON.cc +++ b/src/threading/formatters/JSON.cc @@ -8,6 +8,8 @@ #define __STDC_LIMIT_MACROS #endif +#define RAPIDJSON_HAS_STDSTRING 1 + #include #include #include @@ -20,12 +22,6 @@ namespace zeek::threading::formatter { -// For deprecated NullDoubleWriter -JSON::NullDoubleWriter::NullDoubleWriter(rapidjson::StringBuffer& stream) - : writer(std::make_unique(stream)) {} - -bool JSON::NullDoubleWriter::Double(double d) { return writer->Double(d); } - JSON::JSON(MsgThread* t, TimeFormat tf, bool arg_include_unset_fields) : Formatter(t), timestamps(tf), include_unset_fields(arg_include_unset_fields) {} diff --git a/src/threading/formatters/JSON.h b/src/threading/formatters/JSON.h index d800ae986a..44dd78d198 100644 --- a/src/threading/formatters/JSON.h +++ b/src/threading/formatters/JSON.h @@ -4,12 +4,6 @@ #include -#define RAPIDJSON_HAS_STDSTRING 1 -// Remove in v7.1 when removing NullDoubleWriter below and also remove -// rapidjson include tweaks from CMake's dynamic_plugin_base target. -#include -#include - #include "zeek/threading/Formatter.h" namespace zeek::json::detail { @@ -39,16 +33,6 @@ public: Value* ParseValue(const std::string& s, const std::string& name, TypeTag type, TypeTag subtype = TYPE_ERROR) const override; - class NullDoubleWriter : public rapidjson::Writer { - public: - [[deprecated("Remove in v7.1 - This is an implementation detail.")]] NullDoubleWriter( - rapidjson::StringBuffer& stream); - bool Double(double d); - - private: - std::unique_ptr writer; - }; - private: void BuildJSON(zeek::json::detail::NullDoubleWriter& writer, Value* val, const std::string& name = "") const; From a716903f3aa379ee4428c2c71b4a416c8278612e Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Sat, 3 Aug 2024 11:29:51 -0700 Subject: [PATCH 72/93] Remove deprecated time machine settings --- scripts/base/frameworks/cluster/main.zeek | 13 ------------- .../frameworks/cluster/setup-connections.zeek | 15 --------------- scripts/base/init-bare.zeek | 3 --- .../btest/Baseline/language.init-integration/out | 10 +++++----- .../supervisor.large-cluster/zeek.bare-1.node.out | 2 +- .../zeek.bare-32.node.out | 2 +- 6 files changed, 7 insertions(+), 38 deletions(-) diff --git a/scripts/base/frameworks/cluster/main.zeek b/scripts/base/frameworks/cluster/main.zeek index e3e45a0cbc..d53a695a97 100644 --- a/scripts/base/frameworks/cluster/main.zeek +++ b/scripts/base/frameworks/cluster/main.zeek @@ -40,10 +40,6 @@ export { ## worker nodes in a cluster. Used with broker-enabled cluster communication. const worker_topic = "zeek/cluster/worker" &redef; - ## The topic name used for exchanging messages that are relevant to - ## time machine nodes in a cluster. Used with broker-enabled cluster communication. - const time_machine_topic = "zeek/cluster/time_machine" &redef &deprecated="Remove in v7.1: Unused."; - ## A set of topic names to be used for broadcasting messages that are ## relevant to all nodes in a cluster. Currently, there is not a common ## topic to broadcast to, because enabling implicit Broker forwarding would @@ -53,9 +49,6 @@ export { manager_topic, proxy_topic, worker_topic, -@pragma push ignore-deprecations - time_machine_topic, -@pragma pop ignore-deprecations }; ## The topic prefix used for exchanging messages that are relevant to @@ -169,10 +162,6 @@ export { PROXY, ## The node type doing all the actual traffic analysis. WORKER, - ## A node acting as a traffic recorder using the - ## `Time Machine `_ - ## software. - TIME_MACHINE &deprecated="Remove in v7.1: Unused.", }; ## Record type to indicate a node in a cluster. @@ -191,8 +180,6 @@ export { interface: string &optional &deprecated="Remove in v7.1: interface is not required and not set consistently on workers. Replace usages with packet_source() or keep a separate worker-to-interface mapping in a global table."; ## Name of the manager node this node uses. For workers and proxies. manager: string &optional; - ## Name of a time machine node with which this node connects. - time_machine: string &optional &deprecated="Remove in v7.1: Unused."; ## A unique identifier assigned to the node by the broker framework. ## This field is only set while a node is connected. id: string &optional; diff --git a/scripts/base/frameworks/cluster/setup-connections.zeek b/scripts/base/frameworks/cluster/setup-connections.zeek index 5cd3e310fd..ba3010129c 100644 --- a/scripts/base/frameworks/cluster/setup-connections.zeek +++ b/scripts/base/frameworks/cluster/setup-connections.zeek @@ -94,11 +94,6 @@ event zeek_init() &priority=-10 case WORKER: Broker::subscribe(Cluster::worker_topic); break; -@pragma push ignore-deprecations - case TIME_MACHINE: - Broker::subscribe(Cluster::time_machine_topic); - break; -@pragma pop ignore-deprecations default: Reporter::error(fmt("Unhandled cluster node type: %s", self$node_type)); return; @@ -121,11 +116,6 @@ event zeek_init() &priority=-10 case MANAGER: connect_peers_with_type(LOGGER); -@pragma push ignore-deprecations - if ( self?$time_machine ) - connect_peer(TIME_MACHINE, self$time_machine); -@pragma pop ignore-deprecations - break; case PROXY: connect_peers_with_type(LOGGER); @@ -141,11 +131,6 @@ event zeek_init() &priority=-10 if ( self?$manager ) connect_peer(MANAGER, self$manager); -@pragma push ignore-deprecations - if ( self?$time_machine ) - connect_peer(TIME_MACHINE, self$time_machine); -@pragma pop ignore-deprecations - break; } } diff --git a/scripts/base/init-bare.zeek b/scripts/base/init-bare.zeek index 1d04c2ee09..9ac3870e8b 100644 --- a/scripts/base/init-bare.zeek +++ b/scripts/base/init-bare.zeek @@ -5256,9 +5256,6 @@ const dpd_ignore_ports = F &redef; ## connection if it misses the initial handshake. const likely_server_ports: set[port] &redef; -## If true, output profiling for Time-Machine queries. -const time_machine_profiling = F &redef &deprecated="Remove in v7.1. Unused."; - ## Holds the filename of the trace file given with ``-w`` (empty if none). ## ## .. zeek:see:: record_all_packets diff --git a/testing/btest/Baseline/language.init-integration/out b/testing/btest/Baseline/language.init-integration/out index 12ca8b84ce..60d67b2490 100644 --- a/testing/btest/Baseline/language.init-integration/out +++ b/testing/btest/Baseline/language.init-integration/out @@ -13,15 +13,15 @@ init_key2 in state2: 1 [worker-1] = [node_type=Cluster::WORKER, ip=127.0.0.1, p=5/udp, manager=manager-1] } { -[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, interface=, manager=, time_machine=, id=, metrics_port=] +[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, interface=, manager=, id=, metrics_port=] } { -[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, interface=, manager=, time_machine=, id=, metrics_port=], -[worker-5] = [node_type=Cluster::WORKER, ip=3.4.5.6, zone_id=, p=15/tcp, interface=, manager=, time_machine=, id=, metrics_port=] +[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, interface=, manager=, id=, metrics_port=], +[worker-5] = [node_type=Cluster::WORKER, ip=3.4.5.6, zone_id=, p=15/tcp, interface=, manager=, id=, metrics_port=] } { -[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, interface=, manager=, time_machine=, id=, metrics_port=], -[worker-6] = [node_type=Cluster::WORKER, ip=4.5.6.7, zone_id=, p=17/udp, interface=, manager=, time_machine=, id=, metrics_port=] +[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, interface=, manager=, id=, metrics_port=], +[worker-6] = [node_type=Cluster::WORKER, ip=4.5.6.7, zone_id=, p=17/udp, interface=, manager=, id=, metrics_port=] } { [3.0, 4] diff --git a/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-1.node.out b/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-1.node.out index 8837c1f15f..add93767e0 100644 --- a/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-1.node.out +++ b/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-1.node.out @@ -1,5 +1,5 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. supervised node zeek_init() 1024, cluster_nodes! -[node_type=Cluster::WORKER, ip=127.0.0.1, zone_id=, p=0/tcp, interface=, manager=, time_machine=, id=, metrics_port=] +[node_type=Cluster::WORKER, ip=127.0.0.1, zone_id=, p=0/tcp, interface=, manager=, id=, metrics_port=] supervised node zeek_done() diff --git a/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-32.node.out b/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-32.node.out index 8837c1f15f..add93767e0 100644 --- a/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-32.node.out +++ b/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-32.node.out @@ -1,5 +1,5 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. supervised node zeek_init() 1024, cluster_nodes! -[node_type=Cluster::WORKER, ip=127.0.0.1, zone_id=, p=0/tcp, interface=, manager=, time_machine=, id=, metrics_port=] +[node_type=Cluster::WORKER, ip=127.0.0.1, zone_id=, p=0/tcp, interface=, manager=, id=, metrics_port=] supervised node zeek_done() From 85b4dc773e5408611f7e200a54292093e64049c6 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Sat, 3 Aug 2024 11:33:42 -0700 Subject: [PATCH 73/93] Remove deprecated policy/tuning/default package --- scripts/policy/tuning/__load__.zeek | 2 -- scripts/policy/tuning/defaults/README | 2 -- scripts/policy/tuning/defaults/__load__.zeek | 1 - .../tuning/defaults/extracted_file_limits.zeek | 1 - .../policy/tuning/defaults/packet-fragments.zeek | 1 - scripts/policy/tuning/defaults/warnings.zeek | 1 - scripts/test-all-policy.zeek | 5 ----- .../Baseline/coverage.bare-mode-errors/errors | 13 ------------- .../coverage.test-all-policy-cluster/.stderr | 16 ---------------- testing/btest/scripts/site/local-compat.test | 3 --- 10 files changed, 45 deletions(-) delete mode 100644 scripts/policy/tuning/__load__.zeek delete mode 100644 scripts/policy/tuning/defaults/README delete mode 100644 scripts/policy/tuning/defaults/__load__.zeek delete mode 100644 scripts/policy/tuning/defaults/extracted_file_limits.zeek delete mode 100644 scripts/policy/tuning/defaults/packet-fragments.zeek delete mode 100644 scripts/policy/tuning/defaults/warnings.zeek diff --git a/scripts/policy/tuning/__load__.zeek b/scripts/policy/tuning/__load__.zeek deleted file mode 100644 index db9fe9a572..0000000000 --- a/scripts/policy/tuning/__load__.zeek +++ /dev/null @@ -1,2 +0,0 @@ -##! This loads the default tuning -@load ./defaults \ No newline at end of file diff --git a/scripts/policy/tuning/defaults/README b/scripts/policy/tuning/defaults/README deleted file mode 100644 index d5417588c9..0000000000 --- a/scripts/policy/tuning/defaults/README +++ /dev/null @@ -1,2 +0,0 @@ -Sets various defaults, and prints warning messages to stdout under -certain conditions. diff --git a/scripts/policy/tuning/defaults/__load__.zeek b/scripts/policy/tuning/defaults/__load__.zeek deleted file mode 100644 index 09bacaace3..0000000000 --- a/scripts/policy/tuning/defaults/__load__.zeek +++ /dev/null @@ -1 +0,0 @@ -@deprecated "Remove in v7.1 The policy/tuning/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; diff --git a/scripts/policy/tuning/defaults/extracted_file_limits.zeek b/scripts/policy/tuning/defaults/extracted_file_limits.zeek deleted file mode 100644 index 09bacaace3..0000000000 --- a/scripts/policy/tuning/defaults/extracted_file_limits.zeek +++ /dev/null @@ -1 +0,0 @@ -@deprecated "Remove in v7.1 The policy/tuning/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; diff --git a/scripts/policy/tuning/defaults/packet-fragments.zeek b/scripts/policy/tuning/defaults/packet-fragments.zeek deleted file mode 100644 index 09bacaace3..0000000000 --- a/scripts/policy/tuning/defaults/packet-fragments.zeek +++ /dev/null @@ -1 +0,0 @@ -@deprecated "Remove in v7.1 The policy/tuning/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; diff --git a/scripts/policy/tuning/defaults/warnings.zeek b/scripts/policy/tuning/defaults/warnings.zeek deleted file mode 100644 index 09bacaace3..0000000000 --- a/scripts/policy/tuning/defaults/warnings.zeek +++ /dev/null @@ -1 +0,0 @@ -@deprecated "Remove in v7.1 The policy/tuning/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; diff --git a/scripts/test-all-policy.zeek b/scripts/test-all-policy.zeek index cf75ed5aa0..a28dae0ea6 100644 --- a/scripts/test-all-policy.zeek +++ b/scripts/test-all-policy.zeek @@ -142,10 +142,5 @@ @load protocols/ssl/validate-ocsp.zeek @load protocols/ssl/validate-sct.zeek @load protocols/ssl/weak-keys.zeek -@load tuning/__load__.zeek -@load tuning/defaults/__load__.zeek -@load tuning/defaults/extracted_file_limits.zeek -@load tuning/defaults/packet-fragments.zeek -@load tuning/defaults/warnings.zeek @load tuning/json-logs.zeek @load tuning/track-all-assets.zeek diff --git a/testing/btest/Baseline/coverage.bare-mode-errors/errors b/testing/btest/Baseline/coverage.bare-mode-errors/errors index 96bd73c166..b1bb951e92 100644 --- a/testing/btest/Baseline/coverage.bare-mode-errors/errors +++ b/testing/btest/Baseline/coverage.bare-mode-errors/errors @@ -1,15 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. ### NOTE: This file has been sorted with diff-sort. -warning in <...>/__load__.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:2 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/__load__.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:2 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/__load__.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:2 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/__load__.zeek, line 1: deprecated script loaded from command line arguments "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/extracted_file_limits.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:147 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/extracted_file_limits.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:147 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/extracted_file_limits.zeek, line 1: deprecated script loaded from command line arguments "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/packet-fragments.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:148 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/packet-fragments.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:148 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/packet-fragments.zeek, line 1: deprecated script loaded from command line arguments "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/warnings.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:149 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/warnings.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:149 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/warnings.zeek, line 1: deprecated script loaded from command line arguments "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; diff --git a/testing/btest/Baseline/coverage.test-all-policy-cluster/.stderr b/testing/btest/Baseline/coverage.test-all-policy-cluster/.stderr index c27d68e2df..bff9a64e41 100644 --- a/testing/btest/Baseline/coverage.test-all-policy-cluster/.stderr +++ b/testing/btest/Baseline/coverage.test-all-policy-cluster/.stderr @@ -1,21 +1,5 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -warning in <...>/__load__.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:2 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/extracted_file_limits.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:147 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/packet-fragments.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:148 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/warnings.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:149 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; received termination signal -warning in <...>/__load__.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:2 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/extracted_file_limits.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:147 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/packet-fragments.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:148 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/warnings.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:149 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; received termination signal -warning in <...>/__load__.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:2 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/extracted_file_limits.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:147 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/packet-fragments.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:148 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/warnings.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:149 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; received termination signal -warning in <...>/__load__.zeek, line 1: deprecated script loaded from <...>/__load__.zeek:2 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/extracted_file_limits.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:147 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/packet-fragments.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:148 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; -warning in <...>/warnings.zeek, line 1: deprecated script loaded from <...>/test-all-policy.zeek:149 "Remove in v7.1 The policy<...>/defaults package is deprecated. The options set here are now the defaults for Zeek in general."; received termination signal diff --git a/testing/btest/scripts/site/local-compat.test b/testing/btest/scripts/site/local-compat.test index 0d287bff2e..edff8da24d 100644 --- a/testing/btest/scripts/site/local-compat.test +++ b/testing/btest/scripts/site/local-compat.test @@ -27,9 +27,6 @@ redef digest_salt = "Please change this value."; # This script logs which scripts were loaded during each run. @load misc/loaded-scripts -# Apply the default tuning scripts for common tuning settings. -@load tuning/defaults - # Estimate and log capture loss. @load misc/capture-loss From 1d0f01d6bc7089f179000221da53afbc0dcba55d Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Sat, 3 Aug 2024 11:37:24 -0700 Subject: [PATCH 74/93] Remove deprecated prometheus telemetry policy script --- scripts/policy/frameworks/telemetry/prometheus.zeek | 2 -- scripts/test-all-policy.zeek | 1 - testing/btest/coverage/bare-mode-errors.test | 2 +- testing/btest/coverage/test-all-policy-cluster.test | 2 +- 4 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 scripts/policy/frameworks/telemetry/prometheus.zeek diff --git a/scripts/policy/frameworks/telemetry/prometheus.zeek b/scripts/policy/frameworks/telemetry/prometheus.zeek deleted file mode 100644 index a7d0226d73..0000000000 --- a/scripts/policy/frameworks/telemetry/prometheus.zeek +++ /dev/null @@ -1,2 +0,0 @@ -@deprecated "Remove in v7.1: Cluster nodes now implicitly listen on metrics port if set in cluster-layout." -@load base/frameworks/telemetry diff --git a/scripts/test-all-policy.zeek b/scripts/test-all-policy.zeek index a28dae0ea6..03999b137b 100644 --- a/scripts/test-all-policy.zeek +++ b/scripts/test-all-policy.zeek @@ -78,7 +78,6 @@ # @load frameworks/spicy/record-spicy-batch.zeek # @load frameworks/spicy/resource-usage.zeek @load frameworks/software/windows-version-detection.zeek -@load frameworks/telemetry/prometheus.zeek @load frameworks/telemetry/log.zeek @load integration/collective-intel/__load__.zeek @load integration/collective-intel/main.zeek diff --git a/testing/btest/coverage/bare-mode-errors.test b/testing/btest/coverage/bare-mode-errors.test index be243bcdc0..e477140083 100644 --- a/testing/btest/coverage/bare-mode-errors.test +++ b/testing/btest/coverage/bare-mode-errors.test @@ -9,4 +9,4 @@ # # @TEST-EXEC: test -d $DIST/scripts # @TEST-EXEC: for script in `find $DIST/scripts/ -name \*\.zeek`; do zeek -b --parse-only $script >>errors 2>&1; done -# @TEST-EXEC: TEST_DIFF_CANONIFIER="grep -v -e 'load-balancing.zeek.*deprecated script loaded' | grep -v -e 'prometheus.zeek.*deprecated script loaded' | $SCRIPTS/diff-remove-abspath | $SCRIPTS/diff-sort" btest-diff errors +# @TEST-EXEC: TEST_DIFF_CANONIFIER="grep -v -e 'load-balancing.zeek.*deprecated script loaded' | $SCRIPTS/diff-remove-abspath | $SCRIPTS/diff-sort" btest-diff errors diff --git a/testing/btest/coverage/test-all-policy-cluster.test b/testing/btest/coverage/test-all-policy-cluster.test index 9d88868063..b213b1ac26 100644 --- a/testing/btest/coverage/test-all-policy-cluster.test +++ b/testing/btest/coverage/test-all-policy-cluster.test @@ -9,7 +9,7 @@ # @TEST-EXEC: CLUSTER_NODE=logger-1 zeek %INPUT # @TEST-EXEC: CLUSTER_NODE=proxy-1 zeek %INPUT # @TEST-EXEC: CLUSTER_NODE=worker-1 zeek %INPUT -# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v "load-balancing.zeek.*deprecated script" | grep -v "prometheus.zeek.*deprecated script" | $SCRIPTS/diff-remove-abspath' btest-diff .stderr +# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v "load-balancing.zeek.*deprecated script" | $SCRIPTS/diff-remove-abspath' btest-diff .stderr @load base/frameworks/cluster @load misc/loaded-scripts From 7a5b29ea817ee341654381f99300d15bb77ad373 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Sat, 3 Aug 2024 11:37:51 -0700 Subject: [PATCH 75/93] Remove deprecated load-balacing policy script --- scripts/policy/misc/load-balancing.zeek | 117 ------------------ scripts/test-all-policy.zeek | 1 - testing/btest/coverage/bare-mode-errors.test | 2 +- .../coverage/test-all-policy-cluster.test | 2 +- 4 files changed, 2 insertions(+), 120 deletions(-) delete mode 100644 scripts/policy/misc/load-balancing.zeek diff --git a/scripts/policy/misc/load-balancing.zeek b/scripts/policy/misc/load-balancing.zeek deleted file mode 100644 index f53e65c494..0000000000 --- a/scripts/policy/misc/load-balancing.zeek +++ /dev/null @@ -1,117 +0,0 @@ -##! This script implements the "Zeek side" of several load balancing -##! approaches for Zeek clusters. - -@deprecated "Remove in v7.1. This script has not seen extensions for the past 10 years and is not at all recommended to use for packet load balancing purposes. On Linux, AF_PACKET is recommended and works out of the box. On FreeBSD, there is Netmap with lb. Otherwise, NIC specific packet sources and approaches exist that handle the load balancing." - -@pragma push ignore-deprecations - -@load base/frameworks/cluster -@load base/frameworks/packet-filter - -module LoadBalancing; - -export { - - type Method: enum { - ## Apply BPF filters to each worker in a way that causes them to - ## automatically flow balance traffic between them. - AUTO_BPF, - }; - - ## Defines the method of load balancing to use. - const method = AUTO_BPF &redef; - - redef record Cluster::Node += { - ## A BPF filter for load balancing traffic sniffed on a single - ## interface across a number of processes. In normal uses, this - ## will be assigned dynamically by the manager and installed by - ## the workers. - lb_filter: string &optional; - }; -} - -@if ( Cluster::is_enabled() ) - -event zeek_init() &priority=5 - { - if ( method != AUTO_BPF ) - return; - - local worker_ip_interface: table[addr, string] of count = table(); - local sorted_node_names: vector of string = vector(); - local node: Cluster::Node; - local name: string; - - # Sort nodes list so that every node iterates over it in same order. - for ( name in Cluster::nodes ) - sorted_node_names += name; - - sort(sorted_node_names, strcmp); - - for ( idx in sorted_node_names ) - { - name = sorted_node_names[idx]; - node = Cluster::nodes[name]; - - if ( node$node_type != Cluster::WORKER ) - next; - - if ( ! node?$interface ) - next; - - if ( [node$ip, node$interface] !in worker_ip_interface ) - worker_ip_interface[node$ip, node$interface] = 0; - - ++worker_ip_interface[node$ip, node$interface]; - } - - # Now that we've counted up how many processes are running per - # interface, let's create the filters for each worker. - local lb_proc_track: table[addr, string] of count = table(); - - for ( idx in sorted_node_names ) - { - name = sorted_node_names[idx]; - node = Cluster::nodes[name]; - - if ( node$node_type != Cluster::WORKER ) - next; - - if ( ! node?$interface ) - next; - - if ( [node$ip, node$interface] !in worker_ip_interface ) - next; - - if ( [node$ip, node$interface] !in lb_proc_track ) - lb_proc_track[node$ip, node$interface] = 0; - - local this_lb_proc = lb_proc_track[node$ip, node$interface]; - local total_lb_procs = worker_ip_interface[node$ip, node$interface]; - ++lb_proc_track[node$ip, node$interface]; - - if ( total_lb_procs > 1 ) - node$lb_filter = PacketFilter::sampling_filter(total_lb_procs, - this_lb_proc); - } - - # Finally, install filter for the current node if it needs one. - for ( idx in sorted_node_names ) - { - name = sorted_node_names[idx]; - node = Cluster::nodes[name]; - - if ( name != Cluster::node ) - next; - - if ( ! node?$lb_filter ) - next; - - restrict_filters["lb_filter"] = node$lb_filter; - PacketFilter::install(); - } - } - -@endif - -@pragma pop diff --git a/scripts/test-all-policy.zeek b/scripts/test-all-policy.zeek index 03999b137b..e0da69a8e1 100644 --- a/scripts/test-all-policy.zeek +++ b/scripts/test-all-policy.zeek @@ -85,7 +85,6 @@ @load misc/detect-traceroute/__load__.zeek @load misc/detect-traceroute/main.zeek # @load misc/dump-events.zeek -@load misc/load-balancing.zeek @load misc/loaded-scripts.zeek @load misc/profiling.zeek @load misc/stats.zeek diff --git a/testing/btest/coverage/bare-mode-errors.test b/testing/btest/coverage/bare-mode-errors.test index e477140083..ea5b66955e 100644 --- a/testing/btest/coverage/bare-mode-errors.test +++ b/testing/btest/coverage/bare-mode-errors.test @@ -9,4 +9,4 @@ # # @TEST-EXEC: test -d $DIST/scripts # @TEST-EXEC: for script in `find $DIST/scripts/ -name \*\.zeek`; do zeek -b --parse-only $script >>errors 2>&1; done -# @TEST-EXEC: TEST_DIFF_CANONIFIER="grep -v -e 'load-balancing.zeek.*deprecated script loaded' | $SCRIPTS/diff-remove-abspath | $SCRIPTS/diff-sort" btest-diff errors +# @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-abspath | $SCRIPTS/diff-sort" btest-diff errors diff --git a/testing/btest/coverage/test-all-policy-cluster.test b/testing/btest/coverage/test-all-policy-cluster.test index b213b1ac26..dc5e14e385 100644 --- a/testing/btest/coverage/test-all-policy-cluster.test +++ b/testing/btest/coverage/test-all-policy-cluster.test @@ -9,7 +9,7 @@ # @TEST-EXEC: CLUSTER_NODE=logger-1 zeek %INPUT # @TEST-EXEC: CLUSTER_NODE=proxy-1 zeek %INPUT # @TEST-EXEC: CLUSTER_NODE=worker-1 zeek %INPUT -# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v "load-balancing.zeek.*deprecated script" | $SCRIPTS/diff-remove-abspath' btest-diff .stderr +# @TEST-EXEC: TEST_DIFF_CANONIFIER='$SCRIPTS/diff-remove-abspath' btest-diff .stderr @load base/frameworks/cluster @load misc/loaded-scripts From 535df5e263e9039bc49b4fa788f316c49110da2d Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Sat, 3 Aug 2024 12:14:50 -0700 Subject: [PATCH 76/93] Remove deprecated Controller::auto_assign_ports and Controller::auto_assign_start_port --- .../management/controller/config.zeek | 2 -- .../management/controller/main.zeek | 24 ++----------------- 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/scripts/policy/frameworks/management/controller/config.zeek b/scripts/policy/frameworks/management/controller/config.zeek index 0b3d50b4ab..9fe10edaa6 100644 --- a/scripts/policy/frameworks/management/controller/config.zeek +++ b/scripts/policy/frameworks/management/controller/config.zeek @@ -65,13 +65,11 @@ export { ## cluster nodes that need them and don't have them explicitly specified ## in cluster configurations. const auto_assign_broker_ports = T &redef; - const auto_assign_ports = T &redef &deprecated="Remove in v7.1: replaced by auto_assign_broker_ports."; ## The TCP start port to use for auto-assigning cluster node listening ## ports, if :zeek:see:`Management::Controller::auto_assign_broker_ports` is ## enabled (the default) and nodes don't come with those ports assigned. const auto_assign_broker_start_port = 2200/tcp &redef; - const auto_assign_start_port = 2200/tcp &redef &deprecated="Remove in v7.1: replaced by auto_assign_broker_start_port."; ## Whether the controller should auto-assign metrics ports for Prometheus ## to nodes that need them and don't have them explicitly specified in diff --git a/scripts/policy/frameworks/management/controller/main.zeek b/scripts/policy/frameworks/management/controller/main.zeek index fd7df8343d..efc603e227 100644 --- a/scripts/policy/frameworks/management/controller/main.zeek +++ b/scripts/policy/frameworks/management/controller/main.zeek @@ -335,12 +335,6 @@ function config_assign_broker_ports(config: Management::Configuration) # instances. local start_port = Management::Controller::auto_assign_broker_start_port; -@pragma push ignore-deprecations - # Keep deprecated config setting working until 7.1: - if ( Management::Controller::auto_assign_start_port != 2200/tcp ) - start_port = Management::Controller::auto_assign_start_port; -@pragma pop ignore-deprecations - local p = port_to_count(start_port); # A set that tracks the ports we've used so far. Helpful for avoiding @@ -613,17 +607,10 @@ function config_validate(config: Management::Configuration, # ports. Verify this both for Broker's ports and the metrics export # ones. -@pragma push ignore-deprecations - # Keep deprecated config setting working until 7.1: - local auto_broker_ports = Management::Controller::auto_assign_broker_ports; - if ( ! Management::Controller::auto_assign_ports ) - auto_broker_ports = F; -@pragma pop ignore-deprecations - local nodes: vector of string; local nodes_str: string; - if ( ! auto_broker_ports ) + if ( ! Management::Controller::auto_assign_broker_ports ) { nodes = config_nodes_lacking_broker_ports(config); @@ -1042,17 +1029,10 @@ event Management::Controller::API::stage_configuration_request(reqid: string, co g_configs[STAGED] = config; config_copy = copy(config); -@pragma push ignore-deprecations - # Keep deprecated config setting working until 7.1: - local auto_broker_ports = Management::Controller::auto_assign_broker_ports; - if ( ! Management::Controller::auto_assign_ports ) - auto_broker_ports = F; - - if ( auto_broker_ports ) + if ( Management::Controller::auto_assign_broker_ports ) config_assign_broker_ports(config_copy); if ( Management::Controller::auto_assign_metrics_ports ) config_assign_metrics_ports(config_copy); -@pragma pop ignore-deprecations g_configs[READY] = config_copy; From a53cc4d01b7937289a590780fdd1d05514db21ca Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Sun, 4 Aug 2024 21:22:59 -0700 Subject: [PATCH 77/93] Remove deprecated Trigger constructor --- src/Trigger.cc | 6 ------ src/Trigger.h | 7 ------- 2 files changed, 13 deletions(-) diff --git a/src/Trigger.cc b/src/Trigger.cc index 3dfe76e2dc..d165da7f5a 100644 --- a/src/Trigger.cc +++ b/src/Trigger.cc @@ -89,12 +89,6 @@ protected: double time; }; -Trigger::Trigger(std::shared_ptr wi, double timeout, const IDSet& _globals, std::vector _local_aggrs, - Frame* f, const Location* loc) - : Trigger(std::move(wi), _globals, std::move(_local_aggrs), timeout, f, loc) { - Unref(this); -} - Trigger::Trigger(std::shared_ptr wi, const IDSet& _globals, std::vector _local_aggrs, double timeout, Frame* f, const Location* loc) { timeout_value = timeout; diff --git a/src/Trigger.h b/src/Trigger.h index 5955cc25b4..0cba28fd20 100644 --- a/src/Trigger.h +++ b/src/Trigger.h @@ -46,13 +46,6 @@ class TriggerTraversalCallback; class Trigger final : public Obj, public notifier::detail::Receiver { public: - // This first constructor can return an invalid pointer, so - // its value must not be used further. - [[deprecated( - "Remove in v7.1. Use second Trigger constructor via " - "make_intrusive<...>.")]] Trigger(std::shared_ptr wi, double timeout, const IDSet& globals, - std::vector local_aggrs, Frame* f, const Location* loc); - // Use this constructor via make_intrusive<...>. The usual pattern is // to then discard what's returned, i.e. "(void)make_intrusive<...>" - // however, a valid pointer will be returned that can be used for From 260a8afebe79dffe767fb87c4abf6268680478cd Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Sun, 4 Aug 2024 21:34:49 -0700 Subject: [PATCH 78/93] Make TypePtr::Capture member variables private The public versions were marked as deprecated for 7.0, and accessors should be used to manage them now. --- src/Type.cc | 3 --- src/Type.h | 10 ++++------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/Type.cc b/src/Type.cc index 5341476a3f..402aee2505 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -599,12 +599,9 @@ TypePtr SetType::ShallowClone() { return make_intrusive(indices, elemen SetType::~SetType() = default; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" FuncType::Capture::Capture(detail::IDPtr _id, bool _deep_copy) : id(std::move(_id)), deep_copy(_deep_copy) { is_managed = id ? ZVal::IsManagedType(id->GetType()) : false; } -#pragma GCC diagnostic pop FuncType::FuncType(RecordTypePtr arg_args, TypePtr arg_yield, FunctionFlavor arg_flavor) : Type(TYPE_FUNC), args(std::move(arg_args)), arg_types(make_intrusive()), yield(std::move(arg_yield)) { diff --git a/src/Type.h b/src/Type.h index 7261a445f4..c5c52bc095 100644 --- a/src/Type.h +++ b/src/Type.h @@ -513,8 +513,6 @@ public: public: Capture(detail::IDPtr _id, bool _deep_copy); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" Capture(const Capture&) = default; Capture(Capture&&) = default; Capture& operator=(const Capture&) = default; @@ -527,11 +525,11 @@ public: // For script optimization: void SetID(detail::IDPtr new_id) { id = std::move(new_id); } -#pragma GCC diagnostic pop - [[deprecated("Remove in v7.1. Use non-default constructor and associated accessors.")]] detail::IDPtr id; - [[deprecated("Remove in v7.1. Use non-default constructor and associated accessors.")]] bool deep_copy; - [[deprecated("Remove in v7.1. Use non-default constructor and associated accessors.")]] bool is_managed; + private: + detail::IDPtr id; + bool deep_copy; + bool is_managed; }; using CaptureList = std::vector; From cbe612400c750fa6554cf0c1618b3236833946af Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Sun, 4 Aug 2024 21:38:54 -0700 Subject: [PATCH 79/93] Remove deprecated DECLARE_OPAQUE_VALUE macro --- src/OpaqueVal.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/OpaqueVal.h b/src/OpaqueVal.h index 371e5fad57..8b6c88b69a 100644 --- a/src/OpaqueVal.h +++ b/src/OpaqueVal.h @@ -91,19 +91,6 @@ private: std::unordered_map _types; }; -/** - * Legacy macro to insert into an OpaqueVal-derived class's declaration. Overrides the "old" serialization methods - * DoSerialize and DoUnserialize. - * @deprecated Use DECLARE_OPAQUE_VALUE_DATA instead. Remove in v7.1. - */ -#define DECLARE_OPAQUE_VALUE(T) \ - friend class zeek::OpaqueMgr::Register; \ - friend zeek::IntrusivePtr zeek::make_intrusive(); \ - broker::expected DoSerialize() const override; \ - bool DoUnserialize(const broker::data& data) override; \ - const char* OpaqueName() const override { return #T; } \ - static zeek::OpaqueValPtr OpaqueInstantiate() { return zeek::make_intrusive(); } - /** * Macro to insert into an OpaqueVal-derived class's declaration. Overrides the "new" serialization methods * DoSerializeData and DoUnserializeData. From dd982ee6c4c755bc41d1117e32a563f522384e97 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Sun, 4 Aug 2024 21:50:04 -0700 Subject: [PATCH 80/93] Remove deprecated OpaqueVal serialization methods --- src/OpaqueVal.cc | 25 ++----------------------- src/OpaqueVal.h | 27 --------------------------- 2 files changed, 2 insertions(+), 50 deletions(-) diff --git a/src/OpaqueVal.cc b/src/OpaqueVal.cc index 4c36084091..b4dcc25a32 100644 --- a/src/OpaqueVal.cc +++ b/src/OpaqueVal.cc @@ -70,12 +70,6 @@ OpaqueValPtr OpaqueMgr::Instantiate(const std::string& id) const { return x != _types.end() ? (*x->second)() : nullptr; } -broker::expected OpaqueVal::Serialize() const { - if ( auto res = SerializeData() ) - return zeek::detail::BrokerDataAccess::Unbox(*res); - return {broker::make_error(broker::ec::serialization_failed)}; -} - std::optional OpaqueVal::SerializeData() const { auto type = OpaqueMgr::mgr()->TypeID(this); @@ -89,8 +83,6 @@ std::optional OpaqueVal::SerializeData() const { return std::move(builder).Build(); } -OpaqueValPtr OpaqueVal::Unserialize(const broker::data& data) { return UnserializeData(BrokerDataView(&data)); } - OpaqueValPtr OpaqueVal::UnserializeData(BrokerDataView data) { if ( ! data.IsList() ) return nullptr; @@ -114,22 +106,9 @@ OpaqueValPtr OpaqueVal::UnserializeData(BrokerListView v) { return val; } -broker::expected OpaqueVal::DoSerialize() const { - return {broker::make_error(broker::ec::serialization_failed)}; -} +std::optional OpaqueVal::DoSerializeData() const { return std::nullopt; } -std::optional OpaqueVal::DoSerializeData() const { - if ( auto res = DoSerialize() ) { - return BrokerData{std::move(*res)}; - } - return std::nullopt; -} - -bool OpaqueVal::DoUnserialize(const broker::data&) { return false; } - -bool OpaqueVal::DoUnserializeData(BrokerDataView data) { - return DoUnserialize(zeek::detail::BrokerDataAccess::Unbox(data)); -} +bool OpaqueVal::DoUnserializeData(BrokerDataView data) { return false; } std::optional OpaqueVal::SerializeType(const TypePtr& t) { if ( t->InternalType() == TYPE_INTERNAL_ERROR ) diff --git a/src/OpaqueVal.h b/src/OpaqueVal.h index 8b6c88b69a..ba0a048979 100644 --- a/src/OpaqueVal.h +++ b/src/OpaqueVal.h @@ -119,28 +119,11 @@ public: explicit OpaqueVal(OpaqueTypePtr t); ~OpaqueVal() override = default; - /** - * Serializes the value into a Broker representation. - * - * @return the broker representation, or an error if serialization - * isn't supported or failed. - */ - [[deprecated("Remove in v7.1: use SerializeData instead")]] broker::expected Serialize() const; - /** * @copydoc Serialize */ std::optional SerializeData() const; - /** - * Reinstantiates a value from its serialized Broker representation. - * - * @param data Broker representation as returned by *Serialize()*. - * @return unserialized instances with reference count at +1 - */ - [[deprecated("Remove in v7.1: use UnserializeData instead")]] static OpaqueValPtr Unserialize( - const broker::data& data); - /** * @copydoc Unserialize */ @@ -155,11 +138,6 @@ protected: friend class Val; friend class OpaqueMgr; - /** - * @deprecated Override DoSerializeData instead. Remove in v7.1. - */ - virtual broker::expected DoSerialize() const; - /** * Must be overridden to provide a serialized version of the derived * class' state. @@ -169,11 +147,6 @@ protected: */ virtual std::optional DoSerializeData() const; - /** - * @deprecated Override DoUnserializeData instead. Remove in v7.1. - */ - virtual bool DoUnserialize(const broker::data& data); - /** * Must be overridden to recreate the derived class' state from a * serialization. From ca69d9fb8f4df8a2194c0667600bb4b3f13b9303 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Sun, 4 Aug 2024 21:50:17 -0700 Subject: [PATCH 81/93] Remove deprecated BloomFilter serialization methods --- src/probabilistic/BloomFilter.cc | 10 ---------- src/probabilistic/BloomFilter.h | 3 --- 2 files changed, 13 deletions(-) diff --git a/src/probabilistic/BloomFilter.cc b/src/probabilistic/BloomFilter.cc index e3a970c3c6..9d95cf5a8d 100644 --- a/src/probabilistic/BloomFilter.cc +++ b/src/probabilistic/BloomFilter.cc @@ -18,12 +18,6 @@ BloomFilter::BloomFilter(const detail::Hasher* arg_hasher) { hasher = arg_hasher BloomFilter::~BloomFilter() { delete hasher; } -broker::expected BloomFilter::Serialize() const { - if ( auto res = SerializeData() ) - return zeek::detail::BrokerDataAccess::Unbox(*res); - return {broker::make_error(broker::ec::serialization_failed)}; -} - std::optional BloomFilter::SerializeData() const { auto h = hasher->Serialize(); @@ -43,10 +37,6 @@ std::optional BloomFilter::SerializeData() const { return std::move(builder).Build(); } -std::unique_ptr BloomFilter::Unserialize(const broker::data& data) { - return UnserializeData(BrokerDataView{&data}); -} - std::unique_ptr BloomFilter::UnserializeData(BrokerDataView data) { if ( ! data.IsList() ) return nullptr; diff --git a/src/probabilistic/BloomFilter.h b/src/probabilistic/BloomFilter.h index b3cfb34eb6..f79b81a60e 100644 --- a/src/probabilistic/BloomFilter.h +++ b/src/probabilistic/BloomFilter.h @@ -105,9 +105,6 @@ public: */ virtual std::string InternalState() const = 0; - [[deprecated("Remove in v7.1: use SerializeData instead")]] broker::expected Serialize() const; - [[deprecated("Remove in v7.1: use UnserializeData instead")]] static std::unique_ptr Unserialize( - const broker::data& data); std::optional SerializeData() const; static std::unique_ptr UnserializeData(BrokerDataView data); From 2d68b1d834fbaeb7b55f35c1fee0d04d529a9e2f Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Sun, 4 Aug 2024 21:53:42 -0700 Subject: [PATCH 82/93] Return an error if GLOBAL:: prefix is used --- src/Scope.cc | 8 +++--- .../language.deprecate-global/.stderr | 3 --- .../Baseline/language.deprecate-global/out | 4 --- .../language.global-colon-colon/.stderr | 8 ------ .../Baseline/language.global-colon-colon/out | 20 -------------- testing/btest/language/deprecate-global.zeek | 27 ------------------- .../btest/language/global-colon-colon.zeek | 22 +++------------ testing/btest/language/global-type-clash.zeek | 2 +- 8 files changed, 7 insertions(+), 87 deletions(-) delete mode 100644 testing/btest/Baseline/language.deprecate-global/.stderr delete mode 100644 testing/btest/Baseline/language.deprecate-global/out delete mode 100644 testing/btest/language/deprecate-global.zeek diff --git a/src/Scope.cc b/src/Scope.cc index 91b806c921..4bebbcdbbf 100644 --- a/src/Scope.cc +++ b/src/Scope.cc @@ -93,11 +93,9 @@ const IDPtr& lookup_ID(const char* name, const char* curr_module, bool no_global bool check_export) { bool explicit_global = zeek::util::starts_with(name, "::"); - // Ad-hoc deprecation if a name starts with "GLOBAL::". In v7.1 we could - // tweak {ID} to reject GLOBAL::, or switch this warning to error instead. - static std::string deprecated_prefix = util::fmt("%s::", GLOBAL_MODULE_NAME); - if ( zeek::util::starts_with(name, deprecated_prefix) ) - reporter->Deprecation(util::fmt("Remove in v7.1: Use :: instead of %s (%s)", deprecated_prefix.c_str(), name)); + static std::string global_prefix = util::fmt("%s::", GLOBAL_MODULE_NAME); + if ( zeek::util::starts_with(name, global_prefix) ) + reporter->Error("Using GLOBAL:: as a prefix is invalid. Use :: instead (%s)", name); std::string fullname = make_full_var_name(curr_module, name); std::string ID_module = extract_module_name(fullname.c_str()); diff --git a/testing/btest/Baseline/language.deprecate-global/.stderr b/testing/btest/Baseline/language.deprecate-global/.stderr deleted file mode 100644 index ba832c6e5f..0000000000 --- a/testing/btest/Baseline/language.deprecate-global/.stderr +++ /dev/null @@ -1,3 +0,0 @@ -### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -warning in <...>/deprecate-global.zeek, line 22: Remove in v7.1: Use :: instead of GLOBAL:: (GLOBAL::test_function) -warning in <...>/deprecate-global.zeek, line 26: Remove in v7.1: Use :: instead of GLOBAL:: (GLOBAL::X) diff --git a/testing/btest/Baseline/language.deprecate-global/out b/testing/btest/Baseline/language.deprecate-global/out deleted file mode 100644 index 3987e838f5..0000000000 --- a/testing/btest/Baseline/language.deprecate-global/out +++ /dev/null @@ -1,4 +0,0 @@ -### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -X, shadows ::X (42) -::X, 42 -GLOBAL::X, 42 diff --git a/testing/btest/Baseline/language.global-colon-colon/.stderr b/testing/btest/Baseline/language.global-colon-colon/.stderr index a24c303643..49d861c74c 100644 --- a/testing/btest/Baseline/language.global-colon-colon/.stderr +++ b/testing/btest/Baseline/language.global-colon-colon/.stderr @@ -1,9 +1 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -warning in <...>/global-colon-colon.zeek, line 67: Remove in v7.1: Use :: instead of GLOBAL:: (GLOBAL::X) -warning in <...>/global-colon-colon.zeek, line 75: Remove in v7.1: Use :: instead of GLOBAL:: (GLOBAL::my_hook) -warning in <...>/global-colon-colon.zeek, line 82: Remove in v7.1: Use :: instead of GLOBAL:: (GLOBAL::func) -warning in <...>/global-colon-colon.zeek, line 89: Remove in v7.1: Use :: instead of GLOBAL:: (GLOBAL::funcX) -warning in <...>/global-colon-colon.zeek, line 110: Remove in v7.1: Use :: instead of GLOBAL:: (GLOBAL::X) -warning in <...>/global-colon-colon.zeek, line 118: Remove in v7.1: Use :: instead of GLOBAL:: (GLOBAL::my_hook) -warning in <...>/global-colon-colon.zeek, line 125: Remove in v7.1: Use :: instead of GLOBAL:: (GLOBAL::func) -warning in <...>/global-colon-colon.zeek, line 132: Remove in v7.1: Use :: instead of GLOBAL:: (GLOBAL::funcX) diff --git a/testing/btest/Baseline/language.global-colon-colon/out b/testing/btest/Baseline/language.global-colon-colon/out index 59ffb07de4..bc61803592 100644 --- a/testing/btest/Baseline/language.global-colon-colon/out +++ b/testing/btest/Baseline/language.global-colon-colon/out @@ -3,8 +3,6 @@ MyModule X (MyModule) print MyModule::X MyModule X -(MyModule) print GLOBAL::X - global X (MyModule) print ::X global X (MyModule) hook my_hook() @@ -13,32 +11,22 @@ (MyModule) hook MyModule::my_hook() MyModule::my_hook() (in GLOBAL) MyModule::my_hook() -(MyModule) hook GLOBAL::my_hook() - my_hook() (in GLOBAL) - ::my_hook() (in GLOBAL) - ::my_hook() (in MyModule using ::) (MyModule) hook ::my_hook() my_hook() (in GLOBAL) ::my_hook() (in GLOBAL) ::my_hook() (in MyModule using ::) (MyModule) call func() MyModule::func() -(MyModule) call GLOBAL::func() - GLOBAL::func() (MyModule) call ::func() GLOBAL::func() (MyModule) call funcX() ::funcX() (in MyModule) -(MyModule) call GLOBAL::funcX() - ::funcX() (in MyModule) (MyModule) call ::funcX() ::funcX() (in MyModule) (G) print X global X (G) print MyModule::X MyModule X -(G) print GLOBAL::X - global X (G) print ::X global X (G) hook my_hook() @@ -48,24 +36,16 @@ (G) MyModule::my_hook() MyModule::my_hook() (in GLOBAL) MyModule::my_hook() -(G) hook GLOBAL::my_hook() - my_hook() (in GLOBAL) - ::my_hook() (in GLOBAL) - ::my_hook() (in MyModule using ::) (G) hook ::my_hook() my_hook() (in GLOBAL) ::my_hook() (in GLOBAL) ::my_hook() (in MyModule using ::) (G) call func() GLOBAL::func() -(G) call GLOBAL::func() - GLOBAL::func() (G) call ::func() GLOBAL::func() (G) call funcX() ::funcX() (in MyModule) -(G) call GLOBAL::funcX() - ::funcX() (in MyModule) (G) call ::funcX() ::funcX() (in MyModule) MyModule::my_event() (in MyModule) diff --git a/testing/btest/language/deprecate-global.zeek b/testing/btest/language/deprecate-global.zeek deleted file mode 100644 index 236cc3bf19..0000000000 --- a/testing/btest/language/deprecate-global.zeek +++ /dev/null @@ -1,27 +0,0 @@ -# @TEST-DOC: Adapt in v7.1 to check for errors upon GLOBAL accesses. - -# @TEST-EXEC: zeek -b %INPUT >out -# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out -# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderr - -module GLOBAL; - -function test_function() { } - -global X = 42; - - -module MyModule; - -global X = fmt("shadows ::X (%s)", ::X); - -event zeek_init() - { - test_function(); - ::test_function(); - GLOBAL::test_function(); - - print "X", X; - print "::X", ::X; - print "GLOBAL::X", GLOBAL::X; - } diff --git a/testing/btest/language/global-colon-colon.zeek b/testing/btest/language/global-colon-colon.zeek index f1abef9066..79e3d25bb9 100644 --- a/testing/btest/language/global-colon-colon.zeek +++ b/testing/btest/language/global-colon-colon.zeek @@ -30,7 +30,7 @@ hook my_hook() &priority=9 print " MyModule::my_hook()"; } -# This implements GLOBAL::my_hook() +# This implements a global my_hook() hook ::my_hook() &priority=8 { print " ::my_hook() (in MyModule using ::)"; @@ -63,37 +63,29 @@ event zeek_init() &priority=5 print fmt(" %s", X); print "(MyModule) print MyModule::X"; print fmt(" %s", MyModule::X); - print "(MyModule) print GLOBAL::X"; - print fmt(" %s", GLOBAL::X); print "(MyModule) print ::X"; print fmt(" %s", ::X); print "(MyModule) hook my_hook()"; hook my_hook(); # This uses MyModule::my_hook(); print "(MyModule) hook MyModule::my_hook()"; hook MyModule::my_hook(); # This uses MyModule::hook(); - print "(MyModule) hook GLOBAL::my_hook()"; - hook GLOBAL::my_hook(); print "(MyModule) hook ::my_hook()"; hook ::my_hook(); print "(MyModule) call func()"; func(); - print "(MyModule) call GLOBAL::func()"; - GLOBAL::func(); print "(MyModule) call ::func()"; ::func(); print "(MyModule) call funcX()"; funcX(); - print "(MyModule) call GLOBAL::funcX()"; - GLOBAL::funcX(); print "(MyModule) call ::funcX()"; ::funcX(); # This schedules MyEvent::my_event() event my_event(); - # This schedules the GLOBAL::my_event(); + # This schedules the global ::my_event() event ::my_event(); } @@ -106,30 +98,22 @@ event zeek_init() &priority=5 print fmt(" %s", X); print "(G) print MyModule::X"; print fmt(" %s", MyModule::X); - print "(G) print GLOBAL::X"; - print fmt(" %s", GLOBAL::X); print "(G) print ::X"; print fmt(" %s", ::X); print "(G) hook my_hook()"; - hook my_hook(); # This uses GLOBAL::my_hook(); + hook my_hook(); # This uses global my_hook(); print "(G) MyModule::my_hook()"; hook MyModule::my_hook(); # This uses MyModule::hook(); - print "(G) hook GLOBAL::my_hook()"; - hook GLOBAL::my_hook(); print "(G) hook ::my_hook()"; hook ::my_hook(); print "(G) call func()"; func(); - print "(G) call GLOBAL::func()"; - GLOBAL::func(); print "(G) call ::func()"; ::func(); print "(G) call funcX()"; funcX(); - print "(G) call GLOBAL::funcX()"; - GLOBAL::funcX(); print "(G) call ::funcX()"; ::funcX(); } diff --git a/testing/btest/language/global-type-clash.zeek b/testing/btest/language/global-type-clash.zeek index 9eac7fb53a..e361046b07 100644 --- a/testing/btest/language/global-type-clash.zeek +++ b/testing/btest/language/global-type-clash.zeek @@ -9,7 +9,7 @@ type r: record { b: count; }; event zeek_init() { - local x: GLOBAL::r; + local x: ::r; x$a = 5; local y: test::r; From 9142a48725a459d8aeebe65158101c01c69196a5 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 5 Aug 2024 11:21:28 -0700 Subject: [PATCH 83/93] Remove deprecated signature definition format --- src/rule-parse.y | 14 ++------------ .../signatures.custom-event-errors/.stderr | 7 +++---- .../btest/Baseline/signatures.custom-event/.stderr | 1 - testing/btest/Baseline/signatures.custom-event/out | 1 - testing/btest/signatures/custom-event-errors.zeek | 9 --------- testing/btest/signatures/custom-event.zeek | 7 ------- 6 files changed, 5 insertions(+), 34 deletions(-) diff --git a/src/rule-parse.y b/src/rule-parse.y index 33fa8dd0c5..c50d52ef95 100644 --- a/src/rule-parse.y +++ b/src/rule-parse.y @@ -199,21 +199,11 @@ rule_attr: { const char *msg = id_to_str($2); if ( ! zeek::util::streq(msg, "") ) - zeek::reporter->Deprecation(zeek::util::fmt("Remove in v7.1: Using an identifier for msg is deprecated (%s:%d)", - current_rule_file, rules_line_number+1)); - current_rule->AddAction(new zeek::detail::RuleActionEvent(msg)); + zeek::reporter->Error("Identifier %s is not an event (%s:%d)", id_to_str($2), + current_rule_file, rules_line_number+1); } } - | TOK_EVENT TOK_IDENT TOK_IDENT - { - // Maybe remove in v7.1: Once we do not support msg as identifier, - // this extra messaging isn't all that useful anymore, but it - // beats a syntax error. - rules_error("custom event and identifier for msg unsupported"); - zeek::detail::rule_matcher->SetParseError(); - } - | TOK_EVENT TOK_IDENT TOK_STRING { current_rule->AddAction(new zeek::detail::RuleActionEvent($3, $2)); } diff --git a/testing/btest/Baseline/signatures.custom-event-errors/.stderr b/testing/btest/Baseline/signatures.custom-event-errors/.stderr index 68f7bf5815..1ee7b0b85e 100644 --- a/testing/btest/Baseline/signatures.custom-event-errors/.stderr +++ b/testing/btest/Baseline/signatures.custom-event-errors/.stderr @@ -1,9 +1,8 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -warning in <...>/custom-event-errors.zeek, line 9: Wrong number of arguments for function. Expected 3, got 2. (event(state:signature_state, data:string)) +warning in <...>/custom-event-errors.zeek, line 7: Wrong number of arguments for function. Expected 3, got 2. (event(state:signature_state, data:string)) error: wrong event parameters for 'wrong_signature2' -warning in <...>/custom-event-errors.zeek, line 11: Wrong number of arguments for function. Expected 2, got 3. (event(state:signature_state, msg:string, data:string)) +warning in <...>/custom-event-errors.zeek, line 9: Wrong number of arguments for function. Expected 2, got 3. (event(state:signature_state, msg:string, data:string)) error: wrong event parameters for 'wrong_signature3' -warning in <...>/custom-event-errors.zeek, line 13: Type mismatch in function argument #1. Expected string, got count. (event(state:signature_state, msg:count, data:string)) +warning in <...>/custom-event-errors.zeek, line 11: Type mismatch in function argument #1. Expected string, got count. (event(state:signature_state, msg:count, data:string)) error: wrong event parameters for 'wrong_signature4' error: Error in signature (./id.sig:19): unknown script-level identifier (non_existing_event) -error: Error in signature (./id2.sig:4): custom event and identifier for msg unsupported diff --git a/testing/btest/Baseline/signatures.custom-event/.stderr b/testing/btest/Baseline/signatures.custom-event/.stderr index 82d88c6d62..49d861c74c 100644 --- a/testing/btest/Baseline/signatures.custom-event/.stderr +++ b/testing/btest/Baseline/signatures.custom-event/.stderr @@ -1,2 +1 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -warning: Remove in v7.1: Using an identifier for msg is deprecated (./id.sig:9) diff --git a/testing/btest/Baseline/signatures.custom-event/out b/testing/btest/Baseline/signatures.custom-event/out index e6984c7450..fca040926f 100644 --- a/testing/btest/Baseline/signatures.custom-event/out +++ b/testing/btest/Baseline/signatures.custom-event/out @@ -1,4 +1,3 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. signature_match2 [orig_h=127.0.0.1, orig_p=30000/udp, resp_h=127.0.0.1, resp_p=13000/udp] -signature_match [orig_h=127.0.0.1, orig_p=30000/udp, resp_h=127.0.0.1, resp_p=13000/udp] - message from identifier (cannot be changed) signature_match3 [orig_h=127.0.0.1, orig_p=30000/udp, resp_h=127.0.0.1, resp_p=13000/udp] - message diff --git a/testing/btest/signatures/custom-event-errors.zeek b/testing/btest/signatures/custom-event-errors.zeek index 445d68f443..cfdadf70e6 100644 --- a/testing/btest/signatures/custom-event-errors.zeek +++ b/testing/btest/signatures/custom-event-errors.zeek @@ -1,7 +1,6 @@ # @TEST-DOC: Using the wrong paramters for custom signature events. # # @TEST-EXEC-FAIL: zeek -b -s id -r $TRACES/chksums/ip4-udp-good-chksum.pcap %INPUT >id.out -# @TEST-EXEC-FAIL: zeek -b -s id2 -r $TRACES/chksums/ip4-udp-good-chksum.pcap %INPUT >id.out # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderr @TEST-START-FILE id.sig @@ -26,14 +25,6 @@ signature udp-proto4 { } @TEST-END-FILE -@TEST-START-FILE id2.sig -# Using two identifiers is not supported. -signature udp-proto-msg-id { - ip-proto == 17 - event signature_match message_as_id -} -@TEST-END-FILE - event wrong_signature2(state: signature_state, data: string) { } event wrong_signature3(state: signature_state, msg: string, data: string) { } diff --git a/testing/btest/signatures/custom-event.zeek b/testing/btest/signatures/custom-event.zeek index 9b9a750a78..2a824eba7f 100644 --- a/testing/btest/signatures/custom-event.zeek +++ b/testing/btest/signatures/custom-event.zeek @@ -10,11 +10,6 @@ signature udp-proto { event my_signature_match3 "message" } -signature udp-proto-msg-id2 { - ip-proto == 17 - event message_as_id -} - signature udp-stuff { dst-ip == mynets event my_signature_match2 @@ -22,8 +17,6 @@ signature udp-stuff { @TEST-END-FILE -const message_as_id = "message from identifier (cannot be changed)"; - const mynets: set[subnet] = { 192.168.1.0/24, 10.0.0.0/8, From 4e9d843cec17c4faa696834e33f186db47cd6804 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Mon, 5 Aug 2024 12:05:34 -0700 Subject: [PATCH 84/93] Remove deprecated Cluster::Node::interface field --- scripts/base/frameworks/cluster/main.zeek | 2 -- scripts/base/frameworks/cluster/supervisor.zeek | 4 ---- testing/btest/Baseline/language.init-integration/out | 10 +++++----- .../supervisor.large-cluster/zeek.bare-1.node.out | 2 +- .../supervisor.large-cluster/zeek.bare-32.node.out | 2 +- 5 files changed, 7 insertions(+), 13 deletions(-) diff --git a/scripts/base/frameworks/cluster/main.zeek b/scripts/base/frameworks/cluster/main.zeek index d53a695a97..f112e9669c 100644 --- a/scripts/base/frameworks/cluster/main.zeek +++ b/scripts/base/frameworks/cluster/main.zeek @@ -176,8 +176,6 @@ export { ## The port that this node will listen on for peer connections. ## A value of ``0/unknown`` means the node is not pre-configured to listen. p: port &default=0/unknown; - ## Identifier for the interface a worker is sniffing. - interface: string &optional &deprecated="Remove in v7.1: interface is not required and not set consistently on workers. Replace usages with packet_source() or keep a separate worker-to-interface mapping in a global table."; ## Name of the manager node this node uses. For workers and proxies. manager: string &optional; ## A unique identifier assigned to the node by the broker framework. diff --git a/scripts/base/frameworks/cluster/supervisor.zeek b/scripts/base/frameworks/cluster/supervisor.zeek index ba0d676c6a..cea4a6f96c 100644 --- a/scripts/base/frameworks/cluster/supervisor.zeek +++ b/scripts/base/frameworks/cluster/supervisor.zeek @@ -43,10 +43,6 @@ function __init_cluster_nodes(): bool typ = rolemap[endp$role]; cnode = [$node_type=typ, $ip=endp$host, $p=endp$p]; -@pragma push ignore-deprecations - if ( endp?$interface ) - cnode$interface = endp$interface; -@pragma pop ignore-deprecations if ( |manager_name| > 0 && cnode$node_type != Cluster::MANAGER ) cnode$manager = manager_name; if ( endp?$metrics_port ) diff --git a/testing/btest/Baseline/language.init-integration/out b/testing/btest/Baseline/language.init-integration/out index 60d67b2490..cc8864b11c 100644 --- a/testing/btest/Baseline/language.init-integration/out +++ b/testing/btest/Baseline/language.init-integration/out @@ -13,15 +13,15 @@ init_key2 in state2: 1 [worker-1] = [node_type=Cluster::WORKER, ip=127.0.0.1, p=5/udp, manager=manager-1] } { -[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, interface=, manager=, id=, metrics_port=] +[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, manager=, id=, metrics_port=] } { -[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, interface=, manager=, id=, metrics_port=], -[worker-5] = [node_type=Cluster::WORKER, ip=3.4.5.6, zone_id=, p=15/tcp, interface=, manager=, id=, metrics_port=] +[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, manager=, id=, metrics_port=], +[worker-5] = [node_type=Cluster::WORKER, ip=3.4.5.6, zone_id=, p=15/tcp, manager=, id=, metrics_port=] } { -[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, interface=, manager=, id=, metrics_port=], -[worker-6] = [node_type=Cluster::WORKER, ip=4.5.6.7, zone_id=, p=17/udp, interface=, manager=, id=, metrics_port=] +[worker-4] = [node_type=Cluster::WORKER, ip=2.3.4.5, zone_id=, p=13/udp, manager=, id=, metrics_port=], +[worker-6] = [node_type=Cluster::WORKER, ip=4.5.6.7, zone_id=, p=17/udp, manager=, id=, metrics_port=] } { [3.0, 4] diff --git a/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-1.node.out b/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-1.node.out index add93767e0..4a385b6968 100644 --- a/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-1.node.out +++ b/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-1.node.out @@ -1,5 +1,5 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. supervised node zeek_init() 1024, cluster_nodes! -[node_type=Cluster::WORKER, ip=127.0.0.1, zone_id=, p=0/tcp, interface=, manager=, id=, metrics_port=] +[node_type=Cluster::WORKER, ip=127.0.0.1, zone_id=, p=0/tcp, manager=, id=, metrics_port=] supervised node zeek_done() diff --git a/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-32.node.out b/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-32.node.out index add93767e0..4a385b6968 100644 --- a/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-32.node.out +++ b/testing/btest/Baseline/supervisor.large-cluster/zeek.bare-32.node.out @@ -1,5 +1,5 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. supervised node zeek_init() 1024, cluster_nodes! -[node_type=Cluster::WORKER, ip=127.0.0.1, zone_id=, p=0/tcp, interface=, manager=, id=, metrics_port=] +[node_type=Cluster::WORKER, ip=127.0.0.1, zone_id=, p=0/tcp, manager=, id=, metrics_port=] supervised node zeek_done() From 15d404dd191a723960e4efd956eec22739d3f1c2 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 6 Aug 2024 10:49:31 -0700 Subject: [PATCH 85/93] Remove deprecated port/ports fields for spicy analyzers --- scripts/spicy/zeek_rt.hlt | 2 +- src/spicy/manager.cc | 21 ---- src/spicy/manager.h | 11 +- src/spicy/runtime-support.cc | 9 +- src/spicy/runtime-support.h | 7 +- src/spicy/spicyz/glue-compiler.cc | 109 ------------------- src/spicy/spicyz/glue-compiler.h | 1 - testing/btest/spicy/event-user-type | 10 +- testing/btest/spicy/port-deprecated.evt | 21 ---- testing/btest/spicy/port-fail.evt | 24 ---- testing/btest/spicy/port-range-one-port.zeek | 24 ---- 11 files changed, 20 insertions(+), 219 deletions(-) delete mode 100644 testing/btest/spicy/port-deprecated.evt delete mode 100644 testing/btest/spicy/port-fail.evt delete mode 100644 testing/btest/spicy/port-range-one-port.zeek diff --git a/scripts/spicy/zeek_rt.hlt b/scripts/spicy/zeek_rt.hlt index 3f4dd28adc..801c49a9b1 100644 --- a/scripts/spicy/zeek_rt.hlt +++ b/scripts/spicy/zeek_rt.hlt @@ -18,7 +18,7 @@ type ZeekTypeTag = enum { } &cxxname="::zeek::spicy::rt::ZeekTypeTag"; declare public void register_spicy_module_begin(string name, string description) &cxxname="zeek::spicy::rt::register_spicy_module_begin"; -declare public void register_protocol_analyzer(string name, hilti::Protocol protocol, vector ports, string parser_orig, string parser_resp, string replaces, string linker_scope) &cxxname="zeek::spicy::rt::register_protocol_analyzer" &have_prototype; +declare public void register_protocol_analyzer(string name, hilti::Protocol protocol, string parser_orig, string parser_resp, string replaces, string linker_scope) &cxxname="zeek::spicy::rt::register_protocol_analyzer" &have_prototype; declare public void register_file_analyzer(string name, vector mime_types, string parser, string replaces, string linker_scope) &cxxname="zeek::spicy::rt::register_file_analyzer" &have_prototype; declare public void register_packet_analyzer(string name, string parser, string replaces, string linker_scope) &cxxname="zeek::spicy::rt::register_packet_analyzer" &have_prototype; declare public void register_type(string ns, string id, BroType t) &cxxname="zeek::spicy::rt::register_type" &have_prototype; diff --git a/src/spicy/manager.cc b/src/spicy/manager.cc index 1a9420e22a..7919380111 100644 --- a/src/spicy/manager.cc +++ b/src/spicy/manager.cc @@ -61,7 +61,6 @@ void Manager::registerSpicyModuleEnd() { } void Manager::registerProtocolAnalyzer(const std::string& name, hilti::rt::Protocol proto, - const hilti::rt::Vector<::zeek::spicy::rt::PortRange>& ports, const std::string& parser_orig, const std::string& parser_resp, const std::string& replaces, const std::string& linker_scope) { SPICY_DEBUG(hilti::rt::fmt("Have Spicy protocol analyzer %s", name)); @@ -74,7 +73,6 @@ void Manager::registerProtocolAnalyzer(const std::string& name, hilti::rt::Proto info.name_zeek = hilti::rt::replace(name, "::", "_"); info.name_zeekygen = hilti::rt::fmt("", name); info.protocol = proto; - info.ports = ports; info.linker_scope = linker_scope; // We may have that analyzer already iff it was previously pre-registered @@ -701,25 +699,6 @@ void Manager::InitPostScript() { if ( ! tag ) reporter->InternalError("cannot get analyzer tag for '%s'", p.name_analyzer.c_str()); - for ( const auto& ports : p.ports ) { - const auto proto = ports.begin.protocol(); - - // Port ranges are closed intervals. - for ( auto port = ports.begin.port(); port <= ports.end.port(); ++port ) { - const auto port_ = hilti::rt::Port(port, proto); - SPICY_DEBUG(hilti::rt::fmt(" Scheduling analyzer for port %s", port_)); - analyzer_mgr->RegisterAnalyzerForPort(tag, transport_protocol(port_), port); - - // Don't double register in case of single-port ranges. - if ( ports.begin.port() == ports.end.port() ) - break; - - // Explicitly prevent overflow. - if ( port == std::numeric_limits::max() ) - break; - } - } - if ( p.parser_resp ) { for ( auto port : p.parser_resp->ports ) { if ( port.direction != ::spicy::rt::Direction::Both && diff --git a/src/spicy/manager.h b/src/spicy/manager.h index 118e03b6c3..195ae3adf1 100644 --- a/src/spicy/manager.h +++ b/src/spicy/manager.h @@ -85,7 +85,6 @@ public: * * @param name name of the analyzer as defined in its EVT file * @param proto analyzer's transport-layer protocol - * @param prts well-known ports for the analyzer; it'll be activated automatically for these * @param parser_orig name of the Spicy parser for the originator side; must match the name that * Spicy registers the unit's parser with * @param parser_resp name of the Spicy parser for the originator side; must match the name that @@ -95,10 +94,9 @@ public: * @param linker_scope scope of current HLTO file, which will restrict visibility of the * registration */ - void registerProtocolAnalyzer(const std::string& name, hilti::rt::Protocol proto, - const hilti::rt::Vector<::zeek::spicy::rt::PortRange>& ports, - const std::string& parser_orig, const std::string& parser_resp, - const std::string& replaces, const std::string& linker_scope); + void registerProtocolAnalyzer(const std::string& name, hilti::rt::Protocol proto, const std::string& parser_orig, + const std::string& parser_resp, const std::string& replaces, + const std::string& linker_scope); /** * Runtime method to register a file analyzer with its Zeek-side @@ -343,7 +341,6 @@ private: std::string name_parser_resp; std::string name_replaces; hilti::rt::Protocol protocol = hilti::rt::Protocol::Undef; - hilti::rt::Vector<::zeek::spicy::rt::PortRange> ports; std::string linker_scope; // Computed and available once the analyzer has been registered. @@ -357,7 +354,7 @@ private: bool operator==(const ProtocolAnalyzerInfo& other) const { return name_analyzer == other.name_analyzer && name_parser_orig == other.name_parser_orig && name_parser_resp == other.name_parser_resp && name_replaces == other.name_replaces && - protocol == other.protocol && ports == other.ports && linker_scope == other.linker_scope; + protocol == other.protocol && linker_scope == other.linker_scope; } bool operator!=(const ProtocolAnalyzerInfo& other) const { return ! (*this == other); } diff --git a/src/spicy/runtime-support.cc b/src/spicy/runtime-support.cc index f5afd37461..8dbf0c39a7 100644 --- a/src/spicy/runtime-support.cc +++ b/src/spicy/runtime-support.cc @@ -26,12 +26,11 @@ void rt::register_spicy_module_begin(const std::string& name, const std::string& void rt::register_spicy_module_end() { spicy_mgr->registerSpicyModuleEnd(); } -void rt::register_protocol_analyzer(const std::string& name, hilti::rt::Protocol proto, - const hilti::rt::Vector<::zeek::spicy::rt::PortRange>& ports, - const std::string& parser_orig, const std::string& parser_resp, - const std::string& replaces, const std::string& linker_scope) { +void rt::register_protocol_analyzer(const std::string& name, hilti::rt::Protocol proto, const std::string& parser_orig, + const std::string& parser_resp, const std::string& replaces, + const std::string& linker_scope) { auto _ = hilti::rt::profiler::start("zeek/rt/register_protocol_analyzer"); - spicy_mgr->registerProtocolAnalyzer(name, proto, ports, parser_orig, parser_resp, replaces, linker_scope); + spicy_mgr->registerProtocolAnalyzer(name, proto, parser_orig, parser_resp, replaces, linker_scope); } void rt::register_file_analyzer(const std::string& name, const hilti::rt::Vector& mime_types, diff --git a/src/spicy/runtime-support.h b/src/spicy/runtime-support.h index 0397dc86cc..c0bf9f4631 100644 --- a/src/spicy/runtime-support.h +++ b/src/spicy/runtime-support.h @@ -106,10 +106,9 @@ void register_spicy_module_begin(const std::string& id, const std::string& descr * Registers a Spicy protocol analyzer with its EVT meta information with the * plugin's runtime. */ -void register_protocol_analyzer(const std::string& id, hilti::rt::Protocol proto, - const hilti::rt::Vector<::zeek::spicy::rt::PortRange>& ports, - const std::string& parser_orig, const std::string& parser_resp, - const std::string& replaces, const std::string& linker_scope); +void register_protocol_analyzer(const std::string& id, hilti::rt::Protocol proto, const std::string& parser_orig, + const std::string& parser_resp, const std::string& replaces, + const std::string& linker_scope); /** * Registers a Spicy file analyzer with its EVT meta information with the diff --git a/src/spicy/spicyz/glue-compiler.cc b/src/spicy/spicyz/glue-compiler.cc index e9240ed245..9f992c6538 100644 --- a/src/spicy/spicyz/glue-compiler.cc +++ b/src/spicy/spicyz/glue-compiler.cc @@ -260,79 +260,6 @@ static std::string extract_expr(const std::string& chunk, size_t* i) { return expr; } -static hilti::rt::Port extract_port(const std::string& chunk, size_t* i) { - eat_spaces(chunk, i); - - std::string s; - size_t j = *i; - - while ( j < chunk.size() && isdigit(chunk[j]) ) - ++j; - - if ( *i == j ) - throw ParseError("cannot parse port specification"); - - hilti::rt::Protocol proto; - uint64_t port = std::numeric_limits::max(); - - s = chunk.substr(*i, j - *i); - hilti::util::atoi_n(s.begin(), s.end(), 10, &port); - - if ( port > 65535 ) - throw ParseError("port outside of valid range"); - - *i = j; - - if ( chunk[*i] != '/' ) - throw ParseError("cannot parse port specification"); - - (*i)++; - - if ( looking_at(chunk, *i, "tcp") ) { - proto = hilti::rt::Protocol::TCP; - eat_token(chunk, i, "tcp"); - } - - else if ( looking_at(chunk, *i, "udp") ) { - proto = hilti::rt::Protocol::UDP; - eat_token(chunk, i, "udp"); - } - - else if ( looking_at(chunk, *i, "icmp") ) { - proto = hilti::rt::Protocol::ICMP; - eat_token(chunk, i, "icmp"); - } - - else - throw ParseError("cannot parse port specification"); - - return {static_cast(port), proto}; -} - -static ::zeek::spicy::rt::PortRange extract_port_range(const std::string& chunk, size_t* i) { - auto start = extract_port(chunk, i); - auto end = std::optional(); - - if ( looking_at(chunk, *i, "-") ) { - eat_token(chunk, i, "-"); - end = extract_port(chunk, i); - } - - if ( end ) { - if ( start.protocol() != end->protocol() ) - throw ParseError("start and end of port range must have same protocol"); - - if ( start.port() > end->port() ) - throw ParseError("start of port range cannot be after its end"); - } - - if ( ! end ) - // EVT port ranges are a closed. - end = hilti::rt::Port(start.port(), start.protocol()); - - return {start, *end}; -} - void GlueCompiler::init(Driver* driver, int zeek_version) { _driver = driver; _zeek_version = zeek_version; @@ -704,27 +631,6 @@ glue::ProtocolAnalyzer GlueCompiler::parseProtocolAnalyzer(const std::string& ch } } - else if ( looking_at(chunk, i, "ports") ) { - eat_token(chunk, &i, "ports"); - eat_token(chunk, &i, "{"); - - while ( true ) { - a.ports.push_back(extract_port_range(chunk, &i)); - - if ( looking_at(chunk, i, "}") ) { - eat_token(chunk, &i, "}"); - break; - } - - eat_token(chunk, &i, ","); - } - } - - else if ( looking_at(chunk, i, "port") ) { - eat_token(chunk, &i, "port"); - a.ports.push_back(extract_port_range(chunk, &i)); - } - else if ( looking_at(chunk, i, "replaces") ) { eat_token(chunk, &i, "replaces"); a.replaces = extract_id(chunk, &i); @@ -739,14 +645,6 @@ glue::ProtocolAnalyzer GlueCompiler::parseProtocolAnalyzer(const std::string& ch eat_token(chunk, &i, ","); } - if ( ! a.ports.empty() ) - hilti::logger().warning( - hilti::rt:: - fmt("Remove in v7.1: Analyzer %s is using the deprecated 'port' or 'ports' keyword to register " - "well-known ports. Use Analyzer::register_for_ports() in the accompanying Zeek script instead.", - a.name), - a.location); - return a; } @@ -1034,13 +932,6 @@ bool GlueCompiler::compile() { preinit_body.addCall("zeek_rt::register_protocol_analyzer", {builder()->stringMutable(a.name.str()), builder()->id(protocol), - builder()->vector( - hilti::util::transform(a.ports, - [this](const auto& p) -> hilti::Expression* { - return builder()->call("zeek_rt::make_port_range", - {builder()->port(p.begin), - builder()->port(p.end)}); - })), builder()->stringMutable(a.unit_name_orig.str()), builder()->stringMutable(a.unit_name_resp.str()), builder()->stringMutable(a.replaces), builder()->scope()}); diff --git a/src/spicy/spicyz/glue-compiler.h b/src/spicy/spicyz/glue-compiler.h index 58e42909f3..22ffcdc332 100644 --- a/src/spicy/spicyz/glue-compiler.h +++ b/src/spicy/spicyz/glue-compiler.h @@ -45,7 +45,6 @@ struct ProtocolAnalyzer { hilti::Location location; /**< Location where the analyzer was defined. */ hilti::ID name; /**< Name of the analyzer. */ hilti::rt::Protocol protocol = hilti::rt::Protocol::Undef; /**< The transport layer the analyzer uses. */ - std::vector<::zeek::spicy::rt::PortRange> ports; /**< The ports associated with the analyzer. */ hilti::ID unit_name_orig; /**< The fully-qualified name of the unit type to parse the originator side. */ hilti::ID unit_name_resp; /**< The fully-qualified name of the unit type to parse the originator diff --git a/testing/btest/spicy/event-user-type b/testing/btest/spicy/event-user-type index 75f99b4042..14b0883d5f 100644 --- a/testing/btest/spicy/event-user-type +++ b/testing/btest/spicy/event-user-type @@ -25,8 +25,7 @@ type Y = unit { # @TEST-START-FILE foo.evt protocol analyzer spicy::foo over UDP: - parse with foo::X, - ports { 12345/udp, 31337/udp }; + parse with foo::X; import foo; @@ -36,6 +35,13 @@ on foo::X -> event foo::X($conn, $is_orig, self.y); # @TEST-END-FILE # @TEST-START-FILE foo.zeek +const foo_ports = { 12345/udp, 31337/udp}; + +event zeek_init() +{ + Analyzer::register_for_ports(Analyzer::ANALYZER_SPICY_FOO, foo_ports); +} + event foo::X(c: connection, is_orig: bool, y: foo::Y) { print fmt("is_orig=%d y=%s", is_orig, y); diff --git a/testing/btest/spicy/port-deprecated.evt b/testing/btest/spicy/port-deprecated.evt deleted file mode 100644 index 220a9d1faf..0000000000 --- a/testing/btest/spicy/port-deprecated.evt +++ /dev/null @@ -1,21 +0,0 @@ -# @TEST-REQUIRES: have-spicy -# -# @TEST-EXEC: spicyz -d -o test.hlto ./udp-test.evt 2>out.stderr -# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out.stderr -# -# @TEST-DOC: Remove with v7.1: Specifying ports is deprecated. - -module Test; - -import zeek; - -public type Message = unit { - data: bytes &eod {} -}; - -# @TEST-START-FILE udp-test.evt -protocol analyzer spicy::TEST over UDP: - parse with Test::Message, - port 11337/udp-11340/udp, - ports {31337/udp-31340/udp}; -# @TEST-END-FILE diff --git a/testing/btest/spicy/port-fail.evt b/testing/btest/spicy/port-fail.evt deleted file mode 100644 index e51ca0fb79..0000000000 --- a/testing/btest/spicy/port-fail.evt +++ /dev/null @@ -1,24 +0,0 @@ -# @TEST-REQUIRES: have-spicy -# -# @TEST-EXEC-FAIL: spicyz %INPUT -d -o x.hlto >output 2>&1 -# @TEST-EXEC: TEST_DIFF_CANONIFIER=diff-canonifier-spicy btest-diff output -# -# @TEST-DOC: Remove with v7.1 - -protocol analyzer spicy::SSH over TCP: - port 123456/udp; - -@TEST-START-NEXT - -protocol analyzer spicy::SSH over TCP: - port -1/udp; - -@TEST-START-NEXT - -protocol analyzer spicy::SSH over TCP: - port 1/udp-2/tcp; - -@TEST-START-NEXT - -protocol analyzer spicy::SSH over TCP: - port 2/udp-1/udp; diff --git a/testing/btest/spicy/port-range-one-port.zeek b/testing/btest/spicy/port-range-one-port.zeek deleted file mode 100644 index 95c32f2b27..0000000000 --- a/testing/btest/spicy/port-range-one-port.zeek +++ /dev/null @@ -1,24 +0,0 @@ -# @TEST-REQUIRES: have-spicy -# -# @TEST-EXEC: spicyz -o test.hlto udp-test.spicy ./udp-test.evt -# @TEST-EXEC: HILTI_DEBUG=zeek zeek -Cr ${TRACES}/udp-packet.pcap test.hlto %INPUT >out 2>&1 -# @TEST-EXEC: grep -e 'Scheduling analyzer' -e 'error during parsing' < out > out.filtered -# @TEST-EXEC: btest-diff out.filtered - -# @TEST-DOC: Remove with v7.1. Expect a single 'Scheduling analyzer ...' message in the debug output and no parsing errors. There was a bug that 'port 31336/udp' would be wrongly interpreted as a 31336/udp-31337/udp port range. Regression test for #3278. - -# @TEST-START-FILE udp-test.spicy -module UDPTest; - -public type Message = unit { - data: bytes &eod { - assert False: "not reached"; - } -}; -# @TEST-END-FILE - -# @TEST-START-FILE udp-test.evt -protocol analyzer spicy::UDP_TEST over UDP: - parse with UDPTest::Message, - port 31336/udp; -# @TEST-END-FILE From c56c7af44e0f230710e156a437f983a9f2ae3052 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 7 Aug 2024 12:27:56 -0700 Subject: [PATCH 86/93] Add note to NEWS about the removal of OpaqueVal::DoSerialize and OpaqueVal::DoUnserialize --- NEWS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NEWS b/NEWS index a4506b1577..bfb2deb0a4 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,13 @@ Zeek 7.1.0 Breaking Changes ---------------- +* The ``OpaqueVal::DoSerialize`` and ``OpaqueVal::DoUnserialize`` methods were + marked as deprecated in v7.0 and have now been removed as per the Zeek + deprecation policy. Plugins that were overriding these methods and were not + updated will fail to compile. Those plugins should be updated to override the + new ``OpaqueVal::DoSerializeData`` and ``OpaqueVal::DoUnserializeData`` + methods. + New Functionality ----------------- From bd611945e5ede589c9442fadbecbe404e572f8dc Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Wed, 7 Aug 2024 16:03:12 -0700 Subject: [PATCH 87/93] Update zeekctl submodule --- auxil/zeekctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/zeekctl b/auxil/zeekctl index 39c0ee1e17..5cf3ceb862 160000 --- a/auxil/zeekctl +++ b/auxil/zeekctl @@ -1 +1 @@ -Subproject commit 39c0ee1e1742bb28dff57632ee4620f905b892e7 +Subproject commit 5cf3ceb8628d1824b3254f1e4c918002d53b8041 From 80cf06cb796ee475879325db5763f53e45537841 Mon Sep 17 00:00:00 2001 From: zeek-bot Date: Thu, 8 Aug 2024 00:23:28 +0000 Subject: [PATCH 88/93] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index 25c0805d35..a78c6c3e23 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 25c0805d35e063403e9a4de5db89d59a4ef02c88 +Subproject commit a78c6c3e23d758c67d065010e7ebe173fa3fe4b0 From 3e6511af413c7a8b3803bc7940e0b6dd46048b74 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 8 Aug 2024 15:31:15 +0200 Subject: [PATCH 89/93] btest: Skip core.script-args under TSAN TSAN may re-execute the executable when the memory layout doesn't fullfill requirements, causing argument confusion when that happens. Closes #3774. --- testing/btest/core/script-args.zeek | 4 ++++ testing/scripts/have-tsan | 7 +++++++ 2 files changed, 11 insertions(+) create mode 100755 testing/scripts/have-tsan diff --git a/testing/btest/core/script-args.zeek b/testing/btest/core/script-args.zeek index b229c87ada..7484bb9441 100644 --- a/testing/btest/core/script-args.zeek +++ b/testing/btest/core/script-args.zeek @@ -2,6 +2,10 @@ # the script differently, leading to complaints that there are no scripts. # @TEST-REQUIRES: test "${ZEEK_USE_CPP}" != "1" +# TSAN may re-execute the executable when the memory layout doesn't fullfill +# requirements, causing argument confusion when that happens (see #3774). +# @TEST-REQUIRES: ! have-tsan + # @TEST-EXEC: printf '#!' > test.zeek # @TEST-EXEC: printf "$BUILD/src/zeek -b --\n" >> test.zeek # @TEST-EXEC: cat %INPUT >> test.zeek diff --git a/testing/scripts/have-tsan b/testing/scripts/have-tsan new file mode 100755 index 0000000000..8030c8d248 --- /dev/null +++ b/testing/scripts/have-tsan @@ -0,0 +1,7 @@ +#!/bin/sh + +if grep -q "ZEEK_SANITIZERS:STRING=.*thread.*" "${BUILD}"/CMakeCache.txt; then + exit 0 +fi + +exit 1 From 4298fe16cac13c2a5ec639c73989537aeb49c639 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 8 Aug 2024 09:44:07 -0700 Subject: [PATCH 90/93] Update zeekctl submodule [nomail] --- auxil/zeekctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/zeekctl b/auxil/zeekctl index c6f6c139cb..7e1a844808 160000 --- a/auxil/zeekctl +++ b/auxil/zeekctl @@ -1 +1 @@ -Subproject commit c6f6c139cb78fc5e4f6a820206a73f216ef3616e +Subproject commit 7e1a8448083ef0013f15e67ce001836e680589a2 From 371dcdc94e4234d3d040e2622d84e54a3d59acc9 Mon Sep 17 00:00:00 2001 From: zeek-bot Date: Fri, 9 Aug 2024 00:10:26 +0000 Subject: [PATCH 91/93] Update doc submodule [nomail] [skip ci] --- doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc b/doc index a78c6c3e23..f450f803d3 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit a78c6c3e23d758c67d065010e7ebe173fa3fe4b0 +Subproject commit f450f803d3e69cb2fd474a919b7a6c6885f1f433 From fa9dc159a2b834070b7aafe397c045d3a73635af Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 9 Aug 2024 09:48:54 +0200 Subject: [PATCH 92/93] rule-parse: Remove id_to_str() lookup to squelch coverity warning Coverity didn't like that id_to_str() allocates memory and we didn't free it. Remote its usage wholesale. --- src/rule-parse.y | 7 +------ .../Baseline/signatures.custom-event-errors/.stderr | 4 +++- testing/btest/signatures/custom-event-errors.zeek | 10 ++++++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/rule-parse.y b/src/rule-parse.y index c50d52ef95..e1294d6af9 100644 --- a/src/rule-parse.y +++ b/src/rule-parse.y @@ -196,12 +196,7 @@ rule_attr: if ( is_event($2) ) current_rule->AddAction(new zeek::detail::RuleActionEvent(nullptr, $2)); else - { - const char *msg = id_to_str($2); - if ( ! zeek::util::streq(msg, "") ) - zeek::reporter->Error("Identifier %s is not an event (%s:%d)", id_to_str($2), - current_rule_file, rules_line_number+1); - } + rules_error("identifier is not an event", $2); } | TOK_EVENT TOK_IDENT TOK_STRING diff --git a/testing/btest/Baseline/signatures.custom-event-errors/.stderr b/testing/btest/Baseline/signatures.custom-event-errors/.stderr index 1ee7b0b85e..97f17fa2a5 100644 --- a/testing/btest/Baseline/signatures.custom-event-errors/.stderr +++ b/testing/btest/Baseline/signatures.custom-event-errors/.stderr @@ -5,4 +5,6 @@ warning in <...>/custom-event-errors.zeek, line 9: Wrong number of arguments for error: wrong event parameters for 'wrong_signature3' warning in <...>/custom-event-errors.zeek, line 11: Type mismatch in function argument #1. Expected string, got count. (event(state:signature_state, msg:count, data:string)) error: wrong event parameters for 'wrong_signature4' -error: Error in signature (./id.sig:19): unknown script-level identifier (non_existing_event) +error: Error in signature (./id.sig:19): identifier is not an event (non_existing_event) +error: Error in signature (./id.sig:24): identifier is not an event (cat) +error: Error in signature (./id.sig:29): identifier is not an event (ignore_checksums) diff --git a/testing/btest/signatures/custom-event-errors.zeek b/testing/btest/signatures/custom-event-errors.zeek index cfdadf70e6..9a6d80eb05 100644 --- a/testing/btest/signatures/custom-event-errors.zeek +++ b/testing/btest/signatures/custom-event-errors.zeek @@ -23,6 +23,16 @@ signature udp-proto4 { ip-proto == 17 event non_existing_event } + +signature udp-proto5 { + ip-proto == 17 + event cat # builtin function +} + +signature udp-proto6 { + ip-proto == 17 + event ignore_checksums # variable +} @TEST-END-FILE event wrong_signature2(state: signature_state, data: string) { } From a5aadc11db1292f1752985d5bfc40ce492d625e6 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Mon, 12 Aug 2024 09:45:52 +0200 Subject: [PATCH 93/93] spicyz: Add back message about removed support for port / ports in evt spicy-dhcp, spicy-http and spicy-dns all have this still in their .evt files, so it seems popular. Be more helpful than "unexpected token" to users. --- src/spicy/spicyz/glue-compiler.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/spicy/spicyz/glue-compiler.cc b/src/spicy/spicyz/glue-compiler.cc index 9f992c6538..c34d7e1f6b 100644 --- a/src/spicy/spicyz/glue-compiler.cc +++ b/src/spicy/spicyz/glue-compiler.cc @@ -631,6 +631,13 @@ glue::ProtocolAnalyzer GlueCompiler::parseProtocolAnalyzer(const std::string& ch } } + else if ( looking_at(chunk, i, "ports") || looking_at(chunk, i, "port") ) { + throw ParseError(hilti::rt::fmt( + "Analyzer %s is using the removed 'port' or 'ports' keyword to register " + "well-known ports. Use Analyzer::register_for_ports() in the accompanying Zeek script instead.", + a.name)); + } + else if ( looking_at(chunk, i, "replaces") ) { eat_token(chunk, &i, "replaces"); a.replaces = extract_id(chunk, &i);