Skip to content

Commit 8871dc8

Browse files
committed
Implement support for GSSAPI extension RFC 5587
Signed-off-by: Alexander Scheel <[email protected]>
1 parent 32cb94c commit 8871dc8

File tree

5 files changed

+176
-0
lines changed

5 files changed

+176
-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: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
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)
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)
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)
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+
maj_stat = gss_indicate_mechs_by_attrs(&min_stat, desired_attrs,
51+
except_attrs, critical_attrs,
52+
&mechs)
53+
54+
if maj_stat == GSS_S_COMPLETE:
55+
return c_create_oid_set(mechs)
56+
else:
57+
raise GSSError(maj_stat, min_stat)
58+
59+
60+
def inquire_attrs_for_mech(OID mech):
61+
cdef OM_uint32 maj_stat, min_stat
62+
cdef gss_OID m = GSS_C_NO_OID
63+
cdef gss_OID_set mech_attrs = GSS_C_NO_OID_SET
64+
cdef gss_OID_set known_mech_attrs = GSS_C_NO_OID_SET
65+
66+
if mech is not None:
67+
m = &mech.raw_oid
68+
69+
maj_stat = gss_inquire_attrs_for_mech(&min_stat, m, &mech_attrs,
70+
&known_mech_attrs)
71+
72+
if maj_stat == GSS_S_COMPLETE:
73+
return InquireAttrsResult(c_create_oid_set(mech_attrs),
74+
c_create_oid_set(known_mech_attrs))
75+
else:
76+
raise GSSError(maj_stat, min_stat)
77+
78+
79+
def display_mech_attr(OID attr):
80+
cdef OM_uint32 maj_stat, min_stat
81+
cdef gss_OID a = GSS_C_NO_OID
82+
cdef gss_buffer_desc name
83+
cdef gss_buffer_desc short_desc
84+
cdef gss_buffer_desc long_desc
85+
86+
if attr is not None:
87+
a = &attr.raw_oid
88+
89+
maj_stat = gss_display_mech_attr(&min_stat, a, &name, &short_desc,
90+
&long_desc)
91+
92+
if maj_stat == GSS_S_COMPLETE:
93+
out_name = name.value[:name.length].decode("UTF-8")
94+
out_short = short_desc.value[:short_desc.length].decode("UTF-8")
95+
out_long = long_desc.value[:long_desc.length].decode("UTF-8")
96+
97+
gss_release_buffer(&min_stat, &name)
98+
gss_release_buffer(&min_stat, &short_desc)
99+
gss_release_buffer(&min_stat, &long_desc)
100+
101+
return DisplayAttrResult(out_name, out_short, out_long)
102+
else:
103+
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: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,66 @@ 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+
mechs.shouldnt_be_empty()
651+
mechs.should_be_a(set)
652+
653+
last_mech = None
654+
last_attr = None
655+
656+
for mech in mechs:
657+
mech.shouldnt_be_none
658+
mech.should_be_a(gb.OID)
659+
660+
inquire_out = gb.inquire_attrs_for_mech(mech)
661+
mech_attrs = inquire_out.mech_attrs
662+
known_mech_attrs = inquire_out.known_mech_attrs
663+
664+
mech_attrs.shouldnt_be_empty
665+
known_mech_attrs.shouldnt_be_empty
666+
mech_attrs.should_be_a(set)
667+
known_mech_attrs.should_be_a(set)
668+
669+
for mech_attr in mech_attrs:
670+
mech_attr.shouldnt_be_none
671+
mech_attr.should_be_a(gb.OID)
672+
673+
display_out = gb.display_mech_attr(mech_attr)
674+
display_out.name.shouldnt_be_none
675+
display_out.long_desc.shouldnt_be_none
676+
display_out.short_desc.shouldnt_be_none
677+
678+
last_attr = mech_attr
679+
680+
for mech_attr in known_mech_attrs:
681+
mech_attr.shouldnt_be_none
682+
mech_attr.should_be_a(gb.OID)
683+
684+
display_out = gb.display_mech_attr(mech_attr)
685+
display_out.name.shouldnt_be_none
686+
display_out.long_desc.shouldnt_be_none
687+
display_out.short_desc.shouldnt_be_none
688+
689+
last_mech = mech
690+
691+
last_mech.shouldnt_be_none
692+
last_attr.shouldnt_be_none
693+
694+
attrs = set([last_attr])
695+
696+
mechs = gb.indicate_mechs_by_attrs(attrs, None, None)
697+
mechs.shouldnt_be_empty()
698+
mechs.should_include(last_mech)
699+
700+
mechs = gb.indicate_mechs_by_attrs(None, attrs, None)
701+
mechs.shouldnt_include(last_mech)
702+
703+
mechs = gb.indicate_mechs_by_attrs(None, None, attrs)
704+
mechs.shouldnt_be_empty()
705+
mechs.should_include(last_mech)
706+
647707

648708
class TestIntEnumFlagSet(unittest.TestCase):
649709
def test_create_from_int(self):

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ def gssapi_modules(lst):
253253
main_file('chan_bindings'),
254254
extension_file('s4u', 'gss_acquire_cred_impersonate_name'),
255255
extension_file('cred_store', 'gss_store_cred_into'),
256+
extension_file('rfc5587', 'gss_indicate_mechs_by_attrs'),
256257
extension_file('rfc5588', 'gss_store_cred'),
257258
extension_file('cred_imp_exp', 'gss_import_cred'),
258259
extension_file('dce', 'gss_wrap_iov'),

0 commit comments

Comments
 (0)