From 79e064f3843b41f2e1536724d8f607b588389767 Mon Sep 17 00:00:00 2001 From: Miroslav Lisik Date: Thu, 4 Mar 2021 11:50:09 +0100 Subject: [PATCH] Resolves: rhbz#1927404 - Replace pyOpenSSL with python-cryptography --- ...-replace-pyOpenSSL-with-python-crypt.patch | 702 ++++++++++++++++++ ...t-cluster-setup-with-udp-u-transport.patch | 4 +- pcs.spec | 14 +- 3 files changed, 713 insertions(+), 7 deletions(-) create mode 100644 bz1927404-01-replace-pyOpenSSL-with-python-crypt.patch diff --git a/bz1927404-01-replace-pyOpenSSL-with-python-crypt.patch b/bz1927404-01-replace-pyOpenSSL-with-python-crypt.patch new file mode 100644 index 0000000..6f2ad2d --- /dev/null +++ b/bz1927404-01-replace-pyOpenSSL-with-python-crypt.patch @@ -0,0 +1,702 @@ +From 68157f21fe8051ebd7eace11012738d8d91a1812 Mon Sep 17 00:00:00 2001 +From: Tomas Jelinek +Date: Tue, 2 Mar 2021 14:47:27 +0100 +Subject: [PATCH 1/2] squash bz1927404: replace pyOpenSSL with + python-cryptography + +python-cryptography requires new mypy + +improve TLS certificate verification + +Library methods are now used instead of running openssl processes. That +enabled support for Elliptic Curve certificates. + +cleanup dependencies in spec file +--- + .gitlab-ci.yml | 6 +- + README.md | 2 +- + mypy.ini | 7 +- + pcs.spec.in | 5 +- + pcs/common/ssl.py | 108 +++++++++++++++++------------- + pcs/daemon/ssl.py | 48 ++----------- + pcs/pcsd.py | 19 +++--- + pcs/utils.py | 32 --------- + pcs_test/tier0/daemon/test_ssl.py | 64 +++++++++--------- + pcsd/pcs.rb | 39 ++++------- + pcsd/remote.rb | 2 +- + requirements.txt | 2 +- + test/centos8/Dockerfile | 2 +- + test/fedora31/Dockerfile | 2 +- + test/fedora32/Dockerfile | 2 +- + 15 files changed, 135 insertions(+), 205 deletions(-) + +diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml +index 4cb4c14b..72668787 100644 +--- a/.gitlab-ci.yml ++++ b/.gitlab-ci.yml +@@ -46,12 +46,12 @@ pylint: + script: + - "dnf install -y + python3 ++ python3-cryptography + python3-dateutil + python3-distro + python3-lxml + python3-pip + python3-pycurl +- python3-pyOpenSSL + python3-pyparsing + findutils + make +@@ -66,12 +66,12 @@ mypy: + script: + - "dnf install -y + python3 ++ python3-cryptography + python3-dateutil + python3-distro + python3-lxml + python3-pip + python3-pycurl +- python3-pyOpenSSL + python3-pyparsing + git + make +@@ -111,12 +111,12 @@ python_tier0_tests: + - "dnf install -y + make + python3 ++ python3-cryptography + python3-dateutil + python3-distro + python3-lxml + python3-pip + python3-pycurl +- python3-pyOpenSSL + python3-pyparsing + which + " +diff --git a/README.md b/README.md +index fe6eeed6..a0c01c02 100644 +--- a/README.md ++++ b/README.md +@@ -30,7 +30,7 @@ These are the runtime dependencies of pcs and pcsd: + * python3-lxml + * python3-pycurl + * python3-setuptools +-* python3-pyOpenSSL (python3-openssl) ++* python3-cryptography + * python3-pyparsing + * python3-tornado 6.1.0+ + * python dataclasses (`pip install dataclasses`; required only for python 3.6, +diff --git a/mypy.ini b/mypy.ini +index 6d3d2ff9..e3198530 100644 +--- a/mypy.ini ++++ b/mypy.ini +@@ -48,6 +48,10 @@ disallow_untyped_defs = True + # this is a temporary solution for legacy code + disallow_untyped_defs = False + ++[mypy-pcs.common.ssl] ++disallow_untyped_defs = True ++disallow_untyped_calls = True ++ + [mypy-pcs.common.types] + disallow_untyped_defs = True + disallow_untyped_calls = True +@@ -122,9 +126,6 @@ ignore_missing_imports = True + [mypy-distro] + ignore_missing_imports = True + +-[mypy-OpenSSL] +-ignore_missing_imports = True +- + [mypy-pyagentx.*] + ignore_errors = True + +diff --git a/pcs.spec.in b/pcs.spec.in +index db66c5b0..610fad50 100644 +--- a/pcs.spec.in ++++ b/pcs.spec.in +@@ -139,6 +139,7 @@ BuildRequires: python3-setuptools_scm + + BuildRequires: python3-devel + # for tier0 tests ++BuildRequires: python3-cryptography + BuildRequires: python3-pyparsing + + # gcc for compiling custom rubygems +@@ -171,6 +172,7 @@ Requires: platform-python + Requires: platform-python-setuptools + %endif + ++Requires: python3-cryptography + Requires: python3-lxml + Requires: python3-pycurl + Requires: python3-pyparsing +@@ -190,9 +192,6 @@ Requires: ruby >= 2.2.0 + Requires: rubygems + # for killall + Requires: psmisc +-# for working with certificates (validation etc.) +-Requires: openssl +-Requires: python3-pyOpenSSL + # cluster stack and related packages + Requires: pacemaker >= 2.0.0 + Requires: corosync >= 3.0 +diff --git a/pcs/common/ssl.py b/pcs/common/ssl.py +index 852fea80..74ddd4ec 100644 +--- a/pcs/common/ssl.py ++++ b/pcs/common/ssl.py +@@ -1,45 +1,63 @@ +-import time +-from OpenSSL import crypto +- +- +-def cert_date_format(timestamp): +- return str.encode(time.strftime("%Y%m%d%H%M%SZ", time.gmtime(timestamp))) +- +- +-def generate_key(length=3072): +- key = crypto.PKey() +- key.generate_key(crypto.TYPE_RSA, length) +- return key +- +- +-def generate_cert(key, server_name): +- now = time.time() +- cert = crypto.X509() +- +- subject = cert.get_subject() +- subject.countryName = "US" +- subject.stateOrProvinceName = "MN" +- subject.localityName = "Minneapolis" +- subject.organizationName = "pcsd" +- subject.organizationalUnitName = "pcsd" +- subject.commonName = server_name +- +- cert.set_version(2) +- cert.set_serial_number(int(now * 1000)) +- cert.set_notBefore(cert_date_format(now)) +- cert.set_notAfter( +- cert_date_format(now + 60 * 60 * 24 * 365 * 10) +- ) # 10 years +- cert.set_issuer(subject) +- cert.set_pubkey(key) +- cert.sign(key, "sha256") +- +- return cert +- +- +-def dump_cert(certificate): +- return crypto.dump_certificate(crypto.FILETYPE_PEM, certificate) +- +- +-def dump_key(key): +- return crypto.dump_privatekey(crypto.FILETYPE_PEM, key) ++import datetime ++import ssl ++from typing import List ++ ++from cryptography import x509 ++from cryptography.x509.oid import NameOID ++from cryptography.hazmat.backends import default_backend ++from cryptography.hazmat.primitives import hashes, serialization ++from cryptography.hazmat.primitives.asymmetric import rsa ++ ++ ++def check_cert_key(cert_path: str, key_path: str) -> List[str]: ++ errors = [] ++ try: ++ ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) ++ ssl_context.load_cert_chain(cert_path, key_path) ++ except ssl.SSLError as e: ++ errors.append(f"SSL certificate does not match the key: {e}") ++ except EnvironmentError as e: ++ errors.append(f"Unable to load SSL certificate and/or key: {e}") ++ return errors ++ ++ ++def generate_key(length: int = 3072) -> rsa.RSAPrivateKeyWithSerialization: ++ return rsa.generate_private_key( ++ public_exponent=65537, key_size=length, backend=default_backend() ++ ) ++ ++ ++def generate_cert(key: rsa.RSAPrivateKey, server_name: str) -> x509.Certificate: ++ now = datetime.datetime.utcnow() ++ subject = x509.Name( ++ [ ++ x509.NameAttribute(NameOID.COUNTRY_NAME, "US"), ++ x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "MN"), ++ x509.NameAttribute(NameOID.LOCALITY_NAME, "Minneapolis"), ++ x509.NameAttribute(NameOID.ORGANIZATION_NAME, "pcsd"), ++ x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "pcsd"), ++ x509.NameAttribute(NameOID.COMMON_NAME, server_name), ++ ] ++ ) ++ return ( ++ x509.CertificateBuilder() ++ .subject_name(subject) ++ .issuer_name(subject) ++ .public_key(key.public_key()) ++ .serial_number(int(now.timestamp() * 1000)) ++ .not_valid_before(now) ++ .not_valid_after(now + datetime.timedelta(days=3650)) ++ .sign(key, hashes.SHA256(), default_backend()) ++ ) ++ ++ ++def dump_cert(certificate: x509.Certificate) -> bytes: ++ return certificate.public_bytes(serialization.Encoding.PEM) ++ ++ ++def dump_key(key: rsa.RSAPrivateKeyWithSerialization) -> bytes: ++ return key.private_bytes( ++ serialization.Encoding.PEM, ++ serialization.PrivateFormat.TraditionalOpenSSL, ++ serialization.NoEncryption(), ++ ) +diff --git a/pcs/daemon/ssl.py b/pcs/daemon/ssl.py +index 40cca314..43865631 100644 +--- a/pcs/daemon/ssl.py ++++ b/pcs/daemon/ssl.py +@@ -1,9 +1,8 @@ + import os + import ssl + +-from OpenSSL import crypto, SSL +- + from pcs.common.ssl import ( ++ check_cert_key, + dump_cert, + dump_key, + generate_cert, +@@ -11,53 +10,15 @@ from pcs.common.ssl import ( + ) + + +-def check_cert_key(cert_path, key_path): +- errors = [] +- +- def load(load_ssl_file, label, path): +- try: +- with open(path) as ssl_file: +- return load_ssl_file(crypto.FILETYPE_PEM, ssl_file.read()) +- except EnvironmentError as e: +- errors.append(f"Unable to read SSL {label} '{path}': '{e}'") +- except crypto.Error as e: +- msg = "" +- if e.args and e.args[0] and e.args[0][0]: +- msg = f": '{':'.join(e.args[0][0])}'" +- errors.append(f"Invalid SSL {label} '{path}'{msg}") +- +- cert = load(crypto.load_certificate, "certificate", cert_path) +- key = load(crypto.load_privatekey, "key", key_path) +- +- if errors: +- return errors +- +- try: +- context = SSL.Context(SSL.TLSv1_METHOD) +- context.use_privatekey(key) +- context.use_certificate(cert) +- except SSL.Error as e: +- errors.append(f"Unable to load SSL certificate and/or key: {e}") +- # If we cannot load the files, do not confuse users with other error +- # messages. +- return errors +- try: +- context.check_privatekey() +- except (crypto.Error, SSL.Error) as e: +- errors.append(f"SSL certificate does not match the key: {e}") +- +- return errors +- +- +-def open_ssl_file_to_rewrite(path): ++def _open_ssl_file_to_rewrite(path): + return os.fdopen(os.open(path, os.O_CREAT | os.O_WRONLY, 0o600), "wb") + + + def regenerate_cert_key(server_name, cert_path, key_path, key_length=None): + key = generate_key(key_length) if key_length else generate_key() +- with open_ssl_file_to_rewrite(cert_path) as cert_file: ++ with _open_ssl_file_to_rewrite(cert_path) as cert_file: + cert_file.write(dump_cert(generate_cert(key, server_name))) +- with open_ssl_file_to_rewrite(key_path) as key_file: ++ with _open_ssl_file_to_rewrite(key_path) as key_file: + key_file.write(dump_key(key)) + + +@@ -102,7 +63,6 @@ class PcsdSSL: + self.__ck_pair = CertKeyPair(cert_location, key_location) + + def create_context(self) -> ssl.SSLContext: +- # pylint: disable=no-member + ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + ssl_context.set_ciphers(self.__ssl_ciphers) + ssl_context.options = self.__ssl_options +diff --git a/pcs/pcsd.py b/pcs/pcsd.py +index f3e6bca3..d5ddb443 100644 +--- a/pcs/pcsd.py ++++ b/pcs/pcsd.py +@@ -5,6 +5,7 @@ import sys + from pcs import settings + from pcs import utils + from pcs.cli.common.errors import CmdLineInputError ++import pcs.common.ssl + + + def pcsd_certkey(lib, argv, modifiers): +@@ -21,13 +22,13 @@ def pcsd_certkey(lib, argv, modifiers): + keyfile = argv[1] + + try: +- with open(certfile, "r") as myfile: ++ with open(certfile, "rb") as myfile: + cert = myfile.read() +- with open(keyfile, "r") as myfile: ++ with open(keyfile, "rb") as myfile: + key = myfile.read() + except IOError as e: + utils.err(e) +- errors = utils.verify_cert_key_pair(cert, key) ++ errors = pcs.common.ssl.check_cert_key(certfile, keyfile) + if errors: + for err in errors: + utils.err(err, False) +@@ -43,12 +44,12 @@ def pcsd_certkey(lib, argv, modifiers): + + try: + try: +- os.chmod(settings.pcsd_cert_location, 0o700) ++ os.chmod(settings.pcsd_cert_location, 0o600) + except OSError: # If the file doesn't exist, we don't care + pass + + try: +- os.chmod(settings.pcsd_key_location, 0o700) ++ os.chmod(settings.pcsd_key_location, 0o600) + except OSError: # If the file doesn't exist, we don't care + pass + +@@ -56,9 +57,9 @@ def pcsd_certkey(lib, argv, modifiers): + os.open( + settings.pcsd_cert_location, + os.O_WRONLY | os.O_CREAT | os.O_TRUNC, +- 0o700, ++ 0o600, + ), +- "w", ++ "wb", + ) as myfile: + myfile.write(cert) + +@@ -66,9 +67,9 @@ def pcsd_certkey(lib, argv, modifiers): + os.open( + settings.pcsd_key_location, + os.O_WRONLY | os.O_CREAT | os.O_TRUNC, +- 0o700, ++ 0o600, + ), +- "w", ++ "wb", + ) as myfile: + myfile.write(key) + +diff --git a/pcs/utils.py b/pcs/utils.py +index 97a04787..59d1b66e 100644 +--- a/pcs/utils.py ++++ b/pcs/utils.py +@@ -2105,38 +2105,6 @@ def is_iso8601_date(var): + return retVal == 0 + + +-def verify_cert_key_pair(cert, key): +- """ +- Commandline options: no options +- """ +- errors = [] +- cert_modulus = "" +- key_modulus = "" +- +- output, retval = run( +- ["/usr/bin/openssl", "x509", "-modulus", "-noout"], +- string_for_stdin=cert, +- ) +- if retval != 0: +- errors.append("Invalid certificate: {0}".format(output.strip())) +- else: +- cert_modulus = output.strip() +- +- output, retval = run( +- ["/usr/bin/openssl", "rsa", "-modulus", "-noout"], string_for_stdin=key +- ) +- if retval != 0: +- errors.append("Invalid key: {0}".format(output.strip())) +- else: +- key_modulus = output.strip() +- +- if not errors and cert_modulus and key_modulus: +- if cert_modulus != key_modulus: +- errors.append("Certificate does not match the key") +- +- return errors +- +- + def err(errorText, exit_after_error=True): + sys.stderr.write("Error: %s\n" % errorText) + if exit_after_error: +diff --git a/pcs_test/tier0/daemon/test_ssl.py b/pcs_test/tier0/daemon/test_ssl.py +index e80f7a30..2b2edd36 100644 +--- a/pcs_test/tier0/daemon/test_ssl.py ++++ b/pcs_test/tier0/daemon/test_ssl.py +@@ -1,8 +1,7 @@ + import os ++import ssl + from unittest import mock, TestCase + +-from OpenSSL import SSL +- + from pcs_test.tools.misc import get_tmp_dir + + from pcs.daemon.ssl import PcsdSSL, CertKeyPair, SSLCertKeyException +@@ -19,19 +18,6 @@ class SslFilesMixin: + self.ssl_dir = get_tmp_dir("tier0_daemon_ssl") + self.cert_path = os.path.join(self.ssl_dir.name, "daemon.cert") + self.key_path = os.path.join(self.ssl_dir.name, "daemon.key") +- # various versions of OpenSSL / PyOpenSSL emit different messages +- self.DAMAGED_SSL_FILES_ERRORS_1 = ( +- f"Invalid SSL certificate '{self.cert_path}':" +- " 'PEM routines:PEM_read_bio:no start line'", +- f"Invalid SSL key '{self.key_path}':" +- " 'PEM routines:PEM_read_bio:no start line'", +- ) +- self.DAMAGED_SSL_FILES_ERRORS_2 = ( +- f"Invalid SSL certificate '{self.cert_path}':" +- " 'PEM routines:get_name:no start line'", +- f"Invalid SSL key '{self.key_path}':" +- " 'PEM routines:get_name:no start line'", +- ) + + def tearDown(self): + # pylint cannot possibly know this is being mixed into TestCase classes +@@ -56,21 +42,31 @@ class Pair(SslFilesMixin, TestCase): + + def test_error_if_files_with_bad_content(self): + self.damage_ssl_files() +- self.assertTrue( +- self.pair.check() +- in [ +- list(self.DAMAGED_SSL_FILES_ERRORS_1), +- list(self.DAMAGED_SSL_FILES_ERRORS_2), +- ] ++ errors = self.pair.check() ++ self.assertEqual(len(errors), 1) ++ self.assertRegex( ++ errors[0], ++ r"^SSL certificate does not match the key: " ++ r"\[SSL\] PEM lib \(_ssl\.c:\d+\)", + ) + +- @mock.patch("pcs.daemon.ssl.SSL.Context.use_privatekey") +- def test_error_if_short_key(self, mock_use_key): +- mock_use_key.side_effect = SSL.Error("reason") ++ @mock.patch("pcs.daemon.ssl.ssl.SSLContext.load_cert_chain") ++ def test_error_if_short_key(self, mock_load_cert_chain): ++ mock_load_cert_chain.side_effect = ssl.SSLError( ++ # These are the real args of the exception. ++ 336245135, ++ "[SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:3542)", ++ ) ++ # 512 cannot be used as we would get an error from FIPS and 1024 is ++ # long enough. So a mock must be used. + self.pair.regenerate(SERVER_NAME, 1024) + errors = self.pair.check() + self.assertEqual( +- errors, ["Unable to load SSL certificate and/or key: reason"] ++ errors, ++ [ ++ "SSL certificate does not match the key: " ++ "[SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:3542)", ++ ], + ) + + def test_error_if_cert_does_not_match_key(self): +@@ -83,8 +79,10 @@ class Pair(SslFilesMixin, TestCase): + + errors = self.pair.check() + self.assertEqual(len(errors), 1) +- self.assertTrue( +- errors[0].startswith("SSL certificate does not match the key:") ++ self.assertRegex( ++ errors[0], ++ r"SSL certificate does not match the key: " ++ r"\[X509: KEY_VALUES_MISMATCH\] key values mismatch \(_ssl\.c:\d+\)", + ) + + +@@ -102,12 +100,12 @@ class PcsdSSLTest(SslFilesMixin, TestCase): + self.damage_ssl_files() + with self.assertRaises(SSLCertKeyException) as ctx_manager: + self.pcsd_ssl.guarantee_valid_certs() +- self.assertTrue( +- ctx_manager.exception.args +- in [ +- self.DAMAGED_SSL_FILES_ERRORS_1, +- self.DAMAGED_SSL_FILES_ERRORS_2, +- ] ++ errors = ctx_manager.exception.args ++ self.assertEqual(len(errors), 1) ++ self.assertRegex( ++ errors[0], ++ r"SSL certificate does not match the key: " ++ r"\[SSL\] PEM lib \(_ssl\.c:\d+\)", + ) + + def test_context_uses_given_options(self): +diff --git a/pcsd/pcs.rb b/pcsd/pcs.rb +index bce8e39e..89c26f33 100644 +--- a/pcsd/pcs.rb ++++ b/pcsd/pcs.rb +@@ -12,6 +12,7 @@ require 'fileutils' + require 'backports/latest' + require 'base64' + require 'ethon' ++require 'openssl' + + require 'config.rb' + require 'cfgsync.rb' +@@ -1170,39 +1171,23 @@ def read_file_lock(path, binary=false) + end + end + +-def verify_cert_key_pair(cert, key) ++def verify_cert_key_pair(cert_data, key_data) + errors = [] +- cert_modulus = nil +- key_modulus = nil + +- stdout, stderr, retval = run_cmd_options( +- PCSAuth.getSuperuserAuth(), +- { +- 'stdin' => cert, +- }, +- '/usr/bin/openssl', 'x509', '-modulus', '-noout' +- ) +- if retval != 0 +- errors << "Invalid certificate: #{stderr.join}" +- else +- cert_modulus = stdout.join.strip ++ begin ++ cert = OpenSSL::X509::Certificate.new(cert_data) ++ rescue OpenSSL::X509::CertificateError => e ++ errors << "Invalid certificate: #{e}" + end + +- stdout, stderr, retval = run_cmd_options( +- PCSAuth.getSuperuserAuth(), +- { +- 'stdin' => key, +- }, +- '/usr/bin/openssl', 'rsa', '-modulus', '-noout' +- ) +- if retval != 0 +- errors << "Invalid key: #{stderr.join}" +- else +- key_modulus = stdout.join.strip ++ begin ++ key = OpenSSL::PKey.read(key_data) ++ rescue OpenSSL::PKey::PKeyError => e ++ errors << "Invalid key: #{e}" + end + +- if errors.empty? and cert_modulus and key_modulus +- if cert_modulus != key_modulus ++ if errors.empty? ++ if not cert.check_private_key(key) + errors << 'Certificate does not match the key' + end + end +diff --git a/pcsd/remote.rb b/pcsd/remote.rb +index 3361b3f6..c43e3116 100644 +--- a/pcsd/remote.rb ++++ b/pcsd/remote.rb +@@ -694,7 +694,7 @@ def set_certs(params, request, auth_user) + if !ssl_cert.empty? and !ssl_key.empty? + ssl_errors = verify_cert_key_pair(ssl_cert, ssl_key) + if ssl_errors and !ssl_errors.empty? +- return [400, ssl_errors.join] ++ return [400, ssl_errors.join('; ')] + end + begin + write_file_lock(CRT_FILE, 0600, ssl_cert) +diff --git a/requirements.txt b/requirements.txt +index eb42ce40..2f62b1c3 100644 +--- a/requirements.txt ++++ b/requirements.txt +@@ -2,7 +2,7 @@ + astroid==2.4.2 + pylint==2.6.0 + tornado>=6.1.0 +-mypy==0.790 ++mypy==0.812 + dacite + # temporarily stick to previous version until it's convinient to reformat code + black==20.8b1 +diff --git a/test/centos8/Dockerfile b/test/centos8/Dockerfile +index 910d7652..00c17ffe 100644 +--- a/test/centos8/Dockerfile ++++ b/test/centos8/Dockerfile +@@ -7,11 +7,11 @@ RUN dnf install -y \ + --enablerepo=PowerTools \ + # python + python3 \ ++ python3-cryptography \ + python3-lxml \ + python3-mock \ + python3-pip \ + python3-pycurl \ +- python3-pyOpenSSL \ + python3-pyparsing \ + # ruby + ruby \ +diff --git a/test/fedora31/Dockerfile b/test/fedora31/Dockerfile +index cc94bee2..8d0a0672 100644 +--- a/test/fedora31/Dockerfile ++++ b/test/fedora31/Dockerfile +@@ -5,11 +5,11 @@ ARG src_path + RUN dnf install -y \ + # python + python3 \ ++ python3-cryptography \ + python3-lxml \ + python3-mock \ + python3-pip \ + python3-pycurl \ +- python3-pyOpenSSL \ + python3-pyparsing \ + # ruby + ruby \ +diff --git a/test/fedora32/Dockerfile b/test/fedora32/Dockerfile +index 82bdff74..750ff979 100644 +--- a/test/fedora32/Dockerfile ++++ b/test/fedora32/Dockerfile +@@ -5,12 +5,12 @@ ARG src_path + RUN dnf install -y \ + # python + python3 \ ++ python3-cryptography \ + python3-distro \ + python3-lxml \ + python3-mock \ + python3-pip \ + python3-pycurl \ +- python3-pyOpenSSL \ + python3-pyparsing \ + # ruby + ruby \ +-- +2.26.2 + diff --git a/do-not-support-cluster-setup-with-udp-u-transport.patch b/do-not-support-cluster-setup-with-udp-u-transport.patch index a0a7aab..db65252 100644 --- a/do-not-support-cluster-setup-with-udp-u-transport.patch +++ b/do-not-support-cluster-setup-with-udp-u-transport.patch @@ -1,7 +1,7 @@ -From ab9fd9f223e805247319ac5a7318c15417197a0a Mon Sep 17 00:00:00 2001 +From 6c96d0fd135ca25204efeb5cb75e80053b26c6b1 Mon Sep 17 00:00:00 2001 From: Ivan Devat Date: Tue, 20 Nov 2018 15:03:56 +0100 -Subject: [PATCH] do not support cluster setup with udp(u) transport +Subject: [PATCH 2/2] do not support cluster setup with udp(u) transport --- pcs/pcs.8 | 2 ++ diff --git a/pcs.spec b/pcs.spec index 49c8a5f..f36c1af 100644 --- a/pcs.spec +++ b/pcs.spec @@ -1,6 +1,6 @@ Name: pcs Version: 0.10.8 -Release: 2%{?dist} +Release: 3%{?dist} # https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/ # https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#Good_Licenses # GPLv2: pcs @@ -121,6 +121,7 @@ Source101: https://github.com/idevat/pcs-web-ui/releases/download/%{ui_modules_v # Z-streams are exception here: they can come from upstream but should be # applied at the end to keep z-stream changes as straightforward as possible. # Patch1: bzNUMBER-01-name.patch +Patch1: bz1927404-01-replace-pyOpenSSL-with-python-crypt.patch # Downstream patches do not come from upstream. They adapt pcs for specific # RHEL needs. @@ -132,6 +133,7 @@ BuildRequires: git-core BuildRequires: coreutils # python for pcs BuildRequires: python3 >= 3.6 +BuildRequires: python3-cryptography BuildRequires: python3-dateutil >= 2.7.0 BuildRequires: python3-devel BuildRequires: python3-setuptools @@ -152,7 +154,6 @@ BuildRequires: diffstat BuildRequires: systemd # for tests BuildRequires: python3-lxml -BuildRequires: python3-pyOpenSSL # pcsd fonts and font management tools for creating symlinks to fonts BuildRequires: fontconfig BuildRequires: liberation-sans-fonts @@ -166,6 +167,7 @@ BuildRequires: npm # python and libraries for pcs, setuptools for pcs entrypoint Requires: python3 >= 3.6 +Requires: python3-cryptography Requires: python3-dateutil >= 2.7.0 Requires: python3-lxml Requires: python3-setuptools @@ -176,9 +178,6 @@ Requires: ruby >= 2.2.0 Requires: rubygems # for killall Requires: psmisc -# for working with certificates (validation etc.) -Requires: openssl -Requires: python3-pyOpenSSL # cluster stack and related packages Requires: pcmk-cluster-manager >= 2.0.0 Suggests: pacemaker @@ -296,6 +295,7 @@ update_times_patch(){ } # update_times_patch %%{PATCH1} +update_times_patch %{PATCH1} update_times_patch %{PATCH101} cp -f %SOURCE1 pcsd/public/images @@ -625,6 +625,10 @@ remove_all_tests %license pyagentx_LICENSE.txt %changelog +* Thu Mar 04 2021 Miroslav Lisik - 0.10.8-3 +- Replace pyOpenSSL with python-cryptography +- Resolves: rhbz#1927404 + * Fri Feb 19 2021 Miroslav Lisik - 0.10.8-2 - Bundle rubygem depedencies and python3-tornado - Resolves: rhbz#1929710