Merge branch 'collectd-4.6' into collectd-4.7
[collectd.git] / src / network.c
index 91cfa4c..cf67c2b 100644 (file)
@@ -19,6 +19,8 @@
  *   Florian octo Forster <octo at verplant.org>
  **/
 
+#define _BSD_SOURCE /* For struct ip_mreq */
+
 #include "collectd.h"
 #include "plugin.h"
 #include "common.h"
@@ -47,8 +49,9 @@
 # include <poll.h>
 #endif
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
 # include <gcrypt.h>
+GCRY_THREAD_OPTION_PTHREAD_IMPL;
 #endif
 
 /* 1500 - 40 - 8  =  Ethernet packet - IPv6 header - UDP header */
 /*
  * Maximum size required for encryption / signing:
  *
- *    44 bytes for the encryption header
+ *    42 bytes for the encryption header
  * +  64 bytes for the username
  * -----------
- * = 108 bytes
+ * = 106 bytes
  */
-#define BUFF_SIG_SIZE 108
+#define BUFF_SIG_SIZE 106
 
 /*
  * Private data types
  */
 #define SECURITY_LEVEL_NONE     0
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
 # define SECURITY_LEVEL_SIGN    1
 # define SECURITY_LEVEL_ENCRYPT 2
 #endif
@@ -88,7 +91,7 @@ struct sockent_client
        int fd;
        struct sockaddr_storage *addr;
        socklen_t                addrlen;
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
        int security_level;
        char *username;
        char *password;
@@ -101,7 +104,7 @@ struct sockent_server
 {
        int *fd;
        size_t fd_num;
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
        int security_level;
        char *auth_file;
        fbhash_t *userdb;
@@ -226,7 +229,7 @@ typedef struct part_signature_sha256_s part_signature_sha256_t;
  * +---------------------------------------------------------------+
  */
 /* Minimum size */
-#define PART_ENCRYPTION_AES256_SIZE 44
+#define PART_ENCRYPTION_AES256_SIZE 42
 struct part_encryption_aes256_s
 {
   part_header_t head;
@@ -403,7 +406,7 @@ static int cache_check (const value_list_t *vl)
        return (retval);
 } /* int cache_check */
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
 static gcry_cipher_hd_t network_get_aes256_cypher (sockent_t *se, /* {{{ */
     const void *iv, size_t iv_size, const char *username)
 {
@@ -478,7 +481,7 @@ static gcry_cipher_hd_t network_get_aes256_cypher (sockent_t *se, /* {{{ */
 
   return (*cyper_ptr);
 } /* }}} int network_get_aes256_cypher */
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
 
 static int write_part_values (char **ret_buffer, int *ret_buffer_len,
                const data_set_t *ds, const value_list_t *vl)
@@ -863,7 +866,7 @@ static int parse_packet (sockent_t *se,
   buffer_offset += (s); \
 } while (0)
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
 static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */
     void **ret_buffer, size_t *ret_buffer_len, int flags)
 {
@@ -991,9 +994,9 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */
 
   return (0);
 } /* }}} int parse_part_sign_sha256 */
-/* #endif HAVE_GCRYPT_H */
+/* #endif HAVE_LIBGCRYPT */
 
-#else /* if !HAVE_GCRYPT_H */
+#else /* if !HAVE_LIBGCRYPT */
 static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */
     void **ret_buffer, size_t *ret_buffer_size, int flags)
 {
@@ -1036,9 +1039,9 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */
 
   return (0);
 } /* }}} int parse_part_sign_sha256 */
-#endif /* !HAVE_GCRYPT_H */
+#endif /* !HAVE_LIBGCRYPT */
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
 static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
                void **ret_buffer, size_t *ret_buffer_len,
                int flags)
@@ -1151,9 +1154,9 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
 
   return (0);
 } /* }}} int parse_part_encr_aes256 */
-/* #endif HAVE_GCRYPT_H */
+/* #endif HAVE_LIBGCRYPT */
 
-#else /* if !HAVE_GCRYPT_H */
+#else /* if !HAVE_LIBGCRYPT */
 static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
     void **ret_buffer, size_t *ret_buffer_size, int flags)
 {
@@ -1198,7 +1201,7 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
 
   return (0);
 } /* }}} int parse_part_encr_aes256 */
-#endif /* !HAVE_GCRYPT_H */
+#endif /* !HAVE_LIBGCRYPT */
 
 #undef BUFFER_READ
 
