Module: wine Branch: refs/heads/master Commit: 7b5e5b65b0ebfc413d741fb165b1f3d1af2cb2f9 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=7b5e5b65b0ebfc413d741fb1...
Author: Mike McCormack mike@codeweavers.com Date: Fri May 12 19:20:26 2006 +0900
rpcrt4: Add infrastructure for send authentication data.
---
dlls/rpcrt4/rpc_message.c | 69 ++++++++++++++++++++++++++++++++------------- 1 files changed, 49 insertions(+), 20 deletions(-)
diff --git a/dlls/rpcrt4/rpc_message.c b/dlls/rpcrt4/rpc_message.c index 7646f98..014d60a 100644 --- a/dlls/rpcrt4/rpc_message.c +++ b/dlls/rpcrt4/rpc_message.c @@ -239,53 +239,71 @@ VOID RPCRT4_FreeHeader(RpcPktHdr *Header }
/*********************************************************************** - * RPCRT4_Send (internal) + * RPCRT4_SendAuth (internal) * - * Transmit a packet over connection in acceptable fragments. + * Transmit a packet with authorization data over connection in acceptable fragments. */ -RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, - void *Buffer, unsigned int BufferLength) +static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header, + void *Buffer, unsigned int BufferLength, + void *Auth, unsigned int AuthLength) { PUCHAR buffer_pos; DWORD hdr_size; LONG count; + unsigned char *pkt, *auth_hdr; + LONG alen = AuthLength ? (AuthLength + 8) : 0;
buffer_pos = Buffer; /* The packet building functions save the packet header size, so we can use it. */ hdr_size = Header->common.frag_len; + Header->common.auth_len = AuthLength; Header->common.flags |= RPC_FLG_FIRST; Header->common.flags &= ~RPC_FLG_LAST; while (!(Header->common.flags & RPC_FLG_LAST)) { /* decide if we need to split the packet into fragments */ - if ((BufferLength + hdr_size) <= Connection->MaxTransmissionSize) { + if ((BufferLength + hdr_size + alen) <= Connection->MaxTransmissionSize) { Header->common.flags |= RPC_FLG_LAST; - Header->common.frag_len = BufferLength + hdr_size; + Header->common.frag_len = BufferLength + hdr_size + alen; } else { Header->common.frag_len = Connection->MaxTransmissionSize; }
- /* transmit packet header */ - count = rpcrt4_conn_write(Connection, Header, hdr_size); - if (count<0) { - WARN("rpcrt4_conn_write failed\n"); - return RPC_S_PROTOCOL_ERROR; - } + pkt = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Header->common.frag_len); + + memcpy(pkt, Header, hdr_size);
/* fragment consisted of header only and is the last one */ - if (hdr_size == Header->common.frag_len && - Header->common.flags & RPC_FLG_LAST) { - return RPC_S_OK; + if (hdr_size == Header->common.frag_len) + goto write; + + memcpy(pkt + hdr_size, buffer_pos, Header->common.frag_len - hdr_size - alen); + + /* add the authorization info */ + if (AuthLength) + { + auth_hdr = &pkt[Header->common.frag_len - alen]; + + /* FIXME: is this per fragment or per message? */ + auth_hdr[0] = RPC_C_AUTHN_WINNT; + auth_hdr[1] = RPC_C_AUTHN_LEVEL_CONNECT; + auth_hdr[2] = 0x00; /* FIXME: add padding */ + auth_hdr[3] = 0x00; + + /* a unique number... */ + memcpy(&auth_hdr[4], &Connection, 4); + memcpy(&auth_hdr[8], Auth, AuthLength); }
- /* send the fragment data */ - count = rpcrt4_conn_write(Connection, buffer_pos, Header->common.frag_len - hdr_size); +write: + count = rpcrt4_conn_write(Connection, pkt, Header->common.frag_len); + HeapFree(GetProcessHeap(), 0, pkt); if (count<0) { - WARN("rpcrt4_conn_write failed\n"); + WARN("rpcrt4_conn_write failed (auth)\n"); return RPC_S_PROTOCOL_ERROR; }
- buffer_pos += Header->common.frag_len - hdr_size; - BufferLength -= Header->common.frag_len - hdr_size; + buffer_pos += Header->common.frag_len - hdr_size - alen; + BufferLength -= Header->common.frag_len - hdr_size - alen; Header->common.flags &= ~RPC_FLG_FIRST; }
@@ -293,6 +311,17 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Co }
/*********************************************************************** + * RPCRT4_Send (internal) + * + * Transmit a packet over connection in acceptable fragments. + */ +RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, + void *Buffer, unsigned int BufferLength) +{ + return RPCRT4_SendAuth(Connection, Header, Buffer, BufferLength, NULL, 0); +} + +/*********************************************************************** * RPCRT4_Receive (internal) * * Receive a packet from connection and merge the fragments.