Hello community,

here is the log from the commit of package python-pykerberos for 
openSUSE:Factory checked in at 2019-02-05 11:19:06
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pykerberos (Old)
 and      /work/SRC/openSUSE:Factory/.python-pykerberos.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pykerberos"

Tue Feb  5 11:19:06 2019 rev:5 rq:671252 version:1.2.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pykerberos/python-pykerberos.changes      
2018-02-10 17:57:24.833768401 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-pykerberos.new.28833/python-pykerberos.changes
   2019-02-05 11:19:10.432882188 +0100
@@ -1,0 +2,19 @@
+Tue Feb  5 05:19:12 UTC 2019 - Thomas Bechtold <[email protected]>
+
+- update to 1.2.1:
+  * add crusty CMake support
+  * minor change to CBT struct
+  * get build working on OSX again
+  * changes based on upstream PR
+  * add CHANGELOG with entries for 1.2.1.beta1
+  * add winrm-style IOV encryption support
+  * bump repo version to 1.2.1dev
+  * Removing 3.2 from travis b/c it is no longer fully supported
+  * Added method to build the CBT structure and modified authGSSClientStep
+    to pass along this CBT structure if it is set
+  * obviously, verify shouldn't be const
+  * 1.2.1 final release
+  * Adding life support note to README
+- Use %license macro
+
+-------------------------------------------------------------------

Old:
----
  pykerberos-1.1.14.tar.gz

New:
----
  pykerberos-1.2.1.tar.gz

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

Other differences:
------------------
++++++ python-pykerberos.spec ++++++
--- /var/tmp/diff_new_pack.gBr64H/_old  2019-02-05 11:19:10.940881909 +0100
+++ /var/tmp/diff_new_pack.gBr64H/_new  2019-02-05 11:19:10.940881909 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-pykerberos
 #
-# Copyright (c) 2017 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,13 +12,13 @@
 # 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-%{**}}
 Name:           python-pykerberos
-Version:        1.1.14
+Version:        1.2.1
 Release:        0
 Summary:        High-level interface to Kerberos
 License:        Apache-2.0
@@ -53,7 +53,8 @@
 
 %files %{python_files}
 %defattr(-,root,root,-)
-%doc README.txt LICENSE
+%doc README.txt
+%license LICENSE
 %{python_sitearch}/*
 
 %changelog

++++++ pykerberos-1.1.14.tar.gz -> pykerberos-1.2.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pykerberos-1.1.14/PKG-INFO 
new/pykerberos-1.2.1/PKG-INFO
--- old/pykerberos-1.1.14/PKG-INFO      2017-01-26 08:32:40.000000000 +0100
+++ new/pykerberos-1.2.1/PKG-INFO       2017-12-20 19:27:02.000000000 +0100
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: pykerberos
-Version: 1.1.14
+Version: 1.2.1
 Summary: High-level interface to Kerberos
 Home-page: UNKNOWN
 Author: UNKNOWN
 Author-email: UNKNOWN
 License: ASL 2.0
+Description-Content-Type: UNKNOWN
 Description: 
         This Python package is a high-level wrapper for Kerberos (GSSAPI) 
operations.
         The goal is to avoid having to build a module that wraps the entire 
Kerberos.framework,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pykerberos-1.1.14/README.txt 
new/pykerberos-1.2.1/README.txt
--- old/pykerberos-1.1.14/README.txt    2014-03-25 10:21:31.000000000 +0100
+++ new/pykerberos-1.2.1/README.txt     2017-12-07 02:02:50.000000000 +0100
@@ -1,3 +1,6 @@
+NOTE: this fork of ccs-kerberos is currently on life support mode as Apple has 
resumed work on upstream. Please try to use 
https://pypi.python.org/pypi/kerberos instead of this fork if possible.
+
+
 =========================================================
 PyKerberos Package
 
@@ -62,6 +65,59 @@
     -p : password for basic authenticate
     -s : service principal for GSSAPI authentication (defaults to 
'[email protected]')
 
+================
+CHANNEL BINDINGS
+================
+
+You can use this library to authenticate with Channel Binding support. Channel
+Bindings are tags that identify the particular data channel being used with the
+authentication. You can use Channel bindings to offer more proof of a valid
+identity. Some services like Microsoft's Extended Protection can enforce
+Channel Binding support on authorisation and you can use this library to meet
+those requirements.
+
+More details on Channel Bindings as set through the GSSAPI can be found here
+<https://docs.oracle.com/cd/E19455-01/806-3814/overview-52/index.html>. Using
+TLS as a example this is how you would add Channel Binding support to your
+authentication mechanism. The following code snippet is based on RFC5929
+<https://tools.ietf.org/html/rfc5929> using the 'tls-server-endpoint-point'
+type.
+
+.. code-block:: python
+
+   import hashlib
+
+    def get_channel_bindings_application_data(socket):
+        # This is a highly simplified example, there are other use cases
+        # where you might need to use different hash types or get a socket
+        # object somehow.
+        server_certificate = socket.getpeercert(True)
+        certificate_hash = 
hashlib.sha256(server_certificate).hexdigest().upper()
+        certificate_digest = base64.b16decode(certificate_hash)
+        application_data = b'tls-server-end-point:%s' % certificate_digest
+
+        return application_data
+
+    def main():
+        # Code to setup a socket with the server
+        # A lot of code to setup the handshake and start the auth process
+        socket = getsocketsomehow()
+
+        # Connect to the host and start the auth process
+
+        # Build the channel bindings object
+        application_data = get_channel_bindings_application_data(socket)
+        channel_bindings = 
kerberos.channelBindings(application_data=application_data)
+
+        # More work to get responses from the server
+
+        result, context = kerberos.authGSSClientInit(kerb_spn, 
gssflags=gssflags, principal=principal)
+
+        # Pass through the channel_bindings object as created in the 
kerberos.channelBindings method
+        result = kerberos.authGSSClientStep(context, neg_resp_value, 
channel_bindings=channel_bindings)
+
+        # Repeat as necessary
+
 ===========
 Python APIs
 ===========
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pykerberos-1.1.14/pykerberos.egg-info/PKG-INFO 
new/pykerberos-1.2.1/pykerberos.egg-info/PKG-INFO
--- old/pykerberos-1.1.14/pykerberos.egg-info/PKG-INFO  2017-01-26 
08:32:40.000000000 +0100
+++ new/pykerberos-1.2.1/pykerberos.egg-info/PKG-INFO   2017-12-20 
19:27:02.000000000 +0100
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: pykerberos
-Version: 1.1.14
+Version: 1.2.1
 Summary: High-level interface to Kerberos
 Home-page: UNKNOWN
 Author: UNKNOWN
 Author-email: UNKNOWN
 License: ASL 2.0
+Description-Content-Type: UNKNOWN
 Description: 
         This Python package is a high-level wrapper for Kerberos (GSSAPI) 
operations.
         The goal is to avoid having to build a module that wraps the entire 
Kerberos.framework,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pykerberos-1.1.14/pysrc/kerberos.py 
new/pykerberos-1.2.1/pysrc/kerberos.py
--- old/pykerberos-1.1.14/pysrc/kerberos.py     2017-01-26 08:32:32.000000000 
+0100
+++ new/pykerberos-1.2.1/pysrc/kerberos.py      2017-12-07 02:02:59.000000000 
+0100
@@ -130,13 +130,16 @@
     @return: a result code (see above).
     """
 
-def authGSSClientStep(context, challenge):
+def authGSSClientStep(context, challenge, **kwargs):
     """
     Processes a single GSSAPI client-side step using the supplied server data.
 
     @param context: the context object returned from authGSSClientInit.
     @param challenge: a string containing the base64-encoded server data 
(which may be empty
         for the first step).
+    @param channel_bindings: Optional channel bindings to bind onto the auth 
request. This
+        struct can be built using the channelBindings function and it not 
specified, this process
+        will pass along GSS_C_NO_CHANNEL_BINDINGS as a default
     @return: a result code (see above).
     """
 
@@ -238,3 +241,74 @@
     @param context: the context object returned from authGSSServerInit.
     @return: a string containing the target name.
     """
+
+"""
+Address Types for Channel Bindings
+https://docs.oracle.com/cd/E19455-01/806-3814/6jcugr7dp/index.html#reference-9
+"""
+
+GSS_C_AF_UNSPEC    = 0
+GSS_C_AF_LOCAL     = 1
+GSS_C_AF_INET      = 2
+GSS_C_AF_IMPLINK   = 3
+GSS_C_AF_PUP       = 4
+GSS_C_AF_CHAOS     = 5
+GSS_C_AF_NS        = 6
+GSS_C_AF_NBS       = 7
+GSS_C_AF_ECMA      = 8
+GSS_C_AF_DATAKIT   = 9
+GSS_C_AF_CCITT     = 10
+GSS_C_AF_SNA       = 11
+GSS_C_AF_DECnet    = 12
+GSS_C_AF_DLI       = 13
+GSS_C_AF_LAT       = 14
+GSS_C_AF_HYLINK    = 15
+GSS_C_AF_APPLETALK = 16
+GSS_C_AF_BSC       = 17
+GSS_C_AF_DSS       = 18
+GSS_C_AF_OSI       = 19
+GSS_C_AF_X25       = 21
+GSS_C_AF_NULLADDR  = 255
+
+def channelBindings(**kwargs):
+    """
+    Builds a gss_channel_bindings_struct which can be used to pass onto 
authGSSClientStep to bind
+    onto the auth. Details on Channel Bindings can be found at 
https://tools.ietf.org/html/rfc5929.
+    More details on the struct can be found at 
https://docs.oracle.com/cd/E19455-01/806-3814/overview-52/index.html
+
+    @param initiator_addrtype: Optional integer used to set the
+        initiator_addrtype, defaults to GSS_C_AF_UNSPEC if not set
+    @param initiator_address: Optional byte string containing the
+        initiator_address
+    @param acceptor_addrtype: Optional integer used to set the
+        acceptor_addrtype, defaults to GSS_C_AF_UNSPEC if not set
+    @param acceptor_address: Optional byte string containing the
+        acceptor_address
+    @param application_data: Optional byte string containing the
+        application_data. An example would be 
'tls-server-end-point:{cert-hash}'
+        where {cert-hash} is the byte string hash of the server's certificate
+    @return: The gss_channel_bindings_struct pointer, which is the channel
+        bindings structure that can be passed onto authGSSClientStep
+    """
+
+def authGSSWinRMEncryptMessage(context, message):
+    """
+    Encrypts a message body with the current Kerberos session key using IOV 
settings for WinRM
+
+    @param context: The context object returned from L{authGSSClientInit}.
+    @param message: The plaintext message to be encrypted. 
+    @return: A tuple of (encrypted_data, header) where encrypted_data is the 
+        ciphertext result of the encryption operation, and header is the GSSAPI
+        header describing the encryption parameters. Both strings contain 
opaque
+        binary data.
+    """
+
+def authGSSWinRMDecryptMessage(context, encrypted_data, header):
+    """
+    Decrypts a ciphertext message body with the current Kerberos session key 
using IOV settings for WinRM
+
+    @param context: The context object returned from L{authGSSClientInit}.
+    @param encrypted_data: The ciphertext message to be decrypted.
+    @param header: The GSSAPI message header containing the encryption 
parameters.
+    @return: The decrypted message text.
+    """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pykerberos-1.1.14/setup.cfg 
new/pykerberos-1.2.1/setup.cfg
--- old/pykerberos-1.1.14/setup.cfg     2017-01-26 08:32:40.000000000 +0100
+++ new/pykerberos-1.2.1/setup.cfg      2017-12-20 19:27:02.000000000 +0100
@@ -1,5 +1,4 @@
 [egg_info]
 tag_build = 
 tag_date = 0
-tag_svn_revision = 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pykerberos-1.1.14/setup.py 
new/pykerberos-1.2.1/setup.py
--- old/pykerberos-1.1.14/setup.py      2017-01-26 08:32:32.000000000 +0100
+++ new/pykerberos-1.2.1/setup.py       2017-12-20 19:20:04.000000000 +0100
@@ -58,7 +58,7 @@
 
 setup (
     name = "pykerberos",
-    version = "1.1.14",
+    version = "1.2.1",
     description = "High-level interface to Kerberos",
     long_description=long_description,
     license="ASL 2.0",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pykerberos-1.1.14/src/kerberos.c 
new/pykerberos-1.2.1/src/kerberos.c
--- old/pykerberos-1.1.14/src/kerberos.c        2017-01-26 08:32:32.000000000 
+0100
+++ new/pykerberos-1.2.1/src/kerberos.c 2017-12-08 18:24:45.000000000 +0100
@@ -50,7 +50,7 @@
     const char *pswd = NULL;
     const char *service = NULL;
     const char *default_realm = NULL;
-    const int verify = 1;
+    int verify = 1;
     int result = 0;
 
     if (!PyArg_ParseTuple(args, "ssss|b", &user, &pswd, &service, 
&default_realm, &verify)) {
@@ -163,13 +163,82 @@
     return Py_BuildValue("i", AUTH_GSS_COMPLETE);
 }
 
-static PyObject *authGSSClientStep(PyObject *self, PyObject *args) {
+#if PY_MAJOR_VERSION >= 3
+void destruct_channel_bindings(PyObject* o) {
+    struct gss_channel_bindings_struct *channel_bindings = 
PyCapsule_GetPointer(o, NULL);
+#else
+void destruct_channel_bindings(void* o) {
+    struct gss_channel_bindings_struct *channel_bindings = (struct 
gss_channel_bindings_struct *)o;
+#endif
+
+    if (channel_bindings != NULL) {
+        if (channel_bindings->initiator_address.value != NULL) {
+            PyMem_Free(channel_bindings->initiator_address.value);
+        }
+
+        if (channel_bindings->acceptor_address.value != NULL) {
+            PyMem_Free(channel_bindings->acceptor_address.value);
+        }
+
+        if (channel_bindings->application_data.value != NULL) {
+            PyMem_Free(channel_bindings->application_data.value);
+        }
+
+        free(channel_bindings);
+    }
+}
+
+static PyObject *channelBindings(PyObject *self, PyObject *args, PyObject* 
keywds) {
+    int initiator_addrtype = GSS_C_AF_UNSPEC;
+    int acceptor_addrtype = GSS_C_AF_UNSPEC;
+
+    const char *encoding = NULL;
+    char *initiator_address = NULL;
+    char *acceptor_address = NULL;
+    char *application_data = NULL;
+    int initiator_length = 0;
+    int acceptor_length = 0;
+    int application_length = 0;
+
+    PyObject *pychan_bindings = NULL;
+    struct gss_channel_bindings_struct *input_chan_bindings;
+    static char *kwlist[] = {"initiator_addrtype", "initiator_address", 
"acceptor_addrtype",
+        "acceptor_address", "application_data", NULL};
+
+    if (!PyArg_ParseTupleAndKeywords(args, keywds, "|iet#iet#et#", kwlist,
+            &initiator_addrtype, &encoding, &initiator_address, 
&initiator_length,
+            &acceptor_addrtype, &encoding, &acceptor_address, &acceptor_length,
+            &encoding, &application_data, &application_length)) {
+        return NULL;
+    }
+
+    input_chan_bindings = (struct gss_channel_bindings_struct *) 
malloc(sizeof(struct gss_channel_bindings_struct));
+    pychan_bindings = PyNew(input_chan_bindings, &destruct_channel_bindings);
+
+    input_chan_bindings->initiator_addrtype = initiator_addrtype;
+    input_chan_bindings->initiator_address.length = initiator_length;
+    input_chan_bindings->initiator_address.value = initiator_address;
+
+    input_chan_bindings->acceptor_addrtype = acceptor_addrtype;
+    input_chan_bindings->acceptor_address.length = acceptor_length;
+    input_chan_bindings->acceptor_address.value = acceptor_address;
+
+    input_chan_bindings->application_data.length = application_length;
+    input_chan_bindings->application_data.value = application_data;
+
+    return Py_BuildValue("N", pychan_bindings);
+}
+
+static PyObject *authGSSClientStep(PyObject *self, PyObject *args, PyObject* 
keywds) {
     gss_client_state *state;
     PyObject *pystate;
     char *challenge = NULL;
+    PyObject *pychan_bindings = NULL;
+    struct gss_channel_bindings_struct *channel_bindings;
+    static char *kwlist[] = {"state", "challenge", "channel_bindings", NULL};
     int result = 0;
 
-    if (!PyArg_ParseTuple(args, "Os", &pystate, &challenge)) {
+    if (! PyArg_ParseTupleAndKeywords(args, keywds, "Os|O", kwlist, &pystate, 
&challenge, &pychan_bindings)) {
         return NULL;
     }
 
@@ -183,7 +252,17 @@
         return NULL;
     }
 
-    result = authenticate_gss_client_step(state, challenge);
+    if (pychan_bindings == NULL) {
+        channel_bindings = GSS_C_NO_CHANNEL_BINDINGS;
+    } else {
+        if (!PyCheck(pychan_bindings)) {
+            PyErr_SetString(PyExc_TypeError, "Expected a 
gss_channel_bindings_struct object");
+            return NULL;
+        }
+        channel_bindings = PyGet(pychan_bindings, struct 
gss_channel_bindings_struct);
+    }
+
+    result = authenticate_gss_client_step(state, challenge, channel_bindings);
     if (result == AUTH_GSS_ERROR) {
         return NULL;
     }
@@ -506,6 +585,137 @@
     return Py_BuildValue("s", state->targetname);
 }
 
+#ifdef GSSAPI_EXT
+static PyObject* authGSSWinRMEncryptMessage(PyObject* self, PyObject* args)
+{
+    char *input = NULL;
+    char *header = NULL;
+    int header_len = 0;
+    char *enc_output = NULL;
+    int enc_output_len = 0;
+    PyObject *pystate = NULL;
+    gss_client_state *state = NULL;
+    int result = 0;
+    PyObject *pyresult = NULL;
+
+    // NB: use et so we get a copy of the string (since gss_wrap_iov mutates 
it), and so we're certain it's always
+    // a UTF8 byte string
+    if (! PyArg_ParseTuple(args, "Oet", &pystate, "UTF-8", &input)) {
+        pyresult = NULL;
+        goto end;
+    }
+
+    if (!PyCheck(pystate)) {
+        PyErr_SetString(PyExc_TypeError, "Expected a context object");
+        pyresult = NULL;
+        goto end;
+    }
+
+    state = PyGet(pystate, gss_client_state);
+    if (state == NULL) {
+        pyresult = NULL;
+        goto end;
+    }
+
+    result = encrypt_message(state, input, &header, &header_len, &enc_output, 
&enc_output_len);
+
+    if (result == AUTH_GSS_ERROR) {
+        pyresult = NULL;
+        goto end;
+    }
+
+#if PY_MAJOR_VERSION >= 3
+    pyresult = Py_BuildValue("y# y#", enc_output, enc_output_len, header, 
header_len);
+#else
+    pyresult = Py_BuildValue("s# s#", enc_output, enc_output_len, header, 
header_len);
+#endif
+
+end:
+    if (input) {
+        PyMem_Free(input);
+    }
+    if (header) {
+        free(header);
+    }
+    if (enc_output) {
+        free(enc_output);
+    }
+
+    return pyresult;
+}
+
+static PyObject* authGSSWinRMDecryptMessage(PyObject* self, PyObject* args)
+{
+    char *header = NULL;
+    int header_len = 0;
+    char *enc_data = NULL;
+    int enc_data_len = 0;
+    PyObject *pystate = NULL;
+    PyObject *pyheader = NULL;
+    PyObject *pyenc_data = NULL;
+    gss_client_state *state = NULL;
+    char *dec_output = NULL;
+    int dec_output_len = 0;
+    int result = 0;
+    PyObject *pyresult = 0;
+
+    // NB: since the sig/data strings are arbitrary binary and don't conform to
+    // a valid encoding, none of the normal string marshaling types will work. 
We'll
+    // have to extract the data later.
+    if (! PyArg_ParseTuple(args, "OOO", &pystate, &pyenc_data, &pyheader)) {
+        pyresult = NULL;
+        goto end;
+    }
+
+    if (!PyCheck(pystate)) {
+        PyErr_SetString(PyExc_TypeError, "Expected a context object");
+        pyresult = NULL;
+        goto end;
+    }
+
+    state = PyGet(pystate, gss_client_state);
+    if (state == NULL) {
+        pyresult = NULL;
+        goto end;
+    }
+
+    // request the length and copy the header and encrypted input data from 
the Python strings
+    header_len = (int) PyBytes_Size(pyheader);
+    header = malloc(header_len);
+    memcpy(header, PyBytes_AsString(pyheader), header_len);
+
+    enc_data_len = (int) PyBytes_Size(pyenc_data);
+    enc_data = malloc(enc_data_len);
+    memcpy(enc_data, PyBytes_AsString(pyenc_data), enc_data_len);
+
+    result = decrypt_message(state, header, header_len, enc_data, 
enc_data_len, &dec_output, &dec_output_len);
+
+    if (result == AUTH_GSS_ERROR) {
+        pyresult = NULL;
+        goto end;
+    }
+
+#if PY_MAJOR_VERSION >= 3
+    pyresult = Py_BuildValue("y#", dec_output, dec_output_len);
+#else
+    pyresult = Py_BuildValue("s#", dec_output, dec_output_len);
+#endif
+
+end:
+    if (header) {
+        free(header);
+    }
+    if (enc_data) {
+        free(enc_data);
+    }
+    if (dec_output) {
+        free(dec_output);
+    }
+
+    return pyresult;
+}
+#endif
+
 static PyMethodDef KerberosMethods[] = {
     {"checkPassword",  checkPassword, METH_VARARGS,
      "Check the supplied user/password against Kerberos KDC."},
@@ -517,7 +727,7 @@
      "Initialize client-side GSSAPI operations."},
     {"authGSSClientClean",  authGSSClientClean, METH_VARARGS,
      "Terminate client-side GSSAPI operations."},
-    {"authGSSClientStep",  authGSSClientStep, METH_VARARGS,
+    {"authGSSClientStep",  (PyCFunction)authGSSClientStep, METH_VARARGS | 
METH_KEYWORDS,
      "Do a client-side GSSAPI step."},
     {"authGSSClientResponse",  authGSSClientResponse, METH_VARARGS,
      "Get the response from the last client-side GSSAPI step."},
@@ -531,11 +741,17 @@
      "Do a GSSAPI wrap."},
     {"authGSSClientUnwrap",  authGSSClientUnwrap, METH_VARARGS,
      "Do a GSSAPI unwrap."},
+    {"channelBindings",  (PyCFunction)channelBindings, METH_VARARGS | 
METH_KEYWORDS,
+     "Build the Channel Bindings Structure based on the input."},
 #ifdef GSSAPI_EXT
     {"authGSSClientWrapIov",  authGSSClientWrapIov, METH_VARARGS,
      "Do a GSSAPI iov wrap."},
     {"authGSSClientUnwrapIov",  authGSSClientUnwrapIov, METH_VARARGS,
      "Do a GSSAPI iov unwrap."},
+    {"authGSSWinRMEncryptMessage",  authGSSWinRMEncryptMessage, METH_VARARGS,
+     "Encrypt a message"},
+    {"authGSSWinRMDecryptMessage",  authGSSWinRMDecryptMessage, METH_VARARGS,
+     "Decrypt a message"},
 #endif
     {"authGSSServerClean",  authGSSServerClean, METH_VARARGS,
      "Terminate server-side GSSAPI operations."},
@@ -620,6 +836,29 @@
     PyDict_SetItemString(d, "GSS_MECH_OID_KRB5", PyNew(&krb5_mech_oid, NULL));
     PyDict_SetItemString(d, "GSS_MECH_OID_SPNEGO", PyNew(&spnego_mech_oid, 
NULL));
 
+    PyDict_SetItemString(d, "GSS_C_AF_UNSPEC", 
PyInt_FromLong(GSS_C_AF_UNSPEC));
+    PyDict_SetItemString(d, "GSS_C_AF_LOCAL", PyInt_FromLong(GSS_C_AF_LOCAL));
+    PyDict_SetItemString(d, "GSS_C_AF_INET", PyInt_FromLong(GSS_C_AF_INET));
+    PyDict_SetItemString(d, "GSS_C_AF_IMPLINK", 
PyInt_FromLong(GSS_C_AF_IMPLINK));
+    PyDict_SetItemString(d, "GSS_C_AF_PUP", PyInt_FromLong(GSS_C_AF_PUP));
+    PyDict_SetItemString(d, "GSS_C_AF_CHAOS", PyInt_FromLong(GSS_C_AF_CHAOS));
+    PyDict_SetItemString(d, "GSS_C_AF_NS", PyInt_FromLong(GSS_C_AF_NS));
+    PyDict_SetItemString(d, "GSS_C_AF_NBS", PyInt_FromLong(GSS_C_AF_NBS));
+    PyDict_SetItemString(d, "GSS_C_AF_ECMA", PyInt_FromLong(GSS_C_AF_ECMA));
+    PyDict_SetItemString(d, "GSS_C_AF_DATAKIT", 
PyInt_FromLong(GSS_C_AF_DATAKIT));
+    PyDict_SetItemString(d, "GSS_C_AF_CCITT", PyInt_FromLong(GSS_C_AF_CCITT));
+    PyDict_SetItemString(d, "GSS_C_AF_SNA", PyInt_FromLong(GSS_C_AF_SNA));
+    PyDict_SetItemString(d, "GSS_C_AF_DECnet", 
PyInt_FromLong(GSS_C_AF_DECnet));
+    PyDict_SetItemString(d, "GSS_C_AF_DLI", PyInt_FromLong(GSS_C_AF_DLI));
+    PyDict_SetItemString(d, "GSS_C_AF_LAT", PyInt_FromLong(GSS_C_AF_LAT));
+    PyDict_SetItemString(d, "GSS_C_AF_HYLINK", 
PyInt_FromLong(GSS_C_AF_HYLINK));
+    PyDict_SetItemString(d, "GSS_C_AF_APPLETALK", 
PyInt_FromLong(GSS_C_AF_APPLETALK));
+    PyDict_SetItemString(d, "GSS_C_AF_BSC", PyInt_FromLong(GSS_C_AF_BSC));
+    PyDict_SetItemString(d, "GSS_C_AF_DSS", PyInt_FromLong(GSS_C_AF_DSS));
+    PyDict_SetItemString(d, "GSS_C_AF_OSI", PyInt_FromLong(GSS_C_AF_OSI));
+    PyDict_SetItemString(d, "GSS_C_AF_X25", PyInt_FromLong(GSS_C_AF_X25));
+    PyDict_SetItemString(d, "GSS_C_AF_NULLADDR", 
PyInt_FromLong(GSS_C_AF_NULLADDR));
+
 error:
     if (PyErr_Occurred())
         PyErr_SetString(PyExc_ImportError, "kerberos: init failed");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pykerberos-1.1.14/src/kerberosgss.c 
new/pykerberos-1.2.1/src/kerberosgss.c
--- old/pykerberos-1.1.14/src/kerberosgss.c     2017-01-26 08:32:32.000000000 
+0100
+++ new/pykerberos-1.2.1/src/kerberosgss.c      2017-12-08 18:24:45.000000000 
+0100
@@ -205,7 +205,7 @@
     return ret;
 }
 
-int authenticate_gss_client_step(gss_client_state* state, const char* 
challenge)
+int authenticate_gss_client_step(gss_client_state* state, const char* 
challenge, struct gss_channel_bindings_struct* channel_bindings)
 {
     OM_uint32 maj_stat;
     OM_uint32 min_stat;
@@ -238,7 +238,7 @@
                                     state->mech_oid,
                                     (OM_uint32)state->gss_flags,
                                     0,
-                                    NULL, //GSS_C_NO_CHANNEL_BINDINGS,
+                                    channel_bindings,
                                     &input_token,
                                     NULL,
                                     &output_token,
@@ -840,3 +840,85 @@
 
     PyErr_SetObject(GssException_class, Py_BuildValue("((s:i)(s:i))", buf_maj, 
err_maj, buf_min, err_min));
 }
+
+#ifdef GSSAPI_EXT
+int encrypt_message(gss_client_state *state, char *message_input, char 
**header, int *header_len, char **encrypted_data, int *encrypted_data_len)
+{
+    OM_uint32 maj_stat;
+    OM_uint32 min_stat;
+    int ret;
+    char *outloc = NULL;
+
+    gss_iov_buffer_desc iov[3];
+    iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE;
+    iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
+    // NB: this will modify the message buffer in place, ensure caller has 
copied the string if necessary
+    iov[1].buffer.value = message_input;
+    iov[1].buffer.length = strlen(message_input);
+    iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING | GSS_IOV_BUFFER_FLAG_ALLOCATE;
+
+    maj_stat = gss_wrap_iov(&min_stat, state->context, 1, GSS_C_QOP_DEFAULT, 
NULL, iov, 3);
+
+    if (GSS_ERROR(maj_stat)) {
+        set_gss_error(maj_stat, min_stat);
+        ret = AUTH_GSS_ERROR;
+        goto end;
+    }
+
+    *header_len = iov[0].buffer.length;
+    *header = malloc(*header_len);
+    memcpy(*header, iov[0].buffer.value, *header_len);
+
+    // copy encrypted data, concatenate padding buffer if present
+    *encrypted_data_len = iov[1].buffer.length + iov[2].buffer.length;
+    *encrypted_data = malloc(*encrypted_data_len);
+    outloc = *encrypted_data;
+    outloc = mempcpy(outloc, iov[1].buffer.value, iov[1].buffer.length);
+    // NB: no-op if no padding is necessary (which seems to always be the case 
with aes256-cts-hmac-sha1-96)
+    mempcpy(outloc, iov[2].buffer.value, iov[2].buffer.length);
+
+    ret = 0;
+end:
+    maj_stat = gss_release_iov_buffer(&min_stat, iov, 3);
+
+    return ret;
+}
+
+int decrypt_message(gss_client_state *state, char *header, int header_len, 
char *data, int data_len, char **decrypted_output, int *decrypted_output_len)
+{
+    OM_uint32 maj_stat;
+    OM_uint32 min_stat;
+    int ret = 0;
+    int conf_state;
+    gss_qop_t qop_state;
+
+    // NB: ensure the caller has copied the python input buffer
+    // so we're not mutating somebody else's string
+
+    gss_iov_buffer_desc iov[3];
+    iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
+    iov[0].buffer.value = header;
+    iov[0].buffer.length = header_len;
+
+    iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
+    iov[1].buffer.value = data;
+    iov[1].buffer.length = data_len;
+
+    maj_stat = gss_unwrap_iov(&min_stat, state->context, &conf_state, 
&qop_state, iov, 2);
+
+    if (GSS_ERROR(maj_stat)) {
+        set_gss_error(maj_stat, min_stat);
+        ret = AUTH_GSS_ERROR;
+        goto end;
+    }
+
+    *decrypted_output = malloc(iov[1].buffer.length);
+    *decrypted_output_len = iov[1].buffer.length;
+
+    memcpy(*decrypted_output, iov[1].buffer.value, iov[1].buffer.length);
+
+    ret = 0;
+end:
+    return ret;
+}
+#endif
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pykerberos-1.1.14/src/kerberosgss.h 
new/pykerberos-1.2.1/src/kerberosgss.h
--- old/pykerberos-1.1.14/src/kerberosgss.h     2017-01-26 08:32:32.000000000 
+0100
+++ new/pykerberos-1.2.1/src/kerberosgss.h      2017-12-07 02:02:50.000000000 
+0100
@@ -56,7 +56,7 @@
 
 int authenticate_gss_client_init(const char* service, const char* principal, 
long int gss_flags, gss_OID mech_oid, gss_client_state* state);
 int authenticate_gss_client_clean(gss_client_state *state);
-int authenticate_gss_client_step(gss_client_state *state, const char 
*challenge);
+int authenticate_gss_client_step(gss_client_state *state, const char 
*challenge, struct gss_channel_bindings_struct *channel_bindings);
 int authenticate_gss_client_unwrap(gss_client_state* state, const char* 
challenge);
 int authenticate_gss_client_wrap(gss_client_state* state, const char* 
challenge, const char* user, int protect);
 #ifdef GSSAPI_EXT
@@ -66,3 +66,5 @@
 int authenticate_gss_server_init(const char* service, gss_server_state* state);
 int authenticate_gss_server_clean(gss_server_state *state);
 int authenticate_gss_server_step(gss_server_state *state, const char 
*challenge);
+int encrypt_message(gss_client_state *state, char *message_input, char 
**header, int *header_len, char **encrypted_data, int *encrypted_data_len);
+int decrypt_message(gss_client_state *state, char *header, int header_len, 
char *data, int data_len, char **decrypted_output, int *decrypted_output_len);


Reply via email to