Skip to content

Commit 458ef1b

Browse files
frozencemeteryDirectXMan12
authored andcommitted
Add gss_add_cred() including docs and test
Closes #15.
1 parent 0b82946 commit 458ef1b

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

gssapi/raw/creds.pyx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,75 @@ def release_cred(Creds creds not None):
172172
creds.raw_creds = NULL
173173

174174

175+
def add_cred(Creds input_cred, Name name not None, OID mech not None,
176+
cred_usage='initiate', initiator_ttl=None, acceptor_ttl=None):
177+
"""Add a credential element to a credential.
178+
179+
This method can be used to either compose two credentials (i.e., original
180+
and new credential), or to add a new element to an existing credential.
181+
182+
Args:
183+
input_cred (Cred): the set of credentials to which to add the new
184+
credentials
185+
name (Name): name of principal to acquire a credential for
186+
mech (MechType): the desired security mechanism (required).
187+
cred_usage (str): usage type for credentials. Possible values:
188+
'initiate' (default), 'accept', 'both' (failsafe).
189+
initiator_ttl (int): lifetime of credentials for use in initiating
190+
security contexts (None for indefinite)
191+
acceptor_ttl (int): lifetime of credentials for use in accepting
192+
security contexts (None for indefinite)
193+
194+
Returns:
195+
AddCredResult: the actual mechanisms with which the credentials may be
196+
used, the actual initiator TTL, and the actual acceptor TTL (None for
197+
either indefinite or not supported)
198+
199+
Raises:
200+
GSSError
201+
202+
"""
203+
cdef gss_cred_usage_t usage
204+
if cred_usage == 'initiate':
205+
usage = GSS_C_INITIATE
206+
elif cred_usage == 'accept':
207+
usage = GSS_C_ACCEPT
208+
else: # cred_usage == 'both'
209+
usage = GSS_C_BOTH
210+
211+
cdef gss_cred_id_t raw_input_cred
212+
if input_cred is not None:
213+
raw_input_cred = input_cred.raw_creds
214+
else:
215+
raw_input_cred = GSS_C_NO_CREDENTIAL
216+
217+
cdef OM_uint32 input_initiator_ttl = c_py_ttl_to_c(initiator_ttl)
218+
cdef OM_uint32 input_acceptor_ttl = c_py_ttl_to_c(acceptor_ttl)
219+
220+
cdef gss_cred_id_t output_creds
221+
cdef gss_OID_set actual_mechs
222+
cdef OM_uint32 actual_initiator_ttl, actual_acceptor_ttl
223+
224+
cdef OM_uint32 maj_stat, min_stat
225+
226+
with nogil:
227+
maj_stat = gss_add_cred(&min_stat, raw_input_cred, name.raw_name,
228+
&mech.raw_oid, usage, input_initiator_ttl,
229+
input_acceptor_ttl, &output_creds,
230+
&actual_mechs, &actual_initiator_ttl,
231+
&actual_acceptor_ttl)
232+
233+
cdef Creds rc
234+
if maj_stat == GSS_S_COMPLETE:
235+
rc = Creds()
236+
rc.raw_creds = output_creds
237+
return AddCredResult(rc, c_create_oid_set(actual_mechs),
238+
c_c_ttl_to_py(actual_initiator_ttl),
239+
c_c_ttl_to_py(actual_acceptor_ttl))
240+
else:
241+
raise GSSError(maj_stat, min_stat)
242+
243+
175244
def inquire_cred(Creds creds not None, name=True, ttl=True,
176245
usage=True, mechs=True):
177246
"""Inspect credentials for information

gssapi/tests/test_raw.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,36 @@ def test_store_cred_into_acquire_cred(self):
330330

331331
retrieve_res.lifetime.should_be_an_integer()
332332

333+
def test_add_cred(self):
334+
target_name = gb.import_name(TARGET_SERVICE_NAME,
335+
gb.NameType.hostbased_service)
336+
client_ctx_resp = gb.init_sec_context(target_name)
337+
client_token = client_ctx_resp[3]
338+
del client_ctx_resp # free all the things (except the token)!
339+
340+
server_name = gb.import_name(SERVICE_PRINCIPAL,
341+
gb.NameType.kerberos_principal)
342+
server_creds = gb.acquire_cred(server_name, cred_usage='both')[0]
343+
server_ctx_resp = gb.accept_sec_context(client_token,
344+
acceptor_cred=server_creds)
345+
346+
input_creds = gb.Creds()
347+
imp_resp = gb.add_cred(input_creds,
348+
server_ctx_resp[1],
349+
gb.MechType.kerberos)
350+
351+
imp_resp.shouldnt_be_none()
352+
353+
new_creds, actual_mechs, output_init_ttl, output_accept_ttl = imp_resp
354+
355+
actual_mechs.shouldnt_be_empty()
356+
actual_mechs.should_include(gb.MechType.kerberos)
357+
358+
output_init_ttl.should_be_a(int)
359+
output_accept_ttl.should_be_a(int)
360+
361+
new_creds.should_be_a(gb.Creds)
362+
333363
def test_inquire_creds(self):
334364
name = gb.import_name(SERVICE_PRINCIPAL,
335365
gb.NameType.kerberos_principal)

0 commit comments

Comments
 (0)