Hello community,

here is the log from the commit of package python-pure-sasl for 
openSUSE:Leap:15.2 checked in at 2020-03-09 18:10:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:15.2/python-pure-sasl (Old)
 and      /work/SRC/openSUSE:Leap:15.2/.python-pure-sasl.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pure-sasl"

Mon Mar  9 18:10:47 2020 rev:15 rq:776942 version:0.6.2

Changes:
--------
--- /work/SRC/openSUSE:Leap:15.2/python-pure-sasl/python-pure-sasl.changes      
2020-01-15 15:51:43.535538828 +0100
+++ 
/work/SRC/openSUSE:Leap:15.2/.python-pure-sasl.new.26092/python-pure-sasl.changes
   2020-03-09 18:10:48.193148197 +0100
@@ -1,0 +2,31 @@
+Mon Oct 21 23:24:32 UTC 2019 - Martin Herkt <[email protected]>
+
+- Update to 0.6.2
+  * Fix GSSAPI wrapping using in Python 3
+
+-------------------------------------------------------------------
+Fri Feb 22 04:57:47 UTC 2019 - Martin Herkt <[email protected]>
+
+- Update to 0.6.1 (no relevant changes in changelog)
+
+-------------------------------------------------------------------
+Thu Dec  6 10:21:35 UTC 2018 - MichaƂ Rostecki <[email protected]>
+
+- Switch from python-pykerberos to python-kerberos. Pykerberos as
+  a fork is no longer developed and the work on upstream has
+  resumed.
+
+-------------------------------------------------------------------
+Tue Dec  4 12:51:50 UTC 2018 - Matej Cepl <[email protected]>
+
+- Remove superfluous devel dependency for noarch package
+
+-------------------------------------------------------------------
+Sat May 19 11:34:20 UTC 2018 - [email protected]
+
+- Update to 0.5.1
+  * Fixes for DIGEST-MD5, server auth has been completed and is now
+    tested
+  * Both DIGEST-MD5 and CRAM-MD5 properly set the complete flag now
+
+-------------------------------------------------------------------

Old:
----
  pure-sasl-0.5.0.tar.gz

New:
----
  pure-sasl-0.6.2.tar.gz

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

Other differences:
------------------
++++++ python-pure-sasl.spec ++++++
--- /var/tmp/diff_new_pack.Q09iO3/_old  2020-03-09 18:10:48.477148604 +0100
+++ /var/tmp/diff_new_pack.Q09iO3/_new  2020-03-09 18:10:48.477148604 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-pure-sasl
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -12,25 +12,24 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %bcond_without test
 Name:           python-pure-sasl
-Version:        0.5.0
+Version:        0.6.2
 Release:        0
 Summary:        Pure Python client SASL implementation
 License:        MIT
 Group:          Development/Languages/Python
 Url:            http://github.com/thobbs/pure-sasl
 Source:         
https://files.pythonhosted.org/packages/source/p/pure-sasl/pure-sasl-%{version}.tar.gz
-BuildRequires:  %{python_module devel}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
-Requires:       python-pykerberos
+Requires:       python-kerberos
 BuildArch:      noarch
 %python_subpackages
 

