Keep clang-format happy
[collectd.git] / src / libcollectdclient / network_parse.c
index 83a05d4..9a90f8e 100644 (file)
@@ -23,9 +23,7 @@
  *   Florian octo Forster <octo at collectd.org>
  **/
 
-#if HAVE_CONFIG_H
 #include "config.h"
-#endif
 
 #if !defined(__GNUC__) || !__GNUC__
 #define __attribute__(x) /**/
 #include <errno.h>
 #include <math.h>
 #include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* for be{16,64}toh */
+#if HAVE_ENDIAN_H
+#include <endian.h>
+#elif HAVE_SYS_ENDIAN_H
+#include <sys/endian.h>
+#else /* fallback */
+#include "stdendian.h"
+#endif
 
+#if HAVE_GCRYPT_H
 #define GCRYPT_NO_DEPRECATED
 #include <gcrypt.h>
+#endif
 
 #include <stdio.h>
 #define DEBUG(...) printf(__VA_ARGS__)
 
+#if HAVE_GCRYPT_H
+#if GCRYPT_VERSION_NUMBER < 0x010600
 GCRY_THREAD_OPTION_PTHREAD_IMPL;
+#endif
+#endif
 
 /* forward declaration because parse_sign_sha256()/parse_encrypt_aes256() and
  * network_parse() need to call each other. */
 static int network_parse(void *data, size_t data_size, lcc_security_level_t sl,
                          lcc_network_parse_options_t const *opts);
 
+#if HAVE_GCRYPT_H
 static int init_gcrypt() {
   /* http://lists.gnupg.org/pipermail/gcrypt-devel/2003-August/000458.html
    * Because you can't know in a library whether another library has
@@ -80,6 +96,7 @@ static int init_gcrypt() {
   gcry_control(GCRYCTL_INITIALIZATION_FINISHED);
   return 0;
 }
+#endif
 
 typedef struct {
   uint8_t *data;
@@ -287,8 +304,6 @@ static int parse_values(void *payload, size_t payload_size,
   state->values = calloc(sizeof(*state->values), state->values_len);
   state->values_types = calloc(sizeof(*state->values_types), state->values_len);
   if ((state->values == NULL) || (state->values_types == NULL)) {
-    free(state->values);
-    free(state->values_types);
     return ENOMEM;
   }
 
@@ -332,6 +347,7 @@ static int parse_values(void *payload, size_t payload_size,
   return 0;
 }
 
+#if HAVE_GCRYPT_H
 static int verify_sha256(void *payload, size_t payload_size,
                          char const *username, char const *password,
                          uint8_t hash_provided[32]) {
@@ -339,14 +355,13 @@ static int verify_sha256(void *payload, size_t payload_size,
 
   gcry_error_t err = gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
   if (err != 0) {
-    /* TODO(octo): use gcry_strerror(err) to create an error string. */
-    return -1;
+    return (int)err;
   }
 
   err = gcry_md_setkey(hd, password, strlen(password));
   if (err != 0) {
     gcry_md_close(hd);
-    return -1;
+    return (int)err;
   }
 
   gcry_md_write(hd, username, strlen(username));
@@ -365,12 +380,20 @@ static int verify_sha256(void *payload, size_t payload_size,
 
   return !!ret;
 }
+#else /* !HAVE_GCRYPT_H */
+static int verify_sha256(void *payload, size_t payload_size,
+                         char const *username, char const *password,
+                         uint8_t hash_provided[32]) {
+  return ENOTSUP;
+}
+#endif
 
 static int parse_sign_sha256(void *signature, size_t signature_len,
                              void *payload, size_t payload_size,
                              lcc_network_parse_options_t const *opts) {
   if (opts->password_lookup == NULL) {
-    /* TODO(octo): print warning */
+    /* The sender signed the packet but we can't verify it. Handle it as if it
+     * were unsigned, i.e. security level NONE. */
     return network_parse(payload, payload_size, NONE, opts);
   }
 
@@ -399,6 +422,7 @@ static int parse_sign_sha256(void *signature, size_t signature_len,
   return network_parse(payload, payload_size, SIGN, opts);
 }
 
+#if HAVE_GCRYPT_H
 static int decrypt_aes256(buffer_t *b, void *iv, size_t iv_size,
                           char const *password) {
   gcry_cipher_hd_t cipher = NULL;
@@ -426,7 +450,8 @@ static int decrypt_aes256(buffer_t *b, void *iv, size_t iv_size,
 static int parse_encrypt_aes256(void *data, size_t data_size,
                                 lcc_network_parse_options_t const *opts) {
   if (opts->password_lookup == NULL) {
-    /* TODO(octo): print warning */
+    /* Without a password source it's (hopefully) impossible to decrypt the
+     * network packet. */
     return ENOENT;
   }
 
@@ -470,6 +495,12 @@ static int parse_encrypt_aes256(void *data, size_t data_size,
 
   return network_parse(b->data, b->len, ENCRYPT, opts);
 }
+#else /* !HAVE_GCRYPT_H */
+static int parse_encrypt_aes256(void *data, size_t data_size,
+                                lcc_network_parse_options_t const *opts) {
+  return ENOTSUP;
+}
+#endif
 
 static int network_parse(void *data, size_t data_size, lcc_security_level_t sl,
                          lcc_network_parse_options_t const *opts) {
@@ -525,13 +556,17 @@ static int network_parse(void *data, size_t data_size, lcc_security_level_t sl,
     case TYPE_VALUES: {
       lcc_value_list_t vl = state;
       if (parse_values(payload, sizeof(payload), &vl)) {
+        free(vl.values);
+        free(vl.values_types);
         DEBUG("lcc_network_parse(): parse_values failed.\n");
         return EINVAL;
       }
 
-      /* TODO(octo): skip if current_security_level < required_security_level */
+      int status = 0;
 
-      int status = opts->writer(&vl);
+      /* Write metrics if they have the required security level. */
+      if (sl >= opts->security_level)
+        status = opts->writer(&vl);
 
       free(vl.values);
       free(vl.values_types);
@@ -576,10 +611,14 @@ static int network_parse(void *data, size_t data_size, lcc_security_level_t sl,
 int lcc_network_parse(void *data, size_t data_size,
                       lcc_network_parse_options_t opts) {
   if (opts.password_lookup) {
+#if HAVE_GCRYPT_H
     int status;
     if ((status = init_gcrypt())) {
       return status;
     }
+#else
+    return ENOTSUP;
+#endif
   }
 
   return network_parse(data, data_size, NONE, &opts);