Commit 5f6ae94a authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

rpcrt4: Implement RPC over HTTP support.

CodeWeavers did this work for supporting the optional HTTP connection method of Outlook 2003/2007 (must be running with Windows versions set to XP or higher to see this option). This was written before Microsoft publicly released a specification for the RPC over HTTP protocol and so was developed by examining traffic flowing between a Windows client and an IIS server.
parent 834c5b42
......@@ -6,7 +6,7 @@ VPATH = @srcdir@
MODULE = rpcrt4.dll
IMPORTLIB = rpcrt4
IMPORTS = uuid advapi32 kernel32 ntdll
DELAYIMPORTS = secur32 user32
DELAYIMPORTS = wininet secur32 user32
C_SRCS = \
cproxy.c \
......
......@@ -394,6 +394,7 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc,
if (status != RPC_S_OK)
return status;
NewConnection->assoc = assoc;
status = RPCRT4_OpenClientConnection(NewConnection);
if (status != RPC_S_OK)
{
......
......@@ -34,6 +34,7 @@ typedef struct _RpcAssoc
/* id of this association group */
ULONG assoc_group_id;
UUID http_uuid;
CRITICAL_SECTION cs;
......
......@@ -24,6 +24,7 @@
#include "rpcndr.h"
#include "security.h"
#include "wine/list.h"
#include "rpc_defs.h"
typedef struct _RpcAuthInfo
......@@ -74,6 +75,7 @@ typedef struct _RpcConnection
struct list conn_pool_entry;
ULONG assoc_group_id; /* association group returned during binding */
RPC_ASYNC_STATE *async_state;
struct _RpcAssoc *assoc; /* association this connection is part of */
/* server-only */
/* The active interface bound to server. */
......@@ -96,6 +98,7 @@ struct connection_ops {
int (*wait_for_incoming_data)(RpcConnection *conn);
size_t (*get_top_of_tower)(unsigned char *tower_data, const char *networkaddr, const char *endpoint);
RPC_STATUS (*parse_top_of_tower)(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint);
RPC_STATUS (*receive_fragment)(RpcConnection *conn, RpcPktHdr **Header, void **Payload);
};
/* don't know what MS's structure looks like */
......
......@@ -120,6 +120,14 @@ typedef struct
} protocols[1];
} RpcPktBindNAckHdr;
/* undocumented packet sent during RPC over HTTP */
typedef struct
{
RpcPktCommonHdr common;
unsigned short flags;
unsigned short num_data_items;
} RpcPktHttpHdr;
/* Union representing all possible packet headers */
typedef union
{
......@@ -130,6 +138,7 @@ typedef union
RpcPktBindHdr bind;
RpcPktBindAckHdr bind_ack;
RpcPktBindNAckHdr bind_nack;
RpcPktHttpHdr http;
} RpcPktHdr;
typedef struct
......@@ -174,6 +183,7 @@ typedef struct
#define PKT_SHUTDOWN 17
#define PKT_CO_CANCEL 18
#define PKT_ORPHANED 19
#define PKT_HTTP 20
#define RESULT_ACCEPT 0
#define RESULT_USER_REJECTION 1
......
......@@ -30,10 +30,21 @@ RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, unsigned
RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId);
RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor);
RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, LPCSTR ServerAddress, unsigned long Result, unsigned long Reason, const RPC_SYNTAX_IDENTIFIER *TransferId);
RpcPktHdr *RPCRT4_BuildHttpHeader(unsigned long DataRepresentation, unsigned short flags, unsigned short num_data_items, unsigned int payload_size);
RpcPktHdr *RPCRT4_BuildHttpConnectHeader(unsigned short flags, int out_pipe, const UUID *connection_uuid, const UUID *pipe_uuid, const UUID *association_uuid);
RpcPktHdr *RPCRT4_BuildHttpFlowControlHeader(BOOL server, ULONG bytes_transmitted, ULONG flow_control_increment, const UUID *pipe_uuid);
VOID RPCRT4_FreeHeader(RpcPktHdr *Header);
RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength);
RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg);
RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, unsigned long *auth_length_out);
DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header);
RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr);
BOOL RPCRT4_IsValidHttpPacket(RpcPktHdr *hdr, unsigned char *data, unsigned short data_len);
unsigned char *RPCRT4_NextHttpHeaderField(unsigned char *data);
RPC_STATUS RPCRT4_ParseHttpPrepareHeader1(RpcPktHdr *header, unsigned char *data, ULONG *field1);
RPC_STATUS RPCRT4_ParseHttpPrepareHeader2(RpcPktHdr *header, unsigned char *data, ULONG *field1, ULONG *bytes_until_next_packet, ULONG *field3);
RPC_STATUS RPCRT4_ParseHttpFlowControlHeader(RpcPktHdr *header, unsigned char *data, BOOL server, ULONG *bytes_transmitted, ULONG *flow_control_increment, UUID *pipe_uuid);
NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status);
RPC_STATUS RPCRT4_AuthorizeConnection(RpcConnection* conn, BYTE *challenge, ULONG count);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment