Hello community,

here is the log from the commit of package python-ntlm-auth for 
openSUSE:Factory checked in at 2020-07-16 12:15:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-ntlm-auth (Old)
 and      /work/SRC/openSUSE:Factory/.python-ntlm-auth.new.3592 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-ntlm-auth"

Thu Jul 16 12:15:24 2020 rev:7 rq:821007 version:1.5.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-ntlm-auth/python-ntlm-auth.changes        
2019-08-27 10:27:54.179912117 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-ntlm-auth.new.3592/python-ntlm-auth.changes  
    2020-07-16 12:16:40.494856867 +0200
@@ -1,0 +2,14 @@
+Wed Jul 15 05:51:54 UTC 2020 - Steve Kowalik <steven.kowa...@suse.com>
+
+- Update to 1.5.0:
+  * Added the `mic_present` property to the `NtlmContext` class to determine
+    if a MIC has been added to the authentication message.
+  * Added the `sign` and `verify` function to the `NtlmContext` to sign data
+    and verify signatures.
+  * Added the `reset_rc4_state` function to the `NtlmContext` to allow a
+    caller to reset the incoming and outgoing RC4 cipher.
+  * Added the `NTLMSSP_NEGOTIATE_UNICODE` flag to the negotiate message to
+    ensure the challenge and authentication message's text fields can be
+    unicode encoded 
+
+-------------------------------------------------------------------

Old:
----
  python-ntlm-auth-1.4.0.tar.gz

New:
----
  python-ntlm-auth-1.5.0.tar.gz

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

Other differences:
------------------
++++++ python-ntlm-auth.spec ++++++
--- /var/tmp/diff_new_pack.WB84Ot/_old  2020-07-16 12:16:41.718858105 +0200
+++ /var/tmp/diff_new_pack.WB84Ot/_new  2020-07-16 12:16:41.722858108 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-ntlm-auth
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,11 +18,10 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-ntlm-auth
-Version:        1.4.0
+Version:        1.5.0
 Release:        0
 Summary:        NTLM low-level Python library
 License:        MIT
-Group:          Development/Languages/Python
 URL:            https://github.com/jborean93/ntlm-auth
 Source:         
https://github.com/jborean93/ntlm-auth/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
 BuildRequires:  %{python_module cryptography}

++++++ python-ntlm-auth-1.4.0.tar.gz -> python-ntlm-auth-1.5.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ntlm-auth-1.4.0/.travis.yml 
new/ntlm-auth-1.5.0/.travis.yml
--- old/ntlm-auth-1.4.0/.travis.yml     2019-08-19 02:51:07.000000000 +0200
+++ new/ntlm-auth-1.5.0/.travis.yml     2020-06-16 08:07:58.000000000 +0200
@@ -1,6 +1,6 @@
 language: python
 
-dist: xenial
+dist: bionic
 
 matrix:
   include:
@@ -13,12 +13,14 @@
     dist: trusty
   - python: 3.6
   - python: 3.7
-  - python: 3.8-dev
+  - python: 3.8
 
-  # 3.8 is still an alpha and this is just running to make sure nothing major
+  - python: 3.9-dev
+
+  # 3.9 is still an alpha and this is just running to make sure nothing major
   # breaks but we don't want it to stop the build
   allow_failures:
-  - python: 3.8-dev
+  - python: 3.9-dev
 
 install:
 - pip install --upgrade pip setuptools
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ntlm-auth-1.4.0/CHANGES.md 
new/ntlm-auth-1.5.0/CHANGES.md
--- old/ntlm-auth-1.4.0/CHANGES.md      2019-08-19 02:51:07.000000000 +0200
+++ new/ntlm-auth-1.5.0/CHANGES.md      2020-06-16 08:07:58.000000000 +0200
@@ -1,5 +1,12 @@
 # Changes
 
+## 1.5.0 (Jun 16, 2020)
+
+* Added the `mic_present` property to the `NtlmContext` class to determine if 
a MIC has been added to the authentication message.
+* Added the `sign` and `verify` function to the `NtlmContext` to sign data and 
verify signatures.
+* Added the `reset_rc4_state` function to the `NtlmContext` to allow a caller 
to reset the incoming and outgoing RC4 cipher.
+* Added the `NTLMSSP_NEGOTIATE_UNICODE` flag to the negotiate message to 
ensure the challenge and authentication message's text fields can be unicode 
encoded
+
 ## 1.4.0 (Aug 19, 2019)
 
 * Added the `session_key` attribute to the `NtlmContext` class so the session 
key can be accessed in downstream libraries
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ntlm-auth-1.4.0/appveyor.yml 
new/ntlm-auth-1.5.0/appveyor.yml
--- old/ntlm-auth-1.4.0/appveyor.yml    2019-08-19 02:51:07.000000000 +0200
+++ new/ntlm-auth-1.5.0/appveyor.yml    2020-06-16 08:07:58.000000000 +0200
@@ -13,14 +13,14 @@
   # https://www.appveyor.com/docs/installed-software/#python
   - PYTHON: Python27
   - PYTHON: Python27-x64
-  - PYTHON: Python34
-  - PYTHON: Python34-x64
   - PYTHON: Python35
   - PYTHON: Python35-x64
   - PYTHON: Python36
   - PYTHON: Python36-x64
   - PYTHON: Python37
   - PYTHON: Python37-x64
+  - PYTHON: Python38
+  - PYTHON: Python38-x64
 
 services:
 - iis
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ntlm-auth-1.4.0/ntlm_auth/messages.py 
new/ntlm-auth-1.5.0/ntlm_auth/messages.py
--- old/ntlm-auth-1.4.0/ntlm_auth/messages.py   2019-08-19 02:51:07.000000000 
+0200
+++ new/ntlm-auth-1.5.0/ntlm_auth/messages.py   2020-06-16 08:07:58.000000000 
+0200
@@ -110,10 +110,11 @@
             negotiate_flags |= \
                 NegotiateFlags.NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED
 
-        # Set the encoding flag to use OEM, remove UNICODE if set as it isn't
-        # support in this message
-        negotiate_flags -= NegotiateFlags.NTLMSSP_NEGOTIATE_UNICODE
-        negotiate_flags |= NegotiateFlags.NTLMSSP_NEGOTIATE_OEM
+        # Set the encoding flag to use UNICODE, remove OEM if set.
+        negotiate_flags |= NegotiateFlags.NTLMSSP_NEGOTIATE_UNICODE
+        negotiate_flags &= ~NegotiateFlags.NTLMSSP_NEGOTIATE_OEM
+
+        # The domain name and workstation are always OEM encoded.
         self.domain_name = self.domain_name.encode('ascii')
         self.workstation = self.workstation.encode('ascii')
 
@@ -330,7 +331,7 @@
             self.workstation = workstation
 
         if self.negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_UNICODE:
-            self.negotiate_flags -= NegotiateFlags.NTLMSSP_NEGOTIATE_OEM
+            self.negotiate_flags &= ~NegotiateFlags.NTLMSSP_NEGOTIATE_OEM
             encoding_value = 'utf-16-le'
         else:
             encoding_value = 'ascii'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ntlm-auth-1.4.0/ntlm_auth/ntlm.py 
new/ntlm-auth-1.5.0/ntlm_auth/ntlm.py
--- old/ntlm-auth-1.4.0/ntlm_auth/ntlm.py       2019-08-19 02:51:07.000000000 
+0200
+++ new/ntlm-auth-1.5.0/ntlm_auth/ntlm.py       2020-06-16 08:07:58.000000000 
+0200
@@ -49,7 +49,6 @@
         self._server_certificate_hash = None  # deprecated for backwards compat
         self.ntlm_compatibility = ntlm_compatibility
         self.complete = False
-        self.session_key = None
 
         # Setting up our flags so the challenge message returns the target info
         # block if supported
@@ -71,6 +70,23 @@
         self._authenticate_message = None
         self._session_security = None
 
