rpcrt4: Use the correct authorization trailer length using information from the security provider.

Previously it was hardcoded to 16, so only the NTLM provider would work correctly.
This commit is contained in:
Rob Shearman 2007-03-26 18:19:33 +01:00 committed by Alexandre Julliard
parent 88295b9a02
commit 763fe63213
3 changed files with 37 additions and 10 deletions

View File

@ -80,6 +80,8 @@ typedef struct _RpcConnection
TimeStamp exp; TimeStamp exp;
ULONG attr; ULONG attr;
RpcAuthInfo *AuthInfo; RpcAuthInfo *AuthInfo;
ULONG encryption_auth_len;
ULONG signature_auth_len;
RpcQualityOfService *QOS; RpcQualityOfService *QOS;
/* client-only */ /* client-only */

View File

@ -59,7 +59,7 @@ enum secure_packet_direction
static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg); static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg);
static DWORD RPCRT4_GetHeaderSize(RpcPktHdr *Header) static DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header)
{ {
static const DWORD header_sizes[] = { static const DWORD header_sizes[] = {
sizeof(Header->request), 0, sizeof(Header->response), sizeof(Header->request), 0, sizeof(Header->response),
@ -82,14 +82,14 @@ static DWORD RPCRT4_GetHeaderSize(RpcPktHdr *Header)
return ret; return ret;
} }
static int packet_has_body(RpcPktHdr *Header) static int packet_has_body(const RpcPktHdr *Header)
{ {
return (Header->common.ptype == PKT_FAULT) || return (Header->common.ptype == PKT_FAULT) ||
(Header->common.ptype == PKT_REQUEST) || (Header->common.ptype == PKT_REQUEST) ||
(Header->common.ptype == PKT_RESPONSE); (Header->common.ptype == PKT_RESPONSE);
} }
static int packet_has_auth_verifier(RpcPktHdr *Header) static int packet_has_auth_verifier(const RpcPktHdr *Header)
{ {
return !(Header->common.ptype == PKT_BIND_NACK) && return !(Header->common.ptype == PKT_BIND_NACK) &&
!(Header->common.ptype == PKT_SHUTDOWN); !(Header->common.ptype == PKT_SHUTDOWN);
@ -379,7 +379,12 @@ static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header,
if (AuthLength) if (AuthLength)
Header->common.auth_len = AuthLength; Header->common.auth_len = AuthLength;
else if (Connection->AuthInfo && packet_has_auth_verifier(Header)) else if (Connection->AuthInfo && packet_has_auth_verifier(Header))
Header->common.auth_len = 16 /* FIXME */; {
if ((Connection->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) && packet_has_body(Header))
Header->common.auth_len = Connection->signature_auth_len;
else
Header->common.auth_len = Connection->encryption_auth_len;
}
else else
Header->common.auth_len = 0; Header->common.auth_len = 0;
Header->common.flags |= RPC_FLG_FIRST; Header->common.flags |= RPC_FLG_FIRST;
@ -469,6 +474,8 @@ static RPC_STATUS RPCRT4_ClientAuthorize(RpcConnection *conn, SecBuffer *in,
SECURITY_STATUS r; SECURITY_STATUS r;
SecBufferDesc out_desc; SecBufferDesc out_desc;
SecBufferDesc inp_desc; SecBufferDesc inp_desc;
SecPkgContext_Sizes secctx_sizes;
BOOL continue_needed;
ULONG context_req = ISC_REQ_CONNECTION | ISC_REQ_USE_DCE_STYLE | ULONG context_req = ISC_REQ_CONNECTION | ISC_REQ_USE_DCE_STYLE |
ISC_REQ_MUTUAL_AUTH | ISC_REQ_DELEGATE; ISC_REQ_MUTUAL_AUTH | ISC_REQ_DELEGATE;
@ -480,6 +487,7 @@ static RPC_STATUS RPCRT4_ClientAuthorize(RpcConnection *conn, SecBuffer *in,
out->BufferType = SECBUFFER_TOKEN; out->BufferType = SECBUFFER_TOKEN;
out->cbBuffer = conn->AuthInfo->cbMaxToken; out->cbBuffer = conn->AuthInfo->cbMaxToken;
out->pvBuffer = HeapAlloc(GetProcessHeap(), 0, out->cbBuffer); out->pvBuffer = HeapAlloc(GetProcessHeap(), 0, out->cbBuffer);
if (!out->pvBuffer) return ERROR_OUTOFMEMORY;
out_desc.ulVersion = 0; out_desc.ulVersion = 0;
out_desc.cBuffers = 1; out_desc.cBuffers = 1;
@ -495,13 +503,13 @@ static RPC_STATUS RPCRT4_ClientAuthorize(RpcConnection *conn, SecBuffer *in,
&conn->exp); &conn->exp);
if (FAILED(r)) if (FAILED(r))
{ {
HeapFree(GetProcessHeap(), 0, out->pvBuffer);
out->pvBuffer = NULL;
WARN("InitializeSecurityContext failed with error 0x%08x\n", r); WARN("InitializeSecurityContext failed with error 0x%08x\n", r);
return ERROR_ACCESS_DENIED; /* FIXME: is this correct? */ goto failed;
} }
TRACE("r = 0x%08x, attr = 0x%08x\n", r, conn->attr); TRACE("r = 0x%08x, attr = 0x%08x\n", r, conn->attr);
continue_needed = ((r == SEC_I_CONTINUE_NEEDED) ||
(r == SEC_I_COMPLETE_AND_CONTINUE));
if ((r == SEC_I_COMPLETE_NEEDED) || (r == SEC_I_COMPLETE_AND_CONTINUE)) if ((r == SEC_I_COMPLETE_NEEDED) || (r == SEC_I_COMPLETE_AND_CONTINUE))
{ {
@ -509,16 +517,31 @@ static RPC_STATUS RPCRT4_ClientAuthorize(RpcConnection *conn, SecBuffer *in,
r = CompleteAuthToken(&conn->ctx, &out_desc); r = CompleteAuthToken(&conn->ctx, &out_desc);
if (FAILED(r)) if (FAILED(r))
{ {
HeapFree(GetProcessHeap(), 0, out->pvBuffer);
out->pvBuffer = NULL;
WARN("CompleteAuthToken failed with error 0x%08x\n", r); WARN("CompleteAuthToken failed with error 0x%08x\n", r);
return ERROR_ACCESS_DENIED; /* FIXME: is this correct? */ goto failed;
} }
} }
TRACE("cbBuffer = %ld\n", out->cbBuffer); TRACE("cbBuffer = %ld\n", out->cbBuffer);
if (!continue_needed)
{
r = QueryContextAttributesA(&conn->ctx, SECPKG_ATTR_SIZES, &secctx_sizes);
if (FAILED(r))
{
WARN("QueryContextAttributes failed with error 0x%08x\n", r);
goto failed;
}
conn->signature_auth_len = secctx_sizes.cbMaxSignature;
conn->encryption_auth_len = secctx_sizes.cbSecurityTrailer;
}
return RPC_S_OK; return RPC_S_OK;
failed:
HeapFree(GetProcessHeap(), 0, out->pvBuffer);
out->pvBuffer = NULL;
return ERROR_ACCESS_DENIED; /* FIXME: is this correct? */
} }
/*********************************************************************** /***********************************************************************

View File

@ -1385,6 +1385,8 @@ RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server,
NewConnection->attr = 0; NewConnection->attr = 0;
if (AuthInfo) RpcAuthInfo_AddRef(AuthInfo); if (AuthInfo) RpcAuthInfo_AddRef(AuthInfo);
NewConnection->AuthInfo = AuthInfo; NewConnection->AuthInfo = AuthInfo;
NewConnection->encryption_auth_len = 0;
NewConnection->signature_auth_len = 0;
if (QOS) RpcQualityOfService_AddRef(QOS); if (QOS) RpcQualityOfService_AddRef(QOS);
NewConnection->QOS = QOS; NewConnection->QOS = QOS;