This file is indexed.

/usr/lib/python3/dist-packages/gssapi/names.py is in python3-gssapi 1.1.3-2ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
import collections

import six

from gssapi.raw import names as rname
from gssapi.raw import NameType
from gssapi.raw import named_tuples as tuples
from gssapi import _utils

rname_rfc6680 = _utils.import_gssapi_extension('rfc6680')
rname_rfc6680_comp_oid = _utils.import_gssapi_extension('rfc6680_comp_oid')


class Name(rname.Name):
    """A GSSAPI Name

    This class represents a GSSAPI name which may be used with
    used with and/or returned by other GSSAPI methods.

    It inherits from the low-level GSSAPI :class:`~gssapi.raw.names.Name`
    class, and thus may used with both low-level and high-level API methods.

    This class may be pickled and unpickled, as well as copied.

    The :func:`str` and :func:`bytes` methods may be used to retrieve the
    text of the name.

    Note:
        Name strings will be automatically converted to and from unicode
        strings as appropriate.  If a method is listed as returning a
        :class:`str` object, it will return a unicode string.

        The encoding used will be python-gssapi's current encoding, which
        defaults to UTF-8.
    """

    __slots__ = ('_attr_obj')

    def __new__(cls, base=None, name_type=None, token=None,
                composite=False):
        if token is not None:
            if composite:
                if rname_rfc6680 is None:
                    raise NotImplementedError(
                        "Your GSSAPI implementation does not support RFC 6680 "
                        "(the GSSAPI naming extensions)")

                if rname_rfc6680_comp_oid is not None:
                    base_name = rname.import_name(token,
                                                  NameType.composite_export)
                    displ_name = rname.display_name(base_name, name_type=True)
                    if displ_name.name_type == NameType.composite_export:
                        # NB(directxman12): there's a bug in MIT krb5 <= 1.13
                        # where GSS_C_NT_COMPOSITE_EXPORT doesn't trigger
                        # immediate import logic.  However, we can just use
                        # the normal GSS_C_NT_EXPORT_NAME in this case.
                        base_name = rname.import_name(token, NameType.export)
                else:
                    # NB(directxman12): some older versions of MIT krb5 don't
                    # have support for the GSS_C_NT_COMPOSITE_EXPORT, but do
                    # support composite tokens via GSS_C_NT_EXPORT_NAME.
                    base_name = rname.import_name(token, NameType.export)
            else:
                base_name = rname.import_name(token, NameType.export)
        elif isinstance(base, rname.Name):
            base_name = base
        else:
            if isinstance(base, six.text_type):
                base = base.encode(_utils._get_encoding())

            base_name = rname.import_name(base, name_type)

        return super(Name, cls).__new__(cls, base_name)

    def __init__(self, base=None, name_type=None, token=None, composite=False):
        """
        The constructor can be used to "import" a name from a human readable
        representation, or from a token, and can also be used to convert a
        low-level :class:`gssapi.raw.names.Name` object into a high-level
        object.

        If a :class:`~gssapi.raw.names.Name` object from the low-level API
        is passed as the `base` argument, it will be converted into a
        high-level object.

        If the `token` argument is used, the name will be imported using
        the token.  If the token was exported as a composite token,
        pass `composite=True`.

        Otherwise, a new name will be created, using the `base` argument as
        the human-readable string and the `name_type` argument to denote the
        name type.

        Raises:
            BadNameTypeError
            BadNameError
            BadMechanismError
        """

        if rname_rfc6680 is not None:
            self._attr_obj = _NameAttributeMapping(self)
        else:
            self._attr_obj = None

    def __str__(self):
        if issubclass(str, six.text_type):
            # Python 3 -- we should return unicode
            return bytes(self).decode(_utils._get_encoding())
        else:
            # Python 2 -- we should return a string
            return self.__bytes__()

    def __unicode__(self):
        # Python 2 -- someone asked for unicode
        return self.__bytes__().decode(_utils._get_encoding())

    def __bytes__(self):
        # Python 3 -- someone asked for bytes
        return rname.display_name(self, name_type=False).name

    def display_as(self, name_type):
        """
        Display this name as the given name type.

        This method attempts to display the current :class:`Name`
        using the syntax of the given :class:`NameType`, if possible.

        Warning:

            In MIT krb5 versions below 1.13.3, this method can segfault if
            the name was not *originally* created with a `name_type` that was
            not ``None`` (even in cases when a ``name_type``
            is later "added", such as via :meth:`canonicalize`).
            **Do not use this method unless you are sure the above
            conditions can never happen in your code.**

        Warning:

            In addition to the above warning, current versions of MIT krb5 do
            not actually fully implement this method, and it may return
            incorrect results in the case of canonicalized names.

        :requires-ext:`rfc6680`

        Args:
            name_type (OID): the :class:`NameType` to use to display the given
                name

        Returns:
            str: the displayed name

        Raises:
            OperationUnavailableError
        """

        if rname_rfc6680 is None:
            raise NotImplementedError("Your GSSAPI implementation does not "
                                      "support RFC 6680 (the GSSAPI naming "
                                      "extensions)")
        return rname_rfc6680.display_name_ext(self, name_type).decode(
            _utils._get_encoding())

    @property
    def name_type(self):
        """The :class:`NameType` of this name"""
        return rname.display_name(self, name_type=True).name_type

    def __eq__(self, other):
        if not isinstance(other, rname.Name):
            # maybe something else can compare this
            # to other classes, but we certainly can't
            return NotImplemented
        else:
            return rname.compare_name(self, other)

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

    def __repr__(self):
        disp_res = rname.display_name(self, name_type=True)
        return "Name({name}, {name_type})".format(name=disp_res.name,
                                                  name_type=disp_res.name_type)

    def export(self, composite=False):
        """Export this name as a token.

        This method exports the name into a byte string which can then be
        imported by using the `token` argument of the constructor.

        Args:
            composite (bool): whether or not use to a composite token --
                :requires-ext:`rfc6680`

        Returns:
            bytes: the exported name in token form

        Raises:
            MechanismNameRequiredError
            BadNameTypeError
            BadNameError
        """

        if composite:
            if rname_rfc6680 is None:
                raise NotImplementedError("Your GSSAPI implementation does "
                                          "not support RFC 6680 (the GSSAPI "
                                          "naming extensions)")

            return rname_rfc6680.export_name_composite(self)
        else:
            return rname.export_name(self)

    def canonicalize(self, mech):
        """Canonicalize a name with respect to a mechanism.

        This method returns a new :class:`Name` that is canonicalized according
        to the given mechanism.

        Args:
            mech (OID): the :class:`MechType` to use

        Returns:
            Name: the canonicalized name

        Raises:
            BadMechanismError
            BadNameTypeError
            BadNameError
        """

        return type(self)(rname.canonicalize_name(self, mech))

    def __copy__(self):
        return type(self)(rname.duplicate_name(self))

    def __deepcopy__(self, memo):
        return type(self)(rname.duplicate_name(self))

    def _inquire(self, **kwargs):
        """Inspect this name for information.

        This method inspects the name for information.

        If no keyword arguments are passed, all available information
        is returned.  Otherwise, only the keyword arguments that
        are passed and set to `True` are returned.

        Args:
            mech_name (bool): get whether this is a mechanism name,
                and, if so, the associated mechanism
            attrs (bool): get the attributes names for this name

        Returns:
            InquireNameResult: the results of the inquiry, with unused
                fields set to None

        Raises:
            GSSError
        """

        if rname_rfc6680 is None:
            raise NotImplementedError("Your GSSAPI implementation does not "
                                      "support RFC 6680 (the GSSAPI naming "
                                      "extensions)")

        if not kwargs:
            default_val = True
        else:
            default_val = False

        attrs = kwargs.get('attrs', default_val)
        mech_name = kwargs.get('mech_name', default_val)

        return rname_rfc6680.inquire_name(self, mech_name=mech_name,
                                          attrs=attrs)

    @property
    def is_mech_name(self):
        """Whether or not this name is a mechanism name
        (:requires-ext:`rfc6680`)
        """
        return self._inquire(mech_name=True).is_mech_name

    @property
    def mech(self):
        """The mechanism associated with this name (:requires-ext:`rfc6680`)
        """
        return self._inquire(mech_name=True).mech

    @property
    def attributes(self):
        """The attributes of this name (:requires-ext:`rfc6680`)

        The attributes are presenting in the form of a
        :class:`~collections.MutableMapping` (a dict-like object).

        Retrieved values will always be in the form of :class:`frozensets`.

        When assigning values, if iterables are used, they be considered to be
        the set of values for the given attribute.  If a non-iterable is used,
        it will be considered a single value, and automatically wrapped in an
        iterable.

        Note:
            String types (includes :class:`bytes`) are not considered to
            be iterables in this case.
        """
        if self._attr_obj is None:
            raise NotImplementedError("Your GSSAPI implementation does not "
                                      "support RFC 6680 (the GSSAPI naming "
                                      "extensions)")

        return self._attr_obj


