]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added gnutls_global_set_audit_log_function() that allows associating TLS session...
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 7 May 2011 19:28:23 +0000 (21:28 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 7 May 2011 19:28:23 +0000 (21:28 +0200)
18 files changed:
NEWS
doc/cha-gtls-app.texi
lib/accelerated/intel/aes-x86.c
lib/auth/rsa.c
lib/auth/rsa_export.c
lib/auth/srp.c
lib/gnutls_buffers.c
lib/gnutls_dtls.c
lib/gnutls_errors.c
lib/gnutls_errors.h
lib/gnutls_global.c
lib/gnutls_global.h
lib/gnutls_handshake.c
lib/gnutls_record.c
lib/includes/gnutls/gnutls.h.in
lib/libgnutls.map
src/cli.c
src/serv.c

diff --git a/NEWS b/NEWS
index 02110690e1eec94e2616eca260085b9b0a44b4c2..f5bdcfe417240d00efe37a8e253e01ee4f300866 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,10 @@ See the end for copying conditions.
 ** certtool: Can now load private keys and public keys from PKCS #11 tokens
 via URLs.
 
+** libgnutls: Added gnutls_global_set_audit_log_function() that allows
+to get important auditing information including the corresponding session.
+That might be useful to block DoS or other attacker from specific IPs.
+
 ** libgnutls: gnutls_pkcs11_privkey_import_url() will now correctly read
 the public key algorithm of the key.
 
@@ -27,7 +31,7 @@ the self signature of the request.
 gnutls_certificate_get_issuer: ADDED
 gnutls_x509_trust_list_get_issuer: ADDED
 gnutls_x509_crq_verify: ADDED
-
+gnutls_global_set_audit_log_function: ADDED
 
 * Version 2.99.1 (released 2011-04-23)
 
index 90545493d17ac21096046affa6a7f4ed84ccbdad..935ea40d3ba7dd421d0f7146d9166e660d0819b0 100644 (file)
@@ -24,7 +24,7 @@ the following subsections.
 * Headers::
 * Initialization::
 * Version check::
-* Debugging::
+* Debugging and auditing::
 * Building the source::
 @end menu
 
@@ -66,15 +66,23 @@ with the dynamic linker an old version is actually used.  So you may
 want to check that the version is okay right after program startup.
 See the function @ref{gnutls_check_version}.
 
-@node Debugging
-@subsection Debugging
+@node Debugging and auditing
+@subsection Debugging and auditing
 
 In many cases things may not go as expected and further information,
-to assist debugging, from @acronym{GnuTLS} is desired. Those are the
-case where the @ref{gnutls_global_set_log_level} and
+to assist debugging, from @acronym{GnuTLS} is desired. 
+Those are the cases where the @ref{gnutls_global_set_log_level} and
 @ref{gnutls_global_set_log_function} are to be used. Those will print
 verbose information on the @acronym{GnuTLS} functions internal flow.
 
+
+When debugging is not required, important issues, such as detected
+attacks on the protocol still need to be logged. This is provided
+by @ref{gnutls_global_set_audit_log_function}, that uses a logging
+function that accepts the detected error message and the corresponding
+TLS session. The session information might be used to derive IP addresses
+or other information about the peer involved.
+
 @node Building the source
 @subsection Building the Source
 
index 101569554b84fd2aec884db491b768cdd6380936..daffccd7604598f4ef53860345c7d46e104de51d 100644 (file)
@@ -184,7 +184,7 @@ register_x86_crypto (void)
 
   if (check_optimized_aes ())
     {
-      fprintf (stderr, "Intel AES accelerator was detected\n");
+      _gnutls_debug_log ("Intel AES accelerator was detected\n");
       ret =
         gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_128_CBC, 80,
                                               &cipher_struct);
index 2e5b7f548d32daf618ee7d2a82c6893bb1e8441d..f20a375cfb2fd7d2e2c278050574f87f9b4c6e7a 100644 (file)
@@ -195,7 +195,7 @@ proc_rsa_client_kx (gnutls_session_t session, opaque * data,
        * attack against pkcs-1 formating).
        */
       gnutls_assert ();
-      _gnutls_audit_log ("auth_rsa: Possible PKCS #1 format attack\n");
+      _gnutls_audit_log (session, "auth_rsa: Possible PKCS #1 format attack\n");
       randomize_key = 1;
     }
   else
