Closed jborean93 closed 7 years ago
I couldn't get an instance of CalendarServer up and running and interacting with LDAP so I did the next best thing and just create a site backed by Apache and mod_auth_kerb. Here is the testing setup info and details if you wish to test it manually yourself.
This is my Kerberos config setup and configured to connect to the JORDAN.LOCAL
realm.
# Configuration snippets may be placed in this directory as well
includedir /etc/krb5.conf.d/
includedir /var/lib/sss/pubconf/krb5.include.d/
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
dns_lookup_realm = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
# default_realm = EXAMPLE.COM
default_ccache_name = KEYRING:persistent:%{uid}
default_realm = JORDAN.LOCAL
[realms]
# EXAMPLE.COM = {
# kdc = kerberos.example.com
# admin_server = kerberos.example.com
# }
JORDAN.LOCAL = {
kdc = dc01.jordan.local
admin_server = dc01.jordan.local
}
[domain_realm]
# .example.com = EXAMPLE.COM
# example.com = EXAMPLE.COM
jordan.local = JORDAN.LOCAL
.jordan.local = JORDAN.LOCAL
I have manually set the SPN HTTP/centos01.jordan.local
on my test AD server
This is my keytab setup at etc/krb5.keytab
My Kerberos config at /etc/httpd/conf.d/auth_kerberos.conf
is configured like
<Directory /var/www/centos01.jordan.local>
AuthType Kerberos
AuthName "Kerberos Authentication"
KrbAuthRealms JORDAN.LOCAL
Krb5KeyTab /etc/krb5.keytab
KrbMethodNegotiate On
KrbMethodK5Passwd off
KrbVerifyKDC Off
Require user user1@JORDAN.LOCAL
</Directory>
I also just have a basic HTML site configured on port 80 at `/etc/httpd/sites-available/centos01.jordan.local.conf
<VirtualHost *:80>
ServerName centos01.jordan.local
ServerAlias centos01.jordan.local
DocumentRoot /var/www/centos01.jordan.local/public_html
ErrorLog /var/www/centos01.jordan.local/error.log
CustomLog /var/www/centos01.jordan.local/requests.log combined
</VirtualHost>
This is the script I used to test out all 4 existing tests with the Kerberos backed website. It tests it with both Python 2.7.13 and Python 3.6.1.
I had to modify the existing tests to support both Python 2 and 3 (committed) and modify the principal to work outside of CalendarServer (just done through a sed line replacement)
# Change to run in root to makes things simpler
su
# Ensure any leftover tests are cleared before testing again
rm -rf /testing
# Setup testing repo
mkdir /testing
cd /testing
git clone https://github.com/jborean93/ccs-pykerberos.git -b cbt-support
cd ccs-pykerberos
# Show the current git commit hash for verification
git show --oneline -s
# Change the uri for the server test as we aren't using calendar server
sed -i '/uri = "\/principals\/"/c\ uri = "\/"' test.py
# Get kerberos ticket for Kerberos user
kinit user1@JORDAN.LOCAL
# Create virtual env for Python 2.7.13
virtualenv /testing/py27-venv -p /usr/local/bin/python2.7
source /testing/py27-venv/bin/activate
python --version
# Install new ccs-pykerberos library with CBT support
pip install .
# Run tests for Python 2.7.13
python test.py -s HTTP@centos01.jordan.local service
python test.py -u user1 -p Password01 -s HTTP@centos01.jordan.local -r JORDAN.LOCAL basic
python test.py -s HTTP@centos01.jordan.local -r JORDAN.LOCAL gssapi
python test.py -s HTTP@centos01.jordan.local -h centos01.jordan.local -i 80 server
# Create virtual env for Python 3.6.1 and run tests
deactivate
virtualenv /testing/py36-venv -p /usr/local/bin/python3.6
source /testing/py36-venv/bin/activate
python --version
pip install .
python test.py -s HTTP@centos01.jordan.local service
python test.py -u user1 -p Password01 -s HTTP@centos01.jordan.local -r JORDAN.LOCAL basic
python test.py -s HTTP@centos01.jordan.local -r JORDAN.LOCAL gssapi
python test.py -s HTTP@centos01.jordan.local -h centos01.jordan.local -i 80 server
This is the test output from the script
[administrator@CENTOS01 ~]$ # Change to run in root to makes things simpler
[administrator@CENTOS01 ~]$ su
Password:
[root@CENTOS01 administrator]#
[root@CENTOS01 administrator]# # Ensure any leftover tests are cleared before testing again
[root@CENTOS01 administrator]# rm -rf /testing
[root@CENTOS01 administrator]#
[root@CENTOS01 administrator]# # Setup testing repo
[root@CENTOS01 administrator]# mkdir /testing
[root@CENTOS01 administrator]# cd /testing
[root@CENTOS01 testing]# git clone https://github.com/jborean93/ccs-pykerberos.git -b cbt-support
Cloning into 'ccs-pykerberos'...
remote: Counting objects: 609, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 609 (delta 2), reused 6 (delta 2), pack-reused 603
Receiving objects: 100% (609/609), 144.42 KiB | 0 bytes/s, done.
Resolving deltas: 100% (425/425), done.
[root@CENTOS01 testing]# cd ccs-pykerberos
[root@CENTOS01 ccs-pykerberos]#
[root@CENTOS01 ccs-pykerberos]# # Show the current git commit hash for verification
[root@CENTOS01 ccs-pykerberos]# git show --oneline -s
d87a465 I broke Python 2 now I need to have a fix for both
[root@CENTOS01 ccs-pykerberos]#
[root@CENTOS01 ccs-pykerberos]# # Change the uri for the server test as we aren't using calendar server
[root@CENTOS01 ccs-pykerberos]# sed -i '/uri = "\/principals\/"/c\ uri = "\/"' test.py
[root@CENTOS01 ccs-pykerberos]#
[root@CENTOS01 ccs-pykerberos]# # Get kerberos ticket for Kerberos user
[root@CENTOS01 ccs-pykerberos]# kinit user1@JORDAN.LOCAL
Password for user1@JORDAN.LOCAL:
[root@CENTOS01 ccs-pykerberos]#
[root@CENTOS01 ccs-pykerberos]# # Create virtual env for Python 2.7.13
[root@CENTOS01 ccs-pykerberos]# virtualenv /testing/py27-venv -p /usr/local/bin/python2.7
Running virtualenv with interpreter /usr/local/bin/python2.7
New python executable in /testing/py27-venv/bin/python2.7
Also creating executable in /testing/py27-venv/bin/python
Installing setuptools, pip, wheel...done.
[root@CENTOS01 ccs-pykerberos]# source /testing/py27-venv/bin/activate
(py27-venv) [root@CENTOS01 ccs-pykerberos]# python --version
Python 2.7.13
(py27-venv) [root@CENTOS01 ccs-pykerberos]#
(py27-venv) [root@CENTOS01 ccs-pykerberos]# # Install new ccs-pykerberos library with CBT support
(py27-venv) [root@CENTOS01 ccs-pykerberos]# pip install .
Processing /testing/ccs-pykerberos
Building wheels for collected packages: kerberos
Running setup.py bdist_wheel for kerberos ... done
Stored in directory: /root/.cache/pip/wheels/7c/f0/16/7c29c46808274738267e8967235b93dda40a58a04af5c2b1c0
Successfully built kerberos
Installing collected packages: kerberos
Successfully installed kerberos-1.2.6
(py27-venv) [root@CENTOS01 ccs-pykerberos]#
(py27-venv) [root@CENTOS01 ccs-pykerberos]# # Run tests for Python 2.7.13
(py27-venv) [root@CENTOS01 ccs-pykerberos]# python test.py -s HTTP@centos01.jordan.local service
*** Running Service Principal test
Kerberos service principal for HTTP/centos01.jordan.local succeeded: HTTP/centos01.jordan.local@JORDAN.LOCAL
*** Done
(py27-venv) [root@CENTOS01 ccs-pykerberos]# python test.py -u user1 -p Password01 -s HTTP@centos01.jordan.local -r JORDAN.LOCAL basic
*** Running basic test
Kerberos authentication for user1 succeeded
*** Done
(py27-venv) [root@CENTOS01 ccs-pykerberos]#
(py27-venv) [root@CENTOS01 ccs-pykerberos]# python test.py -s HTTP@centos01.jordan.local -r JORDAN.LOCAL gssapi
*** Running GSSAPI test
Status for authGSSClientInit = Complete
Status for authGSSServerInit = Complete
Status for authGSSClientStep = Continue
Status for authGSSServerStep = Complete
Status for authGSSClientStep = Complete
Server user name: user1@JORDAN.LOCAL
Server target name: None
Client user name: user1@JORDAN.LOCAL
Status for authGSSClientClean = Complete
Status for authGSSServerClean = Complete
*** Done
(py27-venv) [root@CENTOS01 ccs-pykerberos]# python test.py -s HTTP@centos01.jordan.local -h centos01.jordan.local -i 80 server
*** Running HTTP test
Authenticated successfully
*** Done
(py27-venv) [root@CENTOS01 ccs-pykerberos]#
(py27-venv) [root@CENTOS01 ccs-pykerberos]# # Create virtual env for Python 3.6.1 and run tests
(py27-venv) [root@CENTOS01 ccs-pykerberos]# deactivate
[root@CENTOS01 ccs-pykerberos]# virtualenv /testing/py36-venv -p /usr/local/bin/python3.6
Already using interpreter /usr/local/bin/python3.6
Using base prefix '/usr/local'
New python executable in /testing/py36-venv/bin/python3.6
Also creating executable in /testing/py36-venv/bin/python
Installing setuptools, pip, wheel...done.
[root@CENTOS01 ccs-pykerberos]# source /testing/py36-venv/bin/activate
(py36-venv) [root@CENTOS01 ccs-pykerberos]# python --version
Python 3.6.1
(py36-venv) [root@CENTOS01 ccs-pykerberos]#
(py36-venv) [root@CENTOS01 ccs-pykerberos]# pip install .
Processing /testing/ccs-pykerberos
Building wheels for collected packages: kerberos
Running setup.py bdist_wheel for kerberos ... done
Stored in directory: /root/.cache/pip/wheels/7c/f0/16/7c29c46808274738267e8967235b93dda40a58a04af5c2b1c0
Successfully built kerberos
Installing collected packages: kerberos
Successfully installed kerberos-1.2.6
(py36-venv) [root@CENTOS01 ccs-pykerberos]#
(py36-venv) [root@CENTOS01 ccs-pykerberos]# python test.py -s HTTP@centos01.jordan.local service
*** Running Service Principal test
Kerberos service principal for HTTP/centos01.jordan.local succeeded: HTTP/centos01.jordan.local@JORDAN.LOCAL
*** Done
(py36-venv) [root@CENTOS01 ccs-pykerberos]# python test.py -u user1 -p Password01 -s HTTP@centos01.jordan.local -r JORDAN.LOCAL basic
*** Running basic test
Kerberos authentication for user1 succeeded
*** Done
(py36-venv) [root@CENTOS01 ccs-pykerberos]#
(py36-venv) [root@CENTOS01 ccs-pykerberos]# python test.py -s HTTP@centos01.jordan.local -r JORDAN.LOCAL gssapi
*** Running GSSAPI test
Status for authGSSClientInit = Complete
Status for authGSSServerInit = Complete
Status for authGSSClientStep = Continue
Status for authGSSServerStep = Complete
Status for authGSSClientStep = Complete
Server user name: user1@JORDAN.LOCAL
Server target name: None
Client user name: user1@JORDAN.LOCAL
Status for authGSSClientClean = Complete
Status for authGSSServerClean = Complete
*** Done
(py36-venv) [root@CENTOS01 ccs-pykerberos]# python test.py -s HTTP@centos01.jordan.local -h centos01.jordan.local -i 80 server
*** Running HTTP test
Authenticated successfully
*** Done
(py36-venv) [root@CENTOS01 ccs-pykerberos]#
Hopefully this manual test and my test with a CBT endpoint as shown in the first post helps to alleviate any concerns about backwards compatibility. If you have anything else you want me to try or do differently just ask and I should be able to do it.
@dreness I hope you were the person I was talking to in IRC, just hoping the above information is good enough to cover the testing side of things. Not sure what you would like me to do next.
@jborean93 I am. Your testing efforts have been substantial and are well received. I will dig into this and get some comments from others, and can hopefully merge this soon.
Thanks for that, I might spend some time on another PR soon to get integration with travis to make this easier in the future but it all depends on how much time I have.
This looks good -- one question: for this malloc...
input_chan_bindings = (struct gss_channel_bindings_struct *) malloc(sizeof(struct gss_channel_bindings_struct));
Who is responsible for freeing it? Is it handled by Python object reference counting?
I'm not sure on that (my inexperience shining through) but I suppose after the library using this get's a successful authentication it should free it. Is there a way to do this in python or do I need to pass in the object to another method on the C side?
I am not familiar with the Python/CObjects API, but I do see in the docs that PyCObject_FromVoidPtr( ) can take a destructor function which gets called with the python object is reclaimed. Perhaps it needs to be passed a function that does the free? We need to get someone more familiar with this to chime in.
I'll do some research and will see what I can find.
I'm trying to get this loaded up in xcode so I can point the clang static analyzer at it, which should help identify lifecycle issues.
So I think you want to pass "free" to PyCObject_FromVoidPtr, e.g.:
pychan_bindings = PyCObject_FromVoidPtr(input_chan_bindings, free);
I received a hot tip from another frog right around the time that a similar conclusion was reached by m0rgen: If "free" is passed instead of NULL, that should free the C-side object. Doing some testing on that...
So if I pass free to that Python will automatically free the memory or do I still have to call that somewhere else when ready?
The python object is reclaimed automatically, and this "destr" argument is a facility for allowing that reclamation to flow back to the C-side, by the C. sure. (cough). The argument itself is the function that is called (with one argument: a pointer to the thing being freed) when the python object is reclaimed, so to do the moral equivalent on the C-side, we can just pass 'free'.
Made those changes plus I bumped the version. I checked with my original test and the CBT stuff still works after the test.
It would be really helpful if you could update the docstring for authGSSClientStep with the new parameter and an example of how to use it here:
https://github.com/apple/ccs-pykerberos/blob/master/pysrc/kerberos.py
Looking good! @jborean93 - do you still have the test environment available? If so, would it be possible for you to run through the testing and validation again with all the recent changes applied?
Yep I just reran the original tests and the WinRM test and here is the output. Also is there a way of having a collapsable block of text in Github?
Cloning into 'ccs-pykerberos'...
1200d2a More improvements to handle memory deallocation
New python executable in /testing/py27-venv/bin/python2.7
Also creating executable in /testing/py27-venv/bin/python
Installing setuptools, pip, wheel...done.
Running virtualenv with interpreter /usr/local/bin/python2.7
Python 2.7.13
Processing /testing/ccs-pykerberos
Building wheels for collected packages: kerberos
Running setup.py bdist_wheel for kerberos: started
Running setup.py bdist_wheel for kerberos: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/7c/f0/16/7c29c46808274738267e8967235b93dda40a58a04af5c2b1c0
Successfully built kerberos
Installing collected packages: kerberos
Successfully installed kerberos-1.3.0
Collecting pywinrm
Using cached pywinrm-0.2.2-py2.py3-none-any.whl
Collecting xmltodict (from pywinrm)
Using cached xmltodict-0.11.0-py2.py3-none-any.whl
Collecting requests-ntlm>=0.3.0 (from pywinrm)
Using cached requests_ntlm-1.0.0-py2.py3-none-any.whl
Requirement already satisfied: six in /testing/py27-venv/lib/python2.7/site-packages (from pywinrm)
Collecting requests>=2.9.1 (from pywinrm)
Using cached requests-2.17.3-py2.py3-none-any.whl
Collecting ntlm-auth>=1.0.2 (from requests-ntlm>=0.3.0->pywinrm)
Using cached ntlm_auth-1.0.4-py2.py3-none-any.whl
Collecting idna<2.6,>=2.5 (from requests>=2.9.1->pywinrm)
Using cached idna-2.5-py2.py3-none-any.whl
Collecting urllib3<1.22,>=1.21.1 (from requests>=2.9.1->pywinrm)
Using cached urllib3-1.21.1-py2.py3-none-any.whl
Collecting chardet<3.1.0,>=3.0.2 (from requests>=2.9.1->pywinrm)
Using cached chardet-3.0.3-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests>=2.9.1->pywinrm)
Using cached certifi-2017.4.17-py2.py3-none-any.whl
Collecting ordereddict (from ntlm-auth>=1.0.2->requests-ntlm>=0.3.0->pywinrm)
Installing collected packages: xmltodict, ordereddict, ntlm-auth, idna, urllib3, chardet, certifi, requests, requests-ntlm, pywinrm
Successfully installed certifi-2017.4.17 chardet-3.0.3 idna-2.5 ntlm-auth-1.0.4 ordereddict-1.1 pywinrm-0.2.2 requests-2.17.3 requests-ntlm-1.0.0 urllib3-1.21.1 xmltodict-0.11.0
Collecting git+https://github.com/jborean93/requests-kerberos@add-cbt
Cloning https://github.com/jborean93/requests-kerberos (to add-cbt) to /tmp/pip-MFU6oE-build
Requirement already satisfied: requests>=1.1.0 in /testing/py27-venv/lib/python2.7/site-packages (from requests-kerberos==0.11.0)
Collecting pyasn1 (from requests-kerberos==0.11.0)
Using cached pyasn1-0.2.3-py2.py3-none-any.whl
Collecting pyasn1-modules (from requests-kerberos==0.11.0)
Using cached pyasn1_modules-0.0.8-py2.py3-none-any.whl
Requirement already satisfied: kerberos<2.0.0,>=1.2.5 in /testing/py27-venv/lib/python2.7/site-packages (from requests-kerberos==0.11.0)
Requirement already satisfied: idna<2.6,>=2.5 in /testing/py27-venv/lib/python2.7/site-packages (from requests>=1.1.0->requests-kerberos==0.11.0)
Requirement already satisfied: urllib3<1.22,>=1.21.1 in /testing/py27-venv/lib/python2.7/site-packages (from requests>=1.1.0->requests-kerberos==0.11.0)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /testing/py27-venv/lib/python2.7/site-packages (from requests>=1.1.0->requests-kerberos==0.11.0)
Requirement already satisfied: certifi>=2017.4.17 in /testing/py27-venv/lib/python2.7/site-packages (from requests>=1.1.0->requests-kerberos==0.11.0)
Installing collected packages: pyasn1, pyasn1-modules, requests-kerberos
Running setup.py install for requests-kerberos: started
Running setup.py install for requests-kerberos: finished with status 'done'
Successfully installed pyasn1-0.2.3 pyasn1-modules-0.0.8 requests-kerberos-0.11.0
*** Running Service Principal test
Kerberos service principal for HTTP/centos01.jordan.local succeeded: HTTP/centos01.jordan.local@JORDAN.LOCAL
*** Done
*** Running basic test
Kerberos authentication for user1 succeeded
*** Done
*** Running GSSAPI test
Status for authGSSClientInit = Complete
Status for authGSSServerInit = Complete
Status for authGSSClientStep = Continue
Status for authGSSServerStep = Complete
Status for authGSSClientStep = Complete
Server user name: user1@JORDAN.LOCAL
Server target name: None
Client user name: user1@JORDAN.LOCAL
Status for authGSSClientClean = Complete
Status for authGSSServerClean = Complete
*** Done
*** Running HTTP test
Authenticated successfully
*** Done
Return Code: 0
STDOUT:
Windows IP Configuration
Host Name . . . . . . . . . . . . : APP01
Primary Dns Suffix . . . . . . . : jordan.local
Node Type . . . . . . . . . . . . : Hybrid
IP Routing Enabled. . . . . . . . : No
WINS Proxy Enabled. . . . . . . . : No
DNS Suffix Search List. . . . . . : jordan.local
Ethernet adapter Ethernet:
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Microsoft Hyper-V Network Adapter
Physical Address. . . . . . . . . : 00-15-5D-01-03-02
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
Link-local IPv6 Address . . . . . : fe80::e1d3:888b:78d2:b891%5(Preferred)
IPv4 Address. . . . . . . . . . . : 192.168.1.152(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.1.1
DHCPv6 IAID . . . . . . . . . . . : 50337117
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-20-80-CD-75-00-15-5D-01-03-02
DNS Servers . . . . . . . . . . . : 192.168.1.151
NetBIOS over Tcpip. . . . . . . . : Enabled
Tunnel adapter isatap.{D3EFED2A-9F5A-4D9C-B331-6669AC9E118B}:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Microsoft ISATAP Adapter
Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
Tunnel adapter Teredo Tunneling Pseudo-Interface:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Teredo Tunneling Pseudo-Interface
Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
STDERR:
Using base prefix '/usr/local'
New python executable in /testing/py36-venv/bin/python3.6
Also creating executable in /testing/py36-venv/bin/python
Installing setuptools, pip, wheel...done.
Running virtualenv with interpreter /usr/local/bin/python3.6
Python 3.6.1
Processing /testing/ccs-pykerberos
Building wheels for collected packages: kerberos
Running setup.py bdist_wheel for kerberos: started
Running setup.py bdist_wheel for kerberos: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/7c/f0/16/7c29c46808274738267e8967235b93dda40a58a04af5c2b1c0
Successfully built kerberos
Installing collected packages: kerberos
Successfully installed kerberos-1.3.0
Collecting pywinrm
Using cached pywinrm-0.2.2-py2.py3-none-any.whl
Collecting xmltodict (from pywinrm)
Using cached xmltodict-0.11.0-py2.py3-none-any.whl
Collecting requests-ntlm>=0.3.0 (from pywinrm)
Using cached requests_ntlm-1.0.0-py2.py3-none-any.whl
Collecting requests>=2.9.1 (from pywinrm)
Using cached requests-2.17.3-py2.py3-none-any.whl
Requirement already satisfied: six in /testing/py36-venv/lib/python3.6/site-packages (from pywinrm)
Collecting ntlm-auth>=1.0.2 (from requests-ntlm>=0.3.0->pywinrm)
Using cached ntlm_auth-1.0.4-py2.py3-none-any.whl
Collecting idna<2.6,>=2.5 (from requests>=2.9.1->pywinrm)
Using cached idna-2.5-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests>=2.9.1->pywinrm)
Using cached certifi-2017.4.17-py2.py3-none-any.whl
Collecting urllib3<1.22,>=1.21.1 (from requests>=2.9.1->pywinrm)
Using cached urllib3-1.21.1-py2.py3-none-any.whl
Collecting chardet<3.1.0,>=3.0.2 (from requests>=2.9.1->pywinrm)
Using cached chardet-3.0.3-py2.py3-none-any.whl
Collecting ordereddict (from ntlm-auth>=1.0.2->requests-ntlm>=0.3.0->pywinrm)
Installing collected packages: xmltodict, idna, certifi, urllib3, chardet, requests, ordereddict, ntlm-auth, requests-ntlm, pywinrm
Successfully installed certifi-2017.4.17 chardet-3.0.3 idna-2.5 ntlm-auth-1.0.4 ordereddict-1.1 pywinrm-0.2.2 requests-2.17.3 requests-ntlm-1.0.0 urllib3-1.21.1 xmltodict-0.11.0
Collecting git+https://github.com/jborean93/requests-kerberos@add-cbt
Cloning https://github.com/jborean93/requests-kerberos (to add-cbt) to /tmp/pip-5rln0mag-build
Requirement already satisfied: requests>=1.1.0 in /testing/py36-venv/lib/python3.6/site-packages (from requests-kerberos==0.11.0)
Collecting pyasn1 (from requests-kerberos==0.11.0)
Using cached pyasn1-0.2.3-py2.py3-none-any.whl
Collecting pyasn1-modules (from requests-kerberos==0.11.0)
Using cached pyasn1_modules-0.0.8-py2.py3-none-any.whl
Requirement already satisfied: kerberos<2.0.0,>=1.2.5 in /testing/py36-venv/lib/python3.6/site-packages (from requests-kerberos==0.11.0)
Requirement already satisfied: certifi>=2017.4.17 in /testing/py36-venv/lib/python3.6/site-packages (from requests>=1.1.0->requests-kerberos==0.11.0)
Requirement already satisfied: idna<2.6,>=2.5 in /testing/py36-venv/lib/python3.6/site-packages (from requests>=1.1.0->requests-kerberos==0.11.0)
Requirement already satisfied: urllib3<1.22,>=1.21.1 in /testing/py36-venv/lib/python3.6/site-packages (from requests>=1.1.0->requests-kerberos==0.11.0)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /testing/py36-venv/lib/python3.6/site-packages (from requests>=1.1.0->requests-kerberos==0.11.0)
Installing collected packages: pyasn1, pyasn1-modules, requests-kerberos
Running setup.py install for requests-kerberos: started
Running setup.py install for requests-kerberos: finished with status 'done'
Successfully installed pyasn1-0.2.3 pyasn1-modules-0.0.8 requests-kerberos-0.11.0
*** Running Service Principal test
Kerberos service principal for HTTP/centos01.jordan.local succeeded: HTTP/centos01.jordan.local@JORDAN.LOCAL
*** Done
*** Running basic test
Kerberos authentication for user1 succeeded
*** Done
*** Running GSSAPI test
Status for authGSSClientInit = Complete
Status for authGSSServerInit = Complete
Status for authGSSClientStep = Continue
Status for authGSSServerStep = Complete
Status for authGSSClientStep = Complete
Server user name: user1@JORDAN.LOCAL
Server target name: None
Client user name: user1@JORDAN.LOCAL
Status for authGSSClientClean = Complete
Status for authGSSServerClean = Complete
*** Done
*** Running HTTP test
Authenticated successfully
*** Done
Return Code: 0
STDOUT: b'\r\nWindows IP Configuration\r\n\r\n Host Name . . . . . . . . . . . . : APP01\r\n Primary Dns Suffix . . . . . . . : jordan.local\r\n Node Type . . . . . . . . . . . . : Hybrid\r\n IP Routing Enabled. . . . . . . . : No\r\n WINS Proxy Enabled. . . . . . . . : No\r\n DNS Suffix Search List. . . . . . : jordan.local\r\n\r\nEthernet adapter Ethernet:\r\n\r\n Connection-specific DNS Suffix . : \r\n Description . . . . . . . . . . . : Microsoft Hyper-V Network Adapter\r\n Physical Address. . . . . . . . . : 00-15-5D-01-03-02\r\n DHCP Enabled. . . . . . . . . . . : No\r\n Autoconfiguration Enabled . . . . : Yes\r\n Link-local IPv6 Address . . . . . : fe80::e1d3:888b:78d2:b891%5(Preferred) \r\n IPv4 Address. . . . . . . . . . . : 192.168.1.152(Preferred) \r\n Subnet Mask . . . . . . . . . . . : 255.255.255.0\r\n Default Gateway . . . . . . . . . : 192.168.1.1\r\n DHCPv6 IAID . . . . . . . . . . . : 50337117\r\n DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-20-80-CD-75-00-15-5D-01-03-02\r\n DNS Servers . . . . . . . . . . . : 192.168.1.151\r\n NetBIOS over Tcpip. . . . . . . . : Enabled\r\n\r\nTunnel adapter isatap.{D3EFED2A-9F5A-4D9C-B331-6669AC9E118B}:\r\n\r\n Media State . . . . . . . . . . . : Media disconnected\r\n Connection-specific DNS Suffix . : \r\n Description . . . . . . . . . . . : Microsoft ISATAP Adapter\r\n Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0\r\n DHCP Enabled. . . . . . . . . . . : No\r\n Autoconfiguration Enabled . . . . : Yes\r\n\r\nTunnel adapter Teredo Tunneling Pseudo-Interface:\r\n\r\n Media State . . . . . . . . . . . : Media disconnected\r\n Connection-specific DNS Suffix . : \r\n Description . . . . . . . . . . . : Teredo Tunneling Pseudo-Interface\r\n Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0\r\n DHCP Enabled. . . . . . . . . . . : No\r\n Autoconfiguration Enabled . . . . : Yes\r\n'
STDERR: b''
In buildChannelBindingsStruct the "et#" format is not being used properly. This causes warnings when compiling:
src/kerberos.c:272:51: warning: incompatible pointer to integer conversion assigning to 'size_t' (aka 'unsigned long') from 'int *' [-Wint-conversion]
input_chan_bindings->initiator_address.length = initiator_length;
^ ~~~~
I've attached a diff to correct this. Please run all your tests again after this fix.
diff --git a/src/kerberos.c b/src/kerberos.c index 406f5c1..440831d 100644 --- a/src/kerberos.c +++ b/src/kerberos.c @@ -244,12 +244,12 @@ static PyObject buildChannelBindingsStruct(PyObject self, PyObject *args, PyOb int acceptor_addrtype = GSS_C_AF_UNSPEC;
const char *encoding = NULL;
int application_length = 0;
int result = 0;
Ugh! My diff got messed up. Let's try again:
diff --git a/src/kerberos.c b/src/kerberos.c
index 406f5c1..440831d 100644
--- a/src/kerberos.c
+++ b/src/kerberos.c
@@ -244,12 +244,12 @@ static PyObject *buildChannelBindingsStruct(PyObject *self, PyObject *args, PyOb
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 = NULL;
- int *acceptor_length = NULL;
- int *application_length = 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;
int result = 0;
Some other things:
1) I think "buildChannelBindingsStruct" should be renamed to "channelBindings".
3) I think the keyword argument for authGSSClientStep should be "channel_bindings" rather than "input_chan_bindings".
2) I think "channelBindings" should just return the py object and not the tuple of integer result and py object. Reasons:
kerberos.authGSSClientStep(..., ..., channel_bindings=kerberos.channelBindings(initiator_addrtype=0, initiator_address="foobar"))
Slightly better than having to always append "[1]" to the channelBindings result to get the py object.
@cyrusdaboo thanks for the feedback, I've made the changes you have requested and commit them. I also reran the tests and it still works fine. Please let me know if you wish for any more changes.
Merged in the latest changes from the master branch and pushed them to this branch. Looks like the travis build is working fine. Please let me know if there is anything else you need from me.
@dreness @cyrusdaboo any chance you can have another look, I am hoping to get a consensus with this PR and the Windows equivalent https://github.com/mongodb-labs/winkerberos/pull/17 and I am nearing the end of that PR.
@jborean93 I think we're looking good here. I'm going to ping one more possibly interested stakeholder, but personally I'm satisfied.
Thanks again @jborean93 - very nice job on this PR :)
Thanks @dreness and others who helped with this PR.
Added support for creating an input channel bindings value and passing that into the authGSSClientStep as an optional argument. Will continue on with the default behavior if this isn't specified.
I'm fairly new to C so happy to take any pointers and ideas on ways this could be better improved. I've tested this manually on an IIS and WinRM endpoint where the channel bindings token is set to required and verified it worked.
Test Result:
This is the environment set up I had to verify the test results, please ask me any questions around it or if you know of a better way to add automated tests.
Windows Configuration
Run this script on a Server 2008 or newer host that is hooked up to a domain https://github.com/ansible/ansible/blob/devel/examples/scripts/ConfigureRemotingForAnsible.ps1. This will set up a WinRM listener over HTTPS with a self signed cert and open and firewall rules
After running this run the following command in Powershell to set the CBT policy to Strict
You can verify the setting by running this in powershell
Python Host Config
On the *nix server you are using for testing run the following command to install the relevant libraries and set everything up
Create the python script below
Run the following commands to get a kerberos ticket and test out the script
You get the Windows IP configuration returned
If you are using the stock standard kerberos and requests-kerberos library you would get the following error returned