gssapi/ctx.py
def unwrap(self, message, conf_req=True, qop_req=None, supplementary=False):
        """
        Takes a token that has been generated by the peer application with :meth:`wrap`, verifies
        and optionally decrypts it, using this security context's cryptographic keys.

        The `supplementary` parameter determines how this method deals with replayed, unsequential,
        too-old or missing tokens, as follows:

        If the `supplementary` parameter is False (the default), and if a replayed or otherwise
        out-of-sequence token is detected, this method raises a :exc:`~gssapi.error.GSSCException`.
        If no replay or out-of-sequence token is detected, this method returns the unwrapped
        message only.

        If `supplementary` is True, instead of raising an exception when a replayed or
        out-of-sequence token is detected, this method returns a tuple
        ``(unwrapped_message, supplementary_info)`` where ``supplementary_info`` is a tuple
        containing zero or more of the constants :const:`~gssapi.S_DUPLICATE_TOKEN`,
        :const:`~gssapi.S_OLD_TOKEN`, :const:`~gssapi.S_UNSEQ_TOKEN` and
        :const:`~gssapi.S_GAP_TOKEN`. The supplementary info tells the caller whether a replayed or
        out-of-sequence message was detected. The caller must check this and decide how to handle
        the message if any of the flags are set. For a reference to the meaning of the flags, check
        `RFC 2744 Section 3.9.1 <http://tools.ietf.org/html/rfc2744#section-3.9.1>` for the
        corresponding GSS_S_OLD_TOKEN, etc, constants.

        :param message: The wrapped message token
        :type message: bytes
        :param conf_req: Whether to require confidentiality (encryption)
        :type conf_req: bool
        :param qop_req: The quality of protection required. It is recommended to not change this
            from the default None as most GSSAPI implementations do not support it.
        :param supplementary: Whether to also return supplementary info.
        :type supplementary: bool
        :returns: the verified and decrypted message if `supplementary` is False, or a tuple
            ``(unwrapped_message, supplementary_info)`` if `supplementary` is True.
        :raises: :exc:`~gssapi.error.GSSException` if :attr:`integrity_negotiated` is false, or if
            the verification or decryption fails, if the message was modified, or if
            confidentiality was required (`conf_req` was True) but the message did not have
            confidentiality protection applied (was not encrypted), or if the `qop_req`
            parameter was set and it did not match the QOP applied to the message, or if a
            replayed or out-of-sequence message was detected.
        """
        if not (self.flags & C.GSS_C_INTEG_FLAG):
            raise GSSException("No integrity protection negotiated.")
        if not (self.established or (self.flags & C.GSS_C_PROT_READY_FLAG)):
            raise GSSException("Protection not yet ready.")

        minor_status = ffi.new('OM_uint32[1]')
        output_buffer = ffi.new('gss_buffer_desc[1]')
        message_buffer = ffi.new('gss_buffer_desc[1]')
        message_buffer[0].length = len(message)
        c_str_message = ffi.new('char[]', message)
        message_buffer[0].value = c_str_message
        conf_state = ffi.new('int[1]')
        qop_state = ffi.new('gss_qop_t[1]')

        retval = C.gss_unwrap(
            minor_status,
            self._ctx[0],
            message_buffer,
            output_buffer,
            conf_state,
            qop_state
        )
        try:
            if GSS_ERROR(retval):
                if minor_status[0] and self.mech_type:
                    raise _exception_for_status(retval, minor_status[0], self.mech_type)
                else:
                    raise _exception_for_status(retval, minor_status[0])

            output = _buf_to_str(output_buffer[0])
            if conf_req and not conf_state[0]:
                raise GSSException("No confidentiality protection.")
            if qop_req is not None and qop_req != qop_state[0]:
                raise GSSException("QOP {0} does not match required value {1}.".format(qop_state[0], qop_req))
            supp_bits = _status_bits(retval)
            if supplementary:
                return output, supp_bits
            elif len(supp_bits) > 0:
                # Raise if unseq/replayed token detected
                raise _exception_for_status(retval, minor_status[0], token=output)
            else:
                return output
        finally:
            if output_buffer[0].length != 0:
                C.gss_release_buffer(minor_status, output_buffer)
