build2/libbutl-openssl-info-overloads.patch
Matthew Krupcale babacf4446 Update to v0.14.0
* .gitignore, sources: Update to v0.14.0
 * bpkg-openssl-3-pkeyutl.patch, libbutl-openssl-info-overloads.patch: add patches for OpenSSL v3.0 support [1]
 * build2-disable-test-cc-modules-ppc64le.patch: add patch to disable failing C++ modules tests on PPC64LE
 * build2.spec:
    - Update to v0.14.0
    - Re-enable bootstrap required for this releas
    - Update comments on libbutl license
    - Use config.install.etc for specifying system configuration file directory
    - Use config.install.scope to prevent installing statically built, bundled libodb [2,3]
 * libbuild2-config.install.scope-no-update-for-install.patch: add patch to make config.install.scope not apply during update-for-install pre-operation [3]
 * macros.build2:
    - Use config.install.legal for specifying system configuration file directory

[1] https://lists.build2.org/archives/users/2021-November/000923.html
[2] https://lists.build2.org/archives/announce/2021/000021.html
[3] https://lists.build2.org/archives/users/2021-November/000919.html
2022-01-23 18:36:38 -05:00

174 lines
4.9 KiB
Diff

From c6ea3d784ee920f51de3088437b471c8dd6d70e2 Mon Sep 17 00:00:00 2001
From: Karen Arutyunov <karen@codesynthesis.com>
Date: Thu, 18 Nov 2021 15:54:46 +0300
Subject: Add openssl::info() overloads
---
libbutl/openssl.hxx | 35 +++++++++++++++++++++++++++
libbutl/openssl.ixx | 9 +++++++
libbutl/openssl.txx | 63 ++++++++++++++++++++++++++++++++++++++++++++++++
tests/openssl/driver.cxx | 24 +++++++++++++++---
4 files changed, 127 insertions(+), 4 deletions(-)
diff --git a/libbutl/openssl.hxx b/libbutl/openssl.hxx
index 58e38f8..b340f5c 100644
--- a/libbutl/openssl.hxx
+++ b/libbutl/openssl.hxx
@@ -8,8 +8,10 @@
#include <libbutl/path.hxx>
#include <libbutl/process.hxx>
+#include <libbutl/optional.hxx>
#include <libbutl/fdstream.hxx>
#include <libbutl/small-vector.hxx>
+#include <libbutl/semantic-version.hxx>
#include <libbutl/export.hxx>
@@ -78,6 +80,23 @@ namespace butl
// department (that were apparently fixed in 1.0.2). To work around these
// bugs pass user-supplied options first.
//
+ struct openssl_info
+ {
+ // Note that the program name can be used by the caller to properly
+ // interpret the version.
+ //
+ // The name/version examples:
+ //
+ // OpenSSL 3.0.0
+ // OpenSSL 1.1.1l
+ // LibreSSL 2.8.3
+ //
+ // The `l` component above ends up in semantic_version::build.
+ //
+ std::string name;
+ semantic_version version;
+ };
+
class LIBBUTL_SYMEXPORT openssl: public process
{
public:
@@ -111,6 +130,22 @@ namespace butl
const std::string& command,
A&&... options);
+ // Run `openssl version` command and try to parse and return the
+ // information it prints to stdout. Return nullopt if the process hasn't
+ // terminated successfully or stdout parsing has failed. Throw
+ // process_error and io_error in case of errors.
+ //
+ template <typename E>
+ static optional<openssl_info>
+ info (E&& err, const process_env&);
+
+ template <typename C,
+ typename E>
+ static optional<openssl_info>
+ info (const C&,
+ E&& err,
+ const process_env&);
+
private:
template <typename T>
struct is_other
diff --git a/libbutl/openssl.ixx b/libbutl/openssl.ixx
index 1435dcb..db2fbcd 100644
--- a/libbutl/openssl.ixx
+++ b/libbutl/openssl.ixx
@@ -26,4 +26,13 @@ namespace butl
std::forward<A> (options)...)
{
}
+
+ template <typename E>
+ inline optional<openssl_info> openssl::
+ info (E&& err, const process_env& env)
+ {
+ return info ([] (const char* [], std::size_t) {},
+ std::forward<E> (err),
+ env);
+ }
}
diff --git a/libbutl/openssl.txx b/libbutl/openssl.txx
index f198c22..01e854c 100644
--- a/libbutl/openssl.txx
+++ b/libbutl/openssl.txx
@@ -1,6 +1,7 @@
// file : libbutl/openssl.txx -*- C++ -*-
// license : MIT; see accompanying LICENSE file
+#include <cstddef> // size_t
#include <utility> // forward()
namespace butl
@@ -49,4 +50,66 @@ namespace butl
// Note: leaving this scope closes any open ends of the pipes in io_data.
}
+
+ template <typename C,
+ typename E>
+ optional<openssl_info> openssl::
+ info (const C& cmdc, E&& err, const process_env& env)
+ {
+ using namespace std;
+
+ // Run the `openssl version` command.
+ //
+ openssl os (cmdc,
+ nullfd, fdstream_mode::text, forward<E> (err),
+ env,
+ "version");
+
+ // Read the command's stdout and wait for its completion. Bail out if the
+ // command didn't terminate successfully or stdout contains no data.
+ //
+ string s;
+ if (!getline (os.in, s))
+ return nullopt;
+
+ os.in.close ();
+
+ if (!os.wait ())
+ return nullopt;
+
+ // Parse the version string.
+ //
+ // Note that there is some variety in the version representations:
+ //
+ // OpenSSL 3.0.0 7 sep 2021 (Library: OpenSSL 3.0.0 7 sep 2021)
+ // OpenSSL 1.1.1l FIPS 24 Aug 2021
+ // LibreSSL 2.8.3
+ //
+ // We will only consider the first two space separated components as the
+ // program name and version. We will also assume that there are no leading
+ // spaces and the version is delimited from the program name with a single
+ // space character.
+ //
+ size_t e (s.find (' '));
+
+ // Bail out if there is no version present in the string or the program
+ // name is empty.
+ //
+ if (e == string::npos || e == 0)
+ return nullopt;
+
+ string nm (s, 0, e);
+
+ size_t b (e + 1); // The beginning of the version.
+ e = s.find (' ', b); // The end of the version.
+
+ optional<semantic_version> ver (
+ parse_semantic_version (string (s, b, e != string::npos ? e - b : e),
+ "" /* build_separators */));
+
+ if (!ver)
+ return nullopt;
+
+ return openssl_info {move (nm), move (*ver)};
+ }
}
cgit v1.1