Skip to content

Commit

Permalink
Implement support for GSSAPI extension RFC 5587
Browse files Browse the repository at this point in the history
Signed-off-by: Alexander Scheel <ascheel@redhat.com>
  • Loading branch information
cipherboy committed Jul 14, 2017
1 parent 32cb94c commit 6569bce
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 0 deletions.
6 changes: 6 additions & 0 deletions gssapi/raw/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@
except ImportError:
pass

# optional RFC 5587 support
try:
from gssapi.raw.ext_rfc5587 import * # noqa
except ImportError:
pass

# optional RFC 5588 support
try:
from gssapi.raw.ext_rfc5588 import * # noqa
Expand Down
103 changes: 103 additions & 0 deletions gssapi/raw/ext_rfc5587.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
from gssapi.raw.cython_types cimport *
from gssapi.raw.oids cimport OID
from gssapi.raw.cython_converters cimport c_create_oid_set
GSSAPI="BASE" # This ensures that a full module is generated by Cython

from gssapi.raw.cython_converters cimport c_get_mech_oid_set

from gssapi.raw.named_tuples import InquireAttrsResult, DisplayAttrResult
from gssapi.raw.misc import GSSError

cdef extern from "python_gssapi_ext.h":
OM_uint32 gss_indicate_mechs_by_attrs(
OM_uint32 *minor_status,
const gss_OID_set desired_mech_attrs,
const gss_OID_set except_mech_attrs,
const gss_OID_set critical_mech_attrs,
gss_OID_set *mechs)

OM_uint32 gss_inquire_attrs_for_mech(
OM_uint32 *minor_status,
const gss_OID mech,
gss_OID_set *mech_attrs,
gss_OID_set *known_mech_attrs)

OM_uint32 gss_display_mech_attr(
OM_uint32 *minor_status,
const gss_OID mech_attr,
gss_buffer_t name,
gss_buffer_t short_desc,
gss_buffer_t long_desc)


def indicate_mechs_by_attrs(desired_mech_attrs=None, except_mech_attrs=None,
critical_mech_attrs=None):
cdef OM_uint32 maj_stat, min_stat
cdef gss_OID_set desired_attrs = GSS_C_NO_OID_SET
cdef gss_OID_set except_attrs = GSS_C_NO_OID_SET
cdef gss_OID_set critical_attrs = GSS_C_NO_OID_SET
cdef gss_OID_set mechs

if desired_mech_attrs is not None:
desired_attrs = c_get_mech_oid_set(desired_mech_attrs)

if except_mech_attrs is not None:
except_attrs = c_get_mech_oid_set(except_mech_attrs)

if critical_mech_attrs is not None:
critical_attrs = c_get_mech_oid_set(critical_mech_attrs)

maj_stat = gss_indicate_mechs_by_attrs(&min_stat, desired_attrs,
except_attrs, critical_attrs,
&mechs)

if maj_stat == GSS_S_COMPLETE:
return c_create_oid_set(mechs)
else:
raise GSSError(maj_stat, min_stat)


def inquire_attrs_for_mech(OID mech):
cdef OM_uint32 maj_stat, min_stat
cdef gss_OID m = GSS_C_NO_OID
cdef gss_OID_set mech_attrs = GSS_C_NO_OID_SET
cdef gss_OID_set known_mech_attrs = GSS_C_NO_OID_SET

if mech is not None:
m = &mech.raw_oid

maj_stat = gss_inquire_attrs_for_mech(&min_stat, m, &mech_attrs,
&known_mech_attrs)

if maj_stat == GSS_S_COMPLETE:
return InquireAttrsResult(c_create_oid_set(mech_attrs),
c_create_oid_set(known_mech_attrs))
else:
raise GSSError(maj_stat, min_stat)


def display_mech_attr(OID attr):
cdef OM_uint32 maj_stat, min_stat
cdef gss_OID a = GSS_C_NO_OID
cdef gss_buffer_desc name
cdef gss_buffer_desc short_desc
cdef gss_buffer_desc long_desc

if attr is not None:
a = &attr.raw_oid

