mongodb / winkerberos

A native Kerberos client implementation for Python on Windows
Apache License 2.0
54 stars 15 forks source link

Add support for channel bindings #16

Closed behackett closed 7 years ago

behackett commented 7 years ago

Related to https://github.com/requests/requests-kerberos/pull/92 and https://github.com/apple/ccs-pykerberos/pull/55. We should attempt to add channel bindings support to WinKerberos.

Microsoft doesn't document support for channel bindings in InitializeSecurityContext, but they do document it for AcceptSecurityContext. I'm guessing / hoping the missing docs for InitializeSecurityContext are an oversite. It looks like we can add a SecBuffer with BufferType SECBUFFER_CHANNEL_BINDINGS to the SecBufferDesc instance here. There is an example of someone doing this with PyWin32 here.

The SEC_CHANNEL_BINDINGS struct is documented here. It's not clear to me if SSPI equivalents of constants like GSS_C_AF_UNSPEC are actually defined somewhere, or if we can just define them ourselves starting with the value 0. For reference - http://www.shrubbery.net/solaris9ab/SUNWdev/GSSAPIPG/p27.html#REFERENCE-9

It's also unclear to me if the current test suite (which uses MongoDB for all its tests) can actually test this feature.

behackett commented 7 years ago

@jborean93 - let me know if you want to take a crack at this.

jborean93 commented 7 years ago

I had a very brief crack a few months ago but didn't get too far and had to stop due to prior commitments. I'm happy to give it another go once the changes here https://github.com/apple/ccs-pykerberos/pull/55#discussion_r118811789 are through.

As for testing there are 2 ways I know you can test this with, setup an IIS server with extended protection enabled or setup a WinRM endpoint with CBT set to strict. As for testing the Apple stuff I'm trying to find a web service that supports this but the closest I can find is using a test branch of mod_auth_gssapi that is meant to support it.

jborean93 commented 7 years ago

Hey @behackett I've finally got a working prototype for this by hard coding a cert hash and will continue it further to get the hash from the calling library.

Just thought I'd let you know that where Microsoft says Unless the client context was initiated by the server, the value of this parameter must be NULL on the first call to the function is a complete lie, I had to always pass in the SECBUFFER_CHANNEL_BINDINGS SecBuffer on all calls or else it will fail. Edit: This was me being misinformed and it turned out to work even when setting the first call to none

behackett commented 7 years ago

Nice work! I'm looking forward to seeing the patch.

BTW, re-reading the docs for SEC_CHANNEL_BINDINGS, I notice this text:

Schannel sets to zero the value of all members of this structure other than cbApplicationDataLength and dwApplicationDataOffset.

I can't find any constants in SSPI or Schannel for things like GSS_C_AF_UNSPEC. I'm guessing channel bindings in SSPI were designed to work directly with Schannel, so the constants probably don't exist. I'm thinking we can still define GSS_C_AF_UNSPEC to 0, but I'm not sure it makes sense to define any of the other types. What do you think?

jborean93 commented 7 years ago

I was just going to keep GSS_C_AF_UNSPEC like you said as I don't think Windows implements channel bindings in the traditional RFC sense so the other values aren't used. The SSPI structure is a bit different from gss_channel_bindings_t that is used in the gssapi but I should be able to the same method in this library to ensure compatibility with it.

jborean93 commented 7 years ago

I've got some working code here https://github.com/jborean93/winkerberos/tree/channel-bindings if you were interested to have a quick look. I'll be doing some more testing this evening to ensure it hasn't broken the normal behaviour.

The only remaining thing I am aware that I need to do is to free up the memory in the destructure but apart from that I am fairly happy that I can get a similar format to how ccs-kerberos is set up like.

behackett commented 7 years ago

Fixed by https://github.com/mongodb-labs/winkerberos/pull/17.

behackett commented 7 years ago

0.7.0 has been released - https://pypi.python.org/pypi/winkerberos/0.7.0

jborean93 commented 7 years ago

Fantastic, thank you very much for your help.