Skip to content

Commit 11180ad

Browse files
committed
Implement support for GSSAPI extension RFC 5587
RFC 5587 provides extended mech inquiry calls to GSSAPI. This adds the ability to indicate mechs by their mech attrs, along with determining the attrs supported by a mech. These calls are provided as a part of the raw interface and are not exposed in the high-level interface due to not having objects for mechs or attrs. Signed-off-by: Alexander Scheel <[email protected]>
1 parent 0be0230 commit 11180ad

File tree

5 files changed

+194
-0
lines changed

5 files changed

+194
-0
lines changed

gssapi/raw/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@
6969
except ImportError:
7070
pass
7171

72+
# optional RFC 5587 support
73+
try:
74+
from gssapi.raw.ext_rfc5587 import * # noqa
75+
except ImportError:
76+
pass
77+
7278
# optional RFC 5588 support
7379
try:
7480
from gssapi.raw.ext_rfc5588 import * # noqa

gssapi/raw/ext_rfc5587.pyx

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
from gssapi.raw.cython_types cimport *
2+
from gssapi.raw.oids cimport OID
3+
from gssapi.raw.cython_converters cimport c_create_oid_set
4+
GSSAPI="BASE" # This ensures that a full module is generated by Cython
5+
6+
from gssapi.raw.cython_converters cimport c_get_mech_oid_set
7+
8+
from gssapi.raw.named_tuples import InquireAttrsResult, DisplayAttrResult
9+
from gssapi.raw.misc import GSSError
10+
11+
cdef extern from "python_gssapi_ext.h":
12+
OM_uint32 gss_indicate_mechs_by_attrs(
13+
OM_uint32 *minor_status,
14+
const gss_OID_set desired_mech_attrs,
15+
const gss_OID_set except_mech_attrs,
16+
const gss_OID_set critical_mech_attrs,
17+
gss_OID_set *mechs) nogil
18+
19+
OM_uint32 gss_inquire_attrs_for_mech(
20+
OM_uint32 *minor_status,
21+
const gss_OID mech,
22+
gss_OID_set *mech_attrs,
23+
gss_OID_set *known_mech_attrs) nogil
24+
25+
OM_uint32 gss_display_mech_attr(
26+
OM_uint32 *minor_status,
27+
const gss_OID mech_attr,
28+
gss_buffer_t name,
29+
gss_buffer_t short_desc,
30+
gss_buffer_t long_desc) nogil
31+
32+
33+
def indicate_mechs_by_attrs(desired_mech_attrs=None, except_mech_attrs=None,
34+
critical_mech_attrs=None):
35+
cdef OM_uint32 maj_stat, min_stat
36+
cdef gss_OID_set desired_attrs = GSS_C_NO_OID_SET
37+
cdef gss_OID_set except_attrs = GSS_C_NO_OID_SET
38+
cdef gss_OID_set critical_attrs = GSS_C_NO_OID_SET
39+
cdef gss_OID_set mechs
40+
41+
if desired_mech_attrs is not None:
42+
desired_attrs = c_get_mech_oid_set(desired_mech_attrs)
43+
44+
if except_mech_attrs is not None:
45+
except_attrs = c_get_mech_oid_set(except_mech_attrs)
46+
47+
if critical_mech_attrs is not None:
48+
critical_attrs = c_get_mech_oid_set(critical_mech_attrs)
49+
50+
with nogil:
51+
maj_stat = gss_indicate_mechs_by_attrs(&min_stat, desired_attrs,
52+
except_attrs, critical_attrs,
53+
&mechs)
54+
55+
if maj_stat == GSS_S_COMPLETE:
56+
return c_create_oid_set(mechs)
57+
else:
58+
raise GSSError(maj_stat, min_stat)
59+
60+
61+
def inquire_attrs_for_mech(OID mech):
62+
cdef OM_uint32 maj_stat, min_stat
63+
cdef gss_OID m = GSS_C_NO_OID
64+
cdef gss_OID_set mech_attrs = GSS_C_NO_OID_SET
65+
cdef gss_OID_set known_mech_attrs = GSS_C_NO_OID_SET
66+
67+
if mech is not None:
68+
m = &mech.raw_oid
69+
70+
with nogil:
71+
maj_stat = gss_inquire_attrs_for_mech(&min_stat, m, &mech_attrs,
72+
&known_mech_attrs)
73+
74+
if maj_stat == GSS_S_COMPLETE:
75+
return InquireAttrsResult(c_create_oid_set(mech_attrs),
76+
c_create_oid_set(known_mech_attrs))
77+
else:
78+
raise GSSError(maj_stat, min_stat)
79+
80+
81+
def display_mech_attr(OID attr):
82+
cdef OM_uint32 maj_stat, min_stat
83+
cdef gss_OID a = GSS_C_NO_OID
84+
cdef gss_buffer_desc name
85+
cdef gss_buffer_desc short_desc
86+
cdef gss_buffer_desc long_desc
87+
88+
if attr is not None:
89+
a = &attr.raw_oid
90+
91+
with nogil:
92+
maj_stat = gss_display_mech_attr(&min_stat, a, &name, &short_desc,
93+
&long_desc)
94+
95+
if maj_stat == GSS_S_COMPLETE:
96+
out_name = name.value[:name.length]
97+
out_short = short_desc.value[:short_desc.length]
98+
out_long = long_desc.value[:long_desc.length]
99+
100+
gss_release_buffer(&min_stat, &name)
101+
gss_release_buffer(&min_stat, &short_desc)
102+
gss_release_buffer(&min_stat, &long_desc)
103+
104+
return DisplayAttrResult(out_name, out_short, out_long)
105+
else:
106+
raise GSSError(maj_stat, min_stat)

