File: types.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 (238 lines) | stat: -rw-r--r-- 6,987 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
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_make_oid
from gssapi.raw.oids cimport OID

from gssapi.raw._enum_extensions import ExtendableEnum

from enum import IntEnum
import collections
import copy
import numbers
import operator

from collections.abc import MutableSet


class NameType(object):
    # mech-agnostic name types
    hostbased_service = c_make_oid(GSS_C_NT_HOSTBASED_SERVICE)
    # NB(directxman12): skip GSS_C_NT_HOSTBASED_SERVICE_X since it's deprecated
    user = c_make_oid(GSS_C_NT_USER_NAME)
    anonymous = c_make_oid(GSS_C_NT_ANONYMOUS)
    machine_uid = c_make_oid(GSS_C_NT_MACHINE_UID_NAME)
    string_uid = c_make_oid(GSS_C_NT_STRING_UID_NAME)
    export = c_make_oid(GSS_C_NT_EXPORT_NAME)

    # mech-specific name types are added automatically on import


class RequirementFlag(IntEnum, metaclass=ExtendableEnum):
    delegate_to_peer = GSS_C_DELEG_FLAG
    mutual_authentication = GSS_C_MUTUAL_FLAG
    replay_detection = GSS_C_REPLAY_FLAG
    out_of_sequence_detection = GSS_C_SEQUENCE_FLAG
    confidentiality = GSS_C_CONF_FLAG
    integrity = GSS_C_INTEG_FLAG
    anonymity = GSS_C_ANON_FLAG
    protection_ready = GSS_C_PROT_READY_FLAG
    transferable = GSS_C_TRANS_FLAG

    # GSS_C_DELEG_POLICY_FLAG.  cython can't do compile-time detection of
    # this, so take the value from RFC 5896.  Implementations that don't
    # support it will ignore it.
    ok_as_delegate = 32768

    # GSS_C_CHANNEL_BOUND_FLAG, implemented in MIT krb5-1.19
    # See draft-ietf-kitten-channel-bound-flag-04
    channel_bound = 2048


class AddressType(IntEnum, metaclass=ExtendableEnum):
    # unspecified = GSS_C_AF_UNSPEC  # None --> GSS_C_AF_UNSPEC
    local = GSS_C_AF_LOCAL
    ip = GSS_C_AF_INET
    arpanet = GSS_C_AF_IMPLINK  # ARPAnet support, heh, heh
    pup = GSS_C_AF_PUP
    chaos = GSS_C_AF_CHAOS
    xerox_ns = GSS_C_AF_NS  # and XEROX too?
    nbs = GSS_C_AF_NBS
    ecma = GSS_C_AF_ECMA
    datakit = GSS_C_AF_DATAKIT
    ccitt = GSS_C_AF_CCITT
    ibm_sna = GSS_C_AF_SNA
    decnet = GSS_C_AF_DECnet
    dli = GSS_C_AF_DLI
    lat = GSS_C_AF_LAT
    hyperchannel = GSS_C_AF_HYLINK
    appletalk = GSS_C_AF_APPLETALK  # this list just keeps getting better
    bisync = GSS_C_AF_BSC
    dss = GSS_C_AF_DSS
    osi_tp4 = GSS_C_AF_OSI
    x25 = GSS_C_AF_X25
    null = GSS_C_AF_NULLADDR


class MechType(object):
    pass

    # these are added in by the individual mechanism files on import


class GenericFlagSet(MutableSet):

    __slots__ = '_val'
    MAX_VAL = 1 << 31

    def __init__(self, flags=None):
        self._val = 0
        if isinstance(flags, GenericFlagSet):
            self._val = flags._val
        if isinstance(flags, numbers.Integral):
            self._val = int(flags)
        elif flags is not None:
            for flag in flags:
                self._val |= flag

    def __contains__(self, flag):
        return self._val & flag

    def __iter__(self):
        i = 1
        while i < self.MAX_VAL:
            if i & self._val:
                yield i

            i <<= 1

    def __len__(self):
        # get the Hamming weight of _val
        cdef unsigned int size = 0
        cdef unsigned int i = 1
        while i < self.MAX_VAL:
            if i & self._val:
                size += 1

            i <<= 1

        return size

    def add(self, flag):
        self._val |= flag

    def discard(self, flag):
        # NB(directxman12): the 0xFFFFFFFF mask is needed to
        #                   make Python's invert work properly
        self._val = self._val & (~flag & 0xFFFFFFFF)

    def __and__(self, other):
        if isinstance(other, numbers.Integral):
            return self._val & other
        else:
            return super(GenericFlagSet, self).__and__(other)

    def __rand__(self, other):
        return self.__and__(other)

    def __or__(self, other):
        if isinstance(other, numbers.Integral):
            return self._val | other
        else:
            return super(GenericFlagSet, self).__or__(other)

    def __ror__(self, other):
        return self.__or__(other)

    def __xor__(self, other):
        if isinstance(other, numbers.Integral):
            return self._val ^ other
        else:
            return super(GenericFlagSet, self).__xor__(other)

    def __rxor__(self, other):
        return self.__xor__(other)

    def __int__(self):
        return self._val

    def __long__(self):
        return long(self._val)

    def __eq__(self, other):
        if isinstance(other, GenericFlagSet):
            return self._val == other._val
        else:
            return False

    def __ne__(self, other):
        return not self.__eq__(other)

    def __repr__(self):
        bits = "{0:032b}".format(self._val & 0xFFFFFFFF)
        return "<{name} {bits}>".format(name=type(self).__name__,
                                        bits=bits)


class IntEnumFlagSet(GenericFlagSet):

    __slots__ = ('_val', '_enum')

    def __init__(self, enum, flags=None):
        if not issubclass(enum, IntEnum):
            raise Exception('"enum" not an Enum')
        self._enum = enum
        super(IntEnumFlagSet, self).__init__(flags)

    def __iter__(self):
        for i in super(IntEnumFlagSet, self).__iter__():
            yield self._enum(i)

    def __repr__(self):
        fmt_str = "{name}({enum}, [{vals}])"
        vals = ', '.join([elem.name for elem in self])
        return fmt_str.format(name=type(self).__name__,
                              enum=self._enum.__name__,
                              vals=vals)

    def __and__(self, other):
        if isinstance(other, self._enum):
            return other in self
        else:
            res = super(IntEnumFlagSet, self).__and__(other)
            if isinstance(res, GenericFlagSet):
                return IntEnumFlagSet(self._enum, res)
            else:
                return res

    def __or__(self, other):
        if isinstance(other, self._enum):
            cpy = copy.copy(self)
            cpy.add(other)
            return cpy
        else:
            res = super(IntEnumFlagSet, self).__or__(other)
            if isinstance(res, GenericFlagSet):
                return IntEnumFlagSet(self._enum, res)
            else:
                return res

    def __xor__(self, other):
        if isinstance(other, self._enum):
            cpy = copy.copy(self)
            cpy._val = cpy._val ^ other
            return cpy
        else:
            res = super(IntEnumFlagSet, self).__xor__(other)
            if isinstance(res, GenericFlagSet):
                return IntEnumFlagSet(self._enum, res)
            else:
                return res

    def __sub__(self, other):
        return IntEnumFlagSet(self._enum,
                              super(IntEnumFlagSet, self).__sub__(other))

    @classmethod
    def _from_iterable(cls, it):
        return GenericFlagSet(it)