def unwrap(self, message, conf_req=True, qop_req=None, supplementary=False):
        """
        Takes a token that has been generated by the peer application with :meth:`wrap`, verifies
        and optionally decrypts it, using this security context's cryptographic keys.

        The `supplementary` parameter determines how this method deals with replayed, unsequential,
        too-old or missing tokens, as follows:

        If the `supplementary` parameter is False (the default), and if a replayed or otherwise
        out-of-sequence token is detected, this method raises a :exc:`~gssapi.error.GSSCException`.
        If no replay or out-of-sequence token is detected, this method returns the unwrapped
        message only.

        If `supplementary` is True, instead of raising an exception when a replayed or
        out-of-sequence token is detected, this method returns a tuple
        ``(unwrapped_message, supplementary_info)`` where ``supplementary_info`` is a tuple
        containing zero or more of the constants :const:`~gssapi.S_DUPLICATE_TOKEN`,
        :const:`~gssapi.S_OLD_TOKEN`, :const:`~gssapi.S_UNSEQ_TOKEN` and
        :const:`~gssapi.S_GAP_TOKEN`. The supplementary info tells the caller whether a replayed or
        out-of-sequence message was detected. The caller must check this and decide how to handle
        the message if any of the flags are set. For a reference to the meaning of the flags, check
        `RFC 2744 Section 3.9.1 <http://tools.ietf.org/html/rfc2744#section-3.9.1>` for the
        corresponding GSS_S_OLD_TOKEN, etc, constants.

        :param message: The wrapped message token
        :type message: bytes
        :param conf_req: Whether to require confidentiality (encryption)
        :type conf_req: bool
        :param qop_req: The quality of protection required. It is recommended to not change this
            from the default None as most GSSAPI implementations do not support it.
        :param supplementary: Whether to also return supplementary info.
        :type supplementary: bool
        :returns: the verified and decrypted message if `supplementary` is False, or a tuple
            ``(unwrapped_message, supplementary_info)`` if `supplementary` is True.
        :raises: :exc:`~gssapi.error.GSSException` if :attr:`integrity_negotiated` is false, or if
            the verification or decryption fails, if the message was modified, or if
            confidentiality was required (`conf_req` was True) but the message did not have
            confidentiality protection applied (was not encrypted), or if the `qop_req`
            parameter was set and it did not match the QOP applied to the message, or if a
            replayed or out-of-sequence message was detected.
        """
        if not (self.flags & C.GSS_C_INTEG_FLAG):
            raise GSSException("No integrity protection negotiated.")
        if not (self.established or (self.flags & C.GSS_C_PROT_READY_FLAG)):
            raise GSSException("Protection not yet ready.")

        minor_status = ffi.new('OM_uint32[1]')
        output_buffer = ffi.new('gss_buffer_desc[1]')
        message_buffer = ffi.new('gss_buffer_desc[1]')
        message_buffer[0].length = len(message)
        c_str_message = ffi.new('char[]', message)
        message_buffer[0].value = c_str_message
        conf_state = ffi.new('int[1]')
        qop_state = ffi.new('gss_qop_t[1]')

        retval = C.gss_unwrap(
            minor_status,
            self._ctx[0],
            message_buffer,
            output_buffer,
            conf_state,
            qop_state
        )
        try:
            if GSS_ERROR(retval):
                if minor_status[0] and self.mech_type:
                    raise _exception_for_status(retval, minor_status[0], self.mech_type)
                else:
                    raise _exception_for_status(retval, minor_status[0])

            output = _buf_to_str(output_buffer[0])
            if conf_req and not conf_state[0]:
                raise GSSException("No confidentiality protection.")
            if qop_req is not None and qop_req != qop_state[0]:
                raise GSSException("QOP {0} does not match required value {1}.".format(qop_state[0], qop_req))
            supp_bits = _status_bits(retval)
            if supplementary:
                return output, supp_bits
            elif len(supp_bits) > 0:
                # Raise if unseq/replayed token detected
                raise _exception_for_status(retval, minor_status[0], token=output)
            else:
                return output
        finally:
            if output_buffer[0].length != 0:
                C.gss_release_buffer(minor_status, output_buffer)
Takes a token that has been generated by the peer application with :meth:`wrap`, verifies
        and optionally decrypts it, using this security context's cryptographic keys.

        The `supplementary` parameter determines how this method deals with replayed, unsequential,
        too-old or missing tokens, as follows:

        If the `supplementary` parameter is False (the default), and if a replayed or otherwise
        out-of-sequence token is detected, this method raises a :exc:`~gssapi.error.GSSCException`.
        If no replay or out-of-sequence token is detected, this method returns the unwrapped
        message only.

        If `supplementary` is True, instead of raising an exception when a replayed or
        out-of-sequence token is detected, this method returns a tuple
        ``(unwrapped_message, supplementary_info)`` where ``supplementary_info`` is a tuple
        containing zero or more of the constants :const:`~gssapi.S_DUPLICATE_TOKEN`,
        :const:`~gssapi.S_OLD_TOKEN`, :const:`~gssapi.S_UNSEQ_TOKEN` and
        :const:`~gssapi.S_GAP_TOKEN`. The supplementary info tells the caller whether a replayed or
        out-of-sequence message was detected. The caller must check this and decide how to handle
        the message if any of the flags are set. For a reference to the meaning of the flags, check
        `RFC 2744 Section 3.9.1 <http://tools.ietf.org/html/rfc2744#section-3.9.1>` for the
        corresponding GSS_S_OLD_TOKEN, etc, constants.

        :param message: The wrapped message token
        :type message: bytes
        :param conf_req: Whether to require confidentiality (encryption)
        :type conf_req: bool
        :param qop_req: The quality of protection required. It is recommended to not change this
            from the default None as most GSSAPI implementations do not support it.
        :param supplementary: Whether to also return supplementary info.
        :type supplementary: bool
        :returns: the verified and decrypted message if `supplementary` is False, or a tuple
            ``(unwrapped_message, supplementary_info)`` if `supplementary` is True.
        :raises: :exc:`~gssapi.error.GSSException` if :attr:`integrity_negotiated` is false, or if
            the verification or decryption fails, if the message was modified, or if
            confidentiality was required (`conf_req` was True) but the message did not have
            confidentiality protection applied (was not encrypted), or if the `qop_req`
            parameter was set and it did not match the QOP applied to the message, or if a
            replayed or out-of-sequence message was detected.