@@ -214,7 +214,7 @@ proc_rsa_client_kx (gnutls_session_t session, opaque * data,
            */
           gnutls_assert ();
           _gnutls_audit_log
-            ("auth_rsa: Possible PKCS #1 version check format attack\n");
+            (session, "auth_rsa: Possible PKCS #1 version check format attack\n");
         }
     }
 
index 7829a1a63bd20eddcf1f8aa68ce96b9bbc366a23..4f10f55a3166f334cd6b3ddac2c16ce167ef818f 100644 (file)
@@ -173,7 +173,7 @@ proc_rsa_export_client_kx (gnutls_session_t session, opaque * data,
        * attack against pkcs-1 formating).
        */
       gnutls_assert ();
-      _gnutls_audit_log ("auth_rsa: Possible PKCS #1 format attack\n");
+      _gnutls_audit_log (session, "auth_rsa: Possible PKCS #1 format attack\n");
       randomize_key = 1;
     }
   else
@@ -192,7 +192,7 @@ proc_rsa_export_client_kx (gnutls_session_t session, opaque * data,
            */
           gnutls_assert ();
           _gnutls_audit_log
-            ("auth_rsa: Possible PKCS #1 version check format attack\n");
+            (session, "auth_rsa: Possible PKCS #1 version check format attack\n");
         }
     }
 
