FREERDP_API void crypto_reverse(uint8* data, int length);
FREERDP_API void crypto_nonce(uint8* nonce, int size);
-FREERDP_API char* crypto_encode_base64(uint8* data, int length);
-FREERDP_API void crypto_base64_encode(uint8* data, int length, uint8** enc_data, int* res_length);
+FREERDP_API char* crypto_base64_encode(uint8* data, int length);
FREERDP_API void crypto_base64_decode(uint8* enc_data, int length, uint8** dec_data, int* res_length);
#endif /* FREERDP_CRYPTO_H */
HttpContext* http_context;
HttpRequest* http_request;
- base64_ntlm_token = crypto_encode_base64(ntlm_token->pvBuffer, ntlm_token->cbBuffer);
+ base64_ntlm_token = crypto_base64_encode(ntlm_token->pvBuffer, ntlm_token->cbBuffer);
if (strcmp(command, "RPC_IN_DATA") == 0)
http_context = rpc->http_in->context;
boolean rpc_out_send_CONN_A1(rdpRpc* rpc)
{
STREAM* s;
+ RTS_PDU_HEADER header;
uint32 ReceiveWindowSize;
+ header.rpc_vers = 5;
+ header.rpc_vers_minor = 0;
+ header.ptype = PTYPE_RTS;
+ header.pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
+ header.packed_drep[0] = 0x10;
+ header.packed_drep[1] = 0x00;
+ header.packed_drep[2] = 0x00;
+ header.packed_drep[3] = 0x00;
+ header.frag_length = 76;
+ header.auth_length = 0;
+ header.call_id = 0;
+ header.flags = 0;
+ header.numberOfCommands = 4;
+
DEBUG_RPC("Sending CONN_A1");
- s = stream_new(76);
+ s = stream_new(header.frag_length);
ReceiveWindowSize = 0x00010000;
rpc->virtualConnectionCookie = rpc_create_cookie(); /* 16 bytes */
rpc->OUTChannelCookie = rpc_create_cookie(); /* 16 bytes */
rpc->AwailableWindow = ReceiveWindowSize;
- rts_pdu_header_write(s, PFC_FIRST_FRAG | PFC_LAST_FRAG, 76, 0, 0, 0, 4); /* RTS Header (20 bytes) */
+ rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */
rts_version_command_write(s); /* Version (8 bytes) */
rts_cookie_command_write(s, rpc->virtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */
rts_cookie_command_write(s, rpc->OUTChannelCookie); /* OUTChannelCookie (20 bytes) */
rts_receive_window_size_command_write(s, ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */
stream_seal(s);
- rpc_out_write(rpc, s->data, stream_get_length(s));
+ rpc_out_write(rpc, s->data, s->size);
stream_free(s);
boolean rpc_in_send_CONN_B1(rdpRpc* rpc)
{
STREAM* s;
+ RTS_PDU_HEADER header;
uint8* AssociationGroupId;
+ header.rpc_vers = 5;
+ header.rpc_vers_minor = 0;
+ header.ptype = PTYPE_RTS;
+ header.pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
+ header.packed_drep[0] = 0x10;
+ header.packed_drep[1] = 0x00;
+ header.packed_drep[2] = 0x00;
+ header.packed_drep[3] = 0x00;
+ header.frag_length = 104;
+ header.auth_length = 0;
+ header.call_id = 0;
+ header.flags = 0;
+ header.numberOfCommands = 6;
+
DEBUG_RPC("Sending CONN_B1");
- s = stream_new(104);
+ s = stream_new(header.frag_length);
rpc->INChannelCookie = rpc_create_cookie(); /* 16 bytes */
AssociationGroupId = rpc_create_cookie(); /* 16 bytes */
- rts_pdu_header_write(s, PFC_FIRST_FRAG | PFC_LAST_FRAG, 104, 0, 0, 0, 6); /* RTS Header (20 bytes) */
+ rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */
rts_version_command_write(s); /* Version (8 bytes) */
rts_cookie_command_write(s, rpc->virtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */
rts_cookie_command_write(s, rpc->INChannelCookie); /* INChannelCookie (20 bytes) */
boolean rpc_in_send_keep_alive(rdpRpc* rpc)
{
- STREAM* s = stream_new(28);
-
- uint8 rpc_vers = 0x05;
- uint8 rpc_vers_minor = 0x00;
- uint8 ptype = PTYPE_RTS;
- uint8 pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
- uint32 packet_drep = 0x00000010;
- uint16 frag_length = 28;
- uint16 auth_length = 0;
- uint32 call_id = 0x00000000;
- uint16 flags = 0x0002;
- uint16 num_commands = 0x0001;
- uint32 ckCommandType = 0x00000005;
- uint32 ClientKeepalive = 0x00007530;
-
- stream_write_uint8(s, rpc_vers);
- stream_write_uint8(s, rpc_vers_minor);
- stream_write_uint8(s, ptype);
- stream_write_uint8(s, pfc_flags);
- stream_write_uint32(s, packet_drep);
- stream_write_uint16(s, frag_length);
- stream_write_uint16(s, auth_length);
- stream_write_uint32(s, call_id);
- stream_write_uint16(s, flags);
- stream_write_uint16(s, num_commands);
- stream_write_uint32(s, ckCommandType);
- stream_write_uint32(s, ClientKeepalive);
+ STREAM* s;
+ RTS_PDU_HEADER header;
+
+ header.rpc_vers = 5;
+ header.rpc_vers_minor = 0;
+ header.ptype = PTYPE_RTS;
+ header.pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
+ header.packed_drep[0] = 0x10;
+ header.packed_drep[1] = 0x00;
+ header.packed_drep[2] = 0x00;
+ header.packed_drep[3] = 0x00;
+ header.frag_length = 28;
+ header.auth_length = 0;
+ header.call_id = 0;
+ header.flags = 2;
+ header.numberOfCommands = 1;
+
+ s = stream_new(header.frag_length);
+ rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */
+ rts_client_keepalive_command_write(s, 0x00007530); /* ClientKeepalive (8 bytes) */
+ stream_seal(s);
- rpc_in_write(rpc, s->data, stream_get_length(s));
+ rpc_in_write(rpc, s->data, s->size);
stream_free(s);
return status;
}
-int rpc_rts_recv(rdpRpc* rpc, uint8* pdu, int length)
-{
- int i;
- uint32 CommandType;
- uint16 flags = *(uint16*)(pdu + 16);
- uint16 num_commands = *(uint16*)(pdu + 18);
- uint8* iterator = pdu + 20;
-
- if (flags & RTS_FLAG_PING)
- {
- rpc_in_send_keep_alive(rpc);
- return 0;
- }
-
- for (i = 0; i < num_commands; i++)
- {
- CommandType = *(uint32*) iterator;
-
- switch (CommandType)
- {
- case 0x00000000: /* ReceiveWindowSize */
- iterator += 8;
- break;
-
- case 0x00000001: /* FlowControlAck */
- iterator += 28;
- break;
-
- case 0x00000002: /* ConnectionTimeout */
- iterator += 8;
- break;
-
- case 0x00000003: /* Cookie */
- iterator += 20;
- break;
-
- case 0x00000004: /* ChannelLifetime */
- iterator += 8;
- break;
-
- case 0x00000005: /* ClientKeepalive */
- iterator += 8;
- break;
-
- case 0x00000006: /* Version */
- iterator += 8;
- break;
-
- case 0x00000007: /* Empty */
- iterator += 4;
- break;
-
- case 0x00000008: /* Padding */
- iterator += 8 + *(uint32*) (iterator + 4);
- break;
-
- case 0x00000009: /* NegativeANCE */
- iterator += 4;
- break;
-
- case 0x0000000a: /* ANCE */
- iterator += 4;
- break;
-
- case 0x0000000b: /* ClientAddress */
- iterator += 4 + 4 + (12 * (*(uint32*) (iterator + 4))) + 12;
- break;
-
- case 0x0000000c: /* AssociationGroupId */
- iterator += 20;
- break;
-
- case 0x0000000d: /* Destination */
- iterator += 8;
- break;
-
- case 0x0000000e: /* PingTrafficSentNotify */
- iterator += 8;
- break;
-
- default:
- printf(" Error: Unknown RTS CommandType: 0x%x\n", CommandType);
- return -1;
- }
- }
- return 0;
-}
-
int rpc_out_read(rdpRpc* rpc, uint8* data, int length)
{
+ STREAM* s;
int status;
uint8* pdu;
uint8 ptype;
if (ptype == 0x14) /* RTS PDU */
{
- rpc_rts_recv(rpc, pdu, frag_length);
+ s = stream_new(0);
+ stream_attach(s, pdu, frag_length);
+ rts_pdu_recv(rpc, s);
xfree(pdu);
return 0;
}
boolean rpc_attach(rdpRpc* rpc, rdpTcp* tcp_in, rdpTcp* tcp_out, rdpTls* tls_in, rdpTls* tls_out);
boolean rpc_connect(rdpRpc* rpc);
+boolean rpc_in_send_keep_alive(rdpRpc* rpc);
+
int rpc_write(rdpRpc* rpc, uint8* data, int length, uint16 opnum);
int rpc_read(rdpRpc* rpc, uint8* data, int length);
#include "rts.h"
-void rts_pdu_header_write(STREAM* s, uint8 pfc_flags, uint16 frag_length,
- uint16 auth_length, uint32 call_id, uint16 flags, uint16 numberOfCommands)
+void rts_pdu_header_write(STREAM* s, RTS_PDU_HEADER* header)
{
- stream_write_uint8(s, 5); /* rpc_vers (1 byte) */
- stream_write_uint8(s, 0); /* rpc_vers_minor (1 byte) */
- stream_write_uint8(s, PTYPE_RTS); /* PTYPE (1 byte) */
- stream_write_uint8(s, pfc_flags); /* pfc_flags (1 byte) */
- stream_write_uint32(s, 0x00000010); /* packet_drep (4 bytes) */
- stream_write_uint16(s, frag_length); /* frag_length (2 bytes) */
- stream_write_uint16(s, auth_length); /* auth_length (2 bytes) */
- stream_write_uint32(s, call_id); /* call_id (4 bytes) */
- stream_write_uint16(s, flags); /* flags (2 bytes) */
- stream_write_uint16(s, numberOfCommands); /* numberOfCommands (2 bytes) */
+ stream_write_uint8(s, header->rpc_vers); /* rpc_vers (1 byte) */
+ stream_write_uint8(s, header->rpc_vers_minor); /* rpc_vers_minor (1 byte) */
+ stream_write_uint8(s, header->ptype); /* PTYPE (1 byte) */
+ stream_write_uint8(s, header->pfc_flags); /* pfc_flags (1 byte) */
+ stream_write_uint8(s, header->packed_drep[0]); /* packet_drep[0] (1 byte) */
+ stream_write_uint8(s, header->packed_drep[1]); /* packet_drep[1] (1 byte) */
+ stream_write_uint8(s, header->packed_drep[2]); /* packet_drep[2] (1 byte) */
+ stream_write_uint8(s, header->packed_drep[3]); /* packet_drep[3] (1 byte) */
+ stream_write_uint16(s, header->frag_length); /* frag_length (2 bytes) */
+ stream_write_uint16(s, header->auth_length); /* auth_length (2 bytes) */
+ stream_write_uint32(s, header->call_id); /* call_id (4 bytes) */
+ stream_write_uint16(s, header->flags); /* flags (2 bytes) */
+ stream_write_uint16(s, header->numberOfCommands); /* numberOfCommands (2 bytes) */
}
void rts_receive_window_size_command_write(STREAM* s, uint32 receiveWindowSize)
stream_write_uint32(s, 1); /* Version (4 bytes) */
}
+void rts_padding_command_read(STREAM* s)
+{
+ uint32 ConformanceCount;
+
+ stream_read_uint32(s, ConformanceCount); /* ConformanceCount (4 bytes) */
+ stream_seek(s, ConformanceCount); /* Padding (variable) */
+}
+
void rts_association_group_id_command_write(STREAM* s, uint8* associationGroupId)
{
stream_write_uint32(s, RTS_CMD_ASSOCIATION_GROUP_ID); /* CommandType (4 bytes) */
stream_write(s, associationGroupId, 16); /* AssociationGroupId (16 bytes) */
}
+
+void rts_client_address_command_read(STREAM* s)
+{
+ uint32 AddressType;
+
+ stream_read_uint32(s, AddressType); /* ConformanceCount (4 bytes) */
+
+ if (AddressType == 0)
+ {
+ stream_seek(s, 4); /* ClientAddress (4 bytes) */
+ }
+ else
+ {
+ stream_seek(s, 16); /* ClientAddress (16 bytes) */
+ }
+
+ stream_seek(s, 12); /* padding (12 bytes) */
+}
+
+int rts_pdu_recv(rdpRpc* rpc, STREAM* s)
+{
+ int i;
+ uint16 flags;
+ uint32 CommandType;
+ uint16 numberOfCommands;
+
+ stream_seek_uint8(s); /* rpc_vers (1 byte) */
+ stream_seek_uint8(s); /* rpc_vers_minor (1 byte) */
+ stream_seek_uint8(s); /* PTYPE (1 byte) */
+ stream_seek_uint8(s); /* pfc_flags (1 byte) */
+ stream_seek_uint32(s); /* packet_drep (4 bytes) */
+ stream_seek_uint16(s); /* frag_length (2 bytes) */
+ stream_seek_uint16(s); /* auth_length (2 bytes) */
+ stream_seek_uint32(s); /* call_id (4 bytes) */
+ stream_read_uint16(s, flags); /* flags (2 bytes) */
+ stream_read_uint16(s, numberOfCommands); /* numberOfCommands (2 bytes) */
+
+ if (flags & RTS_FLAG_PING)
+ {
+ rpc_in_send_keep_alive(rpc);
+ return 0;
+ }
+
+ for (i = 0; i < numberOfCommands; i++)
+ {
+ stream_read_uint32(s, CommandType); /* CommandType (4 bytes) */
+
+ switch (CommandType)
+ {
+ case RTS_CMD_RECEIVE_WINDOW_SIZE:
+ stream_seek(s, 4);
+ break;
+
+ case RTS_CMD_FLOW_CONTROL_ACK:
+ stream_seek(s, 24);
+ break;
+
+ case RTS_CMD_CONNECTION_TIMEOUT:
+ stream_seek(s, 4);
+ break;
+
+ case RTS_CMD_COOKIE:
+ stream_seek(s, 16);
+ break;
+
+ case RTS_CMD_CHANNEL_LIFETIME:
+ stream_seek(s, 4);
+ break;
+
+ case RTS_CMD_CLIENT_KEEPALIVE:
+ stream_seek(s, 4);
+ break;
+
+ case RTS_CMD_VERSION:
+ stream_seek(s, 4);
+ break;
+
+ case RTS_CMD_EMPTY:
+ break;
+
+ case RTS_CMD_PADDING:
+ rts_padding_command_read(s);
+ break;
+
+ case RTS_CMD_NEGATIVE_ANCE:
+ break;
+
+ case RTS_CMD_ANCE:
+ break;
+
+ case RTS_CMD_CLIENT_ADDRESS:
+ rts_client_address_command_read(s);
+ break;
+
+ case RTS_CMD_ASSOCIATION_GROUP_ID:
+ stream_seek(s, 16);
+ break;
+
+ case RTS_CMD_DESTINATION:
+ stream_seek(s, 4);
+ break;
+
+ case RTS_CMD_PING_TRAFFIC_SENT_NOTIFY:
+ stream_seek(s, 4);
+ break;
+
+ default:
+ printf(" Error: Unknown RTS Command Type: 0x%x\n", CommandType);
+ return -1;
+ break;
+ }
+ }
+
+ return 0;
+}
#ifndef FREERDP_CORE_RTS_H
#define FREERDP_CORE_RTS_H
+#include "rpc.h"
+
#include <freerdp/types.h>
#include <freerdp/utils/stream.h>
#define RTS_CMD_DESTINATION 0x0000000D
#define RTS_CMD_PING_TRAFFIC_SENT_NOTIFY 0x0000000E
-void rts_pdu_header_write(STREAM* s, uint8 pfc_flags, uint16 frag_length,
- uint16 auth_length, uint32 call_id, uint16 flags, uint16 numberOfCommands);
+struct _rts_pdu_header
+{
+ uint8 rpc_vers;
+ uint8 rpc_vers_minor;
+ uint8 ptype;
+ uint8 pfc_flags;
+ uint8 packed_drep[4];
+ uint16 frag_length;
+ uint16 auth_length;
+ uint32 call_id;
+ uint16 flags;
+ uint16 numberOfCommands;
+};
+typedef struct _rts_pdu_header RTS_PDU_HEADER;
+
+void rts_pdu_header_write(STREAM* s, RTS_PDU_HEADER* header);
void rts_receive_window_size_command_write(STREAM* s, uint32 receiveWindowSize);
void rts_cookie_command_write(STREAM* s, uint8* cookie);
void rts_channel_lifetime_command_write(STREAM* s, uint32 channelLifetime);
void rts_client_keepalive_command_write(STREAM* s, uint32 clientKeepalive);
void rts_version_command_write(STREAM* s);
+void rts_padding_command_read(STREAM* s);
void rts_association_group_id_command_write(STREAM* s, uint8* associationGroupId);
+void rts_client_address_command_read(STREAM* s);
+
+int rts_pdu_recv(rdpRpc* rpc, STREAM* s);
#endif /* FREERDP_CORE_RTS_H */
xfree(fp);
}
-void crypto_base64_encode(uint8* data, int length, uint8** enc_data, int* res_length)
-{
- BIO *bmem, *b64;
- BUF_MEM *bptr;
-
- b64 = BIO_new(BIO_f_base64());
- BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
- bmem = BIO_new(BIO_s_mem());
- b64 = BIO_push(b64, bmem);
- BIO_write(b64, data, length);
- BIO_flush(b64);
- BIO_get_mem_ptr(b64, &bptr);
-
- *res_length = bptr->length - 1;
- *enc_data = xmalloc(*res_length);
- memcpy(*enc_data, bptr->data, *res_length);
-
- BIO_free_all(b64);
-}
-
-char* crypto_encode_base64(uint8* data, int length)
+char* crypto_base64_encode(uint8* data, int length)
{
BIO* bmem;
BIO* b64;
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, data, length);
- BIO_flush(b64);
+
+ if (BIO_flush(b64) < 1)
+ return NULL;
+
BIO_get_mem_ptr(b64, &bptr);
base64_string = xmalloc(bptr->length);