File: ext_cred_store.pyx

package info (click to toggle)
python-gssapi 1.10.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 876 kB
  • sloc: python: 3,707; sh: 198; makefile: 154; ansic: 60
file content (279 lines) | stat: -rw-r--r-- 9,739 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
GSSAPI="BASE"  # This ensures that a full module is generated by Cython

from libc.string cimport memcmp, memcpy, memset
from libc.stdlib cimport free, malloc, calloc

from gssapi.raw.cython_types cimport *
from gssapi.raw.names cimport Name
from gssapi.raw.creds cimport Creds
from gssapi.raw.oids cimport OID
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_c_ttl_to_py, c_py_ttl_to_c

from collections import namedtuple

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

from gssapi import _utils

cdef extern from "python_gssapi_ext.h":
    ctypedef struct gss_key_value_element_desc:
        const char *key
        const char *value

    ctypedef struct gss_key_value_set_desc:
        OM_uint32 count
        gss_key_value_element_desc *elements

    OM_uint32 gss_acquire_cred_from(OM_uint32 *min_stat,
                                    gss_name_t desired_name,
                                    OM_uint32 ttl,
                                    gss_OID_set desired_mechs,
                                    gss_cred_usage_t cred_usage,
                                    const gss_key_value_set_desc *cred_store,
                                    gss_cred_id_t *output_creds,
                                    gss_OID_set *actual_mechs,
                                    OM_uint32 *actual_ttl) nogil

    OM_uint32 gss_add_cred_from(OM_uint32 *min_stat,
                                gss_cred_id_t input_creds,
                                gss_name_t desired_name,
                                gss_OID desired_mech,
                                gss_cred_usage_t cred_usage,
                                OM_uint32 initiator_ttl,
                                OM_uint32 acceptor_ttl,
                                const gss_key_value_set_desc *cred_store,
                                gss_cred_id_t *output_creds,
                                gss_OID_set *actual_mechs,
                                OM_uint32 *actual_initiator_ttl,
                                OM_uint32 *actual_acceptor_ttl) nogil

    OM_uint32 gss_store_cred_into(OM_uint32 *min_stat,
                                  gss_cred_id_t input_creds,
                                  gss_cred_usage_t cred_usage,
                                  gss_OID desired_mech,
                                  OM_uint32 overwrite_cred,
                                  OM_uint32 default_cred,
                                  const gss_key_value_set_desc *cred_store,
                                  gss_OID_set *elements_stored,
                                  gss_cred_usage_t *actual_usage) nogil

    # null value for cred stores
    gss_key_value_set_desc *GSS_C_NO_CRED_STORE


cdef gss_key_value_set_desc* c_create_key_value_set(dict values) except NULL:
    cdef gss_key_value_set_desc* res = <gss_key_value_set_desc*>malloc(
        sizeof(gss_key_value_set_desc))
    if res is NULL:
        raise MemoryError("Could not allocate memory for "
                          "key-value set")

    res.count = len(values)

    res.elements = <gss_key_value_element_desc*>calloc(
        res.count, sizeof(gss_key_value_element_desc))

    if res.elements is NULL:
        raise MemoryError("Could not allocate memory for "
                          "key-value set elements")

    for (i, (k, v)) in enumerate(values.items()):
        if isinstance(k, str):
            k1 = k.encode(_utils._get_encoding())
            res.elements[i].key = k1
        else:
            res.elements[i].key = k
        if isinstance(v, str):
            v1 = v.encode(_utils._get_encoding())
            res.elements[i].value = v1
        else:
            res.elements[i].value = v

    return res


cdef void c_free_key_value_set(gss_key_value_set_desc *kvset):
    free(kvset.elements)
    free(kvset)


def acquire_cred_from(dict store=None, Name name=None, lifetime=None,
                      mechs=None, usage='both'):
    cdef gss_OID_set desired_mechs
    if mechs is not None:
        desired_mechs = c_get_mech_oid_set(mechs)
    else:
        desired_mechs = GSS_C_NO_OID_SET

    cdef OM_uint32 input_ttl = c_py_ttl_to_c(lifetime)

    cdef gss_name_t c_name
    if name is None:
        c_name = GSS_C_NO_NAME
    else:
        c_name = name.raw_name

    cdef gss_cred_usage_t c_usage
    if usage == 'initiate':
        c_usage = GSS_C_INITIATE
    elif usage == 'accept':
        c_usage = GSS_C_ACCEPT
    elif usage == 'both':
        c_usage = GSS_C_BOTH
    else:
        raise ValueError(f'Invalid usage "{usage}" - permitted values are '
                         '"initiate", "accept", and "both"')

    cdef gss_key_value_set_desc *c_store
    if store is not None:
        c_store = c_create_key_value_set(store)
    else:
        c_store = GSS_C_NO_CRED_STORE

    cdef gss_cred_id_t creds
    cdef gss_OID_set actual_mechs
    cdef OM_uint32 actual_ttl

    cdef OM_uint32 maj_stat, min_stat

    with nogil:
        maj_stat = gss_acquire_cred_from(&min_stat, c_name, input_ttl,
                                         desired_mechs, c_usage, c_store,
                                         &creds, &actual_mechs, &actual_ttl)

    cdef OM_uint32 tmp_min_stat
    if mechs is not None:
        gss_release_oid_set(&tmp_min_stat, &desired_mechs)

    if store is not None:
        c_free_key_value_set(c_store)

    cdef Creds rc = Creds()
    if maj_stat == GSS_S_COMPLETE:
        rc.raw_creds = creds
        return AcquireCredResult(rc, c_create_oid_set(actual_mechs),
                                 c_c_ttl_to_py(actual_ttl))
    else:
        raise GSSError(maj_stat, min_stat)