class _NameAttributeMapping(collections.MutableMapping):

    """Provides dict-like access to RFC 6680 Name attributes."""
    def __init__(self, name):
        self._name = name

    def __getitem__(self, key):
        if isinstance(key, six.text_type):
            key = key.encode(_utils._get_encoding())

        res = rname_rfc6680.get_name_attribute(self._name, key)
        return tuples.GetNameAttributeResult(frozenset(res.values),
                                             frozenset(res.display_values),
                                             res.authenticated,
                                             res.complete)

    def __setitem__(self, key, value):
        if isinstance(key, six.text_type):
            key = key.encode(_utils._get_encoding())

        rname_rfc6680.delete_name_attribute(self._name, key)

        if isinstance(value, tuples.GetNameAttributeResult):
            complete = value.complete
            value = value.values
        elif isinstance(value, tuple) and len(value) == 2:
            complete = value[1]
            value = value[0]
        else:
            complete = False

        if (isinstance(value, (six.string_types, bytes)) or
                not isinstance(value, collections.Iterable)):
            # NB(directxman12): this allows us to easily assign a single
            # value, since that's a common case
            value = [value]

            rname_rfc6680.set_name_attribute(self._name, key, value,
                                             complete=complete)

    def __delitem__(self, key):
        if isinstance(key, six.text_type):
            key = key.encode(_utils._get_encoding())

        rname_rfc6680.delete_name_attribute(self._name, key)

    def __iter__(self):
        return iter(self._name._inquire(attrs=True).attrs)

    def __len__(self):
        return len(self._name._inquire(attrs=True).attrs)