index f46ec1a267054935dc80619ed861481fb7353cb3..17b2c0ff6c292473284b8b4841dab7d2221d2804 100644 (file)
@@ -814,7 +814,7 @@ _gnutls_proc_srp_server_kx (gnutls_session_t session, opaque * data,
    */
   if ((ret = check_g_n (data_g, _n_g, data_n, _n_n)) < 0)
     {
-      _gnutls_audit_log ("SRP group parameters are not in the white list. Checking validity.\n");
+      _gnutls_audit_log (session, "SRP group parameters are not in the white list. Checking validity.\n");
       if ((ret = group_check_g_n (session, G, N)) < 0)
         {
           gnutls_assert ();
index 510c4e6131bb2cd5cad96a1a84a856986ad1c6d5..3a7cca2682db9909a4d1ba0707da004694930b3f 100644 (file)
@@ -1071,7 +1071,7 @@ parse_record_buffered_msgs (gnutls_session_t session,
               if (ret < 0)
                 {
                   gnutls_assert();
-                  _gnutls_audit_log("Invalid handshake packet headers. Discarding.\n");
+                  _gnutls_audit_log(session, "Invalid handshake packet headers. Discarding.\n");
                   break;
                 }
 
@@ -1111,7 +1111,7 @@ next:
       while(session->internals.handshake_recv_buffer_size > 0 &&
         recv_buf[LAST_ELEMENT].sequence < session->internals.dtls.hsk_read_seq)
         {
-          _gnutls_audit_log("Discarded replayed handshake packet with sequence %d\n", recv_buf[LAST_ELEMENT].sequence);
+          _gnutls_audit_log(session, "Discarded replayed handshake packet with sequence %d\n", recv_buf[LAST_ELEMENT].sequence);
           _gnutls_handshake_buffer_clear(&recv_buf[LAST_ELEMENT]);
           session->internals.handshake_recv_buffer_size--;
         }
index a77b65f63fa88a86a5a05b8c8f84966de3f993e2..b00b3e83e97fdc0052065182b58f14c78aa1bf79 100644 (file)
@@ -652,7 +652,7 @@ uint8_t digest[C_HASH_SIZE];
   cookie.data = &msg[pos];
   if (cookie.size != COOKIE_SIZE)
     {
-      if (cookie.size > 0) _gnutls_audit_log("Received cookie with illegal size %d. Expected %d\n", (int)cookie.size, COOKIE_SIZE);
+      if (cookie.size > 0) _gnutls_audit_log(NULL, "Received cookie with illegal size %d. Expected %d\n", (int)cookie.size, COOKIE_SIZE);
       return gnutls_assert_val(GNUTLS_E_BAD_COOKIE);
     }
 
index 8096c2e424ff0c4bb600af6d8b4e85026290ddec..c5405694d14a551aae9a27319b235f35e7b27141 100644 (file)
@@ -574,6 +574,30 @@ _gnutls_log (int level, const char *fmt, ...)
     }
 }
 
+void
+_gnutls_audit_log (gnutls_session_t session, const char *fmt, ...)
+{
+  va_list args;
+  char *str;
+  int ret;
+
+  if (_gnutls_audit_log_func == NULL && _gnutls_log_func == NULL)
+    return;
+
+  va_start (args, fmt);
+  ret = vasprintf (&str, fmt, args);
+  va_end (args);
+
+  if (ret >= 0)
+    {
+      if (_gnutls_audit_log_func)
+        _gnutls_audit_log_func (session, str);
+      else
+        _gnutls_log_func(1, str);
+      free (str);
+    }
+}
+
 #ifndef DEBUG
 #ifndef C99_MACROS
 
index 43f3c490083abe47a93b308b600e3e497312328b..df27958677eadb85de676318ae8a67663964dc92 100644 (file)
@@ -50,6 +50,14 @@ _gnutls_log (int, const char *fmt, ...)
  ;
 #endif
 
+void
+_gnutls_audit_log (gnutls_session_t, const char *fmt, ...)
+#ifdef __GNUC__
+  __attribute__ ((format (printf, 2, 3)));
+#else
+ ;
+#endif
+
 void _gnutls_mpi_log (const char *prefix, bigint_t a);
 
 #ifdef C99_MACROS
@@ -68,7 +76,6 @@ void _gnutls_mpi_log (const char *prefix, bigint_t a);
 #define _gnutls_dtls_log(...) LEVEL(6, __VA_ARGS__)
 #define _gnutls_read_log(...) LEVEL_EQ(7, __VA_ARGS__)
 #define _gnutls_write_log(...) LEVEL_EQ(7, __VA_ARGS__)
-#define _gnutls_audit_log(...) LEVEL(1, __VA_ARGS__)
 #else
 #define _gnutls_debug_log _gnutls_null_log
 #define _gnutls_handshake_log _gnutls_null_log
@@ -79,7 +86,6 @@ void _gnutls_mpi_log (const char *prefix, bigint_t a);
 #define _gnutls_dtls_log _gnutls_null_log
 #define _gnutls_read_log _gnutls_null_log
 #define _gnutls_write_log _gnutls_null_log
-#define _gnutls_audit_log _gnutls_null_log
 
 void _gnutls_null_log (void *, ...);
 
index 7a424cc5fc70d6a1f954952c47f5cf4507d21beb..c69adcf74d8ce551959029ed42868c7f487fc2ce 100644 (file)
@@ -49,6 +49,7 @@ ASN1_TYPE _gnutls_pkix1_asn;
 ASN1_TYPE _gnutls_gnutls_asn;
 
 gnutls_log_func _gnutls_log_func;
+gnutls_audit_log_func _gnutls_audit_log_func;
 int _gnutls_log_level = 0;      /* default log level */
 
 /**
@@ -69,6 +70,24 @@ gnutls_global_set_log_function (gnutls_log_func log_func)
   _gnutls_log_func = log_func;
 }
 
+/**
+ * gnutls_global_set_audit_log_function:
+ * @log_func: it is the audit log function
+ *
+ * This is the function where you set the logging function gnutls is
+ * going to use.  This is different from gnutls_global_set_log_function()
+ * because it will report the session of the event if any. Note that
+ * that session might be null if there is no corresponding TLS session.
+ *
+ * gnutls_audit_log_func is of the form,
+ * void (*gnutls_audit_log_func)( gnutls_session_t, int level, const char*);
+ **/
+void
+gnutls_global_set_audit_log_function (gnutls_audit_log_func log_func)
+{
+  _gnutls_audit_log_func = log_func;
+}
+
 /**
  * gnutls_global_set_log_level:
  * @level: it's an integer from 0 to 9.
index db2b1b1c2ceabf7bb423e9ec79ae167a0a4e2663..affd1faecfb905eed96a15e332e675d241dbd9c6 100644 (file)
@@ -42,6 +42,7 @@ extern ASN1_TYPE _gnutls_gnutls_asn;
 #define _gnutls_get_pkix() ((ASN1_TYPE) _gnutls_pkix1_asn)
 
 extern gnutls_log_func _gnutls_log_func;
+extern gnutls_audit_log_func _gnutls_audit_log_func;
 extern int _gnutls_log_level;
 extern int gnutls_crypto_init (void);
 
index 7aa53a30fbe0b101a1278682304d9819936d0618..0e11c2fcd14211334cd5240227c9ccaa4ec2caa7 100644 (file)
@@ -1336,7 +1336,7 @@ _gnutls_recv_handshake (gnutls_session_t session,
         }
 
        if (ret == GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET)
-        _gnutls_audit_log("Received unexpected handshake message '%s' (%d). Expected '%s' (%d)\n",
+        _gnutls_audit_log(session, "Received unexpected handshake message '%s' (%d). Expected '%s' (%d)\n",
          _gnutls_handshake2str(hsk.htype), (int)hsk.htype, _gnutls_handshake2str(type), (int)type);
 
       return gnutls_assert_val_fatal(ret);
index ba8310956b7279d6b4a5c3cdffdcc24be1a5a55e..4afac7edfa88a2e5347ba151531ae85fbaca084e 100644 (file)
@@ -500,7 +500,7 @@ _gnutls_send_int (gnutls_session_t session, content_type_t type,
 }
 
 inline static int
-check_recv_type (content_type_t recv_type)
+check_recv_type (gnutls_session_t session, content_type_t recv_type)
 {
   switch (recv_type)
     {
@@ -511,7 +511,7 @@ check_recv_type (content_type_t recv_type)
       return 0;
     default:
       gnutls_assert ();
-      _gnutls_audit_log("Received record packet of unknown type %u\n", (unsigned int)recv_type);
+      _gnutls_audit_log(session, "Received record packet of unknown type %u\n", (unsigned int)recv_type);
       return GNUTLS_E_UNEXPECTED_PACKET;
     }
 
@@ -876,7 +876,7 @@ gnutls_datum_t raw; /* raw headers */
     {
       if (_gnutls_epoch_is_valid(session, record->epoch) == 0)
         {
-          _gnutls_audit_log("Discarded message[%u] with invalid epoch 0x%.2x%.2x.\n",
+          _gnutls_audit_log(session, "Discarded message[%u] with invalid epoch 0x%.2x%.2x.\n",
             (unsigned int)_gnutls_uint64touint32 (&record->sequence), (int)record->sequence.i[0], 
             (int)record->sequence.i[1]);
           gnutls_assert();
@@ -888,7 +888,7 @@ gnutls_datum_t raw; /* raw headers */
   /* Here we check if the Type of the received packet is
    * ok. 
    */
-  if ((ret = check_recv_type (record->type)) < 0)
+  if ((ret = check_recv_type (session, record->type)) < 0)
     return gnutls_assert_val(ret);
 
   /* Here we check if the advertized version is the one we
@@ -900,7 +900,7 @@ gnutls_datum_t raw; /* raw headers */
   if (record->length > MAX_RECV_SIZE(session))
     {
       _gnutls_audit_log
-        ("Received packet with illegal length: %u\n", (unsigned int)record->length);
+        (session, "Received packet with illegal length: %u\n", (unsigned int)record->length);
       return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
     }
 
@@ -1030,7 +1030,7 @@ begin:
       ret = _dtls_record_check(session, packet_sequence);
       if (ret < 0)
         {
-          _gnutls_audit_log("Discarded duplicate message[%u]\n",
+          _gnutls_audit_log(session, "Discarded duplicate message[%u]\n",
             (unsigned int) _gnutls_uint64touint32 (packet_sequence));
           goto sanity_check_error;
         }
@@ -1096,7 +1096,7 @@ discard:
 sanity_check_error:
   if (IS_DTLS(session))
     {
-      _gnutls_audit_log("Discarded message[%u] due to invalid decryption\n", 
+      _gnutls_audit_log(session, "Discarded message[%u] due to invalid decryption\n", 
             (unsigned int)_gnutls_uint64touint32 (packet_sequence));
       ret = gnutls_assert_val(GNUTLS_E_AGAIN);
       goto cleanup;
index 46ea4a86f05048ebb07a4e5c21d226fa639b4c13..f85b6b397bb98ad26f336f02b6c92309a5844ad7 100644 (file)
@@ -1119,7 +1119,9 @@ extern "C"
   extern char *(*gnutls_strdup) (const char *);
 
   typedef void (*gnutls_log_func) (int, const char *);
+  typedef void (*gnutls_audit_log_func) (gnutls_session_t, const char *);
   void gnutls_global_set_log_function (gnutls_log_func log_func);
+  void gnutls_global_set_audit_log_function (gnutls_audit_log_func log_func);
   void gnutls_global_set_log_level (int level);
 
 /* Diffie-Hellman parameter handling.
index 63bacd21043fc1f82c47226b19e66eb7e0cfdca8..ccae4576a0186e9999d79754cc789ef4e336c892 100644 (file)
@@ -712,6 +712,7 @@ GNUTLS_3_0_0 {
        gnutls_pubkey_get_openpgp_key_id;
        gnutls_certificate_set_retrieve_function2;
        gnutls_x509_trust_list_get_issuer;
+       gnutls_global_set_audit_log_function;
 } GNUTLS_2_12;
 
 GNUTLS_PRIVATE {
index 88aa645999ca43f9c031f57838cc22f60b9dd637..cfe047052a45800bc333e4237852a971f37973c9 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -720,6 +720,9 @@ main (int argc, char **argv)
 
   set_program_name (argv[0]);
 
+  gnutls_global_set_log_function (tls_log_func);
+  gnutls_global_set_log_level (info.debug);
+
   if ((ret = gnutls_global_init ()) < 0)
     {
       fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
@@ -734,9 +737,6 @@ main (int argc, char **argv)
       exit (1);
     }
 
-  gnutls_global_set_log_function (tls_log_func);
-  gnutls_global_set_log_level (info.debug);
-
   sockets_init ();
 
 #ifndef _WIN32
index 405e5560aad044f8020ac3970c8ce101fdef868c..32eb9da2e5c2199dbc11266554af9fbe860241c4 100644 (file)
@@ -881,6 +881,12 @@ tls_log_func (int level, const char *str)
   fprintf (stderr, "|<%d>| %s", level, str);
 }
 
+static void
+tls_audit_log_func (gnutls_session_t session, const char *str)
+{
+  fprintf (stderr, "|<%p>| %s", session, str);
+}
+
 static void gaa_parser (int argc, char **argv);
 
 int
@@ -915,6 +921,10 @@ main (int argc, char **argv)
       strcpy (name, "Echo Server");
     }
 
+  gnutls_global_set_log_function (tls_log_func);
+  gnutls_global_set_audit_log_function (tls_audit_log_func);
+  gnutls_global_set_log_level (debug);
+
   if ((ret = gnutls_global_init ()) < 0)
     {
       fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
@@ -928,8 +938,6 @@ main (int argc, char **argv)
     }
 
   pkcs11_common ();
-  gnutls_global_set_log_function (tls_log_func);
-  gnutls_global_set_log_level (debug);
 
   /* Note that servers must generate parameters for
    * Diffie-Hellman. See gnutls_dh_params_generate(), and