gssapi/error.py
def status_list(maj_status, min_status, status_type=C.GSS_C_GSS_CODE, mech_type=C.GSS_C_NO_OID):
    """
    Creates a "friendly" error message from a GSS status code. This is used to create the
    :attr:`GSSCException.message` of a :class:`GSSCException`.

    :param maj_status: The major status reported by the C GSSAPI.
    :type maj_status: int
    :param min_status: The minor status reported by the C GSSAPI.
    :type min_status: int
    :param status_type: Whether the status is a general GSSAPI status or a mechanism status.
    :type status_type: ``GSS_C_GSS_CODE`` or ``GSS_C_MECH_CODE``
    :param mech_type: Optional mechanism type, if the status is a mechanism status.
    :type mech_type: :class:`~gssapi.oids.OID`
    :returns: a list of strings describing the error.
    :rtype: list of strings
    """
    from .oids import OID

    statuses = []
    message_context = ffi.new('OM_uint32[1]')
    minor_status = ffi.new('OM_uint32[1]')

    if isinstance(mech_type, OID):
        mech_type = ffi.addressof(mech_type._oid)  # OID._oid is type "struct gss_OID_desc"
    elif mech_type == C.GSS_C_NO_OID:
        mech_type = ffi.cast('gss_OID', C.GSS_C_NO_OID)
    elif not isinstance(mech_type, ffi.CData) or ffi.typeof(mech_type) != ffi.typeof('gss_OID'):
        raise TypeError(
            "Expected mech_type to be a gssapi.oids.OID or gss_OID, got {0}".format(type(mech_type))
        )

    while True:
        status_buf = ffi.new('gss_buffer_desc[1]')

        try:
            retval = C.gss_display_status(
                minor_status,
                maj_status,
                status_type,
                mech_type,
                message_context,
                status_buf
            )
            if retval == C.GSS_S_COMPLETE:
                statuses.append("({0}) {1}.".format(
                    maj_status,
                    _buf_to_str(status_buf[0]).decode("utf-8", errors="replace")
                ))
            elif retval == C.GSS_S_BAD_MECH:
                statuses.append("Unsupported mechanism type passed to GSSException")
                break
            elif retval == C.GSS_S_BAD_STATUS:
                statuses.append("Unrecognized status value passed to GSSException")
                break
        finally:
            C.gss_release_buffer(minor_status, status_buf)

        if message_context[0] == 0:
            break

    if min_status:
        minor_status_msgs = status_list(min_status, 0, C.GSS_C_MECH_CODE, mech_type)
        if minor_status_msgs:
            statuses.append("Minor code:")
            statuses.extend(minor_status_msgs)
    return statuses
def status_list(maj_status, min_status, status_type=C.GSS_C_GSS_CODE, mech_type=C.GSS_C_NO_OID):
    """
    Creates a "friendly" error message from a GSS status code. This is used to create the
    :attr:`GSSCException.message` of a :class:`GSSCException`.

    :param maj_status: The major status reported by the C GSSAPI.
    :type maj_status: int
    :param min_status: The minor status reported by the C GSSAPI.
    :type min_status: int
    :param status_type: Whether the status is a general GSSAPI status or a mechanism status.
    :type status_type: ``GSS_C_GSS_CODE`` or ``GSS_C_MECH_CODE``
    :param mech_type: Optional mechanism type, if the status is a mechanism status.
    :type mech_type: :class:`~gssapi.oids.OID`
    :returns: a list of strings describing the error.
    :rtype: list of strings
    """
    from .oids import OID

    statuses = []
    message_context = ffi.new('OM_uint32[1]')
    minor_status = ffi.new('OM_uint32[1]')

    if isinstance(mech_type, OID):
        mech_type = ffi.addressof(mech_type._oid)  # OID._oid is type "struct gss_OID_desc"
    elif mech_type == C.GSS_C_NO_OID:
        mech_type = ffi.cast('gss_OID', C.GSS_C_NO_OID)
    elif not isinstance(mech_type, ffi.CData) or ffi.typeof(mech_type) != ffi.typeof('gss_OID'):
        raise TypeError(
            "Expected mech_type to be a gssapi.oids.OID or gss_OID, got {0}".format(type(mech_type))
        )

    while True:
        status_buf = ffi.new('gss_buffer_desc[1]')

        try:
            retval = C.gss_display_status(
                minor_status,
                maj_status,
                status_type,
                mech_type,
                message_context,
                status_buf
            )
            if retval == C.GSS_S_COMPLETE:
                statuses.append("({0}) {1}.".format(
                    maj_status,
                    _buf_to_str(status_buf[0]).decode("utf-8", errors="replace")
                ))
            elif retval == C.GSS_S_BAD_MECH:
                statuses.append("Unsupported mechanism type passed to GSSException")
                break
            elif retval == C.GSS_S_BAD_STATUS:
                statuses.append("Unrecognized status value passed to GSSException")
                break
        finally:
            C.gss_release_buffer(minor_status, status_buf)

        if message_context[0] == 0:
            break

    if min_status:
        minor_status_msgs = status_list(min_status, 0, C.GSS_C_MECH_CODE, mech_type)
        if minor_status_msgs:
            statuses.append("Minor code:")
            statuses.extend(minor_status_msgs)
    return statuses
Creates a "friendly" error message from a GSS status code. This is used to create the
    :attr:`GSSCException.message` of a :class:`GSSCException`.

    :param maj_status: The major status reported by the C GSSAPI.
    :type maj_status: int
    :param min_status: The minor status reported by the C GSSAPI.
    :type min_status: int
    :param status_type: Whether the status is a general GSSAPI status or a mechanism status.
    :type status_type: ``GSS_C_GSS_CODE`` or ``GSS_C_MECH_CODE``
    :param mech_type: Optional mechanism type, if the status is a mechanism status.
    :type mech_type: :class:`~gssapi.oids.OID`
    :returns: a list of strings describing the error.
    :rtype: list of strings