File: ext_rfc6680.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 (181 lines) | stat: -rw-r--r-- 6,433 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
GSSAPI="BASE"  # This ensures that a full module is generated by Cython

from gssapi.raw.cython_types cimport *
from gssapi.raw.ext_buffer_sets cimport *
from gssapi.raw.names cimport Name
from gssapi.raw.oids cimport OID

from gssapi.raw.misc import GSSError
from gssapi.raw.named_tuples import InquireNameResult, GetNameAttributeResult

cdef extern from "python_gssapi_ext.h":
    OM_uint32 gss_display_name_ext(OM_uint32 *min_stat, gss_name_t name,
                                   gss_OID name_type,
                                   gss_buffer_t output_name) nogil

    OM_uint32 gss_inquire_name(OM_uint32 *min_stat, gss_name_t name,
                               int *name_is_mn, gss_OID *mech_type,
                               gss_buffer_set_t *attrs) nogil

    OM_uint32 gss_get_name_attribute(OM_uint32 *min_stat, gss_name_t name,
                                     gss_buffer_t attr, int *authenticated,
                                     int *complete, gss_buffer_t value,
                                     gss_buffer_t display_value,
                                     int *more) nogil

    OM_uint32 gss_set_name_attribute(OM_uint32 *min_stat, gss_name_t name,
                                     int complete, gss_buffer_t attr,
                                     gss_buffer_t value) nogil

    OM_uint32 gss_delete_name_attribute(OM_uint32 *min_stat, gss_name_t name,
                                        gss_buffer_t attr) nogil

    OM_uint32 gss_export_name_composite(OM_uint32 *min_stat, gss_name_t name,
                                        gss_buffer_t exported_name) nogil

    # GSS_C_NT_COMPOSITE_EXPORT lives in ext_rfc6680_comp_oid.pyx


def display_name_ext(Name name not None, OID name_type not None):
    # GSS_C_EMPTY_BUFFER
    cdef gss_buffer_desc output_name = gss_buffer_desc(0, NULL)

    cdef OM_uint32 maj_stat, min_stat

    maj_stat = gss_display_name_ext(&min_stat, name.raw_name,
                                    &name_type.raw_oid, &output_name)

    if maj_stat == GSS_S_COMPLETE:
        name_text = (<char*>output_name.value)[:output_name.length]
        gss_release_buffer(&min_stat, &output_name)
        return name_text
    else:
        raise GSSError(maj_stat, min_stat)


def inquire_name(Name name not None, mech_name=True, attrs=True):
    cdef int *name_is_mn_ptr = NULL
    cdef gss_OID *mn_mech_ptr = NULL
    cdef gss_buffer_set_t *attr_names_ptr = NULL

    cdef gss_buffer_set_t attr_names = GSS_C_NO_BUFFER_SET
    if attrs:
        attr_names_ptr = &attr_names

    cdef int name_is_mn = 0
    cdef gss_OID mn_mech
    if mech_name:
        name_is_mn_ptr = &name_is_mn
        mn_mech_ptr = &mn_mech

    cdef OM_uint32 maj_stat, min_stat

    maj_stat = gss_inquire_name(&min_stat, name.raw_name, name_is_mn_ptr,
                                mn_mech_ptr, attr_names_ptr)

    cdef int i
    cdef OID py_mech = None
    if maj_stat == GSS_S_COMPLETE:
        py_attr_names = []

        if attr_names != GSS_C_NO_BUFFER_SET:
            for i in range(attr_names.count):
                attr_name = attr_names.elements[i]
                py_attr_names.append(
                    (<char*>attr_name.value)[:attr_name.length]
                )

            gss_release_buffer_set(&min_stat, &attr_names)

        if name_is_mn:
            py_mech = OID()
            py_mech.raw_oid = mn_mech[0]

        return InquireNameResult(py_attr_names, <bint>name_is_mn, py_mech)
    else:
        raise GSSError(maj_stat, min_stat)


def set_name_attribute(Name name not None, attr not None, value not None,
                       bint complete=False):
    cdef gss_buffer_desc attr_buff = gss_buffer_desc(len(attr), attr)
    cdef gss_buffer_desc val_buff

    cdef OM_uint32 maj_stat, min_stat

    cdef size_t value_len = len(value)
    cdef size_t i
    for val in value:
        val_buff = gss_buffer_desc(len(val), val)
        i += 1
        if i == value_len:
            maj_stat = gss_set_name_attribute(&min_stat, name.raw_name,
                                              complete, &attr_buff, &val_buff)
        else:
            maj_stat = gss_set_name_attribute(&min_stat, name.raw_name, 0,
                                              &attr_buff, &val_buff)

        if maj_stat != GSS_S_COMPLETE:
            raise GSSError(maj_stat, min_stat)


def get_name_attribute(Name name not None, attr not None, more=None):
    cdef gss_buffer_desc attr_buff = gss_buffer_desc(len(attr), attr)

    cdef gss_buffer_desc val_buff = gss_buffer_desc(0, NULL)
    cdef gss_buffer_desc displ_val_buff = gss_buffer_desc(0, NULL)
    cdef int complete
    cdef int authenticated

    cdef int more_val = -1
    py_vals = []
    py_displ_vals = []

    cdef OM_uint32 maj_stat, min_stat

    while more_val != 0:
        maj_stat = gss_get_name_attribute(&min_stat, name.raw_name,
                                          &attr_buff,
                                          &authenticated, &complete,
                                          &val_buff, &displ_val_buff,
                                          &more_val)

        if maj_stat == GSS_S_COMPLETE:
            py_vals.append((<char*>val_buff.value)[:val_buff.length])
            py_displ_vals.append(
                (<char*>displ_val_buff.value)[:displ_val_buff.length])

            gss_release_buffer(&min_stat, &val_buff)
            gss_release_buffer(&min_stat, &displ_val_buff)
        else:
            raise GSSError(maj_stat, min_stat)

    return GetNameAttributeResult(py_vals, py_displ_vals, <bint>authenticated,
                                  <bint>complete)


def delete_name_attribute(Name name not None, attr not None):
    cdef gss_buffer_desc attr_buff = gss_buffer_desc(len(attr), attr)

    cdef OM_uint32 maj_stat, min_stat

    maj_stat = gss_delete_name_attribute(&min_stat, name.raw_name,
                                         &attr_buff)

    if maj_stat != GSS_S_COMPLETE:
        raise GSSError(maj_stat, min_stat)


def export_name_composite(Name name not None):
    cdef gss_buffer_desc res = gss_buffer_desc(0, NULL)

    cdef OM_uint32 maj_stat, min_stat

    maj_stat = gss_export_name_composite(&min_stat, name.raw_name, &res)

    if maj_stat == GSS_S_COMPLETE:
        py_res = (<char*>res.value)[:res.length]
        gss_release_buffer(&min_stat, &res)
        return py_res
    else:
        raise GSSError(maj_stat, min_stat)