Skip to content

Commit

Permalink
Implement support for GSSAPI extension RFC 5801
Browse files Browse the repository at this point in the history
RFC 5801 provides SASL-specific mechanism inquiry
calls for GSSAPI. The inquire_mech_for_saslname
call allows resolving mechs by their respective
SASL names, and inquire_saslname_for_mech allows
the reverse operation, also providing a mechanism
name and description. These calls are implemented
as part of the raw interface.

Signed-off-by: Alexander Scheel <ascheel@redhat.com>
  • Loading branch information
cipherboy authored and frozencemetery committed Sep 14, 2017
1 parent bd61844 commit d64b9a2
Show file tree
Hide file tree
Showing 5 changed files with 130 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 @@ -81,6 +81,12 @@
except ImportError:
pass

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

try:
from gssapi.raw.ext_cred_imp_exp import * # noqa
except ImportError:
Expand Down
93 changes: 93 additions & 0 deletions gssapi/raw/ext_rfc5801.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from gssapi.raw.cython_types cimport *
from gssapi.raw.oids cimport OID
GSSAPI="BASE" # This ensures that a full module is generated by Cython

from gssapi.raw.cython_converters cimport c_make_oid

from gssapi.raw.named_tuples import InquireSASLNameResult
from gssapi.raw.misc import GSSError

cdef extern from "python_gssapi_ext.h":
OM_uint32 gss_inquire_saslname_for_mech(
OM_uint32 *min_stat,
const gss_OID desired_mech,
gss_buffer_t sasl_mech_name,
gss_buffer_t mech_name,
gss_buffer_t mech_description) nogil

OM_uint32 gss_inquire_mech_for_saslname(
OM_uint32 *min_stat,
const gss_buffer_t sasl_mech_name,
gss_OID *mech_type) nogil


def inquire_saslname_for_mech(OID mech not None):
"""
inquire_saslname_for_mech(mech)
Gets information about a specified mech, including the SASL name,
the mech name, and the mech description.
Args:
mech (OID): Mechanism to inquire about
Returns:
InquireSASLNameResult: the results of inquiry; a mech's SASL name,
name, and description.
Raises:
GSSError: an unknown failure occurred
"""
cdef OM_uint32 maj_stat, min_stat
cdef gss_buffer_desc sasl_mech_name
cdef gss_buffer_desc mech_name
cdef gss_buffer_desc mech_desc
cdef gss_OID m = GSS_C_NO_OID

m = &mech.raw_oid

with nogil:
maj_stat = gss_inquire_saslname_for_mech(&min_stat, m, &sasl_mech_name,
&mech_name, &mech_desc)

if maj_stat == GSS_S_COMPLETE:
out_smn = sasl_mech_name.value[:sasl_mech_name.length]
out_mn = mech_name.value[:mech_name.length]
out_md = mech_desc.value[:mech_desc.length]

gss_release_buffer(&min_stat, &sasl_mech_name)
gss_release_buffer(&min_stat, &mech_name)
gss_release_buffer(&min_stat, &mech_desc)

return InquireSASLNameResult(out_smn, out_mn, out_md)
else:
raise GSSError(maj_stat, min_stat)


def inquire_mech_for_saslname(bytes sasl_name not None):
"""
inquire_mech_for_saslname(sasl_name)
Gets the OID for the mech specified by SASL name.
Args:
sasl_name (bytes): SASL name of the mechanism
Returns:
OID: the mechanism with corresponding SASL name.
Raises:
GSSError: An unknown failure occurred
"""
cdef OM_uint32 maj_stat, min_stat
cdef gss_buffer_desc sn
cdef gss_OID m

sn.length = len(sasl_name)
sn.value = sasl_name

with nogil:
maj_stat = gss_inquire_mech_for_saslname(&min_stat, &sn, &m)

if maj_stat == GSS_S_COMPLETE:
return c_make_oid(m)
else:
raise GSSError(maj_stat, min_stat)
4 changes: 4 additions & 0 deletions gssapi/raw/named_tuples.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,7 @@

DisplayAttrResult = namedtuple('DisplayAttrResult', ['name', 'short_desc',
'long_desc'])

InquireSASLNameResult = namedtuple('InquireSASLNameResult',
['sasl_mech_name', 'mech_name',
'mech_description'])
26 changes: 26 additions & 0 deletions gssapi/tests/test_raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,32 @@ def test_display_mech_attr(self):
display_out.short_desc.should_be(attr[2])
display_out.long_desc.should_be(attr[3])

@ktu.gssapi_extension_test('rfc5801', 'SASL Names')
def test_sasl_names(self):
mechs = gb.indicate_mechs()

for mech in mechs:
out = gb.inquire_saslname_for_mech(mech)

out_smn = out.sasl_mech_name
out_smn.shouldnt_be_none()
out_smn.should_be_a(bytes)
out_smn.shouldnt_be_empty()

out_mn = out.mech_name
out_mn.shouldnt_be_none()
out_mn.should_be_a(bytes)
out_mn.shouldnt_be_empty()

out_md = out.mech_description
out_md.shouldnt_be_none()
out_md.should_be_a(bytes)
out_md.shouldnt_be_empty()

cmp_mech = gb.inquire_mech_for_saslname(out_smn)
cmp_mech.shouldnt_be_none()
cmp_mech.should_be(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 @@ -260,6 +260,7 @@ def gssapi_modules(lst):
extension_file('cred_store', 'gss_store_cred_into'),
extension_file('rfc5587', 'gss_indicate_mechs_by_attrs'),
extension_file('rfc5588', 'gss_store_cred'),
extension_file('rfc5801', 'gss_inquire_saslname_for_mech'),
extension_file('cred_imp_exp', 'gss_import_cred'),
extension_file('dce', 'gss_wrap_iov'),
extension_file('iov_mic', 'gss_get_mic_iov'),
Expand Down

0 comments on commit d64b9a2

Please sign in to comment.