Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit acc28ca

Browse files
Expose mechanisms in the high-level API
This creates a new class, Mechanism, for inquiring information about a mechanism. This includes support for RFCs 5587 and 5801. As Mechanism derives from OID, it is compatible with all places that accept a mech by OID. Signed-off-by: Alexander Scheel <ascheel@redhat.com>
1 parent 51817f5 commit acc28ca

File tree

4 files changed

+250
-0
lines changed

4 files changed

+250
-0
lines changed

‎gssapi/__init__.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@
3333
from gssapi.creds import Credentials # noqa
3434
from gssapi.names import Name # noqa
3535
from gssapi.sec_contexts import SecurityContext # noqa
36+
from gssapi.mechs import Mechanism # noqa
3637

3738
from gssapi._utils import set_encoding # noqa

‎gssapi/mechs.py‎

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
from gssapi.raw import oids as roids
2+
from gssapi._utils import import_gssapi_extension
3+
from gssapi.raw import misc as rmisc
4+
5+
rfc5587 = import_gssapi_extension('rfc5587')
6+
rfc5801 = import_gssapi_extension('rfc5801')
7+
8+
9+
class Mechanism(roids.OID):
10+
"""
11+
A GSSAPI Mechanism
12+
13+
This class represents a mechanism and centralizes functions dealing with
14+
mechanisms and can be used with any calls.
15+
16+
It inherits from the low-level GSSAPI :class:`~gssapi.raw.oids.OID` class,
17+
and thus can be used with both low-level and high-level API calls.
18+
"""
19+
_sasl_name = None
20+
_mech_attrs = None
21+
22+
def __new__(cls, cpy=None, elements=None):
23+
return super(Mechanism, cls).__new__(cls, cpy, elements)
24+
25+
@property
26+
def names(self):
27+
"""
28+
Get the set of name types supported by the mechanism.
29+
"""
30+
return rmisc.inquire_names_for_mech(self)
31+
32+
@property
33+
def _query_saslname(self):
34+
if rfc5801 is None:
35+
raise NotImplementedError("Your GSSAPI implementation does not "
36+
"have support for RFC 5801")
37+
return rfc5801.inquire_saslname_for_mech(self)
38+
39+
@property
40+
def _query_attrs(self):
41+
if rfc5587 is None:
42+
raise NotImplementedError("Your GSSAPI implementation does not "
43+
"have support for RFC 5587")
44+
45+
return rfc5587.inquire_attrs_for_mech(self)
46+
47+
def __repr__(self):
48+
"""
49+
Get a name representing the mechanism; always safe to call
50+
"""
51+
base = super(Mechanism, self).__repr__()
52+
if rfc5801 is not None:
53+
base = "%s %s" % (self._query_saslname.mech_name.decode('UTF-8'),
54+
base)
55+
56+
return base
57+
58+
@property
59+
def sasl_name(self):
60+
"""
61+
Get the SASL name for the mechanism; depends on RFC 5801
62+
63+
:requires-ext:`rfc5801`
64+
"""
65+
return self._query_saslname.sasl_mech_name.decode('UTF-8')
66+
67+
@property
68+
def name(self):
69+
"""
70+
Get the name for the mechanism; depends on RFC 5801
71+
72+
:requires-ext:`rfc5801`
73+
"""
74+
self._query_saslname()
75+
return self._query_saslname.mech_name.decode('UTF-8')
76+
77+
@property
78+
def description(self):
79+
"""
80+
Get the description of the mechanism; depends on RFC 5801
81+
82+
:requires-ext:`rfc5801`
83+
"""
84+
self._query_saslname()
85+
return self._query_saslname.mech_description.decode('UTF-8')
86+
87+
@property
88+
def known_attrs(self):
89+
"""
90+
Get the known attributes of the mechanism; depends on RFC 5587
91+
92+
:requires-ext:`rfc5587`
93+
"""
94+
return self._query_attrs.known_mech_attrs
95+
96+
@property
97+
def attrs(self):
98+
"""
99+
Get the attributes of the mechanism; depends on RFC 5587
100+
101+
:requires-ext:`rfc5587`
102+
"""
103+
return self._query_attrs.mech_attrs
104+
105+
@classmethod
106+
def all_mechs(cls):
107+
"""
108+
all_mechs()
109+
Get a list of all mechanisms supported by GSSAPI
110+
"""
111+
mechs = rmisc.indicate_mechs()
112+
return [cls(mech) for mech in mechs]
113+
114+
@classmethod
115+
def from_name(cls, name=None):
116+
"""
117+
from_name(name)
118+
Get a set of mechanisms that may be able to process the name
119+
120+
Args:
121+
name (Name): a name to inquire about
122+
123+
Returns:
124+
[Mechanism]: a set of mechanisms which support this name
125+
126+
Raises:
127+
GSSError
128+
"""
129+
mechs = rmisc.inquire_mechs_for_name(name)
130+
return [cls(mech) for mech in mechs]
131+
132+
@classmethod
133+
def from_sasl_name(cls, name=None):
134+
"""
135+
from_sasl_name(name)
136+
Create a Mechanism from its SASL name
137+
138+
Args:
139+
name (str): SASL name of the desired mechanism
140+
141+
Returns:
142+
Mechanism: the desired mechanism
143+
144+
Raises:
145+
GSSError
146+
147+
:requires-ext:`rfc5801`
148+
"""
149+
if rfc5801 is None:
150+
raise NotImplementedError("Your GSSAPI implementation does not "
151+
"have support for RFC 5801")
152+
n = name
153+
if type(n) is not bytes:
154+
n = str(n).encode()
155+
156+
m = rfc5801.inquire_mech_for_saslname(n)
157+
158+
return cls(m)
159+
160+
@classmethod
161+
def from_attrs(cls, m_desired=None, m_except=None, m_critical=None):
162+
"""
163+
from_attrs
164+
Get the set of mechanisms supporting the specified attributes. See
165+
RFC 5587's indicate_mechs_by_attrs for more information.
166+
167+
Args:
168+
m_desired ([OID]): Desired attributes
169+
m_except ([OID]): Except attributes
170+
m_critical ([OID]): Critical attributes
171+
172+
Returns:
173+
[Mechanism]: A set of mechanisms having the desired features.
174+
175+
Raises:
176+
GSSError
177+
178+
:requires-ext:`rfc5587`
179+
"""
180+
if type(m_desired) == roids.OID:
181+
m_desired = set([m_desired])
182+
if type(m_except) == roids.OID:
183+
m_except = set([m_except])
184+
if type(m_critical) == roids.OID:
185+
m_critical = set([m_critical])
186+
187+
if rfc5587 is None:
188+
raise NotImplementedError("Your GSSAPI implementation does not "
189+
"have support for RFC 5587")
190+
191+
mechs = rfc5587.indicate_mechs_by_attrs(m_desired,
192+
m_except,
193+
m_critical)
194+
return [cls(mech) for mech in mechs]