maj_stat = gss_display_mech_attr(&min_stat, a, &name, &short_desc,
&long_desc)

if maj_stat == GSS_S_COMPLETE:
out_name = name.value[:name.length].decode("UTF-8")
out_short = short_desc.value[:short_desc.length].decode("UTF-8")
out_long = long_desc.value[:long_desc.length].decode("UTF-8")

gss_release_buffer(&min_stat, &name)
gss_release_buffer(&min_stat, &short_desc)
gss_release_buffer(&min_stat, &long_desc)

return DisplayAttrResult(out_name, out_short, out_long)
else:
raise GSSError(maj_stat, min_stat)
6 changes: 6 additions & 0 deletions gssapi/raw/named_tuples.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,9 @@
GetNameAttributeResult = namedtuple('GetNamedAttributeResult',
['values', 'display_values',
'authenticated', 'complete'])

InquireAttrsResult = namedtuple('InquireAttrsResult',
['mech_attrs', 'known_mech_attrs'])

DisplayAttrResult = namedtuple('DisplayAttrResult', ['name', 'short_desc',
'long_desc'])
66 changes: 66 additions & 0 deletions gssapi/tests/test_raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,72 @@ def test_add_cred_with_password(self):

new_creds.should_be_a(gb.Creds)

@ktu.gssapi_extension_test('rfc5587', 'RFC 5587')
def test_rfc5587(self):
mechs = gb.indicate_mechs_by_attrs(None, None, None)
mechs.shouldnt_be_empty()
mechs.should_be_a(set)

last_mech = None
last_attr = None

for mech in mechs:
mech.shouldnt_be_none
mech.should_be_a(gb.OID)

inquire_out = gb.inquire_attrs_for_mech(mech)
mech_attrs = inquire_out.mech_attrs
known_mech_attrs = inquire_out.known_mech_attrs

mech_attrs.shouldnt_be_empty
known_mech_attrs.shouldnt_be_empty
mech_attrs.should_be_a(set)
known_mech_attrs.should_be_a(set)

for mech_attr in mech_attrs:
mech_attr.shouldnt_be_none
mech_attr.should_be_a(gb.OID)

display_out = gb.display_mech_attr(mech_attr)
display_out.name.shouldnt_be_none
display_out.name.should_be_a(str)
display_out.long_desc.shouldnt_be_none
display_out.long_desc.should_be_a(str)
display_out.short_desc.shouldnt_be_none
display_out.short_desc.should_be_a(str)

last_attr = mech_attr

for mech_attr in known_mech_attrs:
mech_attr.shouldnt_be_none
mech_attr.should_be_a(gb.OID)

display_out = gb.display_mech_attr(mech_attr)
display_out.name.shouldnt_be_none
display_out.name.should_be_a(str)
display_out.long_desc.shouldnt_be_none
display_out.long_desc.should_be_a(str)
display_out.short_desc.shouldnt_be_none
display_out.short_desc.should_be_a(str)

last_mech = mech

last_mech.shouldnt_be_none
last_attr.shouldnt_be_none

attrs = set([last_attr])

mechs = gb.indicate_mechs_by_attrs(attrs, None, None)
mechs.shouldnt_be_empty()
mechs.should_include(last_mech)

mechs = gb.indicate_mechs_by_attrs(None, attrs, None)
mechs.shouldnt_include(last_mech)

mechs = gb.indicate_mechs_by_attrs(None, None, attrs)
mechs.shouldnt_be_empty()
mechs.should_include(last_mech)


class TestIntEnumFlagSet(unittest.TestCase):
def test_create_from_int(self):
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ def gssapi_modules(lst):
main_file('chan_bindings'),
extension_file('s4u', 'gss_acquire_cred_impersonate_name'),
extension_file('cred_store', 'gss_store_cred_into'),
extension_file('rfc5587', 'gss_indicate_mechs_by_attrs'),
extension_file('rfc5588', 'gss_store_cred'),
extension_file('cred_imp_exp', 'gss_import_cred'),
extension_file('dce', 'gss_wrap_iov'),
Expand Down

0 comments on commit 6569bce

Please sign in to comment.