def add_cred_from(dict store, Creds input_creds,
                  Name name not None, OID mech not None,
                  usage='both', init_lifetime=None,
                  accept_lifetime=None):
    cdef OM_uint32 input_initiator_ttl = c_py_ttl_to_c(init_lifetime)
    cdef OM_uint32 input_acceptor_ttl = c_py_ttl_to_c(accept_lifetime)

    cdef gss_cred_usage_t c_usage
    if usage == 'initiate':
        c_usage = GSS_C_INITIATE
    elif usage == 'accept':
        c_usage = GSS_C_ACCEPT
    elif usage == 'both':
        c_usage = GSS_C_BOTH
    else:
        raise ValueError(f'Invalid usage "{usage}" - permitted values are '
                         '"initiate", "accept", and "both"')

    cdef gss_name_t c_name = name.raw_name
    cdef gss_OID c_mech = &mech.raw_oid

    cdef gss_cred_id_t c_input_creds
    if input_creds is not None:
        c_input_creds = input_creds.raw_creds
    else:
        c_input_creds = GSS_C_NO_CREDENTIAL

    cdef gss_key_value_set_desc *c_store
    if store is not None:
        c_store = c_create_key_value_set(store)
    else:
        c_store = GSS_C_NO_CRED_STORE

    cdef gss_cred_id_t creds
    cdef gss_OID_set actual_mechs
    cdef OM_uint32 actual_initiator_ttl
    cdef OM_uint32 actual_acceptor_ttl

    cdef OM_uint32 maj_stat, min_stat

    with nogil:
        maj_stat = gss_add_cred_from(&min_stat, c_input_creds, c_name,
                                     c_mech, c_usage, input_initiator_ttl,
                                     input_acceptor_ttl, c_store, &creds,
                                     &actual_mechs, &actual_initiator_ttl,
                                     &actual_acceptor_ttl)

    if store is not None:
        c_free_key_value_set(c_store)

    cdef Creds rc
    if maj_stat == GSS_S_COMPLETE:
        rc = Creds()
        rc.raw_creds = creds
        return AddCredResult(rc, c_create_oid_set(actual_mechs),
                             c_c_ttl_to_py(actual_initiator_ttl),
                             c_c_ttl_to_py(actual_acceptor_ttl))
    else:
        raise GSSError(maj_stat, min_stat)


def store_cred_into(dict store, Creds creds not None,
                    usage='both', OID mech=None, bint overwrite=False,
                    bint set_default=False):
    cdef gss_OID desired_mech
    if mech is not None:
        desired_mech = &mech.raw_oid
    else:
        desired_mech = GSS_C_NO_OID

    cdef gss_cred_usage_t c_usage
    if usage == 'initiate':
        c_usage = GSS_C_INITIATE
    elif usage == 'accept':
        c_usage = GSS_C_ACCEPT
    elif usage == 'both':
        c_usage = GSS_C_BOTH
    else:
        raise ValueError(f'Invalid usage "{usage}" - permitted values are '
                         '"initiate", "accept", and "both"')

    cdef gss_key_value_set_desc *c_store
    if store is not None:
        c_store = c_create_key_value_set(store)
    else:
        c_store = GSS_C_NO_CRED_STORE

    cdef gss_cred_id_t c_creds = creds.raw_creds

    cdef gss_OID_set actual_mech_types
    cdef gss_cred_usage_t actual_usage

    cdef OM_uint32 maj_stat, min_stat

    with nogil:
        maj_stat = gss_store_cred_into(&min_stat, c_creds, c_usage,
                                       desired_mech, overwrite,
                                       set_default, c_store,
                                       &actual_mech_types,
                                       &actual_usage)

    if store is not None:
        c_free_key_value_set(c_store)

    if maj_stat == GSS_S_COMPLETE:
        if actual_usage == GSS_C_INITIATE:
            py_actual_usage = 'initiate'
        elif actual_usage == GSS_C_ACCEPT:
            py_actual_usage = 'accept'
        else:
            py_actual_usage = 'both'

        return StoreCredResult(c_create_oid_set(actual_mech_types),
                               py_actual_usage)
    else:
        raise GSSError(maj_stat, min_stat)