@@ -75,9 +75,9 @@ struct StringHashByLower {
7575};
7676
7777// / Fields considered sensitive because they may contain user-private
78- // / information. These fields are replaced with auto-generated generic content
79- // / by default. To turn off this behavior, the user should add the
80- // / --promiscuous-mode flag as a commandline argument .
78+ // / information. These fields are replaced with auto-generated generic content by
79+ // / default. To override this behavior, the user should specify their own fields
80+ // / they consider sensitive with --sensitive-fields .
8181// /
8282// / While these are specified with case, they are matched case-insensitively.
8383std::unordered_set<std::string, StringHashByLower, InsensitiveCompare> default_sensitive_fields = {
@@ -568,6 +568,143 @@ session_txn_handler(TSCont contp, TSEvent event, void *edata)
568568 return TS_SUCCESS;
569569}
570570
571+ /* * Create a TLS characteristics node.
572+ *
573+ * This function encapsulates the logic common between the client-side and
574+ * server-side logic for populating the TLS node.
575+ *
576+ * @param[in] ssnp The pointer for this session.
577+ *
578+ * @return The node describing the TLS properties of this session.
579+ */
580+ std::string
581+ get_tls_description_helper (TSVConn ssn_vc)
582+ {
583+ TSSslConnection ssl_conn = TSVConnSslConnectionGet (ssn_vc);
584+ SSL *ssl_obj = (SSL *)ssl_conn;
585+ if (ssl_obj == nullptr ) {
586+ return " " ;
587+ }
588+ std::ostringstream tls_description;
589+ tls_description << R"( "tls":{)" ;
590+ const char *sni_ptr = SSL_get_servername (ssl_obj, TLSEXT_NAMETYPE_host_name);
591+ if (sni_ptr != nullptr ) {
592+ std::string_view sni{sni_ptr};
593+ if (!sni.empty ()) {
594+ tls_description << R"( "sni":")" << sni << R"( ")" ;
595+ }
596+ }
597+ tls_description << R"( ,"verify_mode":")" << std::to_string (SSL_get_verify_mode (ssl_obj)) << R"( ")" ;
598+ tls_description << " }" ;
599+ return tls_description.str ();
600+ }
601+
602+ /* * Create a server-side TLS characteristics node.
603+ *
604+ * @param[in] ssnp The pointer for this session.
605+ *
606+ * @return The node describing the TLS properties of this session.
607+ */
608+ std::string
609+ get_server_tls_description (TSHttpSsn ssnp)
610+ {
611+ TSVConn ssn_vc = TSHttpSsnServerVConnGet (ssnp);
612+ return get_tls_description_helper (ssn_vc);
613+ }
614+
615+ /* * Create a client-side TLS characteristics node.
616+ *
617+ * @param[in] ssnp The pointer for this session.
618+ *
619+ * @return The node describing the TLS properties of this session.
620+ */
621+ std::string
622+ get_client_tls_description (TSHttpSsn ssnp)
623+ {
624+ TSVConn ssn_vc = TSHttpSsnClientVConnGet (ssnp);
625+ return get_tls_description_helper (ssn_vc);
626+ }
627+
628+ // / A named boolean for callers who pass the is_client parameter.
629+ constexpr bool IS_CLIENT = true ;
630+
631+ /* * Create the nodes that describe the session's sub-HTTP protocols.
632+ *
633+ * This function encapsulates the logic common between the client-side and
634+ * server-side logic for describing the session's characteristics.
635+ *
636+ * This will create the string representing the "protocol" and "tls" nodes. The
637+ * "tls" node will only be present if the connection is over SSL/TLS.
638+ *
639+ * @param[in] ssnp The pointer for this session.
640+ *
641+ * @return The description of the protocol stack and certain TLS attributes.
642+ */
643+ std::string
644+ get_protocol_description_helper (TSHttpSsn ssnp, bool is_client)
645+ {
646+ std::ostringstream protocol_description;
647+ protocol_description << R"( "protocol":[)" ;
648+
649+ const char *protocol[10 ];
650+ int count = -1 ;
651+ if (is_client) {
652+ TSAssert (TS_SUCCESS == TSHttpSsnClientProtocolStackGet (ssnp, 10 , protocol, &count));
653+ } else {
654+ // See the TODO below in the commented out defintion of get_server_protocol_description.
655+ // TSAssert(TS_SUCCESS == TSHttpSsnServerProtocolStackGet(ssnp, 10, protocol, &count));
656+ }
657+ for (int i = 0 ; i < count; i++) {
658+ if (i > 0 ) {
659+ protocol_description << " ," ;
660+ }
661+ protocol_description << ' "' << std::string (protocol[i]) << ' "' ;
662+ }
663+
664+ protocol_description << " ]" ;
665+ std::string tls_description;
666+ if (is_client) {
667+ tls_description = get_client_tls_description (ssnp);
668+ } else {
669+ tls_description = get_server_tls_description (ssnp);
670+ }
671+ if (!tls_description.empty ()) {
672+ protocol_description << " ," << tls_description;
673+ }
674+ return protocol_description.str ();
675+ }
676+
677+ #if 0
678+ // TODO It will be important to add this eventually, but
679+ // TSHttpSsnServerProtocolStackGet is not defined yet. Once it (or some other
680+ // mechanism for getting the server side stack) is implemented, we will call
681+ // this as a part of writing the server-response node.
682+
683+ /** Generate the nodes describing the server session.
684+ *
685+ * @param[in] ssnp The pointer for this session.
686+ *
687+ * @return The description of the protocol stack and certain TLS attributes.
688+ */
689+ std::string
690+ get_server_protocol_description(TSHttpSsn ssnp)
691+ {
692+ return get_protocol_description_helper(ssnp, !IS_CLIENT);
693+ }
694+ #endif
695+
696+ /* * Generate the nodes describing the client session.
697+ *
698+ * @param[in] ssnp The pointer for this session.
699+ *
700+ * @return The description of the protocol stack and certain TLS attributes.
701+ */
702+ std::string
703+ get_client_protocol_description (TSHttpSsn ssnp)
704+ {
705+ return get_protocol_description_helper (ssnp, IS_CLIENT);
706+ }
707+
571708// Session handler for global hooks; Assign per-session data structure and log files
572709static int
573710global_ssn_handler (TSCont contp, TSEvent event, void *edata)
@@ -621,9 +758,9 @@ global_ssn_handler(TSCont contp, TSEvent event, void *edata)
621758 TSDebug (PLUGIN_NAME, " global_ssn_handler(): Ignore HTTPS session with non-existent SNI." );
622759 break ;
623760 } else {
624- const std::string sni{sni_ptr};
761+ const std::string_view sni{sni_ptr};
625762 if (sni != sni_filter) {
626- TSDebug (PLUGIN_NAME, " global_ssn_handler(): Ignore HTTPS session with non-filtered SNI: %s" , sni. c_str () );
763+ TSDebug (PLUGIN_NAME, " global_ssn_handler(): Ignore HTTPS session with non-filtered SNI: %s" , sni_ptr );
627764 break ;
628765 }
629766 }
@@ -647,19 +784,11 @@ global_ssn_handler(TSCont contp, TSEvent event, void *edata)
647784
648785 TSContDataSet (ssnData->aio_cont , ssnData);
649786
650- // 1. "protocol":(string)
651- const char *protocol[10 ];
652- int count = 0 ;
653- TSAssert (TS_SUCCESS == TSHttpSsnClientProtocolStackGet (ssnp, 10 , protocol, &count));
654- std::string result;
655- for (int i = 0 ; i < count; i++) {
656- if (i > 0 ) {
657- result += " ," ;
658- }
659- result += ' "' + std::string (protocol[i]) + ' "' ;
660- }
787+ // "protocol":(string),"tls":(string)
788+ // The "tls" node will only be present if the session is over SSL/TLS.
789+ std::string protocol_description = get_client_protocol_description (ssnp);
661790
662- std::string beginning = R"( {"meta":{"version":"1.0"},"sessions":[{"protocol":[ )" + result + " ] " + R"( ,"connection-time":)" +
791+ std::string beginning = R"( {"meta":{"version":"1.0"},"sessions":[{)" + protocol_description + R"( ,"connection-time":)" +
663792 std::to_string (start.count ()) + R"( ,"transactions":[)" ;
664793
665794 // Use the session count's hex string as the filename.
0 commit comments