@@ -1210,11 +1213,11 @@ static int parse_packet (sockent_t *se, /* {{{ */
        value_list_t vl = VALUE_LIST_INIT;
        notification_t n;
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
        int packet_was_signed = (flags & PP_SIGNED);
         int packet_was_encrypted = (flags & PP_ENCRYPTED);
        int printed_ignore_warning = 0;
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
 
 
        memset (&vl, '\0', sizeof (vl));
@@ -1255,7 +1258,7 @@ static int parse_packet (sockent_t *se, /* {{{ */
                                break;
                        }
                }
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
                else if ((se->data.server.security_level == SECURITY_LEVEL_ENCRYPT)
                                && (packet_was_encrypted == 0))
                {
@@ -1268,7 +1271,7 @@ static int parse_packet (sockent_t *se, /* {{{ */
                        buffer = ((char *) buffer) + pkg_length;
                        continue;
                }
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
                else if (pkg_type == TYPE_SIGN_SHA256)
                {
                        status = parse_part_sign_sha256 (se,
@@ -1281,7 +1284,7 @@ static int parse_packet (sockent_t *se, /* {{{ */
                                break;
                        }
                }
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
                else if ((se->data.server.security_level == SECURITY_LEVEL_SIGN)
                                && (packet_was_encrypted == 0)
                                && (packet_was_signed == 0))
@@ -1295,7 +1298,7 @@ static int parse_packet (sockent_t *se, /* {{{ */
                        buffer = ((char *) buffer) + pkg_length;
                        continue;
                }
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
                else if (pkg_type == TYPE_VALUES)
                {
                        status = parse_part_values (&buffer, &buffer_size,
@@ -1442,7 +1445,7 @@ static void free_sockent_client (struct sockent_client *sec) /* {{{ */
     sec->fd = -1;
   }
   sfree (sec->addr);
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
   sfree (sec->username);
   sfree (sec->password);
   if (sec->cypher != NULL)
@@ -1464,7 +1467,7 @@ static void free_sockent_server (struct sockent_server *ses) /* {{{ */
   }
 
   sfree (ses->fd);
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
   sfree (ses->auth_file);
   fbh_destroy (ses->userdb);
   if (ses->cypher != NULL)
@@ -1685,7 +1688,7 @@ static int sockent_init (sockent_t *se, int type) /* {{{ */
        {
                se->type = SOCKENT_TYPE_SERVER;
                se->data.server.fd = NULL;
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
                se->data.server.security_level = SECURITY_LEVEL_NONE;
                se->data.server.auth_file = NULL;
                se->data.server.userdb = NULL;
@@ -1696,7 +1699,7 @@ static int sockent_init (sockent_t *se, int type) /* {{{ */
        {
                se->data.client.fd = -1;
                se->data.client.addr = NULL;
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
                se->data.client.security_level = SECURITY_LEVEL_NONE;
                se->data.client.username = NULL;
                se->data.client.password = NULL;
@@ -1721,7 +1724,7 @@ static int sockent_open (sockent_t *se) /* {{{ */
                return (-1);
 
        /* Set up the security structures. */
-#if HAVE_GCRYPT_H /* {{{ */
+#if HAVE_LIBGCRYPT /* {{{ */
        if (se->type == SOCKENT_TYPE_CLIENT)
        {
                if (se->data.client.security_level > SECURITY_LEVEL_NONE)
@@ -1765,7 +1768,7 @@ static int sockent_open (sockent_t *se) /* {{{ */
                        }
                }
        }
-#endif /* }}} HAVE_GCRYPT_H */
+#endif /* }}} HAVE_LIBGCRYPT */
 
         node = se->node;
         service = se->service;
@@ -2164,7 +2167,7 @@ static void networt_send_buffer_plain (const sockent_t *se, /* {{{ */
        } /* while (42) */
 } /* }}} void networt_send_buffer_plain */
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
 #define BUFFER_ADD(p,s) do { \
   memcpy (buffer + buffer_offset, (p), (s)); \
   buffer_offset += (s); \
@@ -2259,9 +2262,6 @@ static void networt_send_buffer_encrypted (sockent_t *se, /* {{{ */
   gcry_error_t err;
   gcry_cipher_hd_t cypher;
 
-  DEBUG ("network plugin: networt_send_buffer_encrypted: "
-      "buffer_size = %zu;", buffer_size);
-
   /* Initialize the header fields */
   memset (&pea, 0, sizeof (pea));
   pea.head.type = htons (TYPE_ENCR_AES256);
@@ -2280,6 +2280,8 @@ static void networt_send_buffer_encrypted (sockent_t *se, /* {{{ */
     - sizeof (pea.hash);
 
   assert (buffer_size <= sizeof (buffer));
+  DEBUG ("network plugin: networt_send_buffer_encrypted: "
+      "buffer_size = %zu;", buffer_size);
 
   pea.head.length = htons ((uint16_t) (PART_ENCRYPTION_AES256_SIZE
         + username_len + in_buffer_size));
@@ -2328,7 +2330,7 @@ static void networt_send_buffer_encrypted (sockent_t *se, /* {{{ */
   networt_send_buffer_plain (se, buffer, buffer_size);
 } /* }}} void networt_send_buffer_encrypted */
 #undef BUFFER_ADD
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
 
 static void network_send_buffer (char *buffer, size_t buffer_len) /* {{{ */
 {
@@ -2338,13 +2340,13 @@ static void network_send_buffer (char *buffer, size_t buffer_len) /* {{{ */
 
   for (se = sending_sockets; se != NULL; se = se->next)
   {
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
     if (se->data.client.security_level == SECURITY_LEVEL_ENCRYPT)
       networt_send_buffer_encrypted (se, buffer, buffer_len);
     else if (se->data.client.security_level == SECURITY_LEVEL_SIGN)
       networt_send_buffer_signed (se, buffer, buffer_len);
     else /* if (se->data.client.security_level == SECURITY_LEVEL_NONE) */
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
       networt_send_buffer_plain (se, buffer, buffer_len);
   } /* for (sending_sockets) */
 } /* }}} void network_send_buffer */
@@ -2545,6 +2547,7 @@ static int network_config_set_ttl (const oconfig_item_t *ci) /* {{{ */
   return (0);
 } /* }}} int network_config_set_ttl */
 
+#if HAVE_LIBGCRYPT
 static int network_config_set_string (const oconfig_item_t *ci, /* {{{ */
     char **ret_string)
 {
@@ -2566,8 +2569,9 @@ static int network_config_set_string (const oconfig_item_t *ci, /* {{{ */
 
   return (0);
 } /* }}} int network_config_set_string */
+#endif /* HAVE_LIBGCRYPT */
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
 static int network_config_set_security_level (oconfig_item_t *ci, /* {{{ */
     int *retval)
 {
@@ -2595,7 +2599,7 @@ static int network_config_set_security_level (oconfig_item_t *ci, /* {{{ */
 
   return (0);
 } /* }}} int network_config_set_security_level */
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
 
 static int network_config_add_listen (const oconfig_item_t *ci) /* {{{ */
 {
@@ -2628,20 +2632,21 @@ static int network_config_add_listen (const oconfig_item_t *ci) /* {{{ */
   {
     oconfig_item_t *child = ci->children + i;
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
     if (strcasecmp ("AuthFile", child->key) == 0)
       network_config_set_string (child, &se->data.server.auth_file);
     else if (strcasecmp ("SecurityLevel", child->key) == 0)
       network_config_set_security_level (child,
           &se->data.server.security_level);
     else
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
     {
       WARNING ("network plugin: Option `%s' is not allowed here.",
           child->key);
     }
   }
 
+#if HAVE_LIBGCRYPT
   if ((se->data.server.security_level > SECURITY_LEVEL_NONE)
       && (se->data.server.auth_file == NULL))
   {
@@ -2651,6 +2656,7 @@ static int network_config_add_listen (const oconfig_item_t *ci) /* {{{ */
     sockent_destroy (se);
     return (-1);
   }
+#endif /* HAVE_LIBGCRYPT */
 
   status = sockent_open (se);
   if (status != 0)
@@ -2702,7 +2708,7 @@ static int network_config_add_server (const oconfig_item_t *ci) /* {{{ */
   {
     oconfig_item_t *child = ci->children + i;
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
     if (strcasecmp ("Username", child->key) == 0)
       network_config_set_string (child, &se->data.client.username);
     else if (strcasecmp ("Password", child->key) == 0)
@@ -2711,13 +2717,14 @@ static int network_config_add_server (const oconfig_item_t *ci) /* {{{ */
       network_config_set_security_level (child,
           &se->data.client.security_level);
     else
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
     {
       WARNING ("network plugin: Option `%s' is not allowed here.",
           child->key);
     }
   }
 
+#if HAVE_LIBGCRYPT
   if ((se->data.client.security_level > SECURITY_LEVEL_NONE)
       && ((se->data.client.username == NULL)
         || (se->data.client.password == NULL)))
@@ -2728,6 +2735,7 @@ static int network_config_add_server (const oconfig_item_t *ci) /* {{{ */
     sockent_destroy (se);
     return (-1);
   }
+#endif /* HAVE_LIBGCRYPT */
 
   status = sockent_open (se);
   if (status != 0)
@@ -2761,7 +2769,7 @@ static int network_config_set_cache_flush (const oconfig_item_t *ci) /* {{{ */
 
   tmp = (int) ci->values[0].value.number;
   if (tmp > 0)
-    network_config_ttl = tmp;
+    cache_flush_interval = tmp;
 
   return (0);
 } /* }}} int network_config_set_cache_flush */
@@ -2930,6 +2938,12 @@ static int network_init (void)
        if (cache_flush_last != 0)
                return (0);
 
+#if HAVE_LIBGCRYPT
+       gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+       gcry_control (GCRYCTL_INIT_SECMEM, 32768, 0);
+       gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+
        plugin_register_shutdown ("network", network_shutdown);
 
        network_init_buffer ();