Skip to content

Add credentials import-export to low-level API #28

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 23, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions gssapi/raw/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
except ImportError:
pass

try:
from gssapi.raw.ext_cred_imp_exp import * # noqa
except ImportError:
pass

# optional KRB5 mech support
try:
import gssapi.raw.mech_krb5 # noqa
Expand Down
86 changes: 86 additions & 0 deletions gssapi/raw/ext_cred_imp_exp.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
GSSAPI="BASE" # This ensures that a full module is generated by Cython

from gssapi.raw.cython_types cimport *
from gssapi.raw.cython_converters cimport c_create_oid_set
from gssapi.raw.cython_converters cimport c_get_mech_oid_set
from gssapi.raw.cython_converters cimport c_py_ttl_to_c, c_c_ttl_to_py
from gssapi.raw.creds cimport Creds
from gssapi.raw.names cimport Name
from gssapi.raw.oids cimport OID

from gssapi.raw.misc import GSSError
from gssapi.raw.named_tuples import AcquireCredResult, AddCredResult


cdef extern from "gssapi/gssapi_ext.h":
OM_uint32 gss_export_cred(OM_uint32 *min_stat, gss_cred_id_t cred_handle,
gss_buffer_t token) nogil

OM_uint32 gss_import_cred(OM_uint32 *min_stat, gss_buffer_t token,
gss_cred_id_t *cred_handle) nogil


def export_cred(Creds creds not None):
"""Export GSSAPI credentials object

This method exports a GSSSAPI credentials object into a token
which may be transmitted between different processes.

Args:
creds (Creds): the credentials object to be exported

Returns:
bytes: the exported token representing the given credentials object

Raises:
GSSError
"""

# GSS_C_EMPTY_BUFFER
cdef gss_buffer_desc exported_creds = gss_buffer_desc(0, NULL)

cdef OM_uint32 maj_stat, min_stat

with nogil:
maj_stat = gss_export_cred(&min_stat, creds.raw_creds, &exported_creds)

if maj_stat == GSS_S_COMPLETE:
res = exported_creds.value[:exported_creds.length]
gss_release_buffer(&min_stat, &exported_creds)
return res
else:
raise GSSError(maj_stat, min_stat)


def import_cred(token not None):
"""Import GSSAPI credentials from a token

This method imports a credentials object from a token
previously exported by :func:`export_cred`.

Args:
token (bytes): the token to import

Returns:
Creds: the imported credentials object

Raises:
GSSError
"""

cdef gss_buffer_desc token_buffer = gss_buffer_desc(len(token), token)

cdef gss_cred_id_t creds

cdef OM_uint32 maj_stat, min_stat

with nogil:
maj_stat = gss_import_cred(&min_stat, &token_buffer, &creds)

cdef Creds res
if maj_stat == GSS_S_COMPLETE:
res = Creds()
res.raw_creds = creds
return res
else:
raise GSSError(maj_stat, min_stat)
8 changes: 4 additions & 4 deletions gssapi/tests/test_high_level.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,13 +300,13 @@ def test_store_into_add_from(self):
retrieved_creds.shouldnt_be_none()
retrieved_creds.should_be_a(gsscreds.Credentials)

@_extension_test('cred_imp_ext', 'credentials import-export')
@_extension_test('cred_imp_exp', 'credentials import-export')
def test_export(self):
creds = gsscreds.Credentials(name=self.name)
token = creds.export()
token.should_be(bytes)
token.should_be_a(bytes)

@_extension_test('cred_imp_ext', 'credentials import-export')
@_extension_test('cred_imp_exp', 'credentials import-export')
def test_import_by_init(self):
creds = gsscreds.Credentials(name=self.name)
token = creds.export()
Expand All @@ -315,7 +315,7 @@ def test_import_by_init(self):
imported_creds.lifetime.should_be(creds.lifetime)
imported_creds.name.should_be(creds.name)

@_extension_test('cred_imp_ext', 'credentials import-export')
@_extension_test('cred_imp_exp', 'credentials import-export')
def test_pickle_unpickle(self):
creds = gsscreds.Credentials(name=self.name)
pickled_creds = pickle.dumps(creds)
Expand Down
11 changes: 11 additions & 0 deletions gssapi/tests/test_raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,17 @@ def test_acquire_creds(self):
gb.release_name(name)
gb.release_cred(creds)

@_extension_test('cred_imp_exp', 'credentials import-export')
def test_cred_import_export(self):
creds = gb.acquire_cred(None).creds
token = gb.export_cred(creds)
imported_creds = gb.import_cred(token)

inquire_orig = gb.inquire_cred(creds, name=True)
inquire_imp = gb.inquire_cred(imported_creds, name=True)

gb.compare_name(inquire_orig.name, inquire_imp.name).should_be_true()

def test_context_time(self):
target_name = gb.import_name(TARGET_SERVICE_NAME,
gb.NameType.hostbased_service)
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ def gssapi_modules(lst):
extension_file('s4u', 'gss_acquire_cred_impersonate_name'),
extension_file('cred_store', 'gss_store_cred_into'),
extension_file('rfc5588', 'gss_store_cred'),
extension_file('cred_imp_exp', 'gss_import_cred'),
]),
keywords=['gssapi', 'security'],
install_requires=[
Expand Down