[PATCH 8/13] rpcrt4: Use the correct authorization trailer length
using information from the security provider.
Robert Shearman
rob at codeweavers.com
Mon Mar 26 12:19:33 CDT 2007
Previously it was hardcoded to 16, so only the NTLM provider would work
correctly.
---
dlls/rpcrt4/rpc_binding.h | 2 ++
dlls/rpcrt4/rpc_message.c | 43
+++++++++++++++++++++++++++++++++----------
dlls/rpcrt4/rpc_transport.c | 2 ++
3 files changed, 37 insertions(+), 10 deletions(-)
-------------- next part --------------
diff --git a/dlls/rpcrt4/rpc_binding.h b/dlls/rpcrt4/rpc_binding.h
index 1650ad6..6dde2ae 100644
--- a/dlls/rpcrt4/rpc_binding.h
+++ b/dlls/rpcrt4/rpc_binding.h
@@ -80,6 +80,8 @@ typedef struct _RpcConnection
TimeStamp exp;
ULONG attr;
RpcAuthInfo *AuthInfo;
+ ULONG encryption_auth_len;
+ ULONG signature_auth_len;
RpcQualityOfService *QOS;
/* client-only */
diff --git a/dlls/rpcrt4/rpc_message.c b/dlls/rpcrt4/rpc_message.c
index 2519cee..53d191b 100644
--- a/dlls/rpcrt4/rpc_message.c
+++ b/dlls/rpcrt4/rpc_message.c
@@ -59,7 +59,7 @@ enum secure_packet_direction
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[] = {
sizeof(Header->request), 0, sizeof(Header->response),
@@ -82,14 +82,14 @@ static DWORD RPCRT4_GetHeaderSize(RpcPkt
return ret;
}
-static int packet_has_body(RpcPktHdr *Header)
+static int packet_has_body(const RpcPktHdr *Header)
{
return (Header->common.ptype == PKT_FAULT) ||
(Header->common.ptype == PKT_REQUEST) ||
(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) &&
!(Header->common.ptype == PKT_SHUTDOWN);
@@ -379,7 +379,12 @@ static RPC_STATUS RPCRT4_SendAuth(RpcCon
if (AuthLength)
Header->common.auth_len = AuthLength;
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
Header->common.auth_len = 0;
Header->common.flags |= RPC_FLG_FIRST;
@@ -469,6 +474,8 @@ static RPC_STATUS RPCRT4_ClientAuthorize
SECURITY_STATUS r;
SecBufferDesc out_desc;
SecBufferDesc inp_desc;
+ SecPkgContext_Sizes secctx_sizes;
+ BOOL continue_needed;
ULONG context_req = ISC_REQ_CONNECTION | ISC_REQ_USE_DCE_STYLE |
ISC_REQ_MUTUAL_AUTH | ISC_REQ_DELEGATE;
@@ -480,6 +487,7 @@ static RPC_STATUS RPCRT4_ClientAuthorize
out->BufferType = SECBUFFER_TOKEN;
out->cbBuffer = conn->AuthInfo->cbMaxToken;
out->pvBuffer = HeapAlloc(GetProcessHeap(), 0, out->cbBuffer);
+ if (!out->pvBuffer) return ERROR_OUTOFMEMORY;
out_desc.ulVersion = 0;
out_desc.cBuffers = 1;
@@ -495,13 +503,13 @@ static RPC_STATUS RPCRT4_ClientAuthorize
&conn->exp);
if (FAILED(r))
{
- HeapFree(GetProcessHeap(), 0, out->pvBuffer);
- out->pvBuffer = NULL;
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);
+ 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))
{
@@ -509,16 +517,31 @@ static RPC_STATUS RPCRT4_ClientAuthorize
r = CompleteAuthToken(&conn->ctx, &out_desc);
if (FAILED(r))
{
- HeapFree(GetProcessHeap(), 0, out->pvBuffer);
- out->pvBuffer = NULL;
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);
+ 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;
+
+failed:
+ HeapFree(GetProcessHeap(), 0, out->pvBuffer);
+ out->pvBuffer = NULL;
+ return ERROR_ACCESS_DENIED; /* FIXME: is this correct? */
}
/***********************************************************************
diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c
index 4996c12..b4af8e9 100644
--- a/dlls/rpcrt4/rpc_transport.c
+++ b/dlls/rpcrt4/rpc_transport.c
@@ -1385,6 +1385,8 @@ RPC_STATUS RPCRT4_CreateConnection(RpcCo
NewConnection->attr = 0;
if (AuthInfo) RpcAuthInfo_AddRef(AuthInfo);
NewConnection->AuthInfo = AuthInfo;
+ NewConnection->encryption_auth_len = 0;
+ NewConnection->signature_auth_len = 0;
if (QOS) RpcQualityOfService_AddRef(QOS);
NewConnection->QOS = QOS;
More information about the wine-patches
mailing list