]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ssl: Add ssllib_name_startswith precondition
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Mon, 11 Oct 2021 13:34:12 +0000 (15:34 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Wed, 13 Oct 2021 09:28:08 +0000 (11:28 +0200)
This new ssllib_name_startswith precondition check can be used to
distinguish application linked with OpenSSL from the ones linked with
other SSL libraries (LibreSSL or BoringSSL namely). This check takes a
string as input and returns 1 when the SSL library's name starts with
the given string. It is based on the OpenSSL_version function which
returns the same output as the "openssl version" command.

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

index b4be9fe86faa132196fc5e29fb98a7f434498576..1e0929364b454badedbd376dd84699dffe346f3f 100644 (file)
@@ -43,15 +43,16 @@ enum nested_cond_state {
 
 /* supported conditional predicates for .if/.elif */
 enum cond_predicate {
-       CFG_PRED_NONE,            // none
-       CFG_PRED_DEFINED,         // "defined"
-       CFG_PRED_FEATURE,         // "feature"
-       CFG_PRED_STREQ,           // "streq"
-       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"
+       CFG_PRED_NONE,                   // none
+       CFG_PRED_DEFINED,                // "defined"
+       CFG_PRED_FEATURE,                // "feature"
+       CFG_PRED_STREQ,                  // "streq"
+       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"
+       CFG_PRED_SSLLIB_NAME_STARTSWITH, // "ssllib_name_startswith"
 };
 
 /* types for condition terms */
index 141b3dadbec2afb7a95064b5a8f00234412247c8..b6efd72f2aceed08a27a2588d49bec0cd71b8382 100644 (file)
@@ -1096,5 +1096,7 @@ static inline void update_char_fingerprint(uint8_t *fp, char prev, char curr)
 
 /* compare the current OpenSSL version to a string */
 int openssl_compare_current_version(const char *version);
+/* compare the current OpenSSL name to a string */
+int openssl_compare_current_name(const char *name);
 
 #endif /* _HAPROXY_TOOLS_H */
index 4aaa92d9d43f077b7c2b36e399b7ab9bd206be4f..5fb7069128acccd9203a526b0ac0728338dd7170 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)         },
-       { "openssl_version_atleast",  CFG_PRED_OSSL_VERSION_ATLEAST, ARG1(1, STR)         },
-       { "openssl_version_before",   CFG_PRED_OSSL_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)         },
+       { "ssllib_name_startswith",  CFG_PRED_SSLLIB_NAME_STARTSWITH, ARG1(1, STR)         },
        { NULL, CFG_PRED_NONE, 0 }
 };
 
@@ -250,6 +251,10 @@ int cfg_eval_cond_term(const struct cfg_cond_term *term, char **err)
                                ret = opensslret > 0;
                        break;
                }
+               case CFG_PRED_SSLLIB_NAME_STARTSWITH: { // checks if the current SSL library's name starts with a specified string (can be used to distinguish OpenSSL from LibreSSL or BoringSSL)
+                       ret = openssl_compare_current_name(term->args[0].data.str.area) == 0;
+                       break;
+               }
                default:
                        memprintf(err, "internal error: unhandled conditional expression predicate '%s'", term->pred->word);
                        break;
index 91b2acad84c2f0092c59df6474e1e1eaa7c2bc45..144ef7eaf0de97048f9ed2d4b5ffc93f88024a87 100644 (file)
@@ -5624,6 +5624,26 @@ int openssl_compare_current_version(const char *version)
 #endif
 }
 
+/*
+ * This function compares the loaded openssl name with a string <name>
+ * This function returns 0 if the OpenSSL name starts like the passed parameter,
+ * 1 otherwise.
+ */
+int openssl_compare_current_name(const char *name)
+{
+#ifdef USE_OPENSSL
+       int name_len = 0;
+       const char *openssl_version = OpenSSL_version(OPENSSL_VERSION);
+
+       if (name) {
+               name_len = strlen(name);
+               if (strlen(name) <= strlen(openssl_version))
+                       return strncmp(openssl_version, name, name_len);
+       }
+#endif
+       return 1;
+}
+
 static int init_tools_per_thread()
 {
        /* Let's make each thread start from a different position */