libfreerdp-core: implemented parsing of TsProxyCreateTunnel response

This commit is contained in:
Marc-André Moreau 2012-11-08 23:45:29 -05:00
parent e14aeb1d8a
commit 683e05a51b

View File

@ -170,7 +170,7 @@ DWORD TsProxySendToServer(handle_t IDL_handle, byte pRpcMessage[], UINT32 count,
return length;
}
BOOL tsg_proxy_create_tunnel(rdpTsg* tsg)
BOOL tsg_proxy_create_tunnel_write_request(rdpTsg* tsg)
{
int status;
BYTE* buffer;
@ -178,19 +178,6 @@ BOOL tsg_proxy_create_tunnel(rdpTsg* tsg)
UINT32 NapCapabilities;
rdpRpc* rpc = tsg->rpc;
/**
* OpNum = 1
*
* HRESULT TsProxyCreateTunnel(
* [in, ref] PTSG_PACKET tsgPacket,
* [out, ref] PTSG_PACKET* tsgPacketResponse,
* [out] PTUNNEL_CONTEXT_HANDLE_SERIALIZE* tunnelContext,
* [out] unsigned long* tunnelId
* );
*/
DEBUG_TSG("TsProxyCreateTunnel");
length = 108;
buffer = (BYTE*) malloc(length);
@ -230,22 +217,138 @@ BOOL tsg_proxy_create_tunnel(rdpTsg* tsg)
status = rpc_tsg_write(rpc, buffer, length, TsProxyCreateTunnelOpnum);
if (status <= 0)
{
printf("TsProxyCreateTunnel write failure\n");
return FALSE;
}
free(buffer);
return TRUE;
}
BOOL tsg_proxy_create_tunnel_read_response(rdpTsg* tsg)
{
int status;
BYTE* buffer;
UINT32 count;
UINT32 length;
UINT32 offset;
UINT32 Pointer;
PTSG_PACKET packet;
UINT32 SwitchValue;
rdpRpc* rpc = tsg->rpc;
PTSG_PACKET_CAPABILITIES tsgCaps;
PTSG_PACKET_VERSIONCAPS versionCaps;
PTSG_PACKET_CAPS_RESPONSE packetCapsResponse;
status = rpc_recv_pdu(rpc);
if (status <= 0)
return FALSE;
length = status;
buffer = rpc->buffer;
packet = (PTSG_PACKET) malloc(sizeof(TSG_PACKET));
ZeroMemory(packet, sizeof(TSG_PACKET));
packet->packetId = *((UINT32*) &buffer[28]); /* PacketId */
SwitchValue = *((UINT32*) &buffer[32]); /* SwitchValue */
if ((packet->packetId != TSG_PACKET_TYPE_CAPS_RESPONSE) ||
(SwitchValue != TSG_PACKET_TYPE_CAPS_RESPONSE))
{
printf("TsProxyCreateTunnel read failure\n");
printf("Unexpected PacketId: 0x%08X\n", packet->packetId);
return FALSE;
}
CopyMemory(tsg->TunnelContext, rpc->buffer + (status - 48), 16);
packetCapsResponse = (PTSG_PACKET_CAPS_RESPONSE) malloc(sizeof(TSG_PACKET_CAPS_RESPONSE));
ZeroMemory(packetCapsResponse, sizeof(TSG_PACKET_CAPS_RESPONSE));
packet->tsgPacket.packetCapsResponse = packetCapsResponse;
/* PacketQuarResponsePtr (4 bytes) */
packetCapsResponse->pktQuarEncResponse.flags = *((UINT32*) &buffer[40]); /* Flags */
packetCapsResponse->pktQuarEncResponse.certChainLen = *((UINT32*) &buffer[44]); /* CertChainLength */
/* CertChainDataPtr (4 bytes) */
CopyMemory(&packetCapsResponse->pktQuarEncResponse.nonce, &buffer[52], 16); /* Nonce */
offset = 68;
Pointer = *((UINT32*) &buffer[offset]); /* Ptr */
offset += 4;
if (Pointer == 0x0002000C)
{
/* Not sure exactly what this is */
offset += 4; /* 0x00000001 (4 bytes) */
offset += 4; /* 0x00000001 (4 bytes) */
offset += 4; /* 0x00000000 (4 bytes) */
offset += 4; /* 0x00000001 (4 bytes) */
}
Pointer = *((UINT32*) &buffer[offset]); /* Ptr (4 bytes): 0x00020014 */
offset += 4;
offset += 4; /* MaxCount (4 bytes) */
offset += 4; /* Offset (4 bytes) */
count = *((UINT32*) &buffer[offset]); /* ActualCount (4 bytes) */
offset += 4;
/*
* CertChainData is a wide character string, and the count is
* given in characters excluding the null terminator, therefore:
* size = ((count + 1) * 2)
*/
offset += ((count + 1) * 2); /* CertChainData */
versionCaps = (PTSG_PACKET_VERSIONCAPS) malloc(sizeof(TSG_PACKET_VERSIONCAPS));
ZeroMemory(versionCaps, sizeof(TSG_PACKET_VERSIONCAPS));
packetCapsResponse->pktQuarEncResponse.versionCaps = versionCaps;
versionCaps->tsgHeader.ComponentId = *((UINT16*) &buffer[offset]); /* ComponentId */
versionCaps->tsgHeader.PacketId = *((UINT16*) &buffer[offset + 2]); /* PacketId */
offset += 4;
if (versionCaps->tsgHeader.ComponentId != TS_GATEWAY_TRANSPORT)
{
printf("Unexpected ComponentId: 0x%04X\n", versionCaps->tsgHeader.ComponentId);
return FALSE;
}
Pointer = *((UINT32*) &buffer[offset]); /* TsgCapsPtr */
versionCaps->numCapabilities = *((UINT32*) &buffer[offset + 4]); /* NumCapabilities */
versionCaps->majorVersion = *((UINT16*) &buffer[offset + 8]); /* MajorVersion */
versionCaps->majorVersion = *((UINT16*) &buffer[offset + 10]); /* MinorVersion */
versionCaps->quarantineCapabilities = *((UINT16*) &buffer[offset + 12]); /* QuarantineCapabilities */
offset += 14;
/* 4-byte alignment */
rpc_offset_align(&offset, 4);
tsgCaps = (PTSG_PACKET_CAPABILITIES) malloc(sizeof(TSG_PACKET_CAPABILITIES));
ZeroMemory(tsgCaps, sizeof(TSG_PACKET_CAPABILITIES));
versionCaps->tsgCaps = tsgCaps;
offset += 4; /* MaxCount (4 bytes) */
tsgCaps->capabilityType = *((UINT32*) &buffer[offset]); /* CapabilityType */
SwitchValue = *((UINT32*) &buffer[offset + 4]); /* SwitchValue */
offset += 8;
if ((SwitchValue != TSG_CAPABILITY_TYPE_NAP) ||
(tsgCaps->capabilityType != TSG_CAPABILITY_TYPE_NAP))
{
printf("Unexpected CapabilityType: 0x%08X, Expected TSG_CAPABILITY_TYPE_NAP\n",
tsgCaps->capabilityType);
return FALSE;
}
tsgCaps->tsgPacket.tsgCapNap.capabilities = *((UINT32*) &buffer[offset]); /* Capabilities */
offset += 4;
/* ??? (16 bytes): all zeros */
offset += 16;
offset += 4; /* ContextType (4 bytes) */
CopyMemory(tsg->TunnelContext, &buffer[offset], 16); /* ContextUuid */
/* TODO: trailing bytes */
#ifdef WITH_DEBUG_TSG
printf("TSG TunnelContext:\n");
@ -253,6 +356,41 @@ BOOL tsg_proxy_create_tunnel(rdpTsg* tsg)
printf("\n");
#endif
free(tsgCaps);
free(versionCaps);
free(packetCapsResponse);
free(packet);
return TRUE;
}
BOOL tsg_proxy_create_tunnel(rdpTsg* tsg)
{
/**
* OpNum = 1
*
* HRESULT TsProxyCreateTunnel(
* [in, ref] PTSG_PACKET tsgPacket,
* [out, ref] PTSG_PACKET* tsgPacketResponse,
* [out] PTUNNEL_CONTEXT_HANDLE_SERIALIZE* tunnelContext,
* [out] unsigned long* tunnelId
* );
*/
DEBUG_TSG("TsProxyCreateTunnel");
if (!tsg_proxy_create_tunnel_write_request(tsg))
{
printf("TsProxyCreateTunnel: error writing request\n");
return FALSE;
}
if (!tsg_proxy_create_tunnel_read_response(tsg))
{
printf("TsProxyCreateTunnel: error reading response\n");
return FALSE;
}
return TRUE;
}