‎gssapi/raw/oids.pyx‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ cdef class OID:
6161
self._free_on_dealloc = True
6262
return 0
6363

64+
def _copy_oid(self, OID other):
65+
self._copy_from(other.raw_oid)
66+
6467
cdef int _from_bytes(OID self, object base) except -1:
6568
base_bytes = bytes(base)
6669
cdef char* byte_str = base_bytes

‎gssapi/tests/test_high_level.py‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from nose_parameterized import parameterized
1010

1111
from gssapi import creds as gsscreds
12+
from gssapi import mechs as gssmechs
1213
from gssapi import names as gssnames
1314
from gssapi import sec_contexts as gssctx
1415
from gssapi import raw as gb
@@ -369,6 +370,57 @@ def test_add_with_impersonate(self):
369370
new_creds.should_be_a(gsscreds.Credentials)
370371

371372

373+
class MechsTestCase(_GSSAPIKerberosTestCase):
374+
def test_indicate_mechs(self):
375+
mechs = gssmechs.Mechanism.all_mechs()
376+
for mech in mechs:
377+
s = str(mech)
378+
s.shouldnt_be_empty()
379+
380+
@ktu.gssapi_extension_test('rfc5801', 'RFC 5801: SASL Names')
381+
def test_sasl_properties(self):
382+
mechs = gssmechs.Mechanism.all_mechs()
383+
for mech in mechs:
384+
s = str(mech)
385+
s.shouldnt_be_empty()
386+
s.should_be_a(str)
387+
s[0].shouldnt_be('<')
388+
s.should_be(mech.name)
389+
390+
mech.sasl_name.shouldnt_be_empty()
391+
mech.sasl_name.should_be_a(six.text_type)
392+
393+
mech.description.shouldnt_be_empty()
394+
mech.description.should_be_a(six.text_type)
395+
396+
cmp_mech = gssmechs.Mechanism.from_sasl_name(mech.sasl_name)
397+
str(cmp_mech).should_be(str(mech))
398+
399+
@ktu.gssapi_extension_test('rfc5587', 'RFC 5587: Mech Inquiry')
400+
def test_mech_inquiry(self):
401+
mechs = gssmechs.Mechanism.all_mechs()
402+
c = len(mechs)
403+
for mech in mechs:
404+
attrs = mech.attrs
405+
known_attrs = mech.known_attrs
406+
407+
for attr in attrs:
408+
i = gssmechs.Mechanism.from_attrs(m_desired=[attr])
409+
e = gssmechs.Mechanism.from_attrs(m_except=[attr])
410+
411+
count = len(i) + len(e)
412+
count.should_be(c)
413+
i.should_include(mech)
414+
e.shouldnt_include(mech)
415+
416+
for attr in known_attrs:
417+
i = gssmechs.Mechanism.from_attrs(m_desired=[attr])
418+
e = gssmechs.Mechanism.from_attrs(m_except=[attr])
419+
420+
count = len(i) + len(e)
421+
count.should_be(c)
422+
423+
372424
class NamesTestCase(_GSSAPIKerberosTestCase):
373425
def test_create_from_other(self):
374426
raw_name = gb.import_name(SERVICE_PRINCIPAL)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /