Hello community,
here is the log from the commit of package python-requests-kerberos for
openSUSE:Factory checked in at 2019-02-05 11:19:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-requests-kerberos (Old)
and /work/SRC/openSUSE:Factory/.python-requests-kerberos.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-requests-kerberos"
Tue Feb 5 11:19:03 2019 rev:5 rq:671251 version:0.12.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-requests-kerberos/python-requests-kerberos.changes
2018-12-24 11:43:22.541346599 +0100
+++
/work/SRC/openSUSE:Factory/.python-requests-kerberos.new.28833/python-requests-kerberos.changes
2019-02-05 11:19:05.768884751 +0100
@@ -1,0 +2,8 @@
+Tue Feb 5 05:17:02 UTC 2019 - Thomas Bechtold <[email protected]>
+
+- update to 0.12.0:
+ - Add support for channel binding tokens
+ - Add support for kerberos message encryption
+ - Misc CI/test fixes
+
+-------------------------------------------------------------------
Old:
----
requests-kerberos-0.11.0.tar.gz
New:
----
requests-kerberos-0.12.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-requests-kerberos.spec ++++++
--- /var/tmp/diff_new_pack.8ZZegi/_old 2019-02-05 11:19:06.956884098 +0100
+++ /var/tmp/diff_new_pack.8ZZegi/_new 2019-02-05 11:19:06.956884098 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-requests-kerberos
#
-# 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
@@ -18,7 +18,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-requests-kerberos
-Version: 0.11.0
+Version: 0.12.0
Release: 0
Summary: A Kerberos authentication handler for python-requests
License: ISC
++++++ requests-kerberos-0.11.0.tar.gz -> requests-kerberos-0.12.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/requests-kerberos-0.11.0/HISTORY.rst
new/requests-kerberos-0.12.0/HISTORY.rst
--- old/requests-kerberos-0.11.0/HISTORY.rst 2016-11-02 21:30:09.000000000
+0100
+++ new/requests-kerberos-0.12.0/HISTORY.rst 2017-12-20 19:29:53.000000000
+0100
@@ -1,6 +1,13 @@
History
=======
+0.12.0: 2017-12-20
+------------------------
+
+- Add support for channel binding tokens (assumes pykerberos support >= 1.2.1)
+- Add support for kerberos message encryption (assumes pykerberos support >=
1.2.1)
+- Misc CI/test fixes
+
0.11.0: 2016-11-02
------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/requests-kerberos-0.11.0/PKG-INFO
new/requests-kerberos-0.12.0/PKG-INFO
--- old/requests-kerberos-0.11.0/PKG-INFO 2016-11-02 21:32:18.000000000
+0100
+++ new/requests-kerberos-0.12.0/PKG-INFO 2017-12-20 20:23:24.000000000
+0100
@@ -1,14 +1,21 @@
Metadata-Version: 1.0
Name: requests-kerberos
-Version: 0.11.0
+Version: 0.12.0
Summary: A Kerberos authentication handler for python-requests
Home-page: https://github.com/requests/requests-kerberos
Author: Ian Cordasco, Cory Benfield, Michael Komitee
Author-email: [email protected]
License: UNKNOWN
+Description-Content-Type: UNKNOWN
Description: requests Kerberos/GSSAPI authentication library
===============================================
+ .. image::
https://travis-ci.org/requests/requests-kerberos.svg?branch=master
+ :target: https://travis-ci.org/requests/requests-kerberos
+
+ .. image::
https://coveralls.io/repos/github/requests/requests-kerberos/badge.svg?branch=master
+ :target:
https://coveralls.io/github/requests/requests-kerberos?branch=master
+
Requests is an HTTP library, written in Python, for human beings. This
library
adds optional Kerberos/GSSAPI authentication support and supports
mutual
authentication. Basic GET usage:
@@ -144,6 +151,23 @@
use of arbitrary principals instead of a credential cache. Passwords
can be
specified by following the form ``user@realm:password`` for
``principal``.
+ Delegation
+ ----------
+
+ ``requests_kerberos`` supports credential delegation
(``GSS_C_DELEG_FLAG``).
+ To enable delegation of credentials to a server that requests
delegation, pass
+ ``delegate=True`` to ``HTTPKerberosAuth``:
+
+ .. code-block:: python
+
+ >>> import requests
+ >>> from requests_kerberos import HTTPKerberosAuth
+ >>> r = requests.get("http://example.org",
auth=HTTPKerberosAuth(delegate=True))
+ ...
+
+ Be careful to only allow delegation to servers you trust as they will
be able
+ to impersonate you using the delegated credentials.
+
Logging
-------
@@ -161,6 +185,13 @@
History
=======
+ 0.12.0: 2017-12-20
+ ------------------------
+
+ - Add support for channel binding tokens (assumes pykerberos support
>= 1.2.1)
+ - Add support for kerberos message encryption (assumes pykerberos
support >= 1.2.1)
+ - Misc CI/test fixes
+
0.11.0: 2016-11-02
------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/requests-kerberos-0.11.0/README.rst
new/requests-kerberos-0.12.0/README.rst
--- old/requests-kerberos-0.11.0/README.rst 2016-11-02 21:30:09.000000000
+0100
+++ new/requests-kerberos-0.12.0/README.rst 2017-12-08 23:32:12.000000000
+0100
@@ -1,6 +1,12 @@
requests Kerberos/GSSAPI authentication library
===============================================
+.. image:: https://travis-ci.org/requests/requests-kerberos.svg?branch=master
+ :target: https://travis-ci.org/requests/requests-kerberos
+
+.. image::
https://coveralls.io/repos/github/requests/requests-kerberos/badge.svg?branch=master
+ :target:
https://coveralls.io/github/requests/requests-kerberos?branch=master
+
Requests is an HTTP library, written in Python, for human beings. This library
adds optional Kerberos/GSSAPI authentication support and supports mutual
authentication. Basic GET usage:
@@ -136,6 +142,23 @@
use of arbitrary principals instead of a credential cache. Passwords can be
specified by following the form ``user@realm:password`` for ``principal``.
+Delegation
+----------
+
+``requests_kerberos`` supports credential delegation (``GSS_C_DELEG_FLAG``).
+To enable delegation of credentials to a server that requests delegation, pass
+``delegate=True`` to ``HTTPKerberosAuth``:
+
+.. code-block:: python
+
+ >>> import requests
+ >>> from requests_kerberos import HTTPKerberosAuth
+ >>> r = requests.get("http://example.org",
auth=HTTPKerberosAuth(delegate=True))
+ ...
+
+Be careful to only allow delegation to servers you trust as they will be able
+to impersonate you using the delegated credentials.
+
Logging
-------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/requests-kerberos-0.11.0/requests_kerberos/__init__.py
new/requests-kerberos-0.12.0/requests_kerberos/__init__.py
--- old/requests-kerberos-0.11.0/requests_kerberos/__init__.py 2016-11-02
21:30:09.000000000 +0100
+++ new/requests-kerberos-0.12.0/requests_kerberos/__init__.py 2017-12-20
20:20:24.000000000 +0100
@@ -22,4 +22,4 @@
__all__ = ('HTTPKerberosAuth', 'MutualAuthenticationError', 'REQUIRED',
'OPTIONAL', 'DISABLED')
-__version__ = '0.11.0'
+__version__ = '0.12.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/requests-kerberos-0.11.0/requests_kerberos/kerberos_.py
new/requests-kerberos-0.12.0/requests_kerberos/kerberos_.py
--- old/requests-kerberos-0.11.0/requests_kerberos/kerberos_.py 2016-11-02
21:30:09.000000000 +0100
+++ new/requests-kerberos-0.12.0/requests_kerberos/kerberos_.py 2017-12-08
23:32:12.000000000 +0100
@@ -2,14 +2,22 @@
import kerberos
except ImportError:
import winkerberos as kerberos
-import re
import logging
+import re
+import sys
+import warnings
+
+from cryptography import x509
+from cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives import hashes
+from cryptography.exceptions import UnsupportedAlgorithm
from requests.auth import AuthBase
from requests.models import Response
from requests.compat import urlparse, StringIO
from requests.structures import CaseInsensitiveDict
from requests.cookies import cookiejar_from_dict
+from requests.packages.urllib3 import HTTPResponse
from .exceptions import MutualAuthenticationError, KerberosExchangeError
@@ -30,6 +38,14 @@
OPTIONAL = 2
DISABLED = 3
+
+class NoCertificateRetrievedWarning(Warning):
+ pass
+
+class UnknownSignatureAlgorithmOID(Warning):
+ pass
+
+
class SanitizedResponse(Response):
"""The :class:`Response <Response>` object, which contains a server's
response to an HTTP request.
@@ -79,13 +95,80 @@
return None
+def _get_certificate_hash(certificate_der):
+ # https://tools.ietf.org/html/rfc5929#section-4.1
+ cert = x509.load_der_x509_certificate(certificate_der, default_backend())
+
+ try:
+ hash_algorithm = cert.signature_hash_algorithm
+ except UnsupportedAlgorithm as ex:
+ warnings.warn("Failed to get signature algorithm from certificate, "
+ "unable to pass channel bindings: %s" % str(ex),
UnknownSignatureAlgorithmOID)
+ return None
+
+ # if the cert signature algorithm is either md5 or sha1 then use sha256
+ # otherwise use the signature algorithm
+ if hash_algorithm.name in ['md5', 'sha1']:
+ digest = hashes.Hash(hashes.SHA256(), default_backend())
+ else:
+ digest = hashes.Hash(hash_algorithm, default_backend())
+
+ digest.update(certificate_der)
+ certificate_hash = digest.finalize()
+
+ return certificate_hash
+
+
+def _get_channel_bindings_application_data(response):
+ """
+ https://tools.ietf.org/html/rfc5929 4. The 'tls-server-end-point' Channel
Binding Type
+
+ Gets the application_data value for the 'tls-server-end-point' CBT Type.
+ This is ultimately the SHA256 hash of the certificate of the HTTPS endpoint
+ appended onto tls-server-end-point. This value is then passed along to the
+ kerberos library to bind to the auth response. If the socket is not an SSL
+ socket or the raw HTTP object is not a urllib3 HTTPResponse then None will
+ be returned and the Kerberos auth will use GSS_C_NO_CHANNEL_BINDINGS
+
+ :param response: The original 401 response from the server
+ :return: byte string used on the application_data.value field on the CBT
struct
+ """
+
+ application_data = None
+ raw_response = response.raw
+
+ if isinstance(raw_response, HTTPResponse):
+ try:
+ if sys.version_info > (3, 0):
+ socket = raw_response._fp.fp.raw._sock
+ else:
+ socket = raw_response._fp.fp._sock
+ except AttributeError:
+ warnings.warn("Failed to get raw socket for CBT; has urllib3 impl
changed",
+ NoCertificateRetrievedWarning)
+ else:
+ try:
+ server_certificate = socket.getpeercert(True)
+ except AttributeError:
+ pass
+ else:
+ certificate_hash = _get_certificate_hash(server_certificate)
+ application_data = b'tls-server-end-point:' + certificate_hash
+ else:
+ warnings.warn(
+ "Requests is running with a non urllib3 backend, cannot retrieve
server certificate for CBT",
+ NoCertificateRetrievedWarning)
+
+ return application_data
+
class HTTPKerberosAuth(AuthBase):
"""Attaches HTTP GSSAPI/Kerberos Authentication to the given Request
object."""
def __init__(
self, mutual_authentication=REQUIRED,
service="HTTP", delegate=False, force_preemptive=False,
- principal=None, hostname_override=None,
sanitize_mutual_error_response=True):
+ principal=None, hostname_override=None,
+ sanitize_mutual_error_response=True, send_cbt=True):
self.context = {}
self.mutual_authentication = mutual_authentication
self.delegate = delegate
@@ -95,6 +178,13 @@
self.principal = principal
self.hostname_override = hostname_override
self.sanitize_mutual_error_response = sanitize_mutual_error_response
+ self.auth_done = False
+ self.winrm_encryption_available = hasattr(kerberos,
'authGSSWinRMEncryptMessage')
+
+ # Set the CBT values populated after the first response
+ self.send_cbt = send_cbt
+ self.cbt_binding_tried = False
+ self.cbt_struct = None
def generate_request_header(self, response, host, is_preemptive=False):
"""
@@ -130,8 +220,14 @@
negotiate_resp_value = '' if is_preemptive else
_negotiate_value(response)
kerb_stage = "authGSSClientStep()"
- result = kerberos.authGSSClientStep(self.context[host],
- negotiate_resp_value)
+ # If this is set pass along the struct to Kerberos
+ if self.cbt_struct:
+ result = kerberos.authGSSClientStep(self.context[host],
+ negotiate_resp_value,
+
channel_bindings=self.cbt_struct)
+ else:
+ result = kerberos.authGSSClientStep(self.context[host],
+ negotiate_resp_value)
if result < 0:
raise EnvironmentError(result, kerb_stage)
@@ -202,7 +298,7 @@
log.debug("handle_other(): Handling: %d" % response.status_code)
- if self.mutual_authentication in (REQUIRED, OPTIONAL):
+ if self.mutual_authentication in (REQUIRED, OPTIONAL) and not
self.auth_done:
is_http_error = response.status_code >= 400
@@ -218,6 +314,7 @@
# Authentication successful
log.debug("handle_other(): returning {0}".format(response))
+ self.auth_done = True
return response
elif is_http_error or self.mutual_authentication == OPTIONAL:
@@ -232,7 +329,7 @@
return response
else:
# Unable to attempt mutual authentication when mutual auth is
- # required, raise an exception so the user doesnt use an
+ # required, raise an exception so the user doesn't use an
# untrusted response.
log.error("handle_other(): Mutual authentication failed")
raise MutualAuthenticationError("Unable to authenticate "
@@ -254,8 +351,14 @@
host = urlparse(response.url).hostname
try:
- result = kerberos.authGSSClientStep(self.context[host],
- _negotiate_value(response))
+ # If this is set pass along the struct to Kerberos
+ if self.cbt_struct:
+ result = kerberos.authGSSClientStep(self.context[host],
+ _negotiate_value(response),
+
channel_bindings=self.cbt_struct)
+ else:
+ result = kerberos.authGSSClientStep(self.context[host],
+ _negotiate_value(response))
except kerberos.GSSError:
log.exception("authenticate_server(): authGSSClientStep() failed:")
return False
@@ -272,6 +375,20 @@
"""Takes the given response and tries kerberos-auth, as needed."""
num_401s = kwargs.pop('num_401s', 0)
+ # Check if we have already tried to get the CBT data value
+ if not self.cbt_binding_tried and self.send_cbt:
+ # If we haven't tried, try getting it now
+ cbt_application_data =
_get_channel_bindings_application_data(response)
+ if cbt_application_data:
+ # Only the latest version of pykerberos has this method
available
+ try:
+ self.cbt_struct =
kerberos.channelBindings(application_data=cbt_application_data)
+ except AttributeError:
+ # Using older version set to None
+ self.cbt_struct = None
+ # Regardless of the result, set tried to True so we don't waste
time next time
+ self.cbt_binding_tried = True
+
if self.pos is not None:
# Rewind the file position indicator of the body to where
# it was to resend the request.
@@ -299,8 +416,20 @@
"""Deregisters the response handler"""
response.request.deregister_hook('response', self.handle_response)
+ def wrap_winrm(self, host, message):
+ if not self.winrm_encryption_available:
+ raise NotImplementedError("WinRM encryption is not available on
the installed version of pykerberos")
+
+ return kerberos.authGSSWinRMEncryptMessage(self.context[host], message)
+
+ def unwrap_winrm(self, host, message, header):
+ if not self.winrm_encryption_available:
+ raise NotImplementedError("WinRM encryption is not available on
the installed version of pykerberos")
+
+ return kerberos.authGSSWinRMDecryptMessage(self.context[host],
message, header)
+
def __call__(self, request):
- if self.force_preemptive:
+ if self.force_preemptive and not self.auth_done:
# add Authorization header before we receive a 401
# by the 401 handler
host = urlparse(request.url).hostname
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/requests-kerberos-0.11.0/requests_kerberos.egg-info/PKG-INFO
new/requests-kerberos-0.12.0/requests_kerberos.egg-info/PKG-INFO
--- old/requests-kerberos-0.11.0/requests_kerberos.egg-info/PKG-INFO
2016-11-02 21:32:17.000000000 +0100
+++ new/requests-kerberos-0.12.0/requests_kerberos.egg-info/PKG-INFO
2017-12-20 20:23:24.000000000 +0100
@@ -1,14 +1,21 @@
Metadata-Version: 1.0
Name: requests-kerberos
-Version: 0.11.0
+Version: 0.12.0
Summary: A Kerberos authentication handler for python-requests
Home-page: https://github.com/requests/requests-kerberos
Author: Ian Cordasco, Cory Benfield, Michael Komitee
Author-email: [email protected]
License: UNKNOWN
+Description-Content-Type: UNKNOWN
Description: requests Kerberos/GSSAPI authentication library
===============================================
+ .. image::
https://travis-ci.org/requests/requests-kerberos.svg?branch=master
+ :target: https://travis-ci.org/requests/requests-kerberos
+
+ .. image::
https://coveralls.io/repos/github/requests/requests-kerberos/badge.svg?branch=master
+ :target:
https://coveralls.io/github/requests/requests-kerberos?branch=master
+
Requests is an HTTP library, written in Python, for human beings. This
library
adds optional Kerberos/GSSAPI authentication support and supports
mutual
authentication. Basic GET usage:
@@ -144,6 +151,23 @@
use of arbitrary principals instead of a credential cache. Passwords
can be
specified by following the form ``user@realm:password`` for
``principal``.
+ Delegation
+ ----------
+
+ ``requests_kerberos`` supports credential delegation
(``GSS_C_DELEG_FLAG``).
+ To enable delegation of credentials to a server that requests
delegation, pass
+ ``delegate=True`` to ``HTTPKerberosAuth``:
+
+ .. code-block:: python
+
+ >>> import requests
+ >>> from requests_kerberos import HTTPKerberosAuth
+ >>> r = requests.get("http://example.org",
auth=HTTPKerberosAuth(delegate=True))
+ ...
+
+ Be careful to only allow delegation to servers you trust as they will
be able
+ to impersonate you using the delegated credentials.
+
Logging
-------
@@ -161,6 +185,13 @@
History
=======
+ 0.12.0: 2017-12-20
+ ------------------------
+
+ - Add support for channel binding tokens (assumes pykerberos support
>= 1.2.1)
+ - Add support for kerberos message encryption (assumes pykerberos
support >= 1.2.1)
+ - Misc CI/test fixes
+
0.11.0: 2016-11-02
------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/requests-kerberos-0.11.0/requests_kerberos.egg-info/requires.txt
new/requests-kerberos-0.12.0/requests_kerberos.egg-info/requires.txt
--- old/requests-kerberos-0.11.0/requests_kerberos.egg-info/requires.txt
2016-11-02 21:32:17.000000000 +0100
+++ new/requests-kerberos-0.12.0/requests_kerberos.egg-info/requires.txt
2017-12-20 20:23:24.000000000 +0100
@@ -1,7 +1,13 @@
requests>=1.1.0
+[:python_version != "3.3"]
+cryptography>=1.3
+
+[:python_version == "3.3"]
+cryptography<2,>=1.3
+
[:sys_platform!="win32"]
-pykerberos>=1.1.8,<2.0.0
+pykerberos<2.0.0,>=1.1.8
[:sys_platform=="win32"]
winkerberos>=0.5.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/requests-kerberos-0.11.0/requirements.txt
new/requests-kerberos-0.12.0/requirements.txt
--- old/requests-kerberos-0.11.0/requirements.txt 2016-11-02
21:30:09.000000000 +0100
+++ new/requests-kerberos-0.12.0/requirements.txt 2017-12-08
23:32:12.000000000 +0100
@@ -1,3 +1,6 @@
requests>=1.1.0
winkerberos >= 0.5.0; sys.platform == 'win32'
pykerberos >= 1.1.8, < 2.0.0; sys.platform != 'win32'
+cryptography>=1.3
+cryptography>=1.3; python_version!="3.3"
+cryptography>=1.3, <2; python_version=="3.3"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/requests-kerberos-0.11.0/setup.cfg
new/requests-kerberos-0.12.0/setup.cfg
--- old/requests-kerberos-0.11.0/setup.cfg 2016-11-02 21:32:18.000000000
+0100
+++ new/requests-kerberos-0.12.0/setup.cfg 2017-12-20 20:23:24.000000000
+0100
@@ -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/requests-kerberos-0.11.0/setup.py
new/requests-kerberos-0.12.0/setup.py
--- old/requests-kerberos-0.11.0/setup.py 2016-11-02 21:30:09.000000000
+0100
+++ new/requests-kerberos-0.12.0/setup.py 2017-12-08 23:32:12.000000000
+0100
@@ -49,6 +49,8 @@
version=get_version(),
install_requires=[
'requests>=1.1.0',
+ 'cryptography>=1.3;python_version!="3.3"',
+ 'cryptography>=1.3,<2;python_version=="3.3"'
],
extras_require={
':sys_platform=="win32"': ['winkerberos>=0.5.0'],