gssapi/raw/named_tuples.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,9 @@
6464
GetNameAttributeResult = namedtuple('GetNamedAttributeResult',
6565
['values', 'display_values',
6666
'authenticated', 'complete'])
67+
68+
InquireAttrsResult = namedtuple('InquireAttrsResult',
69+
['mech_attrs', 'known_mech_attrs'])
70+
71+
DisplayAttrResult = namedtuple('DisplayAttrResult', ['name', 'short_desc',
72+
'long_desc'])

gssapi/tests/test_raw.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,81 @@ def test_add_cred_with_password(self):
644644

645645
new_creds.should_be_a(gb.Creds)
646646

647+
@ktu.gssapi_extension_test('rfc5587', 'RFC 5587')
648+
def test_rfc5587(self):
649+
mechs = gb.indicate_mechs_by_attrs(None, None, None)
650+
651+
mechs.should_be_a(set)
652+
mechs.shouldnt_be_empty()
653+
654+
last_attr = None
655+
last_mech = None
656+
657+
for mech in mechs:
658+
mech.shouldnt_be_none()
659+
mech.should_be_a(gb.OID)
660+
last_mech = mech
661+
662+
inquire_out = gb.inquire_attrs_for_mech(mech)
663+
mech_attrs = inquire_out.mech_attrs
664+
known_mech_attrs = inquire_out.known_mech_attrs
665+
666+
mech_attrs.should_be_a(set)
667+
mech_attrs.shouldnt_be_empty()
668+
669+
known_mech_attrs.should_be_a(set)
670+
known_mech_attrs.shouldnt_be_empty()
671+
672+
for mech_attr in mech_attrs:
673+
mech_attr.shouldnt_be_none()
674+
mech_attr.should_be_a(gb.OID)
675+
676+
display_out = gb.display_mech_attr(mech_attr)
677+
display_out.name.shouldnt_be_none()
678+
display_out.long_desc.shouldnt_be_none()
679+
display_out.short_desc.shouldnt_be_none()
680+
681+
last_attr = mech_attr
682+
683+
for mech_attr in known_mech_attrs:
684+
mech_attr.shouldnt_be_none()
685+
mech_attr.should_be_a(gb.OID)
686+
687+
display_out = gb.display_mech_attr(mech_attr)
688+
display_out.name.shouldnt_be_none()
689+
display_out.long_desc.shouldnt_be_none()
690+
display_out.short_desc.shouldnt_be_none()
691+
692+
attrs = set([last_attr])
693+
694+
mechs = gb.indicate_mechs_by_attrs(attrs, None, None)
695+
mechs.shouldnt_be_empty()
696+
mechs.should_include(last_mech)
697+
698+
mechs = gb.indicate_mechs_by_attrs(None, attrs, None)
699+
mechs.shouldnt_include(last_mech)
700+
701+
mechs = gb.indicate_mechs_by_attrs(None, None, attrs)
702+
mechs.shouldnt_be_empty()
703+
mechs.should_include(last_mech)
704+
705+
706+
@ktu.gssapi_extension_test('rfc5587', 'RFC 5587')
707+
def test_display_mech_attr(self):
708+
test_attrs = [
709+
# oid, name, short_desc, long_desc
710+
[gb.OID.from_int_seq("1.3.6.1.5.5.13.24"), b"GSS_C_MA_CBINDINGS",
711+
b"channel-bindings", b"Mechanism supports channel bindings."],
712+
[gb.OID.from_int_seq("1.3.6.1.5.5.13.1"), b"GSS_C_MA_MECH_CONCRETE",
713+
b"concrete-mech", b"Mechanism is neither a pseudo-mechanism "
714+
b"nor a composite mechanism."]
715+
]
716+
717+
for attr in test_attrs:
718+
display_out = gb.display_mech_attr(attr[0])
719+
display_out.name.should_be(attr[1])
720+
display_out.short_desc.should_be(attr[2])
721+
display_out.long_desc.should_be(attr[3])
647722

648723
class TestIntEnumFlagSet(unittest.TestCase):
649724
def test_create_from_int(self):

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ def gssapi_modules(lst):
258258
main_file('chan_bindings'),
259259
extension_file('s4u', 'gss_acquire_cred_impersonate_name'),
260260
extension_file('cred_store', 'gss_store_cred_into'),
261+
extension_file('rfc5587', 'gss_indicate_mechs_by_attrs'),
261262
extension_file('rfc5588', 'gss_store_cred'),
262263
extension_file('cred_imp_exp', 'gss_import_cred'),
263264
extension_file('dce', 'gss_wrap_iov'),

0 commit comments

Comments
 (0)