+    @property
+    def mic_present(self):
+        if self._authenticate_message:
+            return bool(self._authenticate_message.mic)
+
+        return False
+
+    @property
+    def session_key(self):
+        if self._authenticate_message:
+            return self._authenticate_message.exported_session_key
+
+    def reset_rc4_state(self, outgoing=True):
+        """ Resets the signing cipher for the incoming or outgoing cipher. For 
SPNEGO for calculating mechListMIC. """
+        if self._session_security:
+            self._session_security.reset_rc4_state(outgoing=outgoing)
+
     def step(self, input_token=None):
         if self._negotiate_message is None:
             self._negotiate_message = NegotiateMessage(self.negotiate_flags,
@@ -92,14 +108,19 @@
             flags = struct.unpack("<I", flag_bytes)[0]
             if flags & NegotiateFlags.NTLMSSP_NEGOTIATE_SEAL or \
                     flags & NegotiateFlags.NTLMSSP_NEGOTIATE_SIGN:
-                self.session_key = 
self._authenticate_message.exported_session_key
                 self._session_security = SessionSecurity(
-                    flags, self._authenticate_message.exported_session_key
+                    flags, self.session_key
                 )
 
             self.complete = True
             return self._authenticate_message.get_data()
 
+    def sign(self, data):
+        return self._session_security.get_signature(data)
+
+    def verify(self, data, signature):
+        self._session_security.verify_signature(data, signature)
+
     def wrap(self, data):
         if self._session_security is None:
             raise NoAuthContextError("Cannot wrap data as no security context "
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ntlm-auth-1.4.0/ntlm_auth/session_security.py 
new/ntlm-auth-1.5.0/ntlm_auth/session_security.py
--- old/ntlm-auth-1.4.0/ntlm_auth/session_security.py   2019-08-19 
02:51:07.000000000 +0200
+++ new/ntlm-auth-1.5.0/ntlm_auth/session_security.py   2020-06-16 
08:07:58.000000000 +0200
@@ -102,36 +102,35 @@
         self.exported_session_key = exported_session_key
         self.outgoing_seq_num = 0
         self.incoming_seq_num = 0
-
-        client_sealing_key = \
-            compkeys.get_seal_key(self.negotiate_flags, exported_session_key,
-                                  SignSealConstants.CLIENT_SEALING)
-        server_sealing_key = \
-            compkeys.get_seal_key(self.negotiate_flags, exported_session_key,
-                                  SignSealConstants.SERVER_SEALING)
+        self._source = source
+        self._client_sealing_key = compkeys.get_seal_key(self.negotiate_flags, 
exported_session_key,
+                                                         
SignSealConstants.CLIENT_SEALING)
+        self._server_sealing_key = compkeys.get_seal_key(self.negotiate_flags, 
exported_session_key,
+                                                         
SignSealConstants.SERVER_SEALING)
+
+        self.outgoing_handle = None
+        self.incoming_handle = None
+        self.reset_rc4_state(True)
+        self.reset_rc4_state(False)
 
         if source == "client":
-            self.outgoing_signing_key = \
-                compkeys.get_sign_key(exported_session_key,
-                                      SignSealConstants.CLIENT_SIGNING)
-            self.incoming_signing_key = \
-                compkeys.get_sign_key(exported_session_key,
-                                      SignSealConstants.SERVER_SIGNING)
-            self.outgoing_handle = ARC4(client_sealing_key)
-            self.incoming_handle = ARC4(server_sealing_key)
+            self.outgoing_signing_key = 
compkeys.get_sign_key(exported_session_key, SignSealConstants.CLIENT_SIGNING)
+            self.incoming_signing_key = 
compkeys.get_sign_key(exported_session_key, SignSealConstants.SERVER_SIGNING)
         elif source == "server":
-            self.outgoing_signing_key = \
-                compkeys.get_sign_key(exported_session_key,
-                                      SignSealConstants.SERVER_SIGNING)
-            self.incoming_signing_key = \
-                compkeys.get_sign_key(exported_session_key,
-                                      SignSealConstants.CLIENT_SIGNING)
-            self.outgoing_handle = ARC4(server_sealing_key)
-            self.incoming_handle = ARC4(client_sealing_key)
+            self.outgoing_signing_key = 
compkeys.get_sign_key(exported_session_key, SignSealConstants.SERVER_SIGNING)
+            self.incoming_signing_key = 
compkeys.get_sign_key(exported_session_key, SignSealConstants.CLIENT_SIGNING)
         else:
             raise ValueError("Invalid source parameter %s, must be client "
                              "or server" % source)
 
+    def reset_rc4_state(self, outgoing=True):
+        csk = self._client_sealing_key
+        ssk = self._server_sealing_key
+        if outgoing:
+            self.outgoing_handle = ARC4(csk if self._source == 'client' else 
ssk)
+        else:
+            self.incoming_handle = ARC4(ssk if self._source == 'client' else 
csk)
+
     def wrap(self, message):
         """
         [MS-NLMP] v28.0 2016-07-14
@@ -147,11 +146,11 @@
         """
         if self.negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_SEAL:
             encrypted_message = self._seal_message(message)
-            signature = self._get_signature(message)
+            signature = self.get_signature(message)
             message = encrypted_message
 
         elif self.negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_SIGN:
-            signature = self._get_signature(message)
+            signature = self.get_signature(message)
         else:
             signature = None
 
@@ -172,10 +171,10 @@
         """
         if self.negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_SEAL:
             message = self._unseal_message(message)
-            self._verify_signature(message, signature)
+            self.verify_signature(message, signature)
 
         elif self.negotiate_flags & NegotiateFlags.NTLMSSP_NEGOTIATE_SIGN:
-            self._verify_signature(message, signature)
+            self.verify_signature(message, signature)
 
         return message
 
@@ -207,7 +206,7 @@
         decrypted_message = self.incoming_handle.update(message)
         return decrypted_message
 
-    def _get_signature(self, message):
+    def get_signature(self, message):
         """
         [MS-NLMP] v28.0 2016-07-14
 
@@ -227,7 +226,7 @@
 
         return signature.get_data()
 
-    def _verify_signature(self, message, signature):
+    def verify_signature(self, message, signature):
         """
         Will verify that the signature received from the server matches up with
         the expected signature computed locally. Will throw an exception if
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ntlm-auth-1.4.0/setup.py new/ntlm-auth-1.5.0/setup.py
--- old/ntlm-auth-1.4.0/setup.py        2019-08-19 02:51:07.000000000 +0200
+++ new/ntlm-auth-1.5.0/setup.py        2020-06-16 08:07:58.000000000 +0200
@@ -13,7 +13,7 @@
 
 setup(
     name='ntlm-auth',
-    version='1.4.0',
+    version='1.5.0',
     packages=['ntlm_auth'],
     install_requires=[],
     extras_require={
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ntlm-auth-1.4.0/tests/test_messages.py 
new/ntlm-auth-1.5.0/tests/test_messages.py
--- old/ntlm-auth-1.4.0/tests/test_messages.py  2019-08-19 02:51:07.000000000 
+0200
+++ new/ntlm-auth-1.5.0/tests/test_messages.py  2020-06-16 08:07:58.000000000 
+0200
@@ -71,7 +71,7 @@
 
     def test_negotiate_with_all(self):
         expected = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \
-                   b"\x01\x00\x00\x00\x32\xb2\x02\xe2" \
+                   b"\x01\x00\x00\x00\x31\xb2\x02\xe2" \
                    b"\x06\x00\x06\x00\x28\x00\x00\x00" \
                    b"\x08\x00\x08\x00\x2e\x00\x00\x00" \
                    b"\x06\x01\xb1\x1d\x00\x00\x00\x0f" \
@@ -83,7 +83,7 @@
     def test_negotiate_without_version(self):
         test_flags = 3791815219 - NegotiateFlags.NTLMSSP_NEGOTIATE_VERSION
         expected = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \
-                   b"\x01\x00\x00\x00\x32\xb2\x02\xe0" \
+                   b"\x01\x00\x00\x00\x31\xb2\x02\xe0" \
                    b"\x06\x00\x06\x00\x28\x00\x00\x00" \
                    b"\x08\x00\x08\x00\x2e\x00\x00\x00" \
                    b"\x00\x00\x00\x00\x00\x00\x00\x00" \
@@ -94,7 +94,7 @@
 
     def test_negotiate_without_domain_workstation(self):
         expected = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \
-                   b"\x01\x00\x00\x00\x32\x82\x02\xe2" \
+                   b"\x01\x00\x00\x00\x31\x82\x02\xe2" \
                    b"\x00\x00\x00\x00\x28\x00\x00\x00" \
                    b"\x00\x00\x00\x00\x28\x00\x00\x00" \
                    b"\x06\x01\xb1\x1d\x00\x00\x00\x0f"
@@ -580,42 +580,42 @@
                                                   "COMPUTER")
 
         # Not a Microsoft example, using pre-computed value
-        expected = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \
+        expected = b"\x4E\x54\x4C\x4D\x53\x53\x50\x00" \
                    b"\x03\x00\x00\x00\x18\x00\x18\x00" \
-                   b"\x7c\x00\x00\x00\x7c\x00\x7c\x00" \
-                   b"\x94\x00\x00\x00\x0c\x00\x0c\x00" \
+                   b"\x7C\x00\x00\x00\x7C\x00\x7C\x00" \
+                   b"\x94\x00\x00\x00\x0C\x00\x0C\x00" \
                    b"\x58\x00\x00\x00\x08\x00\x08\x00" \
                    b"\x64\x00\x00\x00\x10\x00\x10\x00" \
-                   b"\x6c\x00\x00\x00\x10\x00\x10\x00" \
-                   b"\x10\x01\x00\x00\x31\x82\x8a\xe2" \
-                   b"\x06\x01\xb1\x1d\x00\x00\x00\x0f" \
-                   b"\x8b\x69\xf5\x92\xb2\xd7\x8f\xd7" \
-                   b"\x3a\x3a\x49\xdb\xfe\x19\x61\xbc" \
-                   b"\x44\x00\x6f\x00\x6d\x00\x61\x00" \
-                   b"\x69\x00\x6e\x00\x55\x00\x73\x00" \
-                   b"\x65\x00\x72\x00\x43\x00\x4f\x00" \
-                   b"\x4d\x00\x50\x00\x55\x00\x54\x00" \
+                   b"\x6C\x00\x00\x00\x10\x00\x10\x00" \
+                   b"\x10\x01\x00\x00\x31\x82\x8A\xE2" \
+                   b"\x06\x01\xB1\x1D\x00\x00\x00\x0F" \
+                   b"\xD2\xA1\x45\xDE\xA4\x25\x3E\x19" \
+                   b"\x10\xFE\x0F\x5B\x7A\x0D\x2A\x90" \
+                   b"\x44\x00\x6F\x00\x6D\x00\x61\x00" \
+                   b"\x69\x00\x6E\x00\x55\x00\x73\x00" \
+                   b"\x65\x00\x72\x00\x43\x00\x4F\x00" \
+                   b"\x4D\x00\x50\x00\x55\x00\x54\x00" \
                    b"\x45\x00\x52\x00\x00\x00\x00\x00" \
                    b"\x00\x00\x00\x00\x00\x00\x00\x00" \
                    b"\x00\x00\x00\x00\x00\x00\x00\x00" \
-                   b"\x00\x00\x00\x00\xa1\x3d\x03\x8a" \
-                   b"\xd0\xca\x02\x64\x33\x89\x7c\x33" \
-                   b"\x5e\x0f\x56\xdf\x01\x01\x00\x00" \
+                   b"\x00\x00\x00\x00\xA1\x3D\x03\x8A" \
+                   b"\xD0\xCA\x02\x64\x33\x89\x7C\x33" \
+                   b"\x5E\x0F\x56\xDF\x01\x01\x00\x00" \
                    b"\x00\x00\x00\x00\x00\x00\x00\x00" \
-                   b"\x00\x00\x00\x00\xaa\xaa\xaa\xaa" \
-                   b"\xaa\xaa\xaa\xaa\x00\x00\x00\x00" \
-                   b"\x02\x00\x0c\x00\x44\x00\x6f\x00" \
-                   b"\x6d\x00\x61\x00\x69\x00\x6e\x00" \
-                   b"\x01\x00\x0c\x00\x53\x00\x65\x00" \
+                   b"\x00\x00\x00\x00\xAA\xAA\xAA\xAA" \
+                   b"\xAA\xAA\xAA\xAA\x00\x00\x00\x00" \
+                   b"\x02\x00\x0C\x00\x44\x00\x6F\x00" \
+                   b"\x6D\x00\x61\x00\x69\x00\x6E\x00" \
+                   b"\x01\x00\x0C\x00\x53\x00\x65\x00" \
                    b"\x72\x00\x76\x00\x65\x00\x72\x00" \
                    b"\x07\x00\x08\x00\x00\x00\x00\x00" \
                    b"\x00\x00\x00\x00\x06\x00\x04\x00" \
-                   b"\x02\x00\x00\x00\x0a\x00\x10\x00" \
-                   b"\x6e\xa1\x9d\xf0\x66\xda\x46\x22" \
-                   b"\x05\x1f\x9c\x4f\x92\xc6\xdf\x74" \
+                   b"\x02\x00\x00\x00\x0A\x00\x10\x00" \
+                   b"\x6E\xA1\x9D\xF0\x66\xDA\x46\x22" \
+                   b"\x05\x1F\x9C\x4F\x92\xC6\xDF\x74" \
                    b"\x00\x00\x00\x00\x00\x00\x00\x00" \
-                   b"\x1d\x08\x89\xd1\xa5\xee\xed\x21" \
-                   b"\x91\x9e\x1a\xb8\x27\xc3\x0b\x17"
+                   b"\x1D\x08\x89\xD1\xA5\xEE\xED\x21" \
+                   b"\x91\x9E\x1A\xB8\x27\xC3\x0B\x17"
 
         actual = AuthenticateMessage("User", "Password", "Domain", "COMPUTER",
                                      test_challenge_message, 3,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ntlm-auth-1.4.0/tests/test_ntlm.py 
new/ntlm-auth-1.5.0/tests/test_ntlm.py
--- old/ntlm-auth-1.4.0/tests/test_ntlm.py      2019-08-19 02:51:07.000000000 
+0200
+++ new/ntlm-auth-1.5.0/tests/test_ntlm.py      2020-06-16 08:07:58.000000000 
+0200
@@ -126,8 +126,7 @@
     # permutations are in test_message.py
     def test_create_negotiate_message(self):
         ntlm_context = Ntlm()
-        expected = b'TlRMTVNTUAABAAAAMrCI4gYABgAoAAAACAAIAC4AAAA' \
-                   b'GAbEdAAAAD0RvbWFpbkNPTVBVVEVS'
+        expected = 
b'TlRMTVNTUAABAAAAMbCI4gYABgAoAAAACAAIAC4AAAAGAbEdAAAAD0RvbWFpbkNPTVBVVEVS'
         actual = ntlm_context.create_negotiate_message("Domain", "COMPUTER")
         assert actual == expected
 
@@ -312,8 +311,6 @@
         monkeypatch.setattr('ntlm_auth.compute_response.get_windows_timestamp',
                             lambda: b"\x00" * 8)
 
-        import binascii
-
         ch = 'E3CA49271E5089CC48CE82109F1324F41DBEDDC29A777410C738F7868C4FF405'
         cbt_data = GssChannelBindingsStruct()
         cbt_data[cbt_data.APPLICATION_DATA] = b"tls-server-end-point:" + \
@@ -322,13 +319,14 @@
                                    cbt_data=cbt_data)
         actual_nego = ntlm_context.step()
         expected_nego = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \
-                        b"\x01\x00\x00\x00\x32\xb0\x88\xe2" \
+                        b"\x01\x00\x00\x00\x31\xb0\x88\xe2" \
                         b"\x06\x00\x06\x00\x28\x00\x00\x00" \
                         b"\x08\x00\x08\x00\x2e\x00\x00\x00" \
                         b"\x05\x01\x28\x0a\x00\x00\x00\x0f" \
                         b"\x44\x6f\x6d\x61\x69\x6e\x43\x4f" \
                         b"\x4d\x50\x55\x54\x45\x52"
         assert actual_nego == expected_nego
+        assert not ntlm_context.mic_present
         assert not ntlm_context.complete
 
         challenge_msg = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \
@@ -380,6 +378,111 @@
 
         assert actual_auth == expected_auth
         assert ntlm_context.complete
+        assert not ntlm_context.mic_present
+
+        request_msg = b"test req"
+        response_msg = b"test res"
+        actual_wrapped = ntlm_context.wrap(request_msg)
+        expected_wrapped = b"\x01\x00\x00\x00\xbc\xe3\x23\xa1" \
+                           b"\x72\x06\x23\x78\x00\x00\x00\x00" \
+                           b"\x70\x80\x1e\x11\xfe\x6b\x3a\xad"
+        assert actual_wrapped == expected_wrapped
+
+        server_sec = SessionSecurity(
+            ntlm_context._session_security.negotiate_flags,
+            ntlm_context._session_security.exported_session_key, "server"
+        )
+        server_unwrap = server_sec.unwrap(actual_wrapped[16:],
+                                          actual_wrapped[0:16])
+        assert server_unwrap == request_msg
+
+        response_wrapped = server_sec.wrap(response_msg)
+
+        actual_unwrap = ntlm_context.unwrap(
+            response_wrapped[1] + response_wrapped[0]
+        )
+        assert actual_unwrap == response_msg
+
+    def test_ntlm_context_with_mic(self, monkeypatch):
+        monkeypatch.setattr('os.urandom', lambda s: b"\xaa" * 8)
+        monkeypatch.setattr('ntlm_auth.messages.get_version', lambda s: 
b"\x05\x01\x28\x0A\x00\x00\x00\x0F")
+        
monkeypatch.setattr('ntlm_auth.messages.get_random_export_session_key', lambda: 
b"\x55" * 16)
+        
monkeypatch.setattr('ntlm_auth.compute_response.get_windows_timestamp', lambda: 
b"\x00" * 8)
+
+        ch = 'E3CA49271E5089CC48CE82109F1324F41DBEDDC29A777410C738F7868C4FF405'
+        cbt_data = GssChannelBindingsStruct()
+        cbt_data[cbt_data.APPLICATION_DATA] = b"tls-server-end-point:" + \
+                                              base64.b16decode(ch)
+        ntlm_context = NtlmContext("User", "Password", "Domain", "COMPUTER",
+                                   cbt_data=cbt_data)
+        ntlm_context.reset_rc4_state()  # Verifies it won't fail when the 
session security isn't set up.
+
+        actual_nego = ntlm_context.step()
+        expected_nego = b"\x4e\x54\x4c\x4d\x53\x53\x50\x00" \
+                        b"\x01\x00\x00\x00\x31\xb0\x88\xe2" \
+                        b"\x06\x00\x06\x00\x28\x00\x00\x00" \
+                        b"\x08\x00\x08\x00\x2e\x00\x00\x00" \
+                        b"\x05\x01\x28\x0a\x00\x00\x00\x0f" \
+                        b"\x44\x6f\x6d\x61\x69\x6e\x43\x4f" \
+                        b"\x4d\x50\x55\x54\x45\x52"
+        assert actual_nego == expected_nego
+        assert not ntlm_context.mic_present
+        assert not ntlm_context.complete
+
+        challenge_msg = b"\x4E\x54\x4C\x4D\x53\x53\x50\x00" \
+                        b"\x02\x00\x00\x00\x00\x00\x00\x00" \
+                        b"\x38\x00\x00\x00\x33\x82\x8A\xE2" \
+                        b"\x01\x23\x45\x67\x89\xAB\xCD\xEF" \
+                        b"\x00\x00\x00\x00\x00\x00\x00\x00" \
+                        b"\x30\x00\x30\x00\x38\x00\x00\x00" \
+                        b"\x06\x01\xB1\x1D\x00\x00\x00\x0F" \
+                        b"\x02\x00\x0C\x00\x44\x00\x6F\x00" \
+                        b"\x6D\x00\x61\x00\x69\x00\x6E\x00" \
+                        b"\x01\x00\x0C\x00\x53\x00\x65\x00" \
+                        b"\x72\x00\x76\x00\x65\x00\x72\x00" \
+                        b"\x07\x00\x08\x00\x00\x00\x00\x00" \
+                        b"\x00\x00\x00\x00\x00\x00\x00\x00"
+        actual_auth = ntlm_context.step(challenge_msg)
+        expected_auth = b'\x4E\x54\x4C\x4D\x53\x53\x50\x00' \
+                        b'\x03\x00\x00\x00\x18\x00\x18\x00' \
+                        b'\x7C\x00\x00\x00\x7C\x00\x7C\x00' \
+                        b'\x94\x00\x00\x00\x0C\x00\x0C\x00' \
+                        b'\x58\x00\x00\x00\x08\x00\x08\x00' \
+                        b'\x64\x00\x00\x00\x10\x00\x10\x00' \
+                        b'\x6C\x00\x00\x00\x10\x00\x10\x00' \
+                        b'\x10\x01\x00\x00\x31\x82\x8A\xE2' \
+                        b'\x05\x01\x28\x0A\x00\x00\x00\x0F' \
+                        b'\xC4\x45\x2C\xF7\xA8\x1E\x4D\x11' \
+                        b'\xD0\x78\x18\x94\x09\x57\x5D\x9E' \
+                        b'\x44\x00\x6F\x00\x6D\x00\x61\x00' \
+                        b'\x69\x00\x6E\x00\x55\x00\x73\x00' \
+                        b'\x65\x00\x72\x00\x43\x00\x4F\x00' \
+                        b'\x4D\x00\x50\x00\x55\x00\x54\x00' \
+                        b'\x45\x00\x52\x00\x00\x00\x00\x00' \
+                        b'\x00\x00\x00\x00\x00\x00\x00\x00' \
+                        b'\x00\x00\x00\x00\x00\x00\x00\x00' \
+                        b'\x00\x00\x00\x00\xA1\x3D\x03\x8A' \
+                        b'\xD0\xCA\x02\x64\x33\x89\x7C\x33' \
+                        b'\x5E\x0F\x56\xDF\x01\x01\x00\x00' \
+                        b'\x00\x00\x00\x00\x00\x00\x00\x00' \
+                        b'\x00\x00\x00\x00\xAA\xAA\xAA\xAA' \
+                        b'\xAA\xAA\xAA\xAA\x00\x00\x00\x00' \
+                        b'\x02\x00\x0C\x00\x44\x00\x6F\x00' \
+                        b'\x6D\x00\x61\x00\x69\x00\x6E\x00' \
+                        b'\x01\x00\x0C\x00\x53\x00\x65\x00' \
+                        b'\x72\x00\x76\x00\x65\x00\x72\x00' \
+                        b'\x07\x00\x08\x00\x00\x00\x00\x00' \
+                        b'\x00\x00\x00\x00\x06\x00\x04\x00' \
+                        b'\x02\x00\x00\x00\x0A\x00\x10\x00' \
+                        b'\x6E\xA1\x9D\xF0\x66\xDA\x46\x22' \
+                        b'\x05\x1F\x9C\x4F\x92\xC6\xDF\x74' \
+                        b'\x00\x00\x00\x00\x00\x00\x00\x00' \
+                        b'\x1D\x08\x89\xD1\xA5\xEE\xED\x21' \
+                        b'\x91\x9E\x1A\xB8\x27\xC3\x0B\x17'
+
+        assert actual_auth == expected_auth
+        assert ntlm_context.complete
+        assert ntlm_context.mic_present
 
         request_msg = b"test req"
         response_msg = b"test res"
@@ -404,6 +507,28 @@
         )
         assert actual_unwrap == response_msg
 
+        msg = b"Hello"
+        actual_sig1 = ntlm_context.sign(msg)
+        expected_sig1 = 
b"\x01\x00\x00\x00\x08\xF0\x0D\x86\x34\x05\x1A\x1D\x01\x00\x00\x00"
+        assert actual_sig1 == expected_sig1
+        server_sec.verify_signature(msg, actual_sig1)
+
+        actual_sig2 = ntlm_context.sign(msg)
+        expected_sig2 = 
b"\x01\x00\x00\x00\x07\x64\x0C\x30\x1C\xD7\x76\xF0\x02\x00\x00\x00"
+        assert actual_sig2 == expected_sig2
+        server_sec.verify_signature(msg, actual_sig2)
+
+        ntlm_context.reset_rc4_state()
+        actual_sig3 = ntlm_context.sign(msg)
+        expected_sig3 = 
b"\x01\x00\x00\x00\x1E\xD4\xA3\xE5\xE8\x05\x74\x01\x03\x00\x00\x00"
+        assert actual_sig3 == expected_sig3
+
+        server_sec.reset_rc4_state(outgoing=False)
+        server_sec.verify_signature(msg, actual_sig3)
+
+        server_sig = server_sec.get_signature(msg)
+        ntlm_context.verify(msg, server_sig)
+
     def test_fail_wrap_no_context(self):
         ntlm_context = NtlmContext("", "")
         with pytest.raises(NoAuthContextError) as err:


Reply via email to