mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
librpc: add dcerpc_ncacn_pull_pkt_auth() helper function
Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
parent
5f17d3bd29
commit
875d0111b4
@ -28,6 +28,7 @@
|
||||
#include "librpc/gen_ndr/ndr_dcerpc.h"
|
||||
#include "rpc_common.h"
|
||||
#include "lib/util/bitmap.h"
|
||||
#include "auth/gensec/gensec.h"
|
||||
|
||||
/* we need to be able to get/set the fragment length without doing a full
|
||||
decode */
|
||||
@ -360,6 +361,146 @@ NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt,
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
NTSTATUS dcerpc_ncacn_pull_pkt_auth(const struct dcerpc_auth *auth_state,
|
||||
struct gensec_security *gensec,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
enum dcerpc_pkt_type ptype,
|
||||
uint8_t required_flags,
|
||||
uint8_t optional_flags,
|
||||
uint8_t payload_offset,
|
||||
DATA_BLOB *payload_and_verifier,
|
||||
DATA_BLOB *raw_packet,
|
||||
const struct ncacn_packet *pkt)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct dcerpc_auth auth;
|
||||
uint32_t auth_length;
|
||||
|
||||
if (auth_state == NULL) {
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
status = dcerpc_verify_ncacn_packet_header(pkt, ptype,
|
||||
payload_and_verifier->length,
|
||||
required_flags, optional_flags);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (auth_state->auth_level) {
|
||||
case DCERPC_AUTH_LEVEL_PRIVACY:
|
||||
case DCERPC_AUTH_LEVEL_INTEGRITY:
|
||||
case DCERPC_AUTH_LEVEL_PACKET:
|
||||
break;
|
||||
|
||||
case DCERPC_AUTH_LEVEL_CONNECT:
|
||||
if (pkt->auth_length != 0) {
|
||||
break;
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
case DCERPC_AUTH_LEVEL_NONE:
|
||||
if (pkt->auth_length != 0) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
|
||||
default:
|
||||
return NT_STATUS_RPC_UNSUPPORTED_AUTHN_LEVEL;
|
||||
}
|
||||
|
||||
if (pkt->auth_length == 0) {
|
||||
return NT_STATUS_RPC_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
if (gensec == NULL) {
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
status = dcerpc_pull_auth_trailer(pkt, mem_ctx,
|
||||
payload_and_verifier,
|
||||
&auth, &auth_length, false);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (payload_and_verifier->length < auth_length) {
|
||||
/*
|
||||
* should be checked in dcerpc_pull_auth_trailer()
|
||||
*/
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
payload_and_verifier->length -= auth_length;
|
||||
|
||||
if (payload_and_verifier->length < auth.auth_pad_length) {
|
||||
/*
|
||||
* should be checked in dcerpc_pull_auth_trailer()
|
||||
*/
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (auth.auth_type != auth_state->auth_type) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (auth.auth_level != auth_state->auth_level) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (auth.auth_context_id != auth_state->auth_context_id) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/* check signature or unseal the packet */
|
||||
switch (auth_state->auth_level) {
|
||||
case DCERPC_AUTH_LEVEL_PRIVACY:
|
||||
status = gensec_unseal_packet(gensec,
|
||||
raw_packet->data + payload_offset,
|
||||
payload_and_verifier->length,
|
||||
raw_packet->data,
|
||||
raw_packet->length -
|
||||
auth.credentials.length,
|
||||
&auth.credentials);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return NT_STATUS_RPC_SEC_PKG_ERROR;
|
||||
}
|
||||
memcpy(payload_and_verifier->data,
|
||||
raw_packet->data + payload_offset,
|
||||
payload_and_verifier->length);
|
||||
break;
|
||||
|
||||
case DCERPC_AUTH_LEVEL_INTEGRITY:
|
||||
case DCERPC_AUTH_LEVEL_PACKET:
|
||||
status = gensec_check_packet(gensec,
|
||||
payload_and_verifier->data,
|
||||
payload_and_verifier->length,
|
||||
raw_packet->data,
|
||||
raw_packet->length -
|
||||
auth.credentials.length,
|
||||
&auth.credentials);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return NT_STATUS_RPC_SEC_PKG_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case DCERPC_AUTH_LEVEL_CONNECT:
|
||||
/* for now we ignore possible signatures here */
|
||||
break;
|
||||
|
||||
default:
|
||||
return NT_STATUS_RPC_UNSUPPORTED_AUTHN_LEVEL;
|
||||
}
|
||||
|
||||
/*
|
||||
* remove the indicated amount of padding
|
||||
*
|
||||
* A possible overflow is checked above.
|
||||
*/
|
||||
payload_and_verifier->length -= auth.auth_pad_length;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
struct dcerpc_read_ncacn_packet_state {
|
||||
#if 0
|
||||
struct {
|
||||
|
@ -36,6 +36,7 @@ struct epm_floor;
|
||||
struct epm_tower;
|
||||
struct tevent_context;
|
||||
struct tstream_context;
|
||||
struct gensec_security;
|
||||
|
||||
enum dcerpc_transport_t {
|
||||
NCA_UNKNOWN, NCACN_NP, NCACN_IP_TCP, NCACN_IP_UDP, NCACN_VNS_IPC,
|
||||
@ -202,6 +203,16 @@ NTSTATUS dcerpc_verify_ncacn_packet_header(const struct ncacn_packet *pkt,
|
||||
size_t max_auth_info,
|
||||
uint8_t required_flags,
|
||||
uint8_t optional_flags);
|
||||
NTSTATUS dcerpc_ncacn_pull_pkt_auth(const struct dcerpc_auth *auth_state,
|
||||
struct gensec_security *gensec,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
enum dcerpc_pkt_type ptype,
|
||||
uint8_t required_flags,
|
||||
uint8_t optional_flags,
|
||||
uint8_t payload_offset,
|
||||
DATA_BLOB *payload_and_verifier,
|
||||
DATA_BLOB *raw_packet,
|
||||
const struct ncacn_packet *pkt);
|
||||
struct tevent_req *dcerpc_read_ncacn_packet_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct tstream_context *stream);
|
||||
|
@ -715,7 +715,7 @@ bld.SAMBA_LIBRARY('ndr',
|
||||
|
||||
bld.SAMBA_LIBRARY('dcerpc-binding',
|
||||
source='rpc/dcerpc_error.c rpc/binding.c rpc/dcerpc_util.c rpc/binding_handle.c',
|
||||
deps='ndr tevent NDR_DCERPC LIBTSOCKET tevent-util',
|
||||
deps='ndr tevent NDR_DCERPC LIBTSOCKET tevent-util gensec',
|
||||
pc_files=[],
|
||||
public_headers='rpc/rpc_common.h',
|
||||
vnum='0.0.1')
|
||||
|
Loading…
Reference in New Issue
Block a user