Skip to content

Commit

Permalink
Merge 5f3cacb into 9b979ec
Browse files Browse the repository at this point in the history
  • Loading branch information
midnightercz committed Mar 4, 2020
2 parents 9b979ec + 5f3cacb commit 62ae32e
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 15 deletions.
19 changes: 19 additions & 0 deletions docs/source/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- N/A

## [0.6.0] - 2020-03-01

### Fixed

- requests-gssapi replaced with requests-kerberos

## [0.5.0] - 2020-02-29

### Fixed

- kerberos auth fixed

## [0.4.0] - 2020-02-27

### Fixed

- IIB compatiblity fixes
- kerberos auth fixed

## [0.4.0] - 2020-02-27

### Fixed
Expand Down
38 changes: 28 additions & 10 deletions iiblib/iibclient.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import time
import os
import subprocess
import tempfile

import kerberos
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
Expand Down Expand Up @@ -210,7 +213,7 @@ class IIBKrbAuth(IIBAuth):
"""Kerberos authentication support for IIBClient"""

# pylint: disable=super-init-not-called
def __init__(self, krb_princ, ktfile=None):
def __init__(self, krb_princ, service, ktfile=None):
"""
Args:
krb_princ (str)
Expand All @@ -222,23 +225,38 @@ def __init__(self, krb_princ, ktfile=None):
"""
self.krb_princ = krb_princ
self.ktfile = ktfile
self.service = service

def _krb_auth_header(self):
if self.ktfile:
old_kt_file = os.environ.get("KRB5_CLIENT_KTNAME")
retcode = subprocess.Popen(
["klist"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
).wait()
krb5ccname = None
if retcode or self.ktfile:
old_krb5ccname = os.environ.get("KRB5CCNAME", "")
_, krb5ccname = tempfile.mkstemp(prefix="krb5cc")
retcode = subprocess.Popen(
["kinit", self.krb_princ, "-k", "-t", self.ktfile, "-c", krb5ccname],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
).wait()
try:
auth = HTTPKerberosAuth(
mutual_authentication=OPTIONAL, principal=self.krb_princ
)
if krb5ccname:
os.environ["KRB5CCNAME"] = krb5ccname
__, krb_context = kerberos.authGSSClientInit("HTTP@%s" % self.service)
kerberos.authGSSClientStep(krb_context, "")
self._krb_context = krb_context
auth_header = "Negotiate " + kerberos.authGSSClientResponse(krb_context)
finally:
if self.ktfile:
os.environ["KRB5_CLIENT_KTNAME"] = old_kt_file or ""
if krb5ccname:
os.environ["KRB5CCNAME"] = old_krb5ccname
os.unlink(krb5ccname)

return auth
return auth_header

def make_auth(self, iib_session):
"""Setup IIBSession with kerberos authentication"""
iib_session.session.auth = self._krb_auth_header()
iib_session.session.headers["Authorization"] = self._krb_auth_header()


# pylint: disable=bad-option-value,useless-object-inheritance
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def read_content(filepath):

setup(
name="iiblib",
version="0.4.0",
version="0.6.0",
description="IIB client library",
long_description=long_description,
author="Jindrich Luza",
Expand Down
25 changes: 21 additions & 4 deletions tests/test_iib_client.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import copy
from mock import patch, MagicMock
from mock import patch, MagicMock, call

from iiblib.iibclient import (
IIBBuildDetailsModel,
Expand Down Expand Up @@ -218,12 +218,29 @@ def test_iib_basic_auth():
assert session.session.headers["auth"] == ("foo", "bar")


def test_iib_krb_auth():
@patch("subprocess.Popen")
@patch("kerberos.authGSSClientStep")
@patch("kerberos.authGSSClientResponse")
@patch("kerberos.authGSSClientInit")
def test_iib_krb_auth(
mocked_auth_gss_client_init,
mocked_auth_gss_client_response,
mocked_auth_gss_client_step,
mocked_popen,
):
mocked_auth_gss_client_init.return_value = ("", None)
mocked_auth_gss_client_response.return_value = ""
session = MagicMock()
session.session.headers = {}
auth = IIBKrbAuth("test_principal", ktfile="/some/kt/file")
auth = IIBKrbAuth("test_principal", "someservice")
auth.make_auth(session)
mocked_auth_gss_client_init.assert_called_with("HTTP@someservice")
print(mocked_popen.mock_calls)
mocked_popen.assert_has_calls([call(["klist"], stderr=-1, stdout=-1)])

auth = IIBKrbAuth("test_principal", "someservice", ktfile="/some/kt/file")
auth.make_auth(session)
assert isinstance(session.session.auth, requests_kerberos.HTTPKerberosAuth)
mocked_auth_gss_client_init.assert_called_with("HTTP@someservice")


@pytest.mark.xfail
Expand Down

0 comments on commit 62ae32e

Please sign in to comment.