++++++ pure-sasl-0.5.0.tar.gz -> pure-sasl-0.6.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pure-sasl-0.5.0/CHANGES.rst 
new/pure-sasl-0.6.2/CHANGES.rst
--- old/pure-sasl-0.5.0/CHANGES.rst     2018-03-09 06:04:26.000000000 +0100
+++ new/pure-sasl-0.6.2/CHANGES.rst     2019-10-14 23:40:23.000000000 +0200
@@ -1,3 +1,33 @@
+0.6.2
+=====
+October 14th, 2019
+
+* Fix GSSAPI wrapping using in Python 3 (#31)
+* Remove Python 2.6 from testing matrix
+
+0.6.1
+=====
+February 21st, 2019
+
+* Import platform in setup.py
+
+0.6.0
+=====
+February 21st, 2019
+
+* Add support for Windows via winkerberos (#30)
+
+Thanks to @ryan-pip for this release
+
+0.5.1
+=====
+May 18th, 2018
+
+* Fixes for DIGEST-MD5, server auth has been completed and is now tested
+* Both DIGEST-MD5 and CRAM-MD5 properly set the complete flag now
+
+Thanks to @ceache and @bjmb for this release
+
 0.5.0
 =====
 March 8th, 2018
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pure-sasl-0.5.0/PKG-INFO new/pure-sasl-0.6.2/PKG-INFO
--- old/pure-sasl-0.5.0/PKG-INFO        2018-03-09 06:09:02.000000000 +0100
+++ new/pure-sasl-0.6.2/PKG-INFO        2019-10-14 23:43:53.000000000 +0200
@@ -1,10 +1,12 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
 Name: pure-sasl
-Version: 0.5.0
+Version: 0.6.2
 Summary: Pure Python client SASL implementation
 Home-page: http://github.com/thobbs/pure-sasl
-Author: Alex Shafer
-Author-email: [email protected]
+Author: Tyler Hobbs
+Author-email: [email protected]
+Maintainer: Alex Shafer
+Maintainer-email: [email protected]
 License: MIT
 Description: This package provides a reasonably high-level SASL client written
         in pure Python.  New mechanisms may be integrated easily, but by 
default,
@@ -24,3 +26,4 @@
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Provides-Extra: GSSAPI
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pure-sasl-0.5.0/pure_sasl.egg-info/PKG-INFO 
new/pure-sasl-0.6.2/pure_sasl.egg-info/PKG-INFO
--- old/pure-sasl-0.5.0/pure_sasl.egg-info/PKG-INFO     2018-03-09 
06:09:02.000000000 +0100
+++ new/pure-sasl-0.6.2/pure_sasl.egg-info/PKG-INFO     2019-10-14 
23:43:53.000000000 +0200
@@ -1,10 +1,12 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
 Name: pure-sasl
-Version: 0.5.0
+Version: 0.6.2
 Summary: Pure Python client SASL implementation
 Home-page: http://github.com/thobbs/pure-sasl
-Author: Alex Shafer
-Author-email: [email protected]
+Author: Tyler Hobbs
+Author-email: [email protected]
+Maintainer: Alex Shafer
+Maintainer-email: [email protected]
 License: MIT
 Description: This package provides a reasonably high-level SASL client written
         in pure Python.  New mechanisms may be integrated easily, but by 
default,
@@ -24,3 +26,4 @@
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Provides-Extra: GSSAPI
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pure-sasl-0.5.0/puresasl/__init__.py 
new/pure-sasl-0.6.2/puresasl/__init__.py
--- old/pure-sasl-0.5.0/puresasl/__init__.py    2018-03-09 06:04:26.000000000 
+0100
+++ new/pure-sasl-0.6.2/puresasl/__init__.py    2019-10-14 23:40:47.000000000 
+0200
@@ -1,5 +1,5 @@
-__version__ = '0.5.0'
-__version_info__ = (0, 5, 0)
+__version__ = '0.6.2'
+__version_info__ = (0, 6, 2)
 
 
 class SASLError(Exception):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pure-sasl-0.5.0/puresasl/mechanisms.py 
new/pure-sasl-0.6.2/puresasl/mechanisms.py
--- old/pure-sasl-0.5.0/puresasl/mechanisms.py  2018-03-09 06:03:17.000000000 
+0100
+++ new/pure-sasl-0.6.2/puresasl/mechanisms.py  2019-10-14 23:38:05.000000000 
+0200
@@ -4,6 +4,7 @@
 import random
 import struct
 import sys
+import platform
 
 from puresasl import SASLError, SASLProtocolException, QOP
 
@@ -13,6 +14,15 @@
 except ImportError:
     have_kerberos = False
 
+if platform.system() == 'Windows':
+    try:
+        import winkerberos as kerberos
+        # Fix for different capitalisation in winkerberos method name
+        kerberos.authGSSClientUserName = kerberos.authGSSClientUsername
+        have_kerberos = True
+    except ImportError:
+        have_kerberos = False
+
 PY3 = sys.version_info[0] == 3
 if PY3:
     def _b(s):
@@ -210,15 +220,17 @@
         self._fetch_properties('username', 'password')
         mac = hmac.HMAC(key=_b(self.password), digestmod=hashlib.md5)
         mac.update(challenge)
+        self.complete = True
         return b''.join((_b(self.username), b' ', _b(mac.hexdigest())))
 
     def dispose(self):
         self.password = None
 
 
-# functions used in DigestMD5 which were originally defined in the now-removed 
util module
+# functions used in DigestMD5 which were originally defined in the now-removed
+# util module
 
-def bytes(text):
+def to_bytes(text):
     """
     Convert Unicode text to UTF-8 encoded bytes.
 
@@ -250,7 +262,7 @@
 
     :param text: A Unicode or byte string.
     """
-    text = bytes(text)
+    text = to_bytes(text)
     return b'"' + text.replace(b'\\', b'\\\\').replace(b'"', b'\\"') + b'"'
 
 
@@ -267,12 +279,10 @@
         self.username = username
         self.password = password
 
-        self._rspauth_okay = False
         self._digest_uri = None
         self._a1 = None
 
     def dispose(self):
-        self._rspauth_okay = None
         self._digest_uri = None
         self._a1 = None
 
@@ -301,16 +311,16 @@
         if getattr(self, 'realm', None) is not None:
             resp['realm'] = quote(self.realm)
 
-        resp['username'] = quote(bytes(self.username))
+        resp['username'] = quote(to_bytes(self.username))
         resp['nonce'] = quote(self.nonce)
         if self.nc == 0:
-            self.cnonce = bytes('%s' % random.random())[2:]
+            self.cnonce = to_bytes('%s' % random.random())[2:]
         resp['cnonce'] = quote(self.cnonce)
         self.nc += 1
-        resp['nc'] = bytes('%08x' % self.nc)
+        resp['nc'] = to_bytes('%08x' % self.nc)
 
         self._digest_uri = (
-            bytes(self.sasl.service) + b'/' + bytes(self.sasl.host))
+                to_bytes(self.sasl.service) + b'/' + to_bytes(self.sasl.host))
         resp['digest-uri'] = quote(self._digest_uri)
 
         a2 = b'AUTHENTICATE:' + self._digest_uri
@@ -318,29 +328,43 @@
             a2 += b':00000000000000000000000000000000'
             resp['maxbuf'] = b'16777215'  # 2**24-1
         resp['response'] = self.gen_hash(a2)
-        return b','.join([bytes(k) + b'=' + bytes(v) for k, v in resp.items()])
+        return b','.join(
+            [
+                to_bytes(k) + b'=' + to_bytes(v)
+                for k, v in resp.items()
+            ]
+        )
 
     @staticmethod
     def parse_challenge(challenge):
+        """Parse a digest challenge message.
+
+        :param ``bytes`` challenge:
+            Challenge message from the server, in bytes.
+        :returns:
+            ``dict`` of ``str`` keyword to ``bytes`` values.
+        """
         ret = {}
-        var = ''
-        val = ''
+        var = b''
+        val = b''
         in_var = True
         in_quotes = False
         new = False
         escaped = False
         for c in challenge:
+            if sys.version_info[0] == 3:
+                c = to_bytes([c])
             if in_var:
                 if c.isspace():
                     continue
-                if c == '=':
+                if c == b'=':
                     in_var = False
                     new = True
                 else:
                     var += c
             else:
                 if new:
-                    if c == '"':
+                    if c == b'"':
                         in_quotes = True
                     else:
                         val += c
@@ -350,31 +374,31 @@
                         escaped = False
                         val += c
                     else:
-                        if c == '\\':
+                        if c == b'\\':
                             escaped = True
-                        elif c == '"':
+                        elif c == b'"':
                             in_quotes = False
                         else:
                             val += c
                 else:
-                    if c == ',':
+                    if c == b',':
                         if var:
-                            ret[var] = bytes(val)
-                        var = ''
-                        val = ''
+                            ret[var.decode('ascii')] = val
+                        var = b''
+                        val = b''
                         in_var = True
                     else:
                         val += c
         if var:
-            ret[var] = val
+            ret[var.decode('ascii')] = val
         return ret
 
     def gen_hash(self, a2):
         if not getattr(self, 'key_hash', None):
             key_hash = hashlib.md5()
-            user = bytes(self.username)
-            password = bytes(self.password)
-            realm = bytes(self.realm)
+            user = to_bytes(self.username)
+            password = to_bytes(self.password)
+            realm = to_bytes(self.realm)
             kh = user + b':' + realm + b':' + password
             key_hash.update(kh)
             self.key_hash = key_hash.digest()
@@ -384,22 +408,21 @@
         a1.update(a1h)
         response = hashlib.md5()
         self._a1 = a1.digest()
-        rv = bytes(a1.hexdigest().lower())
+        rv = to_bytes(a1.hexdigest().lower())
         rv += b':' + self.nonce
-        rv += b':' + bytes('%08x' % self.nc)
+        rv += b':' + to_bytes('%08x' % self.nc)
         rv += b':' + self.cnonce
         rv += b':' + self.qop
-        rv += b':' + bytes(hashlib.md5(a2).hexdigest().lower())
+        rv += b':' + to_bytes(hashlib.md5(a2).hexdigest().lower())
         response.update(rv)
-        return bytes(response.hexdigest().lower())
+        return to_bytes(response.hexdigest().lower())
 
-    # untested
     def authenticate_server(self, cmp_hash):
         a2 = b':' + self._digest_uri
         if self.qop != QOP.AUTH:
             a2 += b':00000000000000000000000000000000'
-        if self.gen_hash(a2) == cmp_hash:
-            self._rspauth_okay = True
+        if self.gen_hash(a2) != cmp_hash:
+            raise SASLProtocolException('Invalid server auth response')
 
     def process(self, challenge=None):
         if challenge is None:
@@ -411,28 +434,42 @@
                 return None
 
         challenge_dict = DigestMD5Mechanism.parse_challenge(challenge)
-        if self.sasl.mutual_auth and 'rspauth' in challenge_dict:
+        if 'rspauth' in challenge_dict:
             self.authenticate_server(challenge_dict['rspauth'])
+            self.complete = True
+            return None
 
         if 'realm' not in challenge_dict:
             self._fetch_properties('realm')
             challenge_dict['realm'] = self.realm
 
         for key in ('nonce', 'realm'):
+            # TODO: rfc2831#section-2.1.1 realm: "Multiple realm directives are
+            # allowed, in which case the user or client must choose one as the
+            # realm for which to supply to username and password"
+            # TODO: rfc2831#section-2.1.1 nonce: "This directive is required
+            # and MUST appear exactly once; if not present, or if multiple
+            # instances are present, the client should abort the authentication
+            # exchange"
             if key in challenge_dict:
                 setattr(self, key, challenge_dict[key])
 
         self.nc = 0
         if 'qop' in challenge_dict:
-            server_offered_qops = [x.strip() for x in 
challenge_dict['qop'].split(b',')]
+            server_offered_qops = [
+                x.strip() for x in challenge_dict['qop'].split(b',')
+            ]
         else:
-            server_offered_qops = ['auth']
+            server_offered_qops = [QOP.AUTH]
         self._pick_qop(set(server_offered_qops))
 
         if 'maxbuf' in challenge_dict:
             self.max_buffer = min(
                 self.sasl.max_buffer, int(challenge_dict['maxbuf']))
 
+        # TODO: rfc2831#section-2.1.1 algorithm: This directive is required and
+        # MUST appear exactly once; if not present, or if multiple instances
+        # are present, the client should abort the authentication exchange.
         return self.response()
 
 
@@ -525,7 +562,7 @@
                 protect = 1
             else:
                 protect = 0
-            kerberos.authGSSClientWrap(self.context, outgoing, None, protect)
+            kerberos.authGSSClientWrap(self.context, outgoing.decode('utf8'), 
None, protect)
             return 
base64.b64decode(kerberos.authGSSClientResponse(self.context))
         else:
             return outgoing
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pure-sasl-0.5.0/setup.cfg 
new/pure-sasl-0.6.2/setup.cfg
--- old/pure-sasl-0.5.0/setup.cfg       2018-03-09 06:09:02.000000000 +0100
+++ new/pure-sasl-0.6.2/setup.cfg       2019-10-14 23:43:53.000000000 +0200
@@ -4,5 +4,4 @@
 [egg_info]
 tag_build = 
 tag_date = 0
-tag_svn_revision = 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pure-sasl-0.5.0/setup.py new/pure-sasl-0.6.2/setup.py
--- old/pure-sasl-0.5.0/setup.py        2018-03-09 06:03:17.000000000 +0100
+++ new/pure-sasl-0.6.2/setup.py        2019-02-21 22:47:20.000000000 +0100
@@ -3,7 +3,9 @@
 
 from setuptools import setup
 
+import platform
 import puresasl
+import sys
 
 setup(name='pure-sasl',
       version=puresasl.__version__,
@@ -22,7 +24,7 @@
       keywords='sasl',
       packages=['puresasl'],
       extras_require={
-          'GSSAPI': ['kerberos>=1.3.0']
+          'GSSAPI':  ["winkerberos==0.7.0"] if platform.system() == 'Windows' 
else ['kerberos>=1.3.0']
       },
       classifiers=[
           'Development Status :: 4 - Beta',


Reply via email to