File: creds.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 (307 lines) | stat: -rw-r--r-- 10,589 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
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
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_get_mech_oid_set
from gssapi.raw.cython_converters cimport c_create_oid_set
from gssapi.raw.cython_converters cimport c_py_ttl_to_c, c_c_ttl_to_py
from gssapi.raw.names cimport Name
from gssapi.raw.oids cimport OID

from gssapi.raw.types import MechType, NameType
from gssapi.raw.misc import GSSError
from gssapi.raw.named_tuples import AcquireCredResult, AddCredResult
from gssapi.raw.named_tuples import InquireCredResult, InquireCredByMechResult


cdef extern from "python_gssapi.h":
    OM_uint32 gss_acquire_cred(OM_uint32 *min_stat,
                               const gss_name_t name,
                               OM_uint32 ttl,
                               const gss_OID_set mechs,
                               gss_cred_usage_t cred_usage,
                               gss_cred_id_t *creds,
                               gss_OID_set *actual_mechs,
                               OM_uint32 *actual_ttl) nogil

    OM_uint32 gss_release_cred(OM_uint32 *min_stat,
                               gss_cred_id_t *creds) nogil

    OM_uint32 gss_add_cred(OM_uint32 *min_stat,
                           const gss_cred_id_t base_creds,
                           const gss_name_t name,
                           const gss_OID mech,
                           gss_cred_usage_t cred_usage,
                           OM_uint32 initiator_ttl,
                           OM_uint32 acceptor_ttl,
                           gss_cred_id_t *output_creds,
                           gss_OID_set *actual_mechs,
                           OM_uint32 *actual_initiator_ttl,
                           OM_uint32 *actual_acceptor_ttl) nogil

    # NB(directxman12): this is called frequently, so don't release the GIL
    OM_uint32 gss_inquire_cred(OM_uint32 *min_stat,
                               const gss_cred_id_t creds,
                               gss_name_t *name,
                               OM_uint32 *ttl,
                               gss_cred_usage_t *cred_usage,
                               gss_OID_set *mechs) nogil

    OM_uint32 gss_inquire_cred_by_mech(OM_uint32 *min_stat,
                                       const gss_cred_id_t cred_handle,
                                       const gss_OID mech_type,
                                       gss_name_t *name,
                                       OM_uint32 *initiator_ttl,
                                       OM_uint32 *acceptor_ttl,
                                       gss_cred_usage_t *cred_usage) nogil


cdef class Creds:
    # defined in pxd
    # cdef gss_cred_id_t raw_creds

    def __cinit__(self, Creds cpy=None):
        if cpy is not None:
            self.raw_creds = cpy.raw_creds
            cpy.raw_creds = GSS_C_NO_CREDENTIAL
        else:
            self.raw_creds = GSS_C_NO_CREDENTIAL

    def __dealloc__(self):
        # essentially just releaseCred(self), but it is unsafe to call
        # methods
        cdef OM_uint32 maj_stat, min_stat
        if self.raw_creds is not GSS_C_NO_CREDENTIAL:
            maj_stat = gss_release_cred(&min_stat, &self.raw_creds)
            if maj_stat != GSS_S_COMPLETE:
                raise GSSError(maj_stat, min_stat)
            self.raw_creds = NULL


