]> git.proxmox.com Git - mirror_corosync.git/commitdiff
config: Properly check crypto and compress models
authorJan Friesse <jfriesse@redhat.com>
Fri, 9 Apr 2021 10:21:15 +0000 (12:21 +0200)
committerJan Friesse <jfriesse@redhat.com>
Wed, 14 Apr 2021 16:07:20 +0000 (18:07 +0200)
Use knet_get_crypto_list to find knet supported crypto models and use
them instead of hardcoded list.

Also fix compression handling. Previously knet_compression_model
value was not checked at all and was directly passed to knet.

Use knet_get_compress_list to find knet supported compress models and
use them to check validity of config file and for more informative
error message.

Lastly enhance corosync version display with information
about available crypto/compression models.

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
exec/coroparse.c
exec/main.c
exec/totemconfig.c
exec/util.c
exec/util.h
man/corosync.8
man/corosync.conf.5
vqsim/Makefile.am

index 0d36161471d23099396f7cc82af053e9fb7c59e4..741f374177516872bdbd49f0e44e58af1413c99a 100644 (file)
@@ -555,6 +555,28 @@ static int str_to_ull(const char *str, unsigned long long int *res)
        return (0);
 }
 
+static int handle_crypto_model(const char *val, const char **error_string)
+{
+
+       if (util_is_valid_knet_crypto_model(val, NULL, 0,
+           "Invalid crypto model. Should be ", error_string) == 1) {
+               return (0);
+       } else {
+               return (-1);
+       }
+}
+
+static int handle_compress_model(const char *val, const char **error_string)
+{
+
+       if (util_is_valid_knet_compress_model(val, NULL, 0,
+           "Invalid compression model. Should be ", error_string) == 1) {
+               return (0);
+       } else {
+               return (-1);
+       }
+}
+
 static int main_config_parser_cb(const char *path,
                        char *key,
                        char *value,
@@ -748,14 +770,11 @@ static int main_config_parser_cb(const char *path,
                                }
                        }
                        if (strcmp(path, "totem.crypto_model") == 0) {
-                               if ((strcmp(value, "nss") != 0) &&
-                                   (strcmp(value, "openssl") != 0)) {
-                                       *error_string = "Invalid crypto model. "
-                                           "Should be nss or openssl";
-
+                               if (handle_crypto_model(value, error_string) != 0) {
                                        return (0);
                                }
                        }
+
                        if (strcmp(path, "totem.crypto_cipher") == 0) {
                                if ((strcmp(value, "none") != 0) &&
                                    (strcmp(value, "aes256") != 0) &&
@@ -780,6 +799,13 @@ static int main_config_parser_cb(const char *path,
                                        return (0);
                                }
                        }
+
+                       if (strcmp(path, "totem.knet_compression_model") == 0) {
+                               if (handle_compress_model(value, error_string) != 0) {
+                                       return (0);
+                               }
+                       }
+
                        break;
 
                case MAIN_CP_CB_DATA_STATE_SYSTEM:
index 55f8931af36ffc852cf965e68bd57aacec4cda58..72f622d9806a14af9a281eb03e8c9428d050f9b2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2002-2006 MontaVista Software, Inc.
- * Copyright (c) 2006-2018 Red Hat, Inc.
+ * Copyright (c) 2006-2021 Red Hat, Inc.
  *
  * All rights reserved.
  *
@@ -1214,6 +1214,41 @@ exit_res:
         return (res);
 }
 
+static void show_version_info_crypto(void)
+{
+       const char *error_string;
+       const char *list_str;
+
+       if (util_is_valid_knet_crypto_model(NULL, &list_str, 1, "", &error_string) != -1) {
+               printf("Available crypto models: %s\n", list_str);
+       } else {
+               perror(error_string);
+       }
+}
+
+static void show_version_info_compress(void)
+{
+       const char *error_string;
+       const char *list_str;
+
+       if (util_is_valid_knet_compress_model(NULL, &list_str, 1, "", &error_string) != -1) {
+               printf("Available compression models: %s\n", list_str);
+       } else {
+               perror(error_string);
+       }
+}
+
+static void show_version_info(void)
+{
+
+       printf ("Corosync Cluster Engine, version '%s'\n", VERSION);
+       printf ("Copyright (c) 2006-2021 Red Hat, Inc.\n");
+
+       printf ("\nBuilt-in features:" PACKAGE_FEATURES "\n");
+
+       show_version_info_crypto();
+       show_version_info_compress();
+}
 
 int main (int argc, char **argv, char **envp)
 {
@@ -1254,8 +1289,7 @@ int main (int argc, char **argv, char **envp)
                                testonly = 1;
                                break;
                        case 'v':
-                               printf ("Corosync Cluster Engine, version '%s'\n", VERSION);
-                               printf ("Copyright (c) 2006-2018 Red Hat, Inc.\n");
+                               show_version_info();
                                logsys_system_fini();
                                return EXIT_SUCCESS;
 
@@ -1266,7 +1300,7 @@ int main (int argc, char **argv, char **envp)
                                        "        -c     : Corosync config file path.\n"\
                                        "        -f     : Start application in foreground.\n"\
                                        "        -t     : Test configuration and exit.\n"\
-                                       "        -v     : Display version and SVN revision of Corosync and exit.\n");
+                                       "        -v     : Display version, git revision and some useful information about Corosync and exit.\n");
                                logsys_system_fini();
                                return EXIT_FAILURE;
                }
index 645ff9ef89a4a6b6260addf9081993d9a1a09aec..6bd40446422318c0457a2df2cc37655baa2b4e1d 100644 (file)
@@ -535,19 +535,16 @@ static int totem_get_crypto(struct totem_config *totem_config, icmap_map_t map,
        const char *tmp_cipher;
        const char *tmp_hash;
        const char *tmp_model;
+       char *crypto_model_str;
+       int res = 0;
 
        tmp_hash = "none";
        tmp_cipher = "none";
        tmp_model = "none";
 
-       if (icmap_get_string_r(map, "totem.crypto_model", &str) == CS_OK) {
-               if (strcmp(str, "nss") == 0) {
-                       tmp_model = "nss";
-               }
-               if (strcmp(str, "openssl") == 0) {
-                       tmp_model = "openssl";
-               }
-               free(str);
+       crypto_model_str = NULL;
+       if (icmap_get_string_r(map, "totem.crypto_model", &crypto_model_str) == CS_OK) {
+               tmp_model = crypto_model_str;
        } else {
                tmp_model = "nss";
        }
@@ -601,12 +598,19 @@ static int totem_get_crypto(struct totem_config *totem_config, icmap_map_t map,
        if ((strcmp(tmp_cipher, "none") != 0) &&
            (strcmp(tmp_hash, "none") == 0)) {
                *error_string = "crypto_cipher requires crypto_hash with value other than none";
-               return -1;
+               res = -1;
+
+               goto out_free_crypto_model_str;
        }
 
        if (strcmp(tmp_model, "none") == 0) {
-               *error_string = "crypto_model should be 'nss' or 'openssl'";
-               return -1;
+               /*
+                * Shouldn't happen because it is handled by coroparse
+                */
+               *error_string = "invalid crypto_model";
+               res = -1;
+
+               goto out_free_crypto_model_str;
        }
 
        if (strcmp(tmp_cipher, totem_config->crypto_cipher_type) ||
@@ -619,7 +623,10 @@ static int totem_get_crypto(struct totem_config *totem_config, icmap_map_t map,
        strncpy(totem_config->crypto_hash_type, tmp_hash, CONFIG_STRING_LEN_MAX);
        strncpy(totem_config->crypto_model, tmp_model, CONFIG_STRING_LEN_MAX);
 
-       return 0;
+out_free_crypto_model_str:
+       free(crypto_model_str);
+
+       return (res);
 }
 
 static int nodelist_byname(icmap_map_t map, const char *find_name, int strip_domain)
index 7ef3362feffa717cf8a91081dd2a3bc89c53b33e..8988ab29c8a6d29a682a43096a11d25e9945d079 100644 (file)
@@ -43,6 +43,8 @@
 #include <sys/time.h>
 #include <assert.h>
 
+#include <libknet.h>
+
 #include <corosync/corotypes.h>
 #include <corosync/corodefs.h>
 #include <corosync/icmap.h>
@@ -188,3 +190,154 @@ const char *get_state_dir(void)
 
        return (path);
 }
+
+static int safe_strcat(char *dst, size_t dst_len, const char *src)
+{
+
+       if (strlen(dst) + strlen(src) >= dst_len - 1) {
+               return (-1);
+       }
+
+       strcat(dst, src);
+
+       return (0);
+}
+
+/*
+ * val - knet crypto model to find
+ * crypto_list_str - string with concatenated list of available crypto models - can be NULL
+ * machine_parseable_str - 0 - split strings by space, 1 - use human form (split by "," and last item with "or")
+ * error_string_prefix - Prefix to add into error string
+ * error_string - Complete error string
+ */
+int util_is_valid_knet_crypto_model(const char *val,
+       const char **list_str, int machine_parseable_str,
+       const char *error_string_prefix, const char **error_string)
+{
+       size_t entries;
+       struct knet_crypto_info crypto_list[16];
+       size_t zi;
+       static char local_error_str[512];
+       static char local_list_str[256];
+       int model_found = 0;
+
+       if (list_str != NULL) {
+               *list_str = local_list_str;
+       }
+
+       memset(local_error_str, 0, sizeof(local_error_str));
+       memset(local_list_str, 0, sizeof(local_list_str));
+
+       safe_strcat(local_error_str, sizeof(local_error_str), error_string_prefix);
+
+       if (knet_get_crypto_list(NULL, &entries) != 0) {
+               *error_string = "internal error - cannot get knet crypto list";
+               return (-1);
+       }
+
+       if (entries > sizeof(crypto_list) / sizeof(crypto_list[0])) {
+               *error_string = "internal error - too many knet crypto list entries";
+               return (-1);
+       }
+
+       if (knet_get_crypto_list(crypto_list, &entries) != 0) {
+               *error_string = "internal error - cannot get knet crypto list";
+               return (-1);
+       }
+
+       for (zi = 0; zi < entries; zi++) {
+               if (zi == 0) {
+               } else if (zi == entries - 1) {
+                       if (machine_parseable_str) {
+                               (void)safe_strcat(local_list_str, sizeof(local_list_str), " ");
+                       } else {
+                               (void)safe_strcat(local_list_str, sizeof(local_list_str), " or ");
+                       }
+               } else {
+                       if (machine_parseable_str) {
+                               (void)safe_strcat(local_list_str, sizeof(local_list_str), " ");
+                       } else {
+                               (void)safe_strcat(local_list_str, sizeof(local_list_str), ", ");
+                       }
+               }
+
+               (void)safe_strcat(local_list_str, sizeof(local_list_str), crypto_list[zi].name);
+
+               if (val != NULL && strcmp(val, crypto_list[zi].name) == 0) {
+                       model_found = 1;
+               }
+       }
+
+       if (!model_found) {
+               (void)safe_strcat(local_error_str, sizeof(local_error_str), local_list_str);
+               *error_string = local_error_str;
+       }
+
+       return (model_found);
+}
+
+int util_is_valid_knet_compress_model(const char *val,
+       const char **list_str, int machine_parseable_str,
+       const char *error_string_prefix, const char **error_string)
+{
+       size_t entries;
+       struct knet_compress_info compress_list[16];
+       size_t zi;
+       static char local_error_str[512];
+       static char local_list_str[256];
+       int model_found = 0;
+
+       if (list_str != NULL) {
+               *list_str = local_list_str;
+       }
+
+       memset(local_error_str, 0, sizeof(local_error_str));
+       memset(local_list_str, 0, sizeof(local_list_str));
+
+       safe_strcat(local_error_str, sizeof(local_error_str), error_string_prefix);
+
+       if (knet_get_compress_list(NULL, &entries) != 0) {
+               *error_string = "internal error - cannot get knet compress list";
+               return (-1);
+       }
+
+       if (entries > sizeof(compress_list) / sizeof(compress_list[0])) {
+               *error_string = "internal error - too many knet compress list entries";
+               return (-1);
+       }
+
+       if (knet_get_compress_list(compress_list, &entries) != 0) {
+               *error_string = "internal error - cannot get knet compress list";
+               return (-1);
+       }
+
+       for (zi = 0; zi < entries; zi++) {
+               if (zi == 0) {
+               } else if (zi == entries - 1) {
+                       if (machine_parseable_str) {
+                               (void)safe_strcat(local_list_str, sizeof(local_list_str), " ");
+                       } else {
+                               (void)safe_strcat(local_list_str, sizeof(local_list_str), " or ");
+                       }
+               } else {
+                       if (machine_parseable_str) {
+                               (void)safe_strcat(local_list_str, sizeof(local_list_str), " ");
+                       } else {
+                               (void)safe_strcat(local_list_str, sizeof(local_list_str), ", ");
+                       }
+               }
+
+               (void)safe_strcat(local_list_str, sizeof(local_list_str), compress_list[zi].name);
+
+               if (val != NULL && strcmp(val, compress_list[zi].name) == 0) {
+                       model_found = 1;
+               }
+       }
+
+       if (!model_found) {
+               (void)safe_strcat(local_error_str, sizeof(local_error_str), local_list_str);
+               *error_string = local_error_str;
+       }
+
+       return (model_found);
+}
index e493b9a912e8c07d9f4b0d9cb35121b8befb78b1..e6e12af00fa0dd2ec6f3b0fe7d7d801aee663b9b 100644 (file)
@@ -87,4 +87,12 @@ const char * short_service_name_get(uint32_t service_id,
  */
 const char *get_state_dir(void);
 
+extern int util_is_valid_knet_crypto_model(const char *val,
+       const char **list_str, int machine_parseable_str,
+       const char *error_string_prefix, const char **error_string);
+
+extern int util_is_valid_knet_compress_model(const char *val,
+       const char **list_str, int machine_parseable_str,
+       const char *error_string_prefix, const char **error_string);
+
 #endif /* UTIL_H_DEFINED */
index 96494d647787a3bae1d3fe853c7c6eda399fed6b..5d219b126aff301d9004b03579c1beda58a648f9 100644 (file)
@@ -1,5 +1,5 @@
 .\"/*
-.\" * Copyright (C) 2010-2018 Red Hat, Inc.
+.\" * Copyright (C) 2010-2021 Red Hat, Inc.
 .\" *
 .\" * All rights reserved.
 .\" *
@@ -31,7 +31,7 @@
 .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 .\" * THE POSSIBILITY OF SUCH DAMAGE.
 .\" */
-.TH COROSYNC 8 2018-11-12
+.TH COROSYNC 8 2021-04-09
 .SH NAME
 corosync \- The Corosync Cluster Engine.
 .SH SYNOPSIS
@@ -54,7 +54,9 @@ Start application in foreground.
 Test configuration and then exit.
 .TP
 .B -v
-Display version and SVN revision of Corosync and exit.
+Display version, git revision, compiled features and available crypto and compression
+models and exit.
+
 .SH SEE ALSO
 .BR corosync_overview (7),
 .BR corosync.conf (5),
index 3fdf823ff8c5008871e682e4951bbc327d9fef76..25289ba4bb26e591f6b11d5f4254baecacebc624 100644 (file)
@@ -32,7 +32,7 @@
 .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 .\" * THE POSSIBILITY OF SUCH DAMAGE.
 .\" */
-.TH COROSYNC_CONF 5 2020-10-12 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.TH COROSYNC_CONF 5 2021-04-09 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
 .SH NAME
 corosync.conf - corosync executive configuration file
 
@@ -204,8 +204,10 @@ a subset of the cluster (for example during a rolling upgrade).
 
 .TP
 crypto_model
-This specifies which cryptographic library should be used by knet. Options
-are nss and openssl.
+This specifies which cryptographic library should be used by knet.
+Supported values depend on the libknet build and on the installed
+cryptography libraries. Typically nss and openssl will be available
+but gcrypt and others could also be allowed.
 
 The default is nss.
 
index 9a7fbf6f1a5287778b8c31162f461a25cd22b218..7639fcf031855c84ded9282c6f4f7edf4ab1c5ad 100644 (file)
@@ -38,11 +38,14 @@ noinst_HEADERS                      = vqsim.h
 
 bin_PROGRAMS                   = corosync-vqsim
 
+corosync_vqsim_CFLAGS          = $(knet_CFLAGS)
+
 corosync_vqsim_LDADD           = $(top_builddir)/common_lib/libcorosync_common.la \
                                  ../exec/corosync-votequorum.o ../exec/corosync-icmap.o  \
                                  ../exec/corosync-coroparse.o ../exec/corosync-logconfig.o \
                                  ../exec/corosync-util.o ../exec/corosync-logsys.o \
-                               $(LIBQB_LIBS)
+                               $(LIBQB_LIBS) $(knet_LIBS)
+
 if VQSIM_READLINE
 corosync_vqsim_LDADD           += -lreadline
 endif