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 b4be9fe..1e09293 100644
--- a/include/haproxy/cfgcond-t.h
+++ b/include/haproxy/cfgcond-t.h
@@ -43,15 +43,16 @@
/* 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 141b3da..b6efd72 100644
--- a/include/haproxy/tools.h
+++ b/include/haproxy/tools.h
@@ -1096,5 +1096,7 @@
/* 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 4aaa92d..5fb7069 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 @@
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 91b2aca..144ef7e 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -5624,6 +5624,26 @@
#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 */