Skip to content

Commit 4086dae

Browse files
committed
Implement support for GSSAPI extension RFC 5801
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 <[email protected]>
1 parent ae99d0c commit 4086dae

File tree

5 files changed

+125
-0
lines changed

5 files changed

+125
-0
lines changed

gssapi/raw/__init__.py

+6
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@
8181
except ImportError:
8282
pass
8383

84+
# optional RFC 5801 support
85+
try:
86+
from gssapi.raw.ext_rfc5801 import * # noqa
87+
except ImportError:
88+
pass
89+
8490
try:
8591
from gssapi.raw.ext_cred_imp_exp import * # noqa
8692
except ImportError:

gssapi/raw/ext_rfc5801.pyx

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
from gssapi.raw.cython_types cimport *
2+
from gssapi.raw.oids cimport OID
3+
GSSAPI="BASE" # This ensures that a full module is generated by Cython
4+
5+
from gssapi.raw.cython_converters cimport c_make_oid
6+
7+
from gssapi.raw.named_tuples import InquireSASLNameResult
8+
from gssapi.raw.misc import GSSError
9+
10+
cdef extern from "python_gssapi_ext.h":
11+
OM_uint32 gss_inquire_saslname_for_mech(
12+
OM_uint32 *min_stat,
13+
const gss_OID desired_mech,
14+
gss_buffer_t sasl_mech_name,
15+
gss_buffer_t mech_name,
16+
gss_buffer_t mech_description) nogil
17+
18+
OM_uint32 gss_inquire_mech_for_saslname(
19+
OM_uint32 *min_stat,
20+
const gss_buffer_t sasl_mech_name,
21+
gss_OID *mech_type) nogil
22+
23+
24+
def inquire_saslname_for_mech(OID mech):
25+
"""
26+
inquire_saslname_for_mech(mech)
27+
Gets information about a specified mech, including the SASL name,
28+
the mech name, and the mech description.
29+
30+
Args:
31+
mech (OID): Mechanism to inquire about
32+
33+
Returns:
34+
InquireSASLNameResult: the results of inquiry; a mech's SASL name,
35+
name, and description.
36+
"""
37+
cdef OM_uint32 maj_stat, min_stat
38+
cdef gss_buffer_desc sasl_mech_name
39+
cdef gss_buffer_desc mech_name
40+
cdef gss_buffer_desc mech_desc
41+
cdef gss_OID m = GSS_C_NO_OID
42+
43+
if mech is not None:
44+
m = &mech.raw_oid
45+
46+
with nogil:
47+
maj_stat = gss_inquire_saslname_for_mech(&min_stat, m, &sasl_mech_name,
48+
&mech_name, &mech_desc)
49+
50+
if maj_stat == GSS_S_COMPLETE:
51+
out_smn = sasl_mech_name.value[:sasl_mech_name.length]
52+
out_mn = mech_name.value[:mech_name.length]
53+
out_md = mech_desc.value[:mech_desc.length]
54+
55+
gss_release_buffer(&min_stat, &sasl_mech_name)
56+
gss_release_buffer(&min_stat, &mech_name)
57+
gss_release_buffer(&min_stat, &mech_desc)
58+
59+
return InquireSASLNameResult(out_smn, out_mn, out_md)
60+
else:
61+
raise GSSError(maj_stat, min_stat)
62+
63+
64+
def inquire_mech_for_saslname(bytes sasl_name):
65+
"""
66+
inquire_mech_for_saslname(sasl_name)
67+
Gets the OID for the mech specified by SASL name.
68+
69+
Args:
70+
sasl_name (bytes): SASL name of the mechanism
71+
72+
Returns:
73+
OID: the mechanism with corresponding SASL name.
74+
"""
75+
cdef OM_uint32 maj_stat, min_stat
76+
cdef gss_buffer_desc sn
77+
cdef gss_OID m
78+
79+
sn.length = len(sasl_name)
80+
sn.value = sasl_name
81+
82+
with nogil:
83+
maj_stat = gss_inquire_mech_for_saslname(&min_stat, &sn, &m)
84+
85+
if maj_stat == GSS_S_COMPLETE:
86+
return c_make_oid(m)
87+
else:
88+
raise GSSError(maj_stat, min_stat)

gssapi/raw/named_tuples.py

+4
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,7 @@
7070

7171
DisplayAttrResult = namedtuple('DisplayAttrResult', ['name', 'short_desc',
7272
'long_desc'])
73+
74+
InquireSASLNameResult = namedtuple('InquireSASLNameResult',
75+
['sasl_mech_name', 'mech_name',
76+
'mech_description'])

gssapi/tests/test_raw.py

+26
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,32 @@ def test_display_mech_attr(self):
734734
display_out.short_desc.should_be(attr[2])
735735
display_out.long_desc.should_be(attr[3])
736736

737+
@ktu.gssapi_extension_test('rfc5801', 'SASL Names')
738+
def test_sasl_names(self):
739+
mechs = gb.indicate_mechs()
740+
741+
for mech in mechs:
742+
out = gb.inquire_saslname_for_mech(mech)
743+
744+
out_smn = out.sasl_mech_name
745+
out_smn.shouldnt_be_none()
746+
out_smn.should_be_a(bytes)
747+
out_smn.shouldnt_be_empty()
748+
749+
out_mn = out.mech_name
750+
out_mn.shouldnt_be_none()
751+
out_mn.should_be_a(bytes)
752+
out_mn.shouldnt_be_empty()
753+
754+
out_md = out.mech_description
755+
out_md.shouldnt_be_none()
756+
out_md.should_be_a(bytes)
757+
out_md.shouldnt_be_empty()
758+
759+
cmp_mech = gb.inquire_mech_for_saslname(out_smn)
760+
cmp_mech.shouldnt_be_none()
761+
cmp_mech.should_be(mech)
762+
737763

738764
class TestIntEnumFlagSet(unittest.TestCase):
739765
def test_create_from_int(self):

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ def gssapi_modules(lst):
260260
extension_file('cred_store', 'gss_store_cred_into'),
261261
extension_file('rfc5587', 'gss_indicate_mechs_by_attrs'),
262262
extension_file('rfc5588', 'gss_store_cred'),
263+
extension_file('rfc5801', 'gss_inquire_saslname_for_mech'),
263264
extension_file('cred_imp_exp', 'gss_import_cred'),
264265
extension_file('dce', 'gss_wrap_iov'),
265266
extension_file('iov_mic', 'gss_get_mic_iov'),

0 commit comments

Comments
 (0)