static size_t schannel_sig_size(struct gensec_security *gensec_security, size_t data_size)
{
	struct schannel_state *state = (struct schannel_state *)gensec_security->private_data;
	uint32_t sig_size;

	sig_size = netsec_outgoing_sig_size(state);

	return sig_size;
}
示例#2
0
/**
* @brief Calculate how much data we can in a packet, including calculating
*	 auth token and pad lengths.
*
* @param auth		The pipe_auth_data structure for this pipe.
* @param header_len	The length of the packet header
* @param data_left	The data left in the send buffer
* @param max_xmit_frag	The max fragment size.
* @param pad_alignment	The NDR padding size.
* @param data_to_send	[out] The max data we will send in the pdu
* @param frag_len	[out] The total length of the fragment
* @param auth_len	[out] The length of the auth trailer
* @param pad_len	[out] The padding to be applied
*
* @return A NT Error status code.
*/
NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
			    size_t header_len, size_t data_left,
			    size_t max_xmit_frag, size_t pad_alignment,
			    size_t *data_to_send, size_t *frag_len,
			    size_t *auth_len, size_t *pad_len)
{
	size_t max_len;
	size_t mod_len;
	struct schannel_state *schannel_auth;
	struct spnego_context *spnego_ctx;
	struct gse_context *gse_ctx;
	enum spnego_mech auth_type;
	void *auth_ctx;
	bool seal = false;
	NTSTATUS status;

	/* no auth token cases first */
	switch (auth->auth_level) {
	case DCERPC_AUTH_LEVEL_NONE:
	case DCERPC_AUTH_LEVEL_CONNECT:
	case DCERPC_AUTH_LEVEL_PACKET:
		max_len = max_xmit_frag - header_len;
		*data_to_send = MIN(max_len, data_left);
		*pad_len = 0;
		*auth_len = 0;
		*frag_len = header_len + *data_to_send;
		return NT_STATUS_OK;

	case DCERPC_AUTH_LEVEL_PRIVACY:
		seal = true;
		break;

	case DCERPC_AUTH_LEVEL_INTEGRITY:
		break;

	default:
		return NT_STATUS_INVALID_PARAMETER;
	}


	/* Sign/seal case, calculate auth and pad lengths */

	max_len = max_xmit_frag - header_len - DCERPC_AUTH_TRAILER_LENGTH;

	/* Treat the same for all authenticated rpc requests. */
	switch (auth->auth_type) {
	case DCERPC_AUTH_TYPE_SPNEGO:
		spnego_ctx = talloc_get_type_abort(auth->auth_ctx,
						   struct spnego_context);
		status = spnego_get_negotiated_mech(spnego_ctx,
						    &auth_type, &auth_ctx);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}
		switch (auth_type) {
		case SPNEGO_NTLMSSP:
			*auth_len = NTLMSSP_SIG_SIZE;
			break;

		case SPNEGO_KRB5:
			gse_ctx = talloc_get_type_abort(auth_ctx,
							struct gse_context);
			if (!gse_ctx) {
				return NT_STATUS_INVALID_PARAMETER;
			}
			*auth_len = gse_get_signature_length(gse_ctx,
							     seal, max_len);
			break;

		default:
			return NT_STATUS_INVALID_PARAMETER;
		}
		break;

	case DCERPC_AUTH_TYPE_NTLMSSP:
		*auth_len = NTLMSSP_SIG_SIZE;
		break;

	case DCERPC_AUTH_TYPE_SCHANNEL:
		schannel_auth = talloc_get_type_abort(auth->auth_ctx,
						      struct schannel_state);
		*auth_len = netsec_outgoing_sig_size(schannel_auth);
		break;

	case DCERPC_AUTH_TYPE_KRB5:
		gse_ctx = talloc_get_type_abort(auth->auth_ctx,
						struct gse_context);
		*auth_len = gse_get_signature_length(gse_ctx,
						     seal, max_len);
		break;

	default:
		return NT_STATUS_INVALID_PARAMETER;
	}

	max_len -= *auth_len;

	*data_to_send = MIN(max_len, data_left);

	mod_len = (header_len + *data_to_send) % pad_alignment;
	if (mod_len) {
		*pad_len = pad_alignment - mod_len;
	} else {
		*pad_len = 0;
	}

	if (*data_to_send + *pad_len > max_len) {
		*data_to_send -= pad_alignment;
	}

	*frag_len = header_len + *data_to_send + *pad_len
			+ DCERPC_AUTH_TRAILER_LENGTH + *auth_len;

	return NT_STATUS_OK;
}
示例#3
0
/**
* @brief Calculate how much data we can in a packet, including calculating
*	 auth token and pad lengths.
*
* @param auth		The pipe_auth_data structure for this pipe.
* @param header_len	The length of the packet header
* @param data_left	The data left in the send buffer
* @param max_xmit_frag	The max fragment size.
* @param pad_alignment	The NDR padding size.
* @param data_to_send	[out] The max data we will send in the pdu
* @param frag_len	[out] The total length of the fragment
* @param auth_len	[out] The length of the auth trailer
* @param pad_len	[out] The padding to be applied
*
* @return A NT Error status code.
*/
NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
			    size_t header_len, size_t data_left,
			    size_t max_xmit_frag, size_t pad_alignment,
			    size_t *data_to_send, size_t *frag_len,
			    size_t *auth_len, size_t *pad_len)
{
	size_t max_len;
	size_t mod_len;
	struct gensec_security *gensec_security;
	struct schannel_state *schannel_auth;

	/* no auth token cases first */
	switch (auth->auth_level) {
	case DCERPC_AUTH_LEVEL_NONE:
	case DCERPC_AUTH_LEVEL_CONNECT:
	case DCERPC_AUTH_LEVEL_PACKET:
		max_len = max_xmit_frag - header_len;
		*data_to_send = MIN(max_len, data_left);
		*pad_len = 0;
		*auth_len = 0;
		*frag_len = header_len + *data_to_send;
		return NT_STATUS_OK;

	case DCERPC_AUTH_LEVEL_PRIVACY:
		break;

	case DCERPC_AUTH_LEVEL_INTEGRITY:
		break;

	default:
		return NT_STATUS_INVALID_PARAMETER;
	}


	/* Sign/seal case, calculate auth and pad lengths */

	max_len = max_xmit_frag - header_len - DCERPC_AUTH_TRAILER_LENGTH;

	/* Treat the same for all authenticated rpc requests. */
	switch (auth->auth_type) {
	case DCERPC_AUTH_TYPE_SPNEGO:
	case DCERPC_AUTH_TYPE_NTLMSSP:
	case DCERPC_AUTH_TYPE_KRB5:
		gensec_security = talloc_get_type_abort(auth->auth_ctx,
							struct gensec_security);
		*auth_len = gensec_sig_size(gensec_security, max_len);
		break;

	case DCERPC_AUTH_TYPE_SCHANNEL:
		schannel_auth = talloc_get_type_abort(auth->auth_ctx,
						      struct schannel_state);
		*auth_len = netsec_outgoing_sig_size(schannel_auth);
		break;
	default:
		return NT_STATUS_INVALID_PARAMETER;
	}

	max_len -= *auth_len;

	*data_to_send = MIN(max_len, data_left);

	mod_len = (header_len + *data_to_send) % pad_alignment;
	if (mod_len) {
		*pad_len = pad_alignment - mod_len;
	} else {
		*pad_len = 0;
	}

	if (*data_to_send + *pad_len > max_len) {
		*data_to_send -= pad_alignment;
	}

	*frag_len = header_len + *data_to_send + *pad_len
			+ DCERPC_AUTH_TRAILER_LENGTH + *auth_len;

	return NT_STATUS_OK;
}