def acquire_cred(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_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(&min_stat, c_name, input_ttl,
                                    desired_mechs, c_usage, &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)

    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 release_cred(Creds creds not None):
    cdef OM_uint32 maj_stat, min_stat
    maj_stat = gss_release_cred(&min_stat, &creds.raw_creds)
    if maj_stat != GSS_S_COMPLETE:
        raise GSSError(maj_stat, min_stat)
    creds.raw_creds = NULL


def add_cred(Creds input_cred, Name name not None, OID mech not None,
             usage='initiate', init_lifetime=None,
             accept_lifetime=None, mutate_input=False):
    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_cred_id_t raw_input_cred
    if input_cred is not None:
        raw_input_cred = input_cred.raw_creds
    else:
        raw_input_cred = GSS_C_NO_CREDENTIAL

    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_id_t output_creds
    cdef gss_cred_id_t *output_creds_ptr = NULL
    if not mutate_input:
        output_creds_ptr = &output_creds

    cdef gss_OID_set actual_mechs
    cdef OM_uint32 actual_initiator_ttl, actual_acceptor_ttl

    cdef OM_uint32 maj_stat, min_stat

    with nogil:
        maj_stat = gss_add_cred(&min_stat, raw_input_cred, name.raw_name,
                                &mech.raw_oid, c_usage, input_initiator_ttl,
                                input_acceptor_ttl, output_creds_ptr,
                                &actual_mechs, &actual_initiator_ttl,
                                &actual_acceptor_ttl)

    cdef Creds rc
    if maj_stat == GSS_S_COMPLETE:
        if mutate_input:
            rc = None
        else:
            rc = Creds()
            rc.raw_creds = output_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 inquire_cred(Creds creds not None, name=True, lifetime=True, usage=True,
                 mechs=True):
    # TODO(directxman12): add docs
    cdef gss_name_t res_name
    cdef gss_name_t *res_name_ptr = NULL
    if name:
        res_name_ptr = &res_name

    cdef OM_uint32 res_ttl
    cdef OM_uint32 *res_ttl_ptr = NULL
    if lifetime:
        res_ttl_ptr = &res_ttl

    cdef gss_cred_usage_t res_usage
    cdef gss_cred_usage_t *res_usage_ptr = NULL
    if usage:
        res_usage_ptr = &res_usage

    cdef gss_OID_set res_mechs
    cdef gss_OID_set *res_mechs_ptr = NULL
    if mechs:
        res_mechs_ptr = &res_mechs

    cdef OM_uint32 maj_stat, min_stat
    maj_stat = gss_inquire_cred(&min_stat, creds.raw_creds, res_name_ptr,
                                res_ttl_ptr, res_usage_ptr, res_mechs_ptr)

    cdef Name rn
    if maj_stat == GSS_S_COMPLETE:
        if name:
            rn = Name()
            rn.raw_name = res_name
        else:
            rn = None

        py_usage = None
        if usage:
            if res_usage == GSS_C_INITIATE:
                py_usage = 'initiate'
            elif res_usage == GSS_C_ACCEPT:
                py_usage = 'accept'
            elif res_usage == GSS_C_BOTH:
                py_usage = 'both'

        py_ttl = None
        if lifetime:
            py_ttl = c_c_ttl_to_py(res_ttl)

        py_mechs = None
        if mechs:
            py_mechs = c_create_oid_set(res_mechs)

        return InquireCredResult(rn, py_ttl, py_usage, py_mechs)
    else:
        raise GSSError(maj_stat, min_stat)


def inquire_cred_by_mech(Creds creds not None, OID mech not None,
                         name=True, init_lifetime=True,
                         accept_lifetime=True, usage=True):
    # TODO(directxman12): add docs
    cdef gss_name_t res_name
    cdef gss_name_t *res_name_ptr = NULL
    if name:
        res_name_ptr = &res_name

    cdef OM_uint32 res_initiator_ttl
    cdef OM_uint32 *res_initiator_ttl_ptr = NULL
    if init_lifetime:
        res_initiator_ttl_ptr = &res_initiator_ttl

    cdef OM_uint32 res_acceptor_ttl
    cdef OM_uint32 *res_acceptor_ttl_ptr = NULL
    if accept_lifetime:
        res_acceptor_ttl_ptr = &res_acceptor_ttl

    cdef gss_cred_usage_t res_usage
    cdef gss_cred_usage_t *res_usage_ptr = NULL
    if usage:
        res_usage_ptr = &res_usage

    cdef OM_uint32 maj_stat, min_stat
    maj_stat = gss_inquire_cred_by_mech(&min_stat, creds.raw_creds,
                                        &mech.raw_oid, res_name_ptr,
                                        res_initiator_ttl_ptr,
                                        res_acceptor_ttl_ptr, res_usage_ptr)
    cdef Name rn
    if maj_stat == GSS_S_COMPLETE:
        if name:
            rn = Name()
            rn.raw_name = res_name
        else:
            rn = None

        py_initiator_ttl = None
        if init_lifetime:
            py_initiator_ttl = c_c_ttl_to_py(res_initiator_ttl)

        py_acceptor_ttl = None
        if accept_lifetime:
            py_acceptor_ttl = c_c_ttl_to_py(res_acceptor_ttl)

        py_usage = None
        if usage:
            if res_usage == GSS_C_INITIATE:
                py_usage = 'initiate'
            elif res_usage == GSS_C_ACCEPT:
                py_usage = 'accept'
            elif res_usage == GSS_C_BOTH:
                py_usage = 'both'

        return InquireCredByMechResult(rn, py_initiator_ttl,
                                       py_acceptor_ttl, py_usage)
    else:
        raise GSSError(maj_stat, min_stat)