]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: cfgcond: implements openssl_version_atleast and openssl_version_before
authorWilliam Lallemand <wlallemand@haproxy.org>
Sat, 21 Aug 2021 21:59:56 +0000 (23:59 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Sat, 21 Aug 2021 22:30:24 +0000 (00:30 +0200)
Implements a way of checking the running openssl version:

If the OpenSSL support was not compiled within HAProxy it will returns a
error, so it's recommanded to do a SSL feature check before:

$ ./haproxy -cc 'feature(OPENSSL) && openssl_version_atleast(0.9.8zh) && openssl_version_before(3.0.0)'

This will allow to select the SSL reg-tests more carefully.

include/haproxy/cfgcond-t.h
include/haproxy/tools.h
src/cfgcond.c
src/tools.c

index bb196123457fa8a19389e376080bce6f40fc12cf..b4be9fe86faa132196fc5e29fb98a7f434498576 100644 (file)
@@ -50,6 +50,8 @@ enum cond_predicate {
        CFG_PRED_STRNEQ,          // "strneq"
        CFG_PRED_VERSION_ATLEAST, // "version_atleast"
        CFG_PRED_VERSION_BEFORE,  // "version_before"
+       CFG_PRED_OSSL_VERSION_ATLEAST, // "openssl_version_atleast"
+       CFG_PRED_OSSL_VERSION_BEFORE,  // "openssl_version_before"
 };
 
 /* types for condition terms */
index e376a716e17006ba9e5c9aa209bb6471f927e3e5..dec82e6b7210b7164ae39452aa6cfef8bcf46b12 100644 (file)
@@ -1093,4 +1093,8 @@ static inline void update_char_fingerprint(uint8_t *fp, char prev, char curr)
        fp[32 * from + to]++;
 }
 
+
+/* compare the current OpenSSL version to a string */
+int openssl_compare_current_version(const char *version);
+
 #endif /* _HAPROXY_TOOLS_H */
index 4654c1be8a41dbf29b93cfdc94c5f75a45180706..4aaa92d9d43f077b7c2b36e399b7ab9bd206be4f 100644 (file)
 
 /* supported condition predicates */
 const struct cond_pred_kw cond_predicates[] = {
-       { "defined",          CFG_PRED_DEFINED,         ARG1(1, STR)         },
-       { "feature",          CFG_PRED_FEATURE,         ARG1(1, STR)         },
-       { "streq",            CFG_PRED_STREQ,           ARG2(2, STR, STR)    },
-       { "strneq",           CFG_PRED_STRNEQ,          ARG2(2, STR, STR)    },
-       { "version_atleast",  CFG_PRED_VERSION_ATLEAST, ARG1(1, STR)         },
-       { "version_before",   CFG_PRED_VERSION_BEFORE,  ARG1(1, STR)         },
+       { "defined",                  CFG_PRED_DEFINED,              ARG1(1, STR)         },
+       { "feature",                  CFG_PRED_FEATURE,              ARG1(1, STR)         },
+       { "streq",                    CFG_PRED_STREQ,                ARG2(2, STR, STR)    },
+       { "strneq",                   CFG_PRED_STRNEQ,               ARG2(2, STR, STR)    },
+       { "version_atleast",          CFG_PRED_VERSION_ATLEAST,      ARG1(1, STR)         },
+       { "version_before",           CFG_PRED_VERSION_BEFORE,       ARG1(1, STR)         },
+       { "openssl_version_atleast",  CFG_PRED_OSSL_VERSION_ATLEAST, ARG1(1, STR)         },
+       { "openssl_version_before",   CFG_PRED_OSSL_VERSION_BEFORE,  ARG1(1, STR)         },
        { NULL, CFG_PRED_NONE, 0 }
 };
 
@@ -230,6 +232,24 @@ int cfg_eval_cond_term(const struct cfg_cond_term *term, char **err)
                        ret = compare_current_version(term->args[0].data.str.area) > 0;
                        break;
 
+               case CFG_PRED_OSSL_VERSION_ATLEAST: { // checks if the current openssl version is at least this one
+                       int opensslret = openssl_compare_current_version(term->args[0].data.str.area);
+
+                       if (opensslret < -1) /* can't parse the string or no openssl available */
+                               ret = -1;
+                       else
+                               ret = opensslret <= 0;
+                       break;
+               }
+               case CFG_PRED_OSSL_VERSION_BEFORE: { // checks if the current openssl version is older than this one
+                       int opensslret = openssl_compare_current_version(term->args[0].data.str.area);
+
+                       if (opensslret < -1) /* can't parse the string or no openssl available */
+                               ret = -1;
+                       else
+                               ret = opensslret > 0;
+                       break;
+               }
                default:
                        memprintf(err, "internal error: unhandled conditional expression predicate '%s'", term->pred->word);
                        break;
index 1961689dd46f1d982f5031323948828304bec56b..4f536efc3ee4bafc22a58e08416b91096cac8cc4 100644 (file)
@@ -62,6 +62,7 @@ extern void *__elf_aux_vector;
 #include <haproxy/resolvers.h>
 #include <haproxy/sock.h>
 #include <haproxy/ssl_sock.h>
+#include <haproxy/ssl_utils.h>
 #include <haproxy/stream_interface.h>
 #include <haproxy/task.h>
 #include <haproxy/tools.h>
@@ -5592,6 +5593,38 @@ int word_fingerprint_distance(const uint8_t *fp1, const uint8_t *fp2)
        return dist;
 }
 
+/*
+ * This function compares the loaded openssl version with a string <version>
+ * This function use the same return code as compare_current_version:
+ *
+ *  -1 : the version in argument is older than the current openssl version
+ *   0 : the version in argument is the same as the current openssl version
+ *   1 : the version in argument is newer than the current openssl version
+ *
+ * Or some errors:
+ *  -2 : openssl is not available on this process
+ *  -3 : the version in argument is not parsable
+ */
+int openssl_compare_current_version(const char *version)
+{
+#ifdef USE_OPENSSL
+       int numversion;
+
+       numversion = openssl_version_parser(version);
+       if (numversion == 0)
+               return -3;
+
+       if (numversion < OPENSSL_VERSION_NUMBER)
+               return -1;
+       else if (numversion > OPENSSL_VERSION_NUMBER)
+               return 1;
+       else
+               return 0;
+#else
+       return -2;
+#endif
+}
+
 static int init_tools_per_thread()
 {
        /* Let's make each thread start from a different position */