network plugin: Improved error logging on decrypt error (wrong/missing username/password)
[collectd.git] / src / network.c
index 1b560c4..46ec059 100644 (file)
@@ -490,7 +490,7 @@ static int network_dispatch_notification (notification_t *n) /* {{{ */
 } /* }}} int network_dispatch_notification */
 
 #if HAVE_LIBGCRYPT
-static void network_init_gcrypt (void) /* {{{ */
+static int network_init_gcrypt (void) /* {{{ */
 {
   gcry_error_t err;
 
@@ -498,7 +498,7 @@ static void network_init_gcrypt (void) /* {{{ */
    * Because you can't know in a library whether another library has
    * already initialized the library */
   if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
-    return;
+    return (0);
 
  /* http://www.gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html
   * To ensure thread-safety, it's important to set GCRYCTL_SET_THREAD_CBS
@@ -512,7 +512,7 @@ static void network_init_gcrypt (void) /* {{{ */
   if (err)
   {
     ERROR ("network plugin: gcry_control (GCRYCTL_SET_THREAD_CBS) failed: %s", gcry_strerror (err));
-    abort ();
+    return (-1);
   }
 # endif
 
@@ -522,11 +522,12 @@ static void network_init_gcrypt (void) /* {{{ */
   if (err)
   {
     ERROR ("network plugin: gcry_control (GCRYCTL_INIT_SECMEM) failed: %s", gcry_strerror (err));
-    abort ();
+    return (-1);
   }
 
   gcry_control (GCRYCTL_INITIALIZATION_FINISHED);
-} /* }}} void network_init_gcrypt */
+  return (0);
+} /* }}} int network_init_gcrypt */
 
 static gcry_cipher_hd_t network_get_aes256_cypher (sockent_t *se, /* {{{ */
     const void *iv, size_t iv_size, const char *username)
@@ -1232,8 +1233,8 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
   /* Make sure at least the header if available. */
   if (buffer_len <= PART_ENCRYPTION_AES256_SIZE)
   {
-    NOTICE ("network plugin: parse_part_encr_aes256: "
-        "Discarding short packet.");
+    ERROR ("network plugin: Decryption failed: "
+            "Discarding short packet.");
     return (-1);
   }
 
@@ -1248,8 +1249,8 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
   if ((part_size <= PART_ENCRYPTION_AES256_SIZE)
       || (part_size > buffer_len))
   {
-    NOTICE ("network plugin: parse_part_encr_aes256: "
-        "Discarding part with invalid size.");
+    ERROR ("network plugin: Decryption failed: "
+            "Discarding part with invalid size.");
     return (-1);
   }
 
@@ -1260,15 +1261,19 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
   if ((username_len == 0)
       || (username_len > (part_size - (PART_ENCRYPTION_AES256_SIZE + 1))))
   {
-    NOTICE ("network plugin: parse_part_encr_aes256: "
-        "Discarding part with invalid username length.");
+    ERROR ("network plugin: Decryption failed: "
+            "Discarding part with invalid username length.");
     return (-1);
   }
 
   assert (username_len > 0);
   pea.username = malloc (username_len + 1);
   if (pea.username == NULL)
+  {
+    ERROR ("network plugin: Decryption failed: "
+            "malloc() failed.");
     return (-ENOMEM);
+  }
   BUFFER_READ (pea.username, username_len);
   pea.username[username_len] = 0;
 
@@ -1283,6 +1288,8 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
       pea.username);
   if (cypher == NULL)
   {
+    ERROR ("network plugin: Decryption failed: "
+            "Failed to get cypher. Username: %s", pea.username);
     sfree (pea.username);
     return (-1);
   }
@@ -1298,8 +1305,8 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
   if (err != 0)
   {
     sfree (pea.username);
-    ERROR ("network plugin: gcry_cipher_decrypt returned: %s",
-        gcry_strerror (err));
+    ERROR ("network plugin: gcry_cipher_decrypt returned: %s. Username: %s",
+        gcry_strerror (err), pea.username);
     return (-1);
   }
 
@@ -1315,8 +1322,9 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
       buffer + buffer_offset, payload_len);
   if (memcmp (hash, pea.hash, sizeof (hash)) != 0)
   {
+    ERROR ("network plugin: Decryption failed: "
+            "Checksum mismatch. Username: %s", pea.username);
     sfree (pea.username);
-    ERROR ("network plugin: Decryption failed: Checksum mismatch.");
     return (-1);
   }
 
@@ -1395,7 +1403,7 @@ static int parse_packet (sockent_t *se, /* {{{ */
 
 #if HAVE_LIBGCRYPT
        int packet_was_signed = (flags & PP_SIGNED);
-        int packet_was_encrypted = (flags & PP_ENCRYPTED);
+       int packet_was_encrypted = (flags & PP_ENCRYPTED);
        int printed_ignore_warning = 0;
 #endif /* HAVE_LIBGCRYPT */
 
@@ -1430,12 +1438,7 @@ static int parse_packet (sockent_t *se, /* {{{ */
                        status = parse_part_encr_aes256 (se,
                                        &buffer, &buffer_size, flags);
                        if (status != 0)
-                       {
-                               ERROR ("network plugin: Decrypting AES256 "
-                                               "part failed "
-                                               "with status %i.", status);
                                break;
-                       }
                }
 #if HAVE_LIBGCRYPT
                else if ((se->data.server.security_level == SECURITY_LEVEL_ENCRYPT)
@@ -2061,7 +2064,12 @@ static int sockent_init_crypto (sockent_t *se) /* {{{ */
        {
                if (se->data.client.security_level > SECURITY_LEVEL_NONE)
                {
-                       network_init_gcrypt ();
+                       if (network_init_gcrypt () < 0)
+                       {
+                               ERROR ("network plugin: Cannot configure client socket with "
+                                               "security: Failed to initialize crypto library.");
+                               return (-1);
+                       }
 
                        if ((se->data.client.username == NULL)
                                        || (se->data.client.password == NULL))
@@ -2081,7 +2089,12 @@ static int sockent_init_crypto (sockent_t *se) /* {{{ */
        {
                if (se->data.server.security_level > SECURITY_LEVEL_NONE)
                {
-                       network_init_gcrypt ();
+                       if (network_init_gcrypt () < 0)
+                       {
+                               ERROR ("network plugin: Cannot configure server socket with "
+                                               "security: Failed to initialize crypto library.");
+                               return (-1);
+                       }
 
                        if (se->data.server.auth_file == NULL)
                        {
@@ -2880,6 +2893,11 @@ static int network_write (const data_set_t *ds, const value_list_t *vl,
 {
        int status;
 
+       /* listen_loop is set to non-zero in the shutdown callback, which is
+        * guaranteed to be called *after* all the write threads have been shut
+        * down. */
+       assert (listen_loop == 0);
+
        if (!check_send_okay (vl))
        {
 #if COLLECT_DEBUG
@@ -3434,7 +3452,11 @@ static int network_init (void)
        have_init = 1;
 
 #if HAVE_LIBGCRYPT
-       network_init_gcrypt ();
+       if (network_init_gcrypt () < 0)
+       {
+               ERROR ("network plugin: Failed to initialize crypto library.");
+               return (-1);
+       }
 #endif
 
        if (network_config_stats)