From: Remi Tricot-Le Breton Date: Mon, 11 Oct 2021 13:34:12 +0000 (+0200) Subject: MINOR: ssl: Add ssllib_name_startswith precondition X-Git-Tag: v2.5-dev10~66 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b01179aa92f1b5d1b82b0d42cfbedd60b27e99d3;p=thirdparty%2Fhaproxy.git MINOR: ssl: Add ssllib_name_startswith precondition 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. --- diff --git a/include/haproxy/cfgcond-t.h b/include/haproxy/cfgcond-t.h index b4be9fe86f..1e0929364b 100644 --- a/include/haproxy/cfgcond-t.h +++ b/include/haproxy/cfgcond-t.h @@ -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 */ diff --git a/include/haproxy/tools.h b/include/haproxy/tools.h index 141b3dadbe..b6efd72f2a 100644 --- a/include/haproxy/tools.h +++ b/include/haproxy/tools.h @@ -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 */ diff --git a/src/cfgcond.c b/src/cfgcond.c index 4aaa92d9d4..5fb7069128 100644 --- a/src/cfgcond.c +++ b/src/cfgcond.c @@ -18,14 +18,15 @@ /* 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; diff --git a/src/tools.c b/src/tools.c index 91b2acad84..144ef7eaf0 100644 --- a/src/tools.c +++ b/src/tools.c @@ -5624,6 +5624,26 @@ int openssl_compare_current_version(const char *version) #endif } +/* + * This function compares the loaded openssl name with a string + * 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 */