Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package salt for openSUSE:Factory checked in 
at 2025-11-11 19:19:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/salt (Old)
 and      /work/SRC/openSUSE:Factory/.salt.new.1980 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "salt"

Tue Nov 11 19:19:40 2025 rev:186 rq:1317046 version:3006.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/salt/salt.changes        2025-10-31 
16:28:14.454351074 +0100
+++ /work/SRC/openSUSE:Factory/.salt.new.1980/salt.changes      2025-11-11 
19:19:51.455755964 +0100
@@ -1,0 +2,25 @@
+Tue Nov 11 08:02:12 UTC 2025 - Marek Czernek <[email protected]>
+
+- Fix TLS and x509 modules for OSes with older cryptography module
+- Require python-legacy-cgi only for Python > 3.12
+
+- Added:
+  * fix-tls-and-x509-modules-for-older-cryptography-modu.patch
+
+-------------------------------------------------------------------
+Mon Nov 10 09:46:28 UTC 2025 - Marek Czernek <[email protected]>
+
+- Builds with py >=3.13 require python-legacy-cgi
+
+-------------------------------------------------------------------
+Fri Nov  7 16:36:10 UTC 2025 - Pablo Suárez Hernández 
<[email protected]>
+
+- Fix Salt for Python > 3.11 (bsc#1252285) (bsc#1252244)
+  * Use external tornado on Python > 3.11
+  * Make tls and x509 to use python-cryptography
+  * Remove usage of spwd
+
+- Added:
+  * fix-salt-for-python-3.11.patch
+
+-------------------------------------------------------------------

New:
----
  fix-salt-for-python-3.11.patch
  fix-tls-and-x509-modules-for-older-cryptography-modu.patch

----------(New B)----------
  New:- Added:
  * fix-salt-for-python-3.11.patch
  New:- Added:
  * fix-tls-and-x509-modules-for-older-cryptography-modu.patch
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ salt.spec ++++++
--- /var/tmp/diff_new_pack.gmQ60X/_old  2025-11-11 19:20:00.644140801 +0100
+++ /var/tmp/diff_new_pack.gmQ60X/_new  2025-11-11 19:20:00.648140969 +0100
@@ -587,6 +587,10 @@
 Patch184:       use-versioned-python-interpreter-for-salt-ssh.patch
 # PATCH-FIX_OPENSUSE: https://github.com/openSUSE/salt/pull/735
 Patch185:       do-not-break-signature-verification-on-latest-m2cryp.patch
+# PATCH-FIX_OPENSUSE: https://github.com/openSUSE/salt/pull/736
+Patch186:       fix-salt-for-python-3.11.patch
+# PATCH-FIX_OPENSUSE: https://github.com/openSUSE/salt/pull/737
+Patch187:       fix-tls-and-x509-modules-for-older-cryptography-modu.patch
 
 ### IMPORTANT: The line below is used as a snippet marker. Do not touch it.
 ### SALT PATCHES LIST END
@@ -790,6 +794,7 @@
 Requires:       %{python_module looseversion}
 Requires:       %{python_module packaging}
 Requires:       %{python_module contextvars}
+Requires:       %{python_module cryptography}
 %if 0%{?suse_version}
 # required for zypper.py
 Requires:       %{python_module rpm}
@@ -807,6 +812,7 @@
 Requires:       python-looseversion
 Requires:       python-packaging
 Requires:       python-contextvars
+Requires:       python-cryptography
 %if 0%{?suse_version}
 # required for zypper.py
 Requires:       python-rpm
@@ -847,11 +853,18 @@
 Recommends:     python-passlib
 %endif
 
+%if 0%{?suse_version} >= 1600
+Requires:       %{python_module tornado}
+%if 0%{?python3_version_nodots} > 312
+Requires:       %{python_module legacy-cgi}
+%endif
+%else
 %if 0%{?singlespec_compat}
 Provides:       bundled(%{python_module tornado}) = 4.5.3
 %else
 Provides:       bundled(python-tornado) = 4.5.3
 %endif
+%endif
 
 Provides:       %{name}-call = %{version}-%{release}
 

++++++ _lastrevision ++++++
--- /var/tmp/diff_new_pack.gmQ60X/_old  2025-11-11 19:20:00.760145660 +0100
+++ /var/tmp/diff_new_pack.gmQ60X/_new  2025-11-11 19:20:00.764145827 +0100
@@ -1,3 +1,3 @@
-1fc2dab7f7a83e75c56d06f805cf5dcc25d165cc
+c51b56faa8acda43ec37dad57a26fda6303179cf
 (No newline at EOF)
 

++++++ fix-salt-for-python-3.11.patch ++++++
++++ 6675 lines (skipped)

++++++ fix-tls-and-x509-modules-for-older-cryptography-modu.patch ++++++
>From 7f15657c26c4e5e9fabc72f4da2d9a91353d5d3a Mon Sep 17 00:00:00 2001
From: Marek Czernek <[email protected]>
Date: Tue, 11 Nov 2025 08:46:20 +0100
Subject: [PATCH] Fix tls and x509 modules for older cryptography
 module (#737)

---
 salt/modules/tls.py  |  73 +++++++++++++++++-------
 salt/modules/x509.py | 128 +++++++++++++++++++++++++++++++++++--------
 2 files changed, 158 insertions(+), 43 deletions(-)

diff --git a/salt/modules/tls.py b/salt/modules/tls.py
index 9d29bd1e9b..4d7db87f93 100644
--- a/salt/modules/tls.py
+++ b/salt/modules/tls.py
@@ -104,6 +104,7 @@ import logging
 import math
 import os
 import re
+import sys
 import time
 from datetime import datetime
 
@@ -1594,6 +1595,9 @@ def create_pkcs12(ca_name, CN, passphrase="", 
cacert_path=None, replace=False):
 
         salt '*' tls.create_pkcs12 test localhost
     """
+    # Necessary for OSes with older cryptography module
+    compat_mode = sys.version_info < (3,12)
+
     set_ca_path(cacert_path)
     p12_path = f"{cert_base_path()}/{ca_name}/certs/{CN}.p12"
     ca_cert_path = f"{cert_base_path()}/{ca_name}/{ca_name}_ca_cert.crt"
@@ -1605,7 +1609,12 @@ def create_pkcs12(ca_name, CN, passphrase="", 
cacert_path=None, replace=False):
 
     try:
         with salt.utils.files.fopen(ca_cert_path, "rb") as fhr:
-            ca_cert = cryptography.x509.load_pem_x509_certificate(fhr.read())
+            if compat_mode:
+                ca_cert = OpenSSL.crypto.load_certificate(
+                    OpenSSL.crypto.FILETYPE_PEM, fhr.read()
+                )
+            else:
+                ca_cert = 
cryptography.x509.load_pem_x509_certificate(fhr.read())
     except OSError:
         return 'There is no CA named "{}"'.format(ca_name)
     except ValueError as e:
@@ -1613,34 +1622,58 @@ def create_pkcs12(ca_name, CN, passphrase="", 
cacert_path=None, replace=False):
 
     try:
         with salt.utils.files.fopen(cert_path, "rb") as fhr:
-            cert = cryptography.x509.load_pem_x509_certificate(fhr.read())
+            if compat_mode:
+                cert = OpenSSL.crypto.load_certificate(
+                    OpenSSL.crypto.FILETYPE_PEM, fhr.read()
+                )
+            else:
+                cert = cryptography.x509.load_pem_x509_certificate(fhr.read())
         with salt.utils.files.fopen(priv_key_path, "rb") as fhr:
-            key = cryptography_serialization.load_pem_private_key(
-                fhr.read(),
-                password=None,
-            )
+            if compat_mode:
+                key = OpenSSL.crypto.load_privatekey(
+                    OpenSSL.crypto.FILETYPE_PEM, fhr.read()
+                )
+            else:
+                key = cryptography_serialization.load_pem_private_key(
+                    fhr.read(),
+                    password=None,
+                )
     except OSError:
         return 'There is no certificate that matches the CN "{}"'.format(CN)
     except ValueError as e:
         return f'Could not load certificate {cert_path}: {e}'
 
-    if passphrase:
-        encryption_algorithm = 
cryptography_serialization.BestAvailableEncryption(
-            salt.utils.stringutils.to_bytes(passphrase)
-        )
+    if compat_mode:
+        pkcs12 = OpenSSL.crypto.PKCS12()
+
+        pkcs12.set_certificate(cert)
+        pkcs12.set_ca_certificates([ca_cert])
+        pkcs12.set_privatekey(key)
+
+        with salt.utils.files.fopen(
+            "{}/{}/certs/{}.p12".format(cert_base_path(), ca_name, CN), "wb"
+        ) as ofile:
+            ofile.write(
+                
pkcs12.export(passphrase=salt.utils.stringutils.to_bytes(passphrase))
+            )
     else:
-        encryption_algorithm = cryptography_serialization.NoEncryption()
+        if passphrase:
+            encryption_algorithm = 
cryptography_serialization.BestAvailableEncryption(
+                salt.utils.stringutils.to_bytes(passphrase)
+            )
+        else:
+            encryption_algorithm = cryptography_serialization.NoEncryption()
 
-    pkcs12 = cryptography_pkcs12.serialize_key_and_certificates(
-        name=salt.utils.stringutils.to_bytes(CN),
-        key=key,
-        cert=cert,
-        cas=[ca_cert],
-        encryption_algorithm=encryption_algorithm,
-    )
+        pkcs12 = cryptography_pkcs12.serialize_key_and_certificates(
+            name=salt.utils.stringutils.to_bytes(CN),
+            key=key,
+            cert=cert,
+            cas=[ca_cert],
+            encryption_algorithm=encryption_algorithm,
+        )
 
-    with salt.utils.files.fopen(p12_path, "wb") as ofile:
-        ofile.write(pkcs12)
+        with salt.utils.files.fopen(p12_path, "wb") as ofile:
+            ofile.write(pkcs12)
 
     return 'Created PKCS#12 Certificate for "{0}": 
"{1}/{2}/certs/{0}.p12"'.format(
         CN,
diff --git a/salt/modules/x509.py b/salt/modules/x509.py
index 164541fc76..373e394856 100644
--- a/salt/modules/x509.py
+++ b/salt/modules/x509.py
@@ -32,16 +32,20 @@ import tempfile
 
 import salt.exceptions
 import salt.utils.data
-import salt.utils.dictupdate
 import salt.utils.files
 import salt.utils.path
 import salt.utils.platform
 import salt.utils.stringutils
 import salt.utils.versions
-import salt.utils.x509 as x509util
 from salt.state import STATE_INTERNAL_KEYWORDS as _STATE_INTERNAL_KEYWORDS
 from salt.utils.odict import OrderedDict
 
+# Necessary for OSes with older cryptography module
+COMPAT_MODE = sys.version_info < (3,12)
+if not COMPAT_MODE:
+    import salt.utils.dictupdate
+    import salt.utils.x509 as x509util
+
 try:
     import M2Crypto
 
@@ -988,35 +992,113 @@ def create_crl(
 
     if revoked is None:
         revoked = []
+    if COMPAT_MODE:
+        crl = OpenSSL.crypto.CRL()
+        for rev_item in revoked:
+            if "certificate" in rev_item:
+                rev_cert = read_certificate(rev_item["certificate"])
+                rev_item["serial_number"] = rev_cert["Serial Number"]
+                rev_item["not_after"] = rev_cert["Not After"]
 
-    for rev_item in revoked:
-        if "reason" in rev_item:
-            salt.utils.dictupdate.set_dict_key_value(
-                rev_item, "extensions:CRLReason", rev_item["reason"]
+            serial_number = rev_item["serial_number"].replace(":", "")
+            # OpenSSL bindings requires this to be a non-unicode string
+            serial_number = salt.utils.stringutils.to_bytes(serial_number)
+
+            if "not_after" in rev_item and not include_expired:
+                not_after = datetime.datetime.strptime(
+                    rev_item["not_after"], "%Y-%m-%d %H:%M:%S"
+                )
+                if datetime.datetime.now() > not_after:
+                    continue
+
+            if "revocation_date" not in rev_item:
+                rev_item["revocation_date"] = datetime.datetime.now().strftime(
+                    "%Y-%m-%d %H:%M:%S"
+                )
+
+            rev_date = datetime.datetime.strptime(
+                rev_item["revocation_date"], "%Y-%m-%d %H:%M:%S"
             )
+            rev_date = rev_date.strftime("%Y%m%d%H%M%SZ")
+            rev_date = salt.utils.stringutils.to_bytes(rev_date)
 
-    builder, private_key_obj = x509util.build_crl(
-        signing_private_key=signing_private_key,
-        signing_private_key_passphrase=signing_private_key_passphrase,
-        include_expired=include_expired,
-        revoked=revoked,
-        signing_cert=signing_cert,
-        days_valid=days_valid,
-    )
+            rev = OpenSSL.crypto.Revoked()
+            rev.set_serial(salt.utils.stringutils.to_bytes(serial_number))
+            rev.set_rev_date(salt.utils.stringutils.to_bytes(rev_date))
+
+            if "reason" in rev_item:
+                # Same here for OpenSSL bindings and non-unicode strings
+                reason = salt.utils.stringutils.to_bytes(rev_item["reason"])
+                rev.set_reason(reason)
+
+            crl.add_revoked(rev)
+
+        signing_cert = _text_or_file(signing_cert)
+        cert = OpenSSL.crypto.load_certificate(
+            OpenSSL.crypto.FILETYPE_PEM, get_pem_entry(signing_cert, 
pem_type="CERTIFICATE")
+        )
+        signing_private_key = _get_private_key_obj(
+            signing_private_key, passphrase=signing_private_key_passphrase
+        ).as_pem(cipher=None)
+        key = OpenSSL.crypto.load_privatekey(
+            OpenSSL.crypto.FILETYPE_PEM, get_pem_entry(signing_private_key)
+        )
+
+        export_kwargs = {
+            "cert": cert,
+            "key": key,
+            "type": OpenSSL.crypto.FILETYPE_PEM,
+            "days": days_valid,
+        }
+        if digest:
+            export_kwargs["digest"] = salt.utils.stringutils.to_bytes(digest)
+        else:
+            log.warning("No digest specified. The default md5 digest will be 
used.")
+
+        try:
+            crltext = crl.export(**export_kwargs)
+        except (TypeError, ValueError):
+            log.warning(
+                "Error signing crl with specified digest. Are you using "
+                "pyopenssl 0.15 or newer? The default md5 digest will be used."
+            )
+            export_kwargs.pop("digest", None)
+            crltext = crl.export(**export_kwargs)
+
+        if text:
+            return crltext
+
+        return write_pem(text=crltext, path=path, pem_type="X509 CRL")
 
-    if digest:
-        hashing_algorithm = x509util.get_hashing_algorithm(digest)
     else:
-        log.warning("No digest specified. The default md5 digest will be 
used.")
-        hashing_algorithm = x509util.get_hashing_algorithm("MD5")
+        for rev_item in revoked:
+            if "reason" in rev_item:
+                salt.utils.dictupdate.set_dict_key_value(
+                    rev_item, "extensions:CRLReason", rev_item["reason"]
+                )
 
-    crl = builder.sign(private_key_obj, algorithm=hashing_algorithm)
-    crl_bytes = crl.public_bytes(x509util.serialization.Encoding.PEM)
+        builder, private_key_obj = x509util.build_crl(
+            signing_private_key=signing_private_key,
+            signing_private_key_passphrase=signing_private_key_passphrase,
+            include_expired=include_expired,
+            revoked=revoked,
+            signing_cert=signing_cert,
+            days_valid=days_valid,
+        )
 
-    if text:
-        return crl_bytes.decode()
+        if digest:
+            hashing_algorithm = x509util.get_hashing_algorithm(digest)
+        else:
+            log.warning("No digest specified. The default md5 digest will be 
used.")
+            hashing_algorithm = x509util.get_hashing_algorithm("MD5")
 
-    return write_pem(text=crl_bytes, path=path, pem_type="X509 CRL")
+        crl = builder.sign(private_key_obj, algorithm=hashing_algorithm)
+        crl_bytes = crl.public_bytes(x509util.serialization.Encoding.PEM)
+
+        if text:
+            return crl_bytes.decode()
+
+        return write_pem(text=crl_bytes, path=path, pem_type="X509 CRL")
 
 
 def sign_remote_certificate(argdic, **kwargs):
-- 
2.